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

Peter Hutterer peter.hutterer at who-t.net
Wed Mar 4 19:29:05 PST 2015


On Wed, Mar 04, 2015 at 03:26:30PM +0100, Hans de Goede wrote:
> 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.

We should s/zoom/pinch/ - zoom is what (may) happen when you pinch your
fingers, but the latter is the physical motion you do. IMO we can skip the
rotate bit and just name everything gesture_pinch_foo.

> 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);
>  

[...]

> @@ -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.

I think this should include some mention of what happens for 3+ fingers too,
even if we don't support them (yet). Not sure how to correctly express this
though, something like:

"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"

also, should we include the dx/dy of the center of gravity? I think it'd
make sense to do so, it would allow full manipulation of an item in one
gesture.

> + *
> + * @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

I fixed this on master to always have a capital letter after @return, pls
squash that in here too.

Cheers,
   Peter

> + */
> +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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 


More information about the wayland-devel mailing list