From 6ff352f5e34d3f25c53258cd37b6a17a1068dc42 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 20 Dec 2013 10:15:00 +1000 Subject: [PATCH] Promote touch frames to top-level events 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 --- src/evdev.c | 27 +++++++++++++++++++++++++++ src/libinput-private.h | 3 +++ src/libinput.c | 25 +++++++++++++++++++++++++ src/libinput.h | 28 +++++++++++++++++++++++----- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 43e6a107..012c887a 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -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; } } diff --git a/src/libinput-private.h b/src/libinput-private.h index a95967fd..0d7de903 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -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 */ diff --git a/src/libinput.c b/src/libinput.c index 45f922ec..6899163f 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -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) diff --git a/src/libinput.h b/src/libinput.h index 1df6cdd3..8980dabe 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -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