[PATCH 4/5] systemd-logind: Correctly deal with InputDevs sharing a device-node

Hans de Goede hdegoede at redhat.com
Wed Mar 12 08:08:16 PDT 2014


InputDevices may share a single device-node, this happens ie with Wacom
tablets.

This patch makes take_fd and release_fd properly deal with this, together
with the earlier patch for updating the fd in all matching xf86InputDevs
on pause / resume this completes support for such shared device-nodes.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 hw/xfree86/os-support/linux/systemd-logind.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index a2ef7af..62858b0 100644
--- a/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/hw/xfree86/os-support/linux/systemd-logind.c
@@ -87,6 +87,7 @@ systemd_logind_take_fd(int _major, int _minor, const char *path,
                        Bool *paused_ret)
 {
     struct systemd_logind_info *info = &logind_info;
+    InputInfoPtr pInfo;
     DBusError error;
     DBusMessage *msg = NULL;
     DBusMessage *reply = NULL;
@@ -102,6 +103,16 @@ systemd_logind_take_fd(int _major, int _minor, const char *path,
     if (strstr(path, "mouse"))
         return -1;
 
+    /* Check if we already have an InputInfo entry with this major, minor
+     * (shared device-nodes happen ie with Wacom tablets). */
+    pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor);
+    if (pInfo) {
+        LogMessage(X_INFO, "systemd-logind: returning pre-existing fd for %s %u:%u\n",
+               path, major, minor);
+        *paused_ret = FALSE;
+        return pInfo->fd;
+    }
+
     dbus_error_init(&error);
 
     msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
@@ -154,15 +165,31 @@ void
 systemd_logind_release_fd(int _major, int _minor)
 {
     struct systemd_logind_info *info = &logind_info;
+    InputInfoPtr pInfo;
     DBusError error;
     DBusMessage *msg = NULL;
     DBusMessage *reply = NULL;
     dbus_int32_t major = _major;
     dbus_int32_t minor = _minor;
+    int matches = 0;
 
     if (!info->session || major == 0)
         return;
 
+    /* Only release the fd if there is only 1 InputInfo left for this major
+     * and minor, otherwise other InputInfo's are still referencing the fd. */
+    pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor);
+    while (pInfo) {
+        matches++;
+        pInfo = systemd_logind_find_info_ptr_by_devnum(pInfo->next, major, minor);
+    }
+    if (matches > 1) {
+        LogMessage(X_INFO, "systemd-logind: not releasing fd for %u:%u, still in use\n", major, minor);
+        return;
+    }
+
+    LogMessage(X_INFO, "systemd-logind: releasing fd for %u:%u\n", major, minor);
+
     dbus_error_init(&error);
 
     msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
-- 
1.9.0



More information about the xorg-devel mailing list