evdev: Avoid double touch down/up events
authorJonas Ådahl <jadahl@gmail.com>
Mon, 24 Mar 2014 22:37:09 +0000 (23:37 +0100)
committerJonas Ådahl <jadahl@gmail.com>
Tue, 22 Apr 2014 21:45:38 +0000 (23:45 +0200)
When the kernel sends multiple touch down or touch up for the same slot
in a row, ignore any such subsequent event ensuring libinput always
produces 1 x touch down -> [n x touch motion] -> 1 x touch up event
series.

Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev.c

index 8d11e7f..2e0d1d7 100644 (file)
@@ -132,6 +132,12 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
                        break;
 
+               if (device->mt.slots[slot].seat_slot != -1) {
+                       log_bug("%s: Driver sent multiple touch down for the "
+                               "same slot", device->devnode);
+                       break;
+               }
+
                seat_slot = ffs(~seat->slot_map) - 1;
                device->mt.slots[slot].seat_slot = seat_slot;
 
@@ -162,6 +168,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                        break;
 
                seat_slot = device->mt.slots[slot].seat_slot;
+               device->mt.slots[slot].seat_slot = -1;
 
                if (seat_slot == -1)
                        break;
@@ -174,6 +181,12 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
                        break;
 
+               if (device->abs.seat_slot != -1) {
+                       log_bug("%s: Driver sent multiple touch down for the "
+                               "same slot", device->devnode);
+                       break;
+               }
+
                seat_slot = ffs(~seat->slot_map) - 1;
                device->abs.seat_slot = seat_slot;
 
@@ -209,6 +222,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                        break;
 
                seat_slot = device->abs.seat_slot;
+               device->abs.seat_slot = -1;
 
                if (seat_slot == -1)
                        break;
@@ -711,6 +725,7 @@ evdev_device_create(struct libinput_seat *seat,
        device->sysname = strdup(sysname);
        device->rel.dx = 0;
        device->rel.dy = 0;
+       device->abs.seat_slot = -1;
        device->dispatch = NULL;
        device->fd = fd;
        device->pending_event = EVDEV_NONE;