evdev: Ensure the libevdev object receives the new fd on resume
authorCarlos Garnacho <carlosg@gnome.org>
Tue, 9 Dec 2014 14:55:32 +0000 (15:55 +0100)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 10 Dec 2014 03:52:25 +0000 (13:52 +1000)
Otherwise, input_events will be attempted to read from the wrong place,
which also leaves the right/current fd with pending data to be read,
making the epoll fd wake up constantly.

Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev.c

index b32db6849e189450130b3648a99cd5d657972343..dce035ac42ec671dee15cc727733ffc2f44a06fc 100644 (file)
@@ -1986,6 +1986,8 @@ evdev_device_resume(struct evdev_device *device)
        struct libinput *libinput = device->base.seat->libinput;
        int fd;
        const char *devnode;
+       struct input_event ev;
+       enum libevdev_read_status status;
 
        if (device->fd != -1)
                return 0;
@@ -2012,6 +2014,20 @@ evdev_device_resume(struct evdev_device *device)
                        return -ENODEV;
        }
 
+       libevdev_change_fd(device->evdev, fd);
+       libevdev_set_clock_id(device->evdev, CLOCK_MONOTONIC);
+
+       /* re-sync libevdev's view of the device, but discard the actual
+          events. Our device is in a neutral state already */
+       libevdev_next_event(device->evdev,
+                           LIBEVDEV_READ_FLAG_FORCE_SYNC,
+                           &ev);
+       do {
+               status = libevdev_next_event(device->evdev,
+                                            LIBEVDEV_READ_FLAG_SYNC,
+                                            &ev);
+       } while (status == LIBEVDEV_READ_STATUS_SYNC);
+
        device->source =
                libinput_add_fd(libinput, fd, evdev_device_dispatch, device);
        if (!device->source) {