From: Alexia Death <alexiade...@gmail.com> Provide a new "ToolSerials" option which describes tools that should be automatically hotplugged along with the standard devices. This is achieved by parsing "ToolSerials" while the master device is being initialized to create a WacomTool list. This list is then used while hotplugging child devices to create tool-specific devices with the "Serial" option set appropriately.
The "ToolSerials" option should be added to the 50-wacom.conf file in /etc/X11/xorg.conf.d so that it is applied to hotplugged tablets. The option takes the following format: Option "ToolSerials" "serial[,type[,label]][;...]" Or, for a more concrete example: Option "ToolSerials" "113246231,airbrush,Airbrush;85983311,artpen,Artpen" ToolSerials recognizes the "pen", "airbrush", "artpen", and "cursor" types. Unknown (or unspecified) types default to creating "pen"-type tools with both 'stylus' and 'eraser' devices. Signed-off-by: Alexia Death <alexiade...@gmail.com> Acked-by: Jason Gerecke <killert...@gmail.com> --- src/wcmCommon.c | 7 ++ src/wcmValidateDevice.c | 144 +++++++++++++++++++++++++++++++++++++++++++++-- src/xf86Wacom.h | 2 + src/xf86WacomDefs.h | 21 +++++++ 4 files changed, 169 insertions(+), 5 deletions(-) diff --git a/src/wcmCommon.c b/src/wcmCommon.c index 99e2bb6..822306c 100644 --- a/src/wcmCommon.c +++ b/src/wcmCommon.c @@ -1390,6 +1390,13 @@ void wcmFreeCommon(WacomCommonPtr *ptr) if (--common->refcnt == 0) { free(common->private); + while (--common->nserials >= 0) + { + DBG(10, common, "Free common serial %d: %d %s\n", common->nserials, + common->serials[common->nserials]->serial, + common->serials[common->nserials]->name); + free(common->serials[common->nserials]); + } free(common); } *ptr = NULL; diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c index 7fcc351..1a67994 100644 --- a/src/wcmValidateDevice.c +++ b/src/wcmValidateDevice.c @@ -306,9 +306,12 @@ int wcmDeviceTypeKeys(InputInfoPtr pInfo) /** * Duplicate xf86 options, replace the "type" option with the given type * (and the name with "$name $type" and convert them to InputOption */ -static InputOption *wcmOptionDupConvert(InputInfoPtr pInfo, const char* basename, const char *type) +static InputOption *wcmOptionDupConvert(InputInfoPtr pInfo, const char* basename, const char *type, int iserial) { + WacomDevicePtr priv = pInfo->private; + WacomCommonPtr common = priv->common; pointer original = pInfo->options; + WacomToolSerialPtr ser = common->serials[iserial]; InputOption *iopts = NULL, *new; char *name; pointer options; @@ -325,13 +328,26 @@ static InputOption *wcmOptionDupConvert(InputInfoPtr pInfo, const char* basename options = dummy.options; } #endif + if (iserial > -1) + { + + if (strlen(ser->name) > 0) + rc = asprintf(&name, "%s %s %s", basename, ser->name, type); + else + rc = asprintf(&name, "%s %d %s", basename, ser->serial, type); + } + else + rc = asprintf(&name, "%s %s", basename, type); - rc = asprintf(&name, "%s %s", basename, type); if (rc == -1) /* if asprintf fails, strdup will probably too... */ name = strdup("unknown"); options = xf86ReplaceStrOption(options, "Type", type); options = xf86ReplaceStrOption(options, "Name", name); + + if (iserial > -1) + options = xf86ReplaceIntOption(options, "Serial", ser->serial); + free(name); while(options) @@ -435,7 +451,7 @@ wcmHotplugDevice(ClientPtr client, pointer closure ) * @param basename The base name for the device (type will be appended) * @param type Type name for this tool */ -static void wcmQueueHotplug(InputInfoPtr pInfo, const char* basename, const char *type) +static void wcmQueueHotplug(InputInfoPtr pInfo, const char* basename, const char *type, int iserial) { WacomHotplugInfo *hotplug_info; @@ -447,13 +463,42 @@ static void wcmQueueHotplug(InputInfoPtr pInfo, const char* basename, const char return; } - hotplug_info->input_options = wcmOptionDupConvert(pInfo, basename, type); + hotplug_info->input_options = wcmOptionDupConvert(pInfo, basename, type, iserial); #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 11 hotplug_info->attrs = wcmDuplicateAttributes(pInfo, type); #endif QueueWorkProc(wcmHotplugDevice, serverClient, hotplug_info); } +void wcmHotplugSerials(InputInfoPtr pInfo, const char *basename) +{ + WacomDevicePtr priv = (WacomDevicePtr)pInfo->private; + WacomCommonPtr common = priv->common; + int i; + + if (common->nserials > 0) + { + for (i = 0; i < common->nserials; i++) + { + WacomToolSerialPtr ser = common->serials[i]; + xf86Msg(X_INFO, "%s: hotplugging serial %d.\n", pInfo->name, ser->serial); + + if (wcmIsAValidType(pInfo, "stylus") && + (ser->types & SERIAL_HAS_STYLUS)) + wcmQueueHotplug(pInfo, basename, "stylus", i); + + if (wcmIsAValidType(pInfo, "eraser") && + (ser->types & SERIAL_HAS_ERASER)) + wcmQueueHotplug(pInfo, basename, "eraser", i); + + if (wcmIsAValidType(pInfo, "cursor") && + (ser->types & SERIAL_HAS_CURSOR)) + wcmQueueHotplug(pInfo, basename, "cursor", i); + } + } + +} + void wcmHotplugOthers(InputInfoPtr pInfo, const char *basename) { int i, skip = 1; @@ -470,9 +515,12 @@ void wcmHotplugOthers(InputInfoPtr pInfo, const char *basename) if (skip) skip = 0; else - wcmQueueHotplug(pInfo, basename, wcmType[i].type); + wcmQueueHotplug(pInfo, basename, wcmType[i].type, -1); } } + + wcmHotplugSerials(pInfo, basename); + xf86Msg(X_INFO, "%s: hotplugging completed.\n", pInfo->name); } @@ -520,6 +568,88 @@ int wcmNeedAutoHotplug(InputInfoPtr pInfo, const char **type) return 1; } +int wcmParseSerials (InputInfoPtr pInfo) +{ + WacomDevicePtr priv = (WacomDevicePtr)pInfo->private; + WacomCommonPtr common = priv->common; + char *s; + + if (common->nserials > 0) + { + return 0; /*Parsing has been already done*/ + } + + s = xf86SetStrOption(pInfo->options, "ToolSerials", NULL); + if (s) /*Dont parse again, if the commons have values already*/ + { + int nserials = 0; + char* tok = strtok(s, ";"); + while ((tok != NULL) && (nserials < WCM_MAX_SERIALS)) + { + int serial, nmatch; + char type[strlen(tok) + 1]; + char name[strlen(tok) + 1]; + WacomToolSerialPtr ser = calloc(1, sizeof(WacomToolSerial)); + + if (ser == NULL) + return 1; + + nmatch = sscanf(tok,"%d,%[a-z],%[A-Za-z ]",&serial, type, name); + + if (nmatch < 1) + { + xf86Msg(X_ERROR, "%s: %s is invalid serial string.\n", + pInfo->name, tok); + return 1; + } + + if (nmatch >= 1) + { + xf86Msg(X_CONFIG, "%s: Tool serial %d found.\n", + pInfo->name, serial); + + ser->serial = serial; + + ser->types = SERIAL_HAS_STYLUS | SERIAL_HAS_ERASER; /*Default to both tools*/ + } + + if (nmatch >= 2) + { + xf86Msg(X_CONFIG, "%s: Tool %d has type %s.\n", + pInfo->name, serial, type); + if ((strcmp(type, "pen") == 0) || (strcmp(type, "airbrush") == 0)) + ser->types = SERIAL_HAS_STYLUS | SERIAL_HAS_ERASER; + else if (strcmp(type, "artpen") == 0) + ser->types = SERIAL_HAS_STYLUS; + else if (strcmp(type, "cursor") == 0) + ser->types = SERIAL_HAS_CURSOR; + else xf86Msg(X_CONFIG, "%s: Invalid type %s, defaulting to pen.\n", + pInfo->name, type); + } + + if (nmatch == 3) + { + xf86Msg(X_CONFIG, "%s: Tool %d is named %s.\n", + pInfo->name, serial, name); + ser->name = strdup(name); + } + else ser->name = ""; /*no name yet*/ + + common->serials[nserials] = ser; + + tok = strtok(NULL,";"); + nserials++; + } + common->nserials = nserials; + + if ((nserials == WCM_MAX_SERIALS) && (tok != NULL)) + xf86Msg(X_CONFIG, "%s: Only %d tool serials supported, ignored the rest.\n", + pInfo->name, WCM_MAX_SERIALS); + + } + return 0; +} + /** * Parse the options for this device. * Note that parameters is_primary and is_dependent are mutually exclusive, @@ -641,6 +771,10 @@ Bool wcmParseOptions(InputInfoPtr pInfo, Bool is_primary, Bool is_dependent) wcmSetPressureCurve(priv,a,b,c,d); } + /*Serials of tools we want hotpluged*/ + if (wcmParseSerials (pInfo) != 0) + goto error; + if (IsCursor(priv)) { common->wcmCursorProxoutDist = xf86SetIntOption(pInfo->options, "CursorProx", 0); diff --git a/src/xf86Wacom.h b/src/xf86Wacom.h index 72c7b62..6834844 100644 --- a/src/xf86Wacom.h +++ b/src/xf86Wacom.h @@ -137,10 +137,12 @@ extern int wcmDeviceTypeKeys(InputInfoPtr pInfo); /* hotplug */ extern int wcmNeedAutoHotplug(InputInfoPtr pInfo, const char **type); +extern void wcmHotplugSerials(InputInfoPtr pInfo, const char *basename); extern void wcmHotplugOthers(InputInfoPtr pInfo, const char *basename); /* setup */ extern Bool wcmParseOptions(InputInfoPtr pInfo, Bool is_primary, Bool is_dependent); +extern int wcmParseSerials(InputInfoPtr pinfo); extern void wcmInitialCoordinates(InputInfoPtr pInfo, int axes); extern void wcmInitialScreens(InputInfoPtr pInfo); extern void wcmInitialScreens(InputInfoPtr pInfo); diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h index 755f4cc..f045762 100644 --- a/src/xf86WacomDefs.h +++ b/src/xf86WacomDefs.h @@ -117,6 +117,8 @@ typedef struct _WacomFilterState WacomFilterState, *WacomFilterStatePtr; typedef struct _WacomDeviceClass WacomDeviceClass, *WacomDeviceClassPtr; typedef struct _WacomTool WacomTool, *WacomToolPtr; typedef struct _WacomToolArea WacomToolArea, *WacomToolAreaPtr; +typedef struct _WacomToolSerial WacomToolSerial, *WacomToolSerialPtr; + /****************************************************************************** * WacomModel - model-specific device capabilities @@ -197,6 +199,8 @@ struct _WacomModel * For backword compability support, * tablet buttons besides the strips are * treated as buttons */ +#define WCM_MAX_SERIALS 32 /* maximum number of tool serials to be hotplugged */ + /* get/set/property */ typedef struct _PROPINFO PROPINFO; @@ -409,6 +413,10 @@ enum WacomProtocol { WCM_PROTOCOL_5 }; +#define SERIAL_HAS_ERASER 1 +#define SERIAL_HAS_STYLUS 2 +#define SERIAL_HAS_CURSOR 4 + struct _WacomCommonRec { /* Do not move device_path, same offset as priv->name. Used by DBG macro */ @@ -482,6 +490,8 @@ struct _WacomCommonRec void *private; /* backend-specific information */ WacomToolPtr wcmTool; /* List of unique tools */ + WacomToolSerialPtr serials[WCM_MAX_SERIALS];/* Serial numbers provided at startup*/ + int nserials; /*Number of serials configured*/ /* DO NOT TOUCH THIS. use wcmRefCommon() instead */ int refcnt; /* number of devices sharing this struct */ @@ -503,6 +513,17 @@ struct _WacomTool InputInfoPtr device; /* The InputDevice connected to this tool */ }; +/****************************************************************************** + * WacomToolSerial + *****************************************************************************/ +struct _WacomToolSerial +{ + + uint serial; /* Serial id */ + uint types; /* Tool types this serial has */ + char *name; /* Label for the tool*/ +}; + #endif /*__XF86_XF86WACOMDEFS_H */ /* vim: set noexpandtab tabstop=8 shiftwidth=8: */ -- 1.7.4.1 ------------------------------------------------------------------------------ Benefiting from Server Virtualization: Beyond Initial Workload Consolidation -- Increasing the use of server virtualization is a top priority.Virtualization can reduce costs, simplify management, and improve application availability and disaster protection. Learn more about boosting the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel