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

Hans de Goede hdegoede at redhat.com
Thu Mar 5 02:04:38 PST 2015


Hi,

On 05-03-15 04:29, Peter Hutterer wrote:
> 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.

Ok, done in my personal tree.

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

Added (verbatim).

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

Good point, I've made the dx / dy getters apply to pinch gestures too in my
personal tree.

Regards,

Hans


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