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

Peter Hutterer peter.hutterer at who-t.net
Thu Mar 12 15:57:10 PDT 2015


On Wed, Mar 11, 2015 at 03:20:54PM +0100, Hans de Goede wrote:
> 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);
> +}
> +

maybe more obvious to have a static void gesture_notify() and then call that
from gesture_notify_pinch and gesture_notify_swipe. Less confusing than
calling the notify_pinch from a notify_swipe.

>  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

annoying as it is, I'd prefer this spelled out for all possibilities and
@ref'd accordingly.

Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
otherwise

Cheers,
   Peter


>   * 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
> 
> _______________________________________________
> 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