The current approach to hotplugging is to call NIDR directly from the parent
device's PreInit. This causes a nested device layout as the dependent
devices are initialised fully before the parent device is initialised.

Switch to a WorkProc instead. Copy the necessary information to create a new
device later and tell the server to call the actual hotplug function when it
has time.

Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
---
 src/wcmValidateDevice.c |   79 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 61 insertions(+), 18 deletions(-)

diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c
index 1b6c4e2..cc1f678 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);
-- 
1.7.4


------------------------------------------------------------------------------
Free Software Download: Index, Search & Analyze Logs and other IT data in 
Real-Time with Splunk. Collect, index and harness all the fast moving IT data 
generated by your applications, servers and devices whether physical, virtual
or in the cloud. Deliver compliance at lower cost and gain new business 
insights. http://p.sf.net/sfu/splunk-dev2dev 
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to