[PATCH v2 12/14] systemd-logind: Add delayed input device probing

Hans de Goede hdegoede at redhat.com
Tue Feb 4 12:49:18 CET 2014


With systemd-logind we cannot probe input devices while switched away, so
if we're switched away, put the pInfo on a list, and probe everything on
that list on VT-Enter.

This is using an array grown by re-alloc, rather then an xorg_list since
creating a new data-type to store a pInfo + list-entry just for this seems
overkill.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 hw/xfree86/common/xf86Xinput.c               | 49 +++++++++++++++++++++++++---
 hw/xfree86/common/xf86Xinput.h               |  1 +
 hw/xfree86/os-support/linux/systemd-logind.c |  3 ++
 3 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 9ad07ca..317c771 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -105,6 +105,9 @@
 static int
  xf86InputDevicePostInit(DeviceIntPtr dev);
 
+static InputInfoPtr *new_input_devices;
+static int new_input_devices_count;
+
 /**
  * Eval config and modify DeviceVelocityRec accordingly
  */
@@ -839,10 +842,20 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
     }
 
     if (drv->capabilities & XI86_DRV_CAP_SERVER_FD) {
-        pInfo->fd = systemd_logind_take_fd(pInfo->major, pInfo->minor,
-                                           pInfo->attrs->device, &paused);
-        if (pInfo->fd != -1) {
-            /* FIXME handle paused */
+        int fd = systemd_logind_take_fd(pInfo->major, pInfo->minor,
+                                        pInfo->attrs->device, &paused);
+        if (fd != -1) {
+            if (paused) {
+                /* Put on new_input_devices list for delayed probe */
+                new_input_devices = xnfrealloc(new_input_devices,
+                            sizeof(pInfo) * (new_input_devices_count + 1));
+                new_input_devices[new_input_devices_count] = pInfo;
+                new_input_devices_count++;
+                systemd_logind_release_fd(pInfo->major, pInfo->minor);
+                close(fd);
+                return BadMatch;
+            }
+            pInfo->fd = fd;
             pInfo->flags |= XI86_SERVER_FD;
             pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);
         }
@@ -1493,4 +1506,32 @@ xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid, uint16_t type,
     QueueTouchEvents(dev, type, touchid, flags, mask);
 }
 
+void
+xf86inputEnableVTProbe(void)
+{
+    int i, is_auto = 0;
+    InputOption *option = NULL;
+    DeviceIntPtr pdev;
+
+    for (i = 0; i < new_input_devices_count; i++) {
+        InputInfoPtr pInfo = new_input_devices[i];
+
+        is_auto = 0;
+        nt_list_for_each_entry(option, pInfo->options, list.next) {
+            const char *key = input_option_get_key(option);
+            const char *value = input_option_get_value(option);
+
+            if (strcmp(key, "_source") == 0 &&
+                (strcmp(value, "server/hal") == 0 ||
+                 strcmp(value, "server/udev") == 0 ||
+                 strcmp(value, "server/wscons") == 0))
+                is_auto = 1;
+        }
+        xf86NewInputDevice(pInfo, &pdev,
+                                  (!is_auto ||
+                                   (is_auto && xf86Info.autoEnableDevices)));
+    }
+    new_input_devices_count = 0;
+}
+
 /* end of xf86Xinput.c */
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index bf81971..dcd3d93 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -179,6 +179,7 @@ extern _X_EXPORT void xf86AddEnabledDevice(InputInfoPtr pInfo);
 extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
 extern _X_EXPORT void xf86DisableDevice(DeviceIntPtr dev, Bool panic);
 extern _X_EXPORT void xf86EnableDevice(DeviceIntPtr dev);
+extern _X_EXPORT void xf86inputEnableVTProbe(void);
 
 /* not exported */
 int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto);
diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index 176defd..56f6c63 100644
--- a/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/hw/xfree86/os-support/linux/systemd-logind.c
@@ -198,6 +198,9 @@ systemd_logind_vtenter(void)
     for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
         if ((pInfo->flags & XI86_SERVER_FD) && pInfo->fd != -1)
             xf86EnableInputDeviceForVTSwitch(pInfo);
+
+    /* Do delayed input probing, this must be done after the above enabling */
+    xf86inputEnableVTProbe();
 }
 
 static InputInfoPtr
-- 
1.8.5.3



More information about the xorg-devel mailing list