summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-03-14 15:42:00 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-03-14 15:42:00 +1000
commita3b6e2079155c5774baabcd9e3c53b3336536e49 (patch)
treeb5ab8ff3229115f80e078dc24702a565367420ee /src
parent43c82c3139ef8b9abee7eb79a8d9055df9874329 (diff)
parent69d3e9387105e0a92cae95f6f81a62e868506c06 (diff)
downloadxf86-input-wacom-a3b6e2079155c5774baabcd9e3c53b3336536e49.tar.gz
Merge branch 'race-condition'
Diffstat (limited to 'src')
-rw-r--r--src/wcmCommon.c9
-rw-r--r--src/wcmConfig.c8
-rw-r--r--src/wcmValidateDevice.c79
-rw-r--r--src/xf86Wacom.c19
-rw-r--r--src/xf86WacomDefs.h1
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 */
};