[RFC libinput 1/2] touchpad: Extend the touchpad gesture API with pinch gestures

Hans de Goede hdegoede at redhat.com
Wed Mar 11 07:20:54 PDT 2015


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 <hdegoede at redhat.com>
---
 src/libinput-private.h | 12 +++++++++
 src/libinput.c         | 51 +++++++++++++++++++++++++++++++++++--
 src/libinput.h         | 68 ++++++++++++++++++++++++++++++++++++++++++--------
 src/libinput.sym       |  2 ++
 test/litest.c          |  9 +++++++
 tools/event-debug.c    | 27 +++++++++++++++++++-
 6 files changed, 156 insertions(+), 13 deletions(-)

diff --git a/src/libinput-private.h b/src/libinput-private.h
index 86d1636..c0847bd 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -330,6 +330,18 @@ touch_notify_touch_up(struct libinput_device *device,
 		      int32_t seat_slot);
 
 void
+gesture_notify_pinch(struct libinput_device *device,
+		     uint64_t time,
+		     enum libinput_event_type type,
+		     int finger_count,
+		     double dx,
+		     double dy,
+		     double dx_unaccel,
+		     double dy_unaccel,
+		     double distance,
+		     double angle);
+
+void
 gesture_notify_swipe(struct libinput_device *device,
 		     uint64_t time,
 		     enum libinput_event_type type,
diff --git a/src/libinput.c b/src/libinput.c
index f49e7fe..5fb0c65 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -87,6 +87,8 @@ struct libinput_event_gesture {
 	double dy;
 	double dx_unaccel;
 	double dy_unaccel;
+	double distance;
+	double angle;
 };
 
 static void
@@ -196,6 +198,9 @@ libinput_event_get_pointer_event(struct libinput_event *event)
 	case LIBINPUT_EVENT_GESTURE_SWIPE_START:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
+	case LIBINPUT_EVENT_GESTURE_PINCH_START:
+	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_PINCH_END:
 		break;
 	}
 
@@ -226,6 +231,9 @@ libinput_event_get_keyboard_event(struct libinput_event *event)
 	case LIBINPUT_EVENT_GESTURE_SWIPE_START:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
+	case LIBINPUT_EVENT_GESTURE_PINCH_START:
+	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_PINCH_END:
 		break;
 	}
 
@@ -255,6 +263,9 @@ libinput_event_get_touch_event(struct libinput_event *event)
 	case LIBINPUT_EVENT_GESTURE_SWIPE_START:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
+	case LIBINPUT_EVENT_GESTURE_PINCH_START:
+	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_PINCH_END:
 		break;
 	}
 
@@ -285,6 +296,9 @@ libinput_event_get_gesture_event(struct libinput_event *event)
 	case LIBINPUT_EVENT_GESTURE_SWIPE_START:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
+	case LIBINPUT_EVENT_GESTURE_PINCH_START:
+	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_PINCH_END:
 		return (struct libinput_event_gesture *) event;
 	}
 
@@ -314,6 +328,9 @@ libinput_event_get_device_notify_event(struct libinput_event *event)
 	case LIBINPUT_EVENT_GESTURE_SWIPE_START:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
 	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
+	case LIBINPUT_EVENT_GESTURE_PINCH_START:
+	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_PINCH_END:
 		break;
 	}
 
@@ -595,6 +612,18 @@ libinput_event_gesture_get_dy_unaccelerated(
 	return event->dy_unaccel;
 }
 
+LIBINPUT_EXPORT double
+libinput_event_gesture_get_distance(struct libinput_event_gesture *event)
+{
+	return event->distance;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_gesture_get_angle(struct libinput_event_gesture *event)
+{
+	return event->angle;
+}
+
 struct libinput_source *
 libinput_add_fd(struct libinput *libinput,
 		int fd,
@@ -1257,14 +1286,16 @@ touch_notify_frame(struct libinput_device *device,
 }
 
 void
-gesture_notify_swipe(struct libinput_device *device,
+gesture_notify_pinch(struct libinput_device *device,
 		     uint64_t time,
 		     enum libinput_event_type type,
 		     int finger_count,
 		     double dx,
 		     double dy,
 		     double dx_unaccel,
-		     double dy_unaccel)
+		     double dy_unaccel,
+		     double distance,
+		     double angle)
 {
 	struct libinput_event_gesture *gesture_event;
 
@@ -1279,12 +1310,28 @@ gesture_notify_swipe(struct libinput_device *device,
 		.dy = dy,
 		.dx_unaccel = dx_unaccel,
 		.dy_unaccel = dy_unaccel,
+		.distance = distance,
+		.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,
+		     double dx,
+		     double dy,
+		     double dx_unaccel,
+		     double dy_unaccel)
+{
+	gesture_notify_pinch(device, time, type, finger_count,
+			     dx, dy, dx_unaccel, dy_unaccel, 0.0, 0.0);
+}
+
 static void
 libinput_post_event(struct libinput *libinput,
 		    struct libinput_event *event)
diff --git a/src/libinput.h b/src/libinput.h
index 1637a64..a005d66 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -178,6 +178,9 @@ enum libinput_event_type {
 	LIBINPUT_EVENT_GESTURE_SWIPE_START = 800,
 	LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
 	LIBINPUT_EVENT_GESTURE_SWIPE_END,
+	LIBINPUT_EVENT_GESTURE_PINCH_START,
+	LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
+	LIBINPUT_EVENT_GESTURE_PINCH_END,
 };
 
 /**
@@ -957,7 +960,7 @@ 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
+ * events that are not of type LIBINPUT_EVENT_GESTURE_FOO_UPDATE, this
  * function returns 0.
  *
  * If a device employs pointer acceleration, the delta returned by this
@@ -967,7 +970,7 @@ 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.
+ * LIBINPUT_EVENT_GESTURE_FOO_UPDATE.
  *
  * @return the relative x movement since the last event
  */
@@ -978,7 +981,7 @@ 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
+ * events that are not of type LIBINPUT_EVENT_GESTURE_FOO_UPDATE, this
  * function returns 0.
  *
  * If a device employs pointer acceleration, the delta returned by this
@@ -988,7 +991,7 @@ 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.
+ * LIBINPUT_EVENT_GESTURE_FOO_UPDATE.
  *
  * @return the relative y movement since the last event
  */
@@ -999,8 +1002,8 @@ 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
+ * LIBINPUT_EVENT_GESTURE_FOO_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
@@ -1008,7 +1011,7 @@ 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.
+ * LIBINPUT_EVENT_GESTURE_FOO_UPDATE.
  *
  * @return the unaccelerated relative x movement since the last event
  */
@@ -1020,8 +1023,8 @@ 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
+ * LIBINPUT_EVENT_GESTURE_FOO_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
@@ -1029,7 +1032,7 @@ 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.
+ * LIBINPUT_EVENT_GESTURE_FOO_UPDATE.
  *
  * @return the unaccelerated relative y movement since the last event
  */
@@ -1038,6 +1041,51 @@ libinput_event_gesture_get_dy_unaccelerated(
 	struct libinput_event_gesture *event);
 
 /**
+ * @ingroup event_gesture
+ *
+ * Return the change in distance between the fingers of a pinch gesture.
+ * For gesture events that are not of type @ref
+ * LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, this function returns 0.
+ *
+ * The distance deltas are normalized to represent those of a device with
+ * 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_PINCH_UPDATE.
+ *
+ * @return the change in finger distance
+ */
+double
+libinput_event_gesture_get_distance(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(struct libinput_event_gesture *event);
+
+/**
  * @defgroup base Initialization and manipulation of libinput contexts
  */
 
diff --git a/src/libinput.sym b/src/libinput.sym
index 050c696..650069f 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -129,7 +129,9 @@ local:
 };
 
 LIBINPUT_0.13.0 {
+	libinput_event_gesture_get_angle;
 	libinput_event_gesture_get_base_event;
+	libinput_event_gesture_get_distance;
 	libinput_event_gesture_get_dx;
 	libinput_event_gesture_get_dx_unaccelerated;
 	libinput_event_gesture_get_dy;
diff --git a/test/litest.c b/test/litest.c
index a4b323a..a1a9627 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -1070,6 +1070,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_START:
+		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 db7b54a..798828f 100644
--- a/tools/event-debug.c
+++ b/tools/event-debug.c
@@ -115,6 +115,15 @@ print_event_header(struct libinput_event *ev)
 	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
 		type = "GESTURE_SWIPE_END";
 		break;
+	case LIBINPUT_EVENT_GESTURE_PINCH_START:
+		type = "GESTURE_PINCH_START";
+		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);
@@ -306,12 +315,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 distance = libinput_event_gesture_get_distance(t);
+	double angle = libinput_event_gesture_get_angle(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", distance, angle);
+	else
+		printf("\n");
 }
 
 static int
@@ -372,6 +388,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_START:
+			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);
-- 
2.3.1



More information about the wayland-devel mailing list