evdev: Process touch up events of single-touch devices
authorNeil Roberts <neil@linux.intel.com>
Tue, 24 Sep 2013 19:05:07 +0000 (20:05 +0100)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 24 Sep 2013 23:22:43 +0000 (16:22 -0700)
Previously only the touch up key event was used for single-touch
devices and the touch down event was generated on the first motion
event. This was breaking if the touch up and down events were sent
without a motion in-between because the evdev driver wouldn't generate
a touch down event and Weston would lose track of the number of touch
points that are down. This patch changes it to track the up and down
key events as pending events similar to how it does for multi-touch
devices.

https://bugs.freedesktop.org/show_bug.cgi?id=69759

src/evdev.c
src/evdev.h

index c1e11d3..48e5470 100644 (file)
@@ -121,21 +121,25 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                notify_touch(master, time, slot, 0, 0,
                             WL_TOUCH_UP);
                goto handled;
+       case EVDEV_ABSOLUTE_TOUCH_DOWN:
+               transform_absolute(device, &cx, &cy);
+               weston_output_transform_coordinate(device->output,
+                                                  cx, cy, &x, &y);
+               notify_touch(master, time, 0, x, y, WL_TOUCH_DOWN);
+               goto handled;
        case EVDEV_ABSOLUTE_MOTION:
                transform_absolute(device, &cx, &cy);
                weston_output_transform_coordinate(device->output,
                                                   cx, cy, &x, &y);
 
-               if (device->caps & EVDEV_TOUCH) {
-                       if (master->num_tp == 0)
-                               notify_touch(master, time, 0,
-                                            x, y, WL_TOUCH_DOWN);
-                       else
-                               notify_touch(master, time, 0,
-                                            x, y, WL_TOUCH_MOTION);
-               } else
+               if (device->caps & EVDEV_TOUCH)
+                       notify_touch(master, time, 0, x, y, WL_TOUCH_MOTION);
+               else
                        notify_motion_absolute(master, time, x, y);
                goto handled;
+       case EVDEV_ABSOLUTE_TOUCH_UP:
+               notify_touch(master, time, 0, 0, 0, WL_TOUCH_UP);
+               goto handled;
        }
 
        assert(0 && "Unknown pending event type");
@@ -144,6 +148,18 @@ handled:
        device->pending_event = EVDEV_NONE;
 }
 
+static void
+evdev_process_touch_button(struct evdev_device *device, int time, int value)
+{
+       if (device->pending_event != EVDEV_NONE &&
+           device->pending_event != EVDEV_ABSOLUTE_MOTION)
+               evdev_flush_pending_event(device, time);
+
+       device->pending_event = (value ?
+                                EVDEV_ABSOLUTE_TOUCH_DOWN :
+                                EVDEV_ABSOLUTE_TOUCH_UP);
+}
+
 static inline void
 evdev_process_key(struct evdev_device *device, struct input_event *e, int time)
 {
@@ -151,6 +167,12 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time)
        if (e->value == 2)
                return;
 
+       if (e->code == BTN_TOUCH) {
+               if (!device->is_mt)
+                       evdev_process_touch_button(device, time, e->value);
+               return;
+       }
+
        evdev_flush_pending_event(device, time);
 
        switch (e->code) {
@@ -168,11 +190,6 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time)
                                         WL_POINTER_BUTTON_STATE_RELEASED);
                break;
 
-       case BTN_TOUCH:
-               if (e->value == 0 && !device->is_mt)
-                       notify_touch(device->seat, time, 0, 0, 0,
-                                    WL_TOUCH_UP);
-               break;
        default:
                notify_key(device->seat,
                           time, e->code,
index 6d91620..5e4d11a 100644 (file)
@@ -32,7 +32,9 @@
 
 enum evdev_event_type {
        EVDEV_NONE,
+       EVDEV_ABSOLUTE_TOUCH_DOWN,
        EVDEV_ABSOLUTE_MOTION,
+       EVDEV_ABSOLUTE_TOUCH_UP,
        EVDEV_ABSOLUTE_MT_DOWN,
        EVDEV_ABSOLUTE_MT_MOTION,
        EVDEV_ABSOLUTE_MT_UP,