From 98b1e212ac458ab0c1757b276a5128b575adfe05 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Mar 2015 15:24:04 +0100 Subject: touchpad: Extend the touchpad gesture API with pinch gestures Extend the touchpad gesture API with pinch gestures. Note that this new API offers a single event stream for both pinch and rotate data, this is deliberate as some applications may be interested in getting both at the same time. Applications which are only interested in one or the other can simply ignore the other. Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer Acked-by: Jason Gerecke --- src/libinput-private.h | 9 ++++++ src/libinput.c | 61 +++++++++++++++++++++++++++++++++----- src/libinput.h | 80 ++++++++++++++++++++++++++++++++++++++++++-------- src/libinput.sym | 2 ++ test/litest.c | 9 ++++++ tools/event-debug.c | 27 ++++++++++++++++- tools/event-gui.c | 3 ++ 7 files changed, 170 insertions(+), 21 deletions(-) diff --git a/src/libinput-private.h b/src/libinput-private.h index d0299c61..9a2643cf 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -373,6 +373,15 @@ gesture_notify_swipe(struct libinput_device *device, const struct normalized_coords *delta, const struct normalized_coords *unaccel); +void +gesture_notify_pinch(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + const struct normalized_coords *delta, + const struct normalized_coords *unaccel, + double scale, + double angle); + void touch_notify_frame(struct libinput_device *device, uint64_t time); diff --git a/src/libinput.c b/src/libinput.c index ceb47387..84e623f1 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -120,6 +120,8 @@ struct libinput_event_gesture { int finger_count; struct normalized_coords delta; struct normalized_coords delta_unaccel; + double scale; + double angle; }; static void @@ -253,7 +255,10 @@ libinput_event_get_gesture_event(struct libinput_event *event) NULL, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, - LIBINPUT_EVENT_GESTURE_SWIPE_END); + LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END); return (struct libinput_event_gesture *) event; } @@ -696,6 +701,18 @@ libinput_event_gesture_get_dy_unaccelerated( return event->delta_unaccel.y; } +LIBINPUT_EXPORT double +libinput_event_gesture_get_scale(struct libinput_event_gesture *event) +{ + return event->scale; +} + +LIBINPUT_EXPORT double +libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event) +{ + return event->angle; +} + struct libinput_source * libinput_add_fd(struct libinput *libinput, int fd, @@ -1404,13 +1421,15 @@ touch_notify_frame(struct libinput_device *device, &touch_event->base); } -void -gesture_notify_swipe(struct libinput_device *device, - uint64_t time, - enum libinput_event_type type, - int finger_count, - const struct normalized_coords *delta, - const struct normalized_coords *unaccel) +static void +gesture_notify(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + int finger_count, + const struct normalized_coords *delta, + const struct normalized_coords *unaccel, + double scale, + double angle) { struct libinput_event_gesture *gesture_event; @@ -1426,12 +1445,38 @@ gesture_notify_swipe(struct libinput_device *device, .finger_count = finger_count, .delta = *delta, .delta_unaccel = *unaccel, + .scale = scale, + .angle = angle, }; post_device_event(device, time, type, &gesture_event->base); } +void +gesture_notify_swipe(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + int finger_count, + const struct normalized_coords *delta, + const struct normalized_coords *unaccel) +{ + gesture_notify(device, time, type, finger_count, delta, unaccel, + 0.0, 0.0); +} + +void +gesture_notify_pinch(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + const struct normalized_coords *delta, + const struct normalized_coords *unaccel, + double scale, + double angle) +{ + gesture_notify(device, time, type, 2, delta, unaccel, scale, angle); +} + static void libinput_post_event(struct libinput *libinput, struct libinput_event *event) diff --git a/src/libinput.h b/src/libinput.h index 5cc7a4c5..e1a2dd7e 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -182,6 +182,9 @@ enum libinput_event_type { LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN = 800, LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, }; /** @@ -988,8 +991,8 @@ libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event); * @ingroup event_gesture * * Return the delta between the last event and the current event. For gesture - * events that are not of type @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, this - * function returns 0. + * events that are not of type @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, this function returns 0. * * If a device employs pointer acceleration, the delta returned by this * function is the accelerated delta. @@ -998,7 +1001,8 @@ libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event); * 1000dpi resolution. See @ref motion_normalization for more details. * * @note It is an application bug to call this function for events other than - * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE. + * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE. * * @return the relative x movement since the last event */ @@ -1009,8 +1013,8 @@ libinput_event_gesture_get_dx(struct libinput_event_gesture *event); * @ingroup event_gesture * * Return the delta between the last event and the current event. For gesture - * events that are not of type @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, this - * function returns 0. + * events that are not of type @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, this function returns 0. * * If a device employs pointer acceleration, the delta returned by this * function is the accelerated delta. @@ -1019,7 +1023,8 @@ libinput_event_gesture_get_dx(struct libinput_event_gesture *event); * 1000dpi resolution. See @ref motion_normalization for more details. * * @note It is an application bug to call this function for events other than - * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE. + * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE. * * @return the relative y movement since the last event */ @@ -1030,8 +1035,9 @@ libinput_event_gesture_get_dy(struct libinput_event_gesture *event); * @ingroup event_gesture * * Return the relative delta of the unaccelerated motion vector of the - * current event. For gesture events that are not of type @ref - * LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, this function returns 0. + * current event. For gesture events that are not of type + * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, this function returns 0. * * Relative unaccelerated motion deltas are normalized to represent those of a * device with 1000dpi resolution. See @ref motion_normalization for more @@ -1039,7 +1045,8 @@ libinput_event_gesture_get_dy(struct libinput_event_gesture *event); * as read from the device. * * @note It is an application bug to call this function for events other than - * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE. + * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE. * * @return the unaccelerated relative x movement since the last event */ @@ -1051,8 +1058,9 @@ libinput_event_gesture_get_dx_unaccelerated( * @ingroup event_gesture * * Return the relative delta of the unaccelerated motion vector of the - * current event. For gesture events that are not of type @ref - * LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, this function returns 0. + * current event. For gesture events that are not of type + * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, this function returns 0. * * Relative unaccelerated motion deltas are normalized to represent those of a * device with 1000dpi resolution. See @ref motion_normalization for more @@ -1060,7 +1068,8 @@ libinput_event_gesture_get_dx_unaccelerated( * as read from the device. * * @note It is an application bug to call this function for events other than - * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE. + * @ref LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE or + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE. * * @return the unaccelerated relative y movement since the last event */ @@ -1068,6 +1077,53 @@ double libinput_event_gesture_get_dy_unaccelerated( struct libinput_event_gesture *event); +/** + * @ingroup event_gesture + * + * Return the absolute scale of a pinch gesture, the scale is the division + * of the current distance between the fingers and the distance at the start + * of the gesture. The scale begins at 1.0, and if e.g. the fingers moved + * together by 50% then the scale will become 0.5, if they move twice as far + * apart as initially the scale becomes 2.0, etc. + * + * For gesture events that are not of type @ref + * LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, this function returns 0. + * + * @note It is an application bug to call this function for events other than + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE. + * + * @return the absolute scale of a pinch gesture + */ +double +libinput_event_gesture_get_scale(struct libinput_event_gesture *event); + +/** + * @ingroup event_gesture + * + * Return the angle delta in degrees between the last and the current @ref + * LIBINPUT_EVENT_GESTURE_PINCH_UPDATE event. For gesture events that + * are not of type @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, this + * function returns 0. + * + * The angle delta is defined as the change in angle of the line formed by + * the 2 fingers of a pinch gesture. Clockwise rotation is represented + * by a postive delta, counter-clockwise by a negative delta. If e.g. the + * fingers are on the 12 and 6 location of a clock face plate and they move + * to the 1 resp. 7 location in a single event then the angle delta is + * 30 degrees. + * + * If more than two fingers are present, the angle represents the rotation + * around the center of gravity. The calculation of the center of gravity is + * implementation-dependent. + * + * @note It is an application bug to call this function for events other than + * @ref LIBINPUT_EVENT_GESTURE_PINCH_UPDATE. + * + * @return the angle delta since the last event + */ +double +libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event); + /** * @defgroup base Initialization and manipulation of libinput contexts */ diff --git a/src/libinput.sym b/src/libinput.sym index f81ce0d7..0060ba87 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -148,12 +148,14 @@ LIBINPUT_0.19.0 { } LIBINPUT_0.15.0; TOUCHPAD_GESTURES { + libinput_event_gesture_get_angle_delta; libinput_event_gesture_get_base_event; libinput_event_gesture_get_dx; libinput_event_gesture_get_dx_unaccelerated; libinput_event_gesture_get_dy; libinput_event_gesture_get_dy_unaccelerated; libinput_event_gesture_get_finger_count; + libinput_event_gesture_get_scale; libinput_event_gesture_get_time; libinput_event_get_gesture_event; } LIBINPUT_0.19.0; diff --git a/test/litest.c b/test/litest.c index 115c9ca8..b8758470 100644 --- a/test/litest.c +++ b/test/litest.c @@ -1664,6 +1664,15 @@ litest_event_type_str(struct libinput_event *event) case LIBINPUT_EVENT_GESTURE_SWIPE_END: str = "GESTURE SWIPE END"; break; + case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: + str = "GESTURE PINCH START"; + break; + case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: + str = "GESTURE PINCH UPDATE"; + break; + case LIBINPUT_EVENT_GESTURE_PINCH_END: + str = "GESTURE PINCH END"; + break; } return str; } diff --git a/tools/event-debug.c b/tools/event-debug.c index f3e52b45..1902dd35 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -99,6 +99,15 @@ print_event_header(struct libinput_event *ev) case LIBINPUT_EVENT_GESTURE_SWIPE_END: type = "GESTURE_SWIPE_END"; break; + case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: + type = "GESTURE_PINCH_BEGIN"; + break; + case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: + type = "GESTURE_PINCH_UPDATE"; + break; + case LIBINPUT_EVENT_GESTURE_PINCH_END: + type = "GESTURE_PINCH_END"; + break; } printf("%-7s %s ", libinput_device_get_sysname(dev), type); @@ -310,12 +319,19 @@ print_gesture_event_with_coords(struct libinput_event *ev) double dy = libinput_event_gesture_get_dy(t); double dx_unaccel = libinput_event_gesture_get_dx_unaccelerated(t); double dy_unaccel = libinput_event_gesture_get_dy_unaccelerated(t); + double scale = libinput_event_gesture_get_scale(t); + double angle = libinput_event_gesture_get_angle_delta(t); print_event_time(libinput_event_gesture_get_time(t)); - printf("%d %5.2f/%5.2f (%5.2f/%5.2f unaccelerated)\n", + printf("%d %5.2f/%5.2f (%5.2f/%5.2f unaccelerated)", libinput_event_gesture_get_finger_count(t), dx, dy, dx_unaccel, dy_unaccel); + + if (libinput_event_get_type(ev) == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE) + printf(" %5.2f @ %5.2f\n", scale, angle); + else + printf("\n"); } static int @@ -376,6 +392,15 @@ handle_and_print_events(struct libinput *li) case LIBINPUT_EVENT_GESTURE_SWIPE_END: print_gesture_event_without_coords(ev); break; + case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: + print_gesture_event_without_coords(ev); + break; + case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: + print_gesture_event_with_coords(ev); + break; + case LIBINPUT_EVENT_GESTURE_PINCH_END: + print_gesture_event_without_coords(ev); + break; } libinput_event_destroy(ev); diff --git a/tools/event-gui.c b/tools/event-gui.c index 0c2896a7..3806014b 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -476,6 +476,9 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data) case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: case LIBINPUT_EVENT_GESTURE_SWIPE_END: + case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: + case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: + case LIBINPUT_EVENT_GESTURE_PINCH_END: break; } -- cgit v1.2.3