Promote touch frames to top-level events
authorPeter Hutterer <peter.hutterer@who-t.net>
Fri, 20 Dec 2013 00:15:00 +0000 (10:15 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 22 Jan 2014 01:16:28 +0000 (11:16 +1000)
These events are not a state of a single touchpoints but rather a notification
that all touchpoints finished processing. As such, they should have their own
type.

And make sure we actually send them when needed.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev.c
src/libinput-private.h
src/libinput.c
src/libinput.h

index 43e6a107ba40b9a44eb175af06e15b21814de4c4..012c887acca4f01a0fd7e140cca0f0180e8380b2 100644 (file)
@@ -368,12 +368,36 @@ evdev_process_absolute(struct evdev_device *device,
        }
 }
 
+static inline int
+evdev_need_touch_frame(struct evdev_device *device)
+{
+       switch (device->pending_event) {
+       case EVDEV_NONE:
+       case EVDEV_RELATIVE_MOTION:
+               break;
+       case EVDEV_ABSOLUTE_MT_DOWN:
+       case EVDEV_ABSOLUTE_MT_MOTION:
+       case EVDEV_ABSOLUTE_MT_UP:
+       case EVDEV_ABSOLUTE_TOUCH_DOWN:
+       case EVDEV_ABSOLUTE_TOUCH_UP:
+               return 1;
+       case EVDEV_ABSOLUTE_MOTION:
+               if (device->seat_caps & EVDEV_DEVICE_TOUCH)
+                       return 1;
+               break;
+       }
+
+       return 0;
+}
+
 static void
 fallback_process(struct evdev_dispatch *dispatch,
                 struct evdev_device *device,
                 struct input_event *event,
                 uint32_t time)
 {
+       int need_frame = 0;
+
        switch (event->type) {
        case EV_REL:
                evdev_process_relative(device, event, time);
@@ -385,7 +409,10 @@ fallback_process(struct evdev_dispatch *dispatch,
                evdev_process_key(device, event, time);
                break;
        case EV_SYN:
+               need_frame = evdev_need_touch_frame(device);
                evdev_flush_pending_event(device, time);
+               if (need_frame)
+                       touch_notify_frame(&device->base, time);
                break;
        }
 }
index a95967fdbe93639ee6f9f6c96c4e048be0e3a92f..0d7de903159daa40d63a9a3fdbb02b16e77a7a3c 100644 (file)
@@ -152,4 +152,7 @@ touch_notify_touch(struct libinput_device *device,
                   li_fixed_t y,
                   enum libinput_touch_type touch_type);
 
+void
+touch_notify_frame(struct libinput_device *device,
+                  uint32_t time);
 #endif /* LIBINPUT_PRIVATE_H */
index 45f922ecb915cee589e42e4302152042f1e339a9..6899163f2d5cc170d57db05f71ed9e0b8aeaae1a 100644 (file)
@@ -123,6 +123,7 @@ libinput_event_get_pointer_event(struct libinput_event *event)
        case LIBINPUT_EVENT_POINTER_AXIS:
                return (struct libinput_event_pointer*)event;
        case LIBINPUT_EVENT_TOUCH_TOUCH:
+       case LIBINPUT_EVENT_TOUCH_FRAME:
                break;
        }
 
@@ -145,6 +146,7 @@ libinput_event_get_keyboard_event(struct libinput_event *event)
        case LIBINPUT_EVENT_POINTER_BUTTON:
        case LIBINPUT_EVENT_POINTER_AXIS:
        case LIBINPUT_EVENT_TOUCH_TOUCH:
+       case LIBINPUT_EVENT_TOUCH_FRAME:
                break;
        }
 
@@ -166,6 +168,7 @@ libinput_event_get_touch_event(struct libinput_event *event)
        case LIBINPUT_EVENT_POINTER_AXIS:
                break;
        case LIBINPUT_EVENT_TOUCH_TOUCH:
+       case LIBINPUT_EVENT_TOUCH_FRAME:
                return (struct libinput_event_touch*)event;
        }
 
@@ -187,6 +190,7 @@ libinput_event_get_device_notify_event(struct libinput_event *event)
        case LIBINPUT_EVENT_POINTER_BUTTON:
        case LIBINPUT_EVENT_POINTER_AXIS:
        case LIBINPUT_EVENT_TOUCH_TOUCH:
+       case LIBINPUT_EVENT_TOUCH_FRAME:
                break;
        }
 
@@ -445,6 +449,7 @@ libinput_event_get_class(struct libinput_event *event)
        case LIBINPUT_EVENT_POINTER_BUTTON:
        case LIBINPUT_EVENT_POINTER_AXIS:
        case LIBINPUT_EVENT_TOUCH_TOUCH:
+       case LIBINPUT_EVENT_TOUCH_FRAME:
                return LIBINPUT_EVENT_CLASS_DEVICE;
        }
 
@@ -816,6 +821,26 @@ touch_notify_touch(struct libinput_device *device,
                          &touch_event->base);
 }
 
+void
+touch_notify_frame(struct libinput_device *device,
+                  uint32_t time)
+{
+       struct libinput_event_touch *touch_event;
+
+       touch_event = zalloc(sizeof *touch_event);
+       if (!touch_event)
+               return;
+
+       *touch_event = (struct libinput_event_touch) {
+               .time = time,
+       };
+
+       post_device_event(device,
+                         LIBINPUT_EVENT_TOUCH_FRAME,
+                         &touch_event->base);
+}
+
+
 static void
 libinput_post_event(struct libinput *libinput,
                    struct libinput_event *event)
index 1df6cdd341c22056ea339709fe213c7deabb6e91..8980dabee9649e9c5844eec19c0f25f21319b536 100644 (file)
@@ -105,15 +105,11 @@ enum libinput_pointer_axis {
  * sequence down, motion, up, with the number of motion events being zero or
  * greater. If a touch point was used for gesture interpretation internally
  * and will not generate any further events, the touchpoint is cancelled.
- *
- * A frame event is set after a set of touchpoints that constitute one
- * logical set of points at a sampling point.
  */
 enum libinput_touch_type {
        LIBINPUT_TOUCH_TYPE_DOWN = 0,
        LIBINPUT_TOUCH_TYPE_UP = 1,
        LIBINPUT_TOUCH_TYPE_MOTION = 2,
-       LIBINPUT_TOUCH_TYPE_FRAME = 3,
        LIBINPUT_TOUCH_TYPE_CANCEL = 4
 };
 
@@ -134,7 +130,12 @@ enum libinput_event_type {
        LIBINPUT_EVENT_POINTER_BUTTON,
        LIBINPUT_EVENT_POINTER_AXIS,
 
-       LIBINPUT_EVENT_TOUCH_TOUCH = 500
+       LIBINPUT_EVENT_TOUCH_TOUCH = 500,
+       /**
+        * Signals the end of a set of touchpoints at one device sample
+        * time. This event has no coordinate information attached.
+        */
+       LIBINPUT_EVENT_TOUCH_FRAME
 };
 
 struct libinput;
@@ -145,6 +146,15 @@ struct libinput_event;
 struct libinput_event_device_notify;
 struct libinput_event_keyboard;
 struct libinput_event_pointer;
+
+/**
+ * @ingroup event_touch
+ * @struct libinput_event_touch
+ *
+ * Touch event representing a touch down, move or up, as well as a touch
+ * cancel and touch frame events. Valid event types for this event are @ref
+ * LIBINPUT_EVENT_TOUCH_TOUCH and @ref LIBINPUT_EVENT_TOUCH_FRAME.
+ */
 struct libinput_event_touch;
 
 /**
@@ -491,6 +501,8 @@ libinput_event_touch_get_time(
  * Get the currently active slot on this device. See the kernel's multitouch
  * protocol B documentation for more information.
  *
+ * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME.
+ *
  * @return The currently active slot on this multitouch device
  */
 uint32_t
@@ -500,6 +512,8 @@ libinput_event_touch_get_slot(
 /**
  * @ingroup event_touch
  *
+ * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME.
+ *
  * @return the absolute X coordinate on this touch device, scaled to screen coordinates.
  */
 li_fixed_t
@@ -509,6 +523,8 @@ libinput_event_touch_get_x(
 /**
  * @ingroup event_touch
  *
+ * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME.
+ *
  * @return the absolute X coordinate on this touch device, scaled to screen coordinates.
  */
 li_fixed_t
@@ -518,6 +534,8 @@ libinput_event_touch_get_y(
 /**
  * @ingroup event_touch
  *
+ * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME.
+ *
  * @return the type of touch that occured on the device
  */
 enum libinput_touch_type