[PATCH libinput] Extend the touchpad gesture API with zoom/rotate gestures

Hans de Goede hdegoede at redhat.com
Wed Mar 4 06:26:30 PST 2015


Extend the touchpad gesture API with zoom/rotate gestures. Note that this
new API offers a single event stream for both zoom 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 |  7 +++++++
 src/libinput.c         | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libinput.h         | 41 ++++++++++++++++++++++++++++++++++++++
 src/libinput.sym       |  2 ++
 test/litest.c          |  9 +++++++++
 tools/event-debug.c    | 35 +++++++++++++++++++++++++++++++--
 6 files changed, 145 insertions(+), 2 deletions(-)

diff --git a/src/libinput-private.h b/src/libinput-private.h
index 86d1636..2c812b3 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -340,6 +340,13 @@ gesture_notify_swipe(struct libinput_device *device,
 		     double dy_unaccel);
 
 void
+gesture_notify_zoom_rotate(struct libinput_device *device,
+			   uint64_t time,
+			   enum libinput_event_type type,
+			   double distance,
+			   double angle);
+
+void
 touch_notify_frame(struct libinput_device *device,
 		   uint64_t time);
 
diff --git a/src/libinput.c b/src/libinput.c
index 37f0342..97ae80d 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_ZOOM_ROTATE_START:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_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_ZOOM_ROTATE_START:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_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_ZOOM_ROTATE_START:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_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_ZOOM_ROTATE_START:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_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_ZOOM_ROTATE_START:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_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,
@@ -1285,6 +1314,30 @@ gesture_notify_swipe(struct libinput_device *device,
 			  &gesture_event->base);
 }
 
+void
+gesture_notify_zoom_rotate(struct libinput_device *device,
+			   uint64_t time,
+			   enum libinput_event_type type,
+			   double distance,
+			   double angle)
+{
+	struct libinput_event_gesture *gesture_event;
+
+	gesture_event = zalloc(sizeof *gesture_event);
+	if (!gesture_event)
+		return;
+
+	*gesture_event = (struct libinput_event_gesture) {
+		.time = time,
+		.finger_count = 2,
+		.distance = distance,
+		.angle = angle,
+	};
+
+	post_device_event(device, time, type,
+			  &gesture_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 8c51665..5860a02 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_ZOOM_ROTATE_START,
+	LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE,
+	LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_END,
 };
 
 /**
@@ -1038,6 +1041,44 @@ libinput_event_gesture_get_dy_unaccelerated(
 	struct libinput_event_gesture *event);
 
 /**
+ * @ingroup event_gesture
+ *
+ * Return the distance in mm between the 2 fingers of a zoom/rotate gesture.
+ * For gesture events that are not of type @ref
+ * LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE, this function returns 0.
+ *
+ * @note It is an application bug to call this function for events other than
+ * @ref LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE.
+ *
+ * @return the 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_ZOOM_ROTATE_UPDATE event. For gesture events that
+ * are not of type @ref LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_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 zoom/rotate 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.
+ *
+ * @note It is an application bug to call this function for events other than
+ * @ref LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_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 13f0a69..e9f213e 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -138,7 +138,9 @@ LIBINPUT_0.11.0 {
 } LIBINPUT_0.9.0;
 
 LIBINPUT_0.12.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 f8c85c8..38b8f3d 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -1068,6 +1068,15 @@ litest_event_type_str(struct libinput_event *event)
 	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
 		str = "GESTURE SWIPE END";
 		break;
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_START:
+		str = "GESTURE ZOOM_ROTATE START";
+		break;
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+		str = "GESTURE ZOOM_ROTATE UPDATE";
+		break;
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_END:
+		str = "GESTURE ZOOM_ROTATE END";
+		break;
 	}
 	return str;
 }
diff --git a/tools/event-debug.c b/tools/event-debug.c
index db7b54a..e11789f 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_ZOOM_ROTATE_START:
+		type = "GESTURE_ZOOM_ROTATE_START";
+		break;
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+		type = "GESTURE_ZOOM_ROTATE_UPDATE";
+		break;
+	case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_END:
+		type = "GESTURE_ZOOM_ROTATE_END";
+		break;
 	}
 
 	printf("%-7s	%s	", libinput_device_get_sysname(dev), type);
@@ -299,7 +308,7 @@ print_gesture_event_without_coords(struct libinput_event *ev)
 }
 
 static void
-print_gesture_event_with_coords(struct libinput_event *ev)
+print_gesture_event_with_swipe_coords(struct libinput_event *ev)
 {
 	struct libinput_event_gesture *t = libinput_event_get_gesture_event(ev);
 	double dx = libinput_event_gesture_get_dx(t);
@@ -314,6 +323,19 @@ print_gesture_event_with_coords(struct libinput_event *ev)
 	       dx, dy, dx_unaccel, dy_unaccel);
 }
 
+static void
+print_gesture_event_with_zoom_rotate_coords(struct libinput_event *ev)
+{
+	struct libinput_event_gesture *t = libinput_event_get_gesture_event(ev);
+	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\n",
+	       libinput_event_gesture_get_finger_count(t), distance, angle);
+}
+
 static int
 handle_and_print_events(struct libinput *li)
 {
@@ -367,11 +389,20 @@ handle_and_print_events(struct libinput *li)
 			print_gesture_event_without_coords(ev);
 			break;
 		case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
-			print_gesture_event_with_coords(ev);
+			print_gesture_event_with_swipe_coords(ev);
 			break;
 		case LIBINPUT_EVENT_GESTURE_SWIPE_END:
 			print_gesture_event_without_coords(ev);
 			break;
+		case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_START:
+			print_gesture_event_without_coords(ev);
+			break;
+		case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_UPDATE:
+			print_gesture_event_with_zoom_rotate_coords(ev);
+			break;
+		case LIBINPUT_EVENT_GESTURE_ZOOM_ROTATE_END:
+			print_gesture_event_without_coords(ev);
+			break;
 		}
 
 		libinput_event_destroy(ev);
-- 
2.3.1



More information about the wayland-devel mailing list