summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-03-12 14:57:24 +0100
committerHans de Goede <hdegoede@redhat.com>2014-03-13 13:11:52 +0100
commit0e972b6037d3709c13d46adef9d14b702f477abc (patch)
tree56532fad06dff9399fb437823fde2516eb8d5cf3
parent8d3f63dbe9bfd816beb6475fd0e00df4dbba269f (diff)
systemd-logind: Correctly deal with InputDevs sharing a device-node
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@redhat.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--hw/xfree86/os-support/linux/systemd-logind.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index a2ef7afba..62858b062 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,