diff options
Diffstat (limited to '')
-rw-r--r-- | x11/libinput/files/patch-src_evdev.c | 92 |
1 files changed, 84 insertions, 8 deletions
diff --git a/x11/libinput/files/patch-src_evdev.c b/x11/libinput/files/patch-src_evdev.c index 65fd54de6be3..79386c458c9e 100644 --- a/x11/libinput/files/patch-src_evdev.c +++ b/x11/libinput/files/patch-src_evdev.c @@ -1,11 +1,87 @@ ---- src/evdev.c.orig 2017-01-19 21:36:55 UTC +When a process without full /dev/input access enumerates devices via libudev-devd, +the udev_device structs do not get udev properties that mark them as inputs, keyboards, etc, +and get rejected as not being input devices. + +libinput reopens devices just to check path equality. +The udev_devices from reopening do have the right properties, +so we just use them instead of the original (enumerated) ones. + +--- src/evdev.c.orig 2018-06-09 12:13:43 UTC +++ src/evdev.c -@@ -25,6 +25,8 @@ +@@ -895,7 +895,7 @@ evdev_sync_device(struct evdev_device *device) + evdev_device_dispatch_one(device, &ev); + } while (rc == LIBEVDEV_READ_STATUS_SYNC); - #include "config.h" +- return rc == -EAGAIN ? 0 : rc; ++ return (rc == -EAGAIN || rc == -EINVAL)? 0 : rc; + } -+#include <sys/stat.h> -+ - #include <errno.h> - #include <stdbool.h> - #include <stdlib.h> + static void +@@ -933,6 +933,17 @@ evdev_device_dispatch(void *data) + + if (rc != -EAGAIN && rc != -EINTR) { + libinput_remove_source(libinput, device->source); ++ /* ++ * Dirty hack to allow cuse-based evdev backends to release ++ * character device file when device has been detached ++ * but still have it descriptor opened. ++ * Issuing evdev_device_suspend() here leads to SIGSEGV ++ */ ++ int dummy_fd = open("/dev/null", O_RDONLY | O_CLOEXEC); ++ if (dummy_fd >= 0) { ++ dup2(dummy_fd, device->fd); ++ close(dummy_fd); ++ } + device->source = NULL; + } + } +@@ -1785,9 +1796,9 @@ evdev_notify_added_device(struct evdev_device *device) + } + + static bool +-evdev_device_have_same_syspath(struct udev_device *udev_device, int fd) ++evdev_device_have_same_syspath(struct udev_device **udev_device, int fd, bool reopen) + { +- struct udev *udev = udev_device_get_udev(udev_device); ++ struct udev *udev = udev_device_get_udev(*udev_device); + struct udev_device *udev_device_new = NULL; + struct stat st; + bool rc = false; +@@ -1800,10 +1811,16 @@ evdev_device_have_same_syspath(struct udev_device *ude + goto out; + + rc = streq(udev_device_get_syspath(udev_device_new), +- udev_device_get_syspath(udev_device)); ++ udev_device_get_syspath(*udev_device)); + out: +- if (udev_device_new) +- udev_device_unref(udev_device_new); ++ if (udev_device_new) { ++ if (reopen) { ++ udev_device_unref(*udev_device); ++ *udev_device = udev_device_new; ++ } else { ++ udev_device_unref(udev_device_new); ++ } ++ } + return rc; + } + +@@ -2003,7 +2020,7 @@ evdev_device_create(struct libinput_seat *seat, + return NULL; + } + +- if (!evdev_device_have_same_syspath(udev_device, fd)) ++ if (!evdev_device_have_same_syspath(&udev_device, fd, true)) + goto err; + + device = zalloc(sizeof *device); +@@ -2559,7 +2576,7 @@ evdev_device_resume(struct evdev_device *device) + if (fd < 0) + return -errno; + +- if (!evdev_device_have_same_syspath(device->udev_device, fd)) { ++ if (!evdev_device_have_same_syspath(&device->udev_device, fd, false)) { + close_restricted(libinput, fd); + return -ENODEV; + } |