diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-03-14 15:42:00 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-03-14 15:42:00 +1000 |
commit | a3b6e2079155c5774baabcd9e3c53b3336536e49 (patch) | |
tree | b5ab8ff3229115f80e078dc24702a565367420ee /src | |
parent | 43c82c3139ef8b9abee7eb79a8d9055df9874329 (diff) | |
parent | 69d3e9387105e0a92cae95f6f81a62e868506c06 (diff) | |
download | xf86-input-wacom-a3b6e2079155c5774baabcd9e3c53b3336536e49.tar.gz |
Merge branch 'race-condition'
Diffstat (limited to 'src')
-rw-r--r-- | src/wcmCommon.c | 9 | ||||
-rw-r--r-- | src/wcmConfig.c | 8 | ||||
-rw-r--r-- | src/wcmValidateDevice.c | 79 | ||||
-rw-r--r-- | src/xf86Wacom.c | 19 | ||||
-rw-r--r-- | src/xf86WacomDefs.h | 1 |
5 files changed, 93 insertions, 23 deletions
diff --git a/src/wcmCommon.c b/src/wcmCommon.c index e27120a..d024ad8 100644 --- a/src/wcmCommon.c +++ b/src/wcmCommon.c @@ -1198,17 +1198,16 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel, return; } - pInfo = tool->device; - DBG(11, common, "tool id=%d for %s\n", ds->device_type, pInfo->name); - /* Tool on the tablet when driver starts. This sometime causes * access errors to the device */ - if (!pInfo || !pInfo->dev || !pInfo->dev->enabled) - { + if (!tool->enabled) { xf86Msg(X_ERROR, "wcmEvent: tool not initialized yet. Skipping event. \n"); return; } + pInfo = tool->device; + DBG(11, common, "tool id=%d for %s\n", ds->device_type, pInfo->name); + filtered = pChannel->valid.state; /* Device transformations come first */ diff --git a/src/wcmConfig.c b/src/wcmConfig.c index 5d9d85b..2bf0ed3 100644 --- a/src/wcmConfig.c +++ b/src/wcmConfig.c @@ -249,6 +249,8 @@ static void wcmUninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) DBG(1, priv, "\n"); + /* Server 1.10 will UnInit all devices for us */ +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 if (priv->isParent) { /* HAL removal sees the parent device removed first. */ @@ -273,6 +275,7 @@ static void wcmUninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) free(pInfo->name); pInfo->name = NULL; } +#endif if (priv->tool) { @@ -337,6 +340,11 @@ static Bool wcmMatchDevice(InputInfoPtr pLocal, WacomCommonPtr *common_return) { DBG(2, priv, "port share between %s and %s\n", pLocal->name, pMatch->name); + /* FIXME: we loose the common->wcmTool here but it + * gets re-added during wcmParseOptions. This is + * currently required by the code, adding the tool + * again here means we trigger the duplicate tool + * detection */ wcmFreeCommon(&priv->common); priv->common = wcmRefCommon(privMatch->common); priv->next = priv->common->wcmDevices; diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c index 0d838fb..69bb3a3 100644 --- a/src/wcmValidateDevice.c +++ b/src/wcmValidateDevice.c @@ -380,35 +380,78 @@ static InputAttributes* wcmDuplicateAttributes(InputInfoPtr pInfo, #endif /** - * Hotplug one device of the given type. - * Device has the same options as the "parent" device, type is one of - * erasor, stylus, pad, touch, cursor, etc. - * Name of the new device is set automatically to "<device name> <type>". + * This struct contains the necessary info for hotplugging a device later. + * Memory must be freed after use. */ -static void wcmHotplug(InputInfoPtr pInfo, const char* basename, const char *type) -{ - DeviceIntPtr dev; /* dummy */ +typedef struct { InputOption *input_options; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9 - InputAttributes *attrs = NULL; + InputAttributes *attrs; #endif +} WacomHotplugInfo; - input_options = wcmOptionDupConvert(pInfo, basename, type); +/** + * Actually hotplug the device. This function is called by the server when + * the WorkProcs are processed. + * + * @param client The server client. unused + * @param closure A pointer to a struct WcmHotplugInfo containing the + * necessary information to create a new device. + * @return TRUE to remove this function from the server's work queue. + */ +static Bool +wcmHotplugDevice(ClientPtr client, pointer closure ) +{ + WacomHotplugInfo *hotplug_info = closure; + DeviceIntPtr dev; /* dummy */ -#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 11 - attrs = wcmDuplicateAttributes(pInfo, type); + NewInputDeviceRequest(hotplug_info->input_options, +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9 + hotplug_info->attrs, #endif + &dev); + wcmFreeInputOpts(hotplug_info->input_options); - NewInputDeviceRequest(input_options, -#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9 - attrs, +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 11 + FreeInputAttributes(hotplug_info->attrs); #endif - &dev); - wcmFreeInputOpts(input_options); + free(hotplug_info); + + return TRUE; +} + +/** + * Queue the hotplug for one tool/device of the given type. + * Device has the same options as the "parent" device, type is one of + * erasor, stylus, pad, touch, cursor, etc. + * Name of the new device is set automatically to "<device name> <type>". + * + * Note that we don't actually hotplug the device here. We store the + * information needed to hotplug the device later and then queue the + * hotplug. The server will come back and call the @wcmHotplugDevice + * later. + * + * @param pInfo The parent device + * @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) +{ + WacomHotplugInfo *hotplug_info; + + hotplug_info = calloc(1, sizeof(WacomHotplugInfo)); + + if (!hotplug_info) + { + xf86Msg(X_ERROR, "%s: OOM, cannot hotplug dependent devices\n", pInfo->name); + return; + } + hotplug_info->input_options = wcmOptionDupConvert(pInfo, basename, type); #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 11 - FreeInputAttributes(attrs); + hotplug_info->attrs = wcmDuplicateAttributes(pInfo, type); #endif + QueueWorkProc(wcmHotplugDevice, serverClient, hotplug_info); } void wcmHotplugOthers(InputInfoPtr pInfo, const char *basename) @@ -427,7 +470,7 @@ void wcmHotplugOthers(InputInfoPtr pInfo, const char *basename) if (skip) skip = 0; else - wcmHotplug(pInfo, basename, wcmType[i].type); + wcmQueueHotplug(pInfo, basename, wcmType[i].type); } } xf86Msg(X_INFO, "%s: hotplugging completed.\n", pInfo->name); diff --git a/src/xf86Wacom.c b/src/xf86Wacom.c index 0480d02..6762a3d 100644 --- a/src/xf86Wacom.c +++ b/src/xf86Wacom.c @@ -755,6 +755,23 @@ static void wcmDevClose(InputInfoPtr pInfo) } } +static void wcmEnableDisableTool(DeviceIntPtr dev, Bool enable) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + WacomDevicePtr priv = pInfo->private; + WacomToolPtr tool = priv->tool; + + tool->enabled = enable; +} + +static void wcmEnableTool(DeviceIntPtr dev) +{ + wcmEnableDisableTool(dev, TRUE); +} +static void wcmDisableTool(DeviceIntPtr dev) +{ + wcmEnableDisableTool(dev, FALSE); +} /***************************************************************************** * wcmDevProc -- * Handle the initialization, etc. of a wacom tablet. Called by the server @@ -791,12 +808,14 @@ static int wcmDevProc(DeviceIntPtr pWcm, int what) case DEVICE_ON: if (!wcmDevOpen(pWcm)) goto out; + wcmEnableTool(pWcm); xf86AddEnabledDevice(pInfo); pWcm->public.on = TRUE; break; case DEVICE_OFF: case DEVICE_CLOSE: + wcmDisableTool(pWcm); if (pInfo->fd >= 0) { xf86RemoveEnabledDevice(pInfo); diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h index 8f93211..e80afb0 100644 --- a/src/xf86WacomDefs.h +++ b/src/xf86WacomDefs.h @@ -491,6 +491,7 @@ struct _WacomTool int typeid; /* Tool type */ int serial; /* Serial id, 0 == no serial id */ + Bool enabled; InputInfoPtr device; /* The InputDevice connected to this tool */ }; |