[PATCH weston v3 2/5] compositor: Implement wl_pointer_gesture_swipe/pinch interfaces

Jonas Ådahl jadahl at gmail.com
Sat Aug 1 23:32:43 PDT 2015


On Fri, Jul 31, 2015 at 03:59:52PM +0200, Carlos Garnacho wrote:
> These are obtained from the _wl_pointer_gestures global resource,
> although each pointer will maintain the resources list and additional
> information for the pinch/swipe gestures. The lifetime and focus
> management of gesture resources is thus attached to the pointer.
> 
> The translation of libinput events into _wl_pointer_gesture_pinch/swipe
> ones is fairly straight forward.
> 
> It could be deemed convenient in the future that gesture events
> go through the pointer grab interface. It could be useful in case
> we want gesture support in any weston_pointer_grab_interface, it is
> just not needed at the moment, so has been left aside.
> 
> v3: Update commit log. Merged protocol implementation and input handling
>     together. Reworked above weston_pointer_client.
> v2: Update to use standalone XML.
> 
> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
> ---
>  src/compositor.c      |   2 +
>  src/compositor.h      |  12 +++
>  src/input.c           | 218 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  src/libinput-device.c | 141 ++++++++++++++++++++++++++++++++
>  4 files changed, 372 insertions(+), 1 deletion(-)
> 
> diff --git a/src/compositor.c b/src/compositor.c
> index 66c3eee..351fdb6 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -4501,6 +4501,8 @@ weston_compositor_create(struct wl_display *display, void *user_data)
>  			      ec, bind_presentation))
>  		goto fail;
>  
> +	weston_pointer_gestures_init (ec);
> +
>  	wl_list_init(&ec->view_list);
>  	wl_list_init(&ec->plane_list);
>  	wl_list_init(&ec->layer_list);
> diff --git a/src/compositor.h b/src/compositor.h
> index dd9c046..e91ff9e 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -315,6 +315,8 @@ struct weston_pointer_client {
>  	struct wl_list link;
>  	struct wl_client *client;
>  	struct wl_list pointer_resources;
> +	struct wl_list swipe_gesture_resources;
> +	struct wl_list pinch_gesture_resources;
>  };
>  
>  struct weston_pointer {
> @@ -1099,6 +1101,13 @@ void
>  notify_touch_frame(struct weston_seat *seat);
>  
>  void
> +notify_pointer_swipe(struct weston_seat *seat, uint32_t time, int cancelled,
> +		     int fingers, wl_fixed_t dx, wl_fixed_t dy, int gesture_type);
> +void
> +notify_pointer_pinch(struct weston_seat *seat, uint32_t time, int cancelled,
> +		     int fingers, wl_fixed_t dx, wl_fixed_t dy,
> +		     wl_fixed_t scale, wl_fixed_t rotation_diff, int gesture_type);
> +void
>  weston_layer_entry_insert(struct weston_layer_entry *list,
>  			  struct weston_layer_entry *entry);
>  void
> @@ -1423,6 +1432,9 @@ weston_compositor_xkb_init(struct weston_compositor *ec,
>  void
>  weston_compositor_xkb_destroy(struct weston_compositor *ec);
>  
> +void
> +weston_pointer_gestures_init(struct weston_compositor *ec);
> +
>  /* String literal of spaces, the same width as the timestamp. */
>  #define STAMP_SPACE "               "
>  
> diff --git a/src/input.c b/src/input.c
> index 1365869..fdbec04 100644
> --- a/src/input.c
> +++ b/src/input.c
> @@ -37,6 +37,7 @@
>  #include "shared/helpers.h"
>  #include "shared/os-compatibility.h"
>  #include "compositor.h"
> +#include "protocol/pointer-gestures-server-protocol.h"
>  
>  static void
>  empty_region(pixman_region32_t *region)
> @@ -56,6 +57,8 @@ weston_pointer_client_create(struct wl_client *client)
>  
>  	pointer_client->client = client;
>  	wl_list_init(&pointer_client->pointer_resources);
> +	wl_list_init(&pointer_client->swipe_gesture_resources);
> +	wl_list_init(&pointer_client->pinch_gesture_resources);
>  
>  	return pointer_client;
>  }
> @@ -69,7 +72,9 @@ weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
>  static bool
>  weston_pointer_client_is_empty(struct weston_pointer_client *pointer_client)
>  {
> -	return wl_list_empty(&pointer_client->pointer_resources);
> +	return (wl_list_empty(&pointer_client->pointer_resources) &&
> +		wl_list_empty(&pointer_client->swipe_gesture_resources) &&
> +		wl_list_empty(&pointer_client->pinch_gesture_resources));
>  }
>  
>  static struct weston_pointer_client *
> @@ -1815,6 +1820,112 @@ static const struct wl_pointer_interface pointer_interface = {
>  	pointer_release
>  };
>  
> +WL_EXPORT void
> +notify_pointer_swipe(struct weston_seat *seat, uint32_t time, int cancelled,
> +		     int fingers, wl_fixed_t dx, wl_fixed_t dy, int gesture_type)
> +{
> +	struct weston_compositor *ec = seat->compositor;
> +	struct weston_pointer *pointer = seat->pointer;

FYI, this will need to be rebased according to
http://cgit.freedesktop.org/wayland/weston/commit/?id=1281a36e3bcd27345bd4a107f282213ecca56f0e

Other than that, this is Reviewed-by: Jonas Ådahl <jadahl at gmail.com>


Jonas

> +	struct weston_view *focus;
> +	struct wl_display *display = ec->wl_display;
> +	struct wl_list *resource_list;
> +	struct wl_resource *resource;
> +	uint32_t serial;
> +
> +	/* XXX: make gestures go through grab interface? */
> +
> +	if (!pointer || !pointer->focus || !pointer->focus_client)
> +		return;
> +
> +	weston_compositor_wake(ec);
> +	resource_list = &pointer->focus_client->swipe_gesture_resources;
> +	focus = seat->pointer->focus;
> +
> +	if (wl_list_empty(resource_list))
> +		return;
> +
> +	switch (gesture_type) {
> +	case _WL_POINTER_GESTURE_SWIPE_BEGIN:
> +		serial = wl_display_next_serial(display);
> +		wl_resource_for_each(resource, resource_list) {
> +			_wl_pointer_gesture_swipe_send_begin(resource, serial,
> +							     time,
> +							     focus->surface->resource,
> +							     fingers);
> +		}
> +		break;
> +	case _WL_POINTER_GESTURE_SWIPE_UPDATE:
> +		wl_resource_for_each(resource, resource_list) {
> +			_wl_pointer_gesture_swipe_send_update(resource, time,
> +							      dx, dy);
> +		}
> +		break;
> +	case _WL_POINTER_GESTURE_SWIPE_END:
> +		serial = wl_display_next_serial(display);
> +		wl_resource_for_each(resource, resource_list) {
> +			_wl_pointer_gesture_swipe_send_end(resource, serial,
> +							   time, cancelled);
> +		}
> +		break;
> +	default:
> +		return;
> +	}
> +}
> +
> +WL_EXPORT void
> +notify_pointer_pinch(struct weston_seat *seat, uint32_t time, int cancelled,
> +		     int fingers, wl_fixed_t dx, wl_fixed_t dy,
> +		     wl_fixed_t scale, wl_fixed_t rotation_diff, int gesture_type)
> +{
> +	struct weston_compositor *ec = seat->compositor;
> +	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_view *focus;
> +	struct wl_display *display = ec->wl_display;
> +	struct wl_list *resource_list;
> +	struct wl_resource *resource;
> +	uint32_t serial;
> +
> +	if (!pointer || !pointer->focus || !pointer->focus_client)
> +		return;
> +
> +	/* XXX: make gestures go through grab interface? */
> +
> +	weston_compositor_wake(ec);
> +	resource_list = &pointer->focus_client->pinch_gesture_resources;
> +	focus = seat->pointer->focus;
> +
> +	if (wl_list_empty(resource_list))
> +		return;
> +
> +	switch (gesture_type) {
> +	case _WL_POINTER_GESTURE_PINCH_BEGIN:
> +		serial = wl_display_next_serial(display);
> +		wl_resource_for_each(resource, resource_list) {
> +			_wl_pointer_gesture_pinch_send_begin(resource, serial,
> +							     time,
> +							     focus->surface->resource,
> +							     fingers);
> +		}
> +		break;
> +	case _WL_POINTER_GESTURE_PINCH_UPDATE:
> +		wl_resource_for_each(resource, resource_list) {
> +			_wl_pointer_gesture_pinch_send_update(resource, time,
> +							      dx, dy, scale,
> +							      rotation_diff);
> +		}
> +		break;
> +	case _WL_POINTER_GESTURE_PINCH_END:
> +		serial = wl_display_next_serial(display);
> +		wl_resource_for_each(resource, resource_list) {
> +			_wl_pointer_gesture_pinch_send_end(resource, serial,
> +							   time, cancelled);
> +		}
> +		break;
> +	default:
> +		return;
> +	}
> +}
> +
>  static void
>  seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
>  		 uint32_t id)
> @@ -2446,3 +2557,108 @@ weston_seat_release(struct weston_seat *seat)
>  
>  	wl_signal_emit(&seat->destroy_signal, seat);
>  }
> +
> +static void
> +pointer_gesture_swipe_destroy(struct wl_client *client,
> +			      struct wl_resource *resource)
> +{
> +	wl_resource_destroy(resource);
> +}
> +
> +static const struct
> +_wl_pointer_gesture_swipe_interface pointer_gesture_swipe_interface = {
> +	pointer_gesture_swipe_destroy
> +};
> +
> +static void
> +pointer_gesture_pinch_destroy(struct wl_client *client,
> +			      struct wl_resource *resource)
> +{
> +	wl_resource_destroy(resource);
> +}
> +
> +static const struct
> +_wl_pointer_gesture_swipe_interface pointer_gesture_pinch_interface = {
> +	pointer_gesture_pinch_destroy
> +};
> +
> +static void
> +pointer_gestures_get_swipe(struct wl_client *client,
> +			   struct wl_resource *resource,
> +			   uint32_t id, struct wl_resource *pointer_resource)
> +{
> +	struct weston_pointer *pointer =
> +		wl_resource_get_user_data(pointer_resource);
> +	struct weston_pointer_client *pointer_client;
> +	struct wl_resource *cr;
> +
> +	cr = wl_resource_create(client, &_wl_pointer_gesture_swipe_interface,
> +				wl_resource_get_version(resource), id);
> +	if (cr == NULL) {
> +		wl_client_post_no_memory(client);
> +		return;
> +	}
> +
> +	wl_resource_set_implementation(cr, &pointer_gesture_swipe_interface,
> +				       pointer, unbind_resource);
> +
> +	pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
> +	wl_list_insert(&pointer_client->swipe_gesture_resources,
> +		       wl_resource_get_link(cr));
> +}
> +
> +static void
> +pointer_gestures_get_pinch(struct wl_client *client,
> +			   struct wl_resource *resource,
> +			   uint32_t id, struct wl_resource *pointer_resource)
> +{
> +	struct weston_pointer *pointer =
> +		wl_resource_get_user_data(pointer_resource);
> +	struct weston_pointer_client *pointer_client;
> +	struct wl_resource *cr;
> +
> +	cr = wl_resource_create(client, &_wl_pointer_gesture_pinch_interface,
> +				wl_resource_get_version(resource), id);
> +	if (cr == NULL) {
> +		wl_client_post_no_memory(client);
> +		return;
> +	}
> +
> +	wl_resource_set_implementation(cr, &pointer_gesture_pinch_interface,
> +				       pointer, unbind_resource);
> +
> +	pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
> +	wl_list_insert(&pointer_client->pinch_gesture_resources,
> +		       wl_resource_get_link(cr));
> +}
> +
> +static const struct
> +_wl_pointer_gestures_interface pointer_gestures_interface = {
> +	pointer_gestures_get_swipe,
> +	pointer_gestures_get_pinch
> +};
> +
> +static void
> +bind_pointer_gestures(struct wl_client *client,
> +		      void *data, uint32_t version, uint32_t id)
> +{
> +	struct weston_compositor *compositor = data;
> +	struct wl_resource *resource;
> +
> +	resource = wl_resource_create(client, &_wl_pointer_gestures_interface,
> +				      MIN(version, 1), id);
> +	if (resource == NULL) {
> +		wl_client_post_no_memory(client);
> +		return;
> +	}
> +
> +	wl_resource_set_implementation(resource, &pointer_gestures_interface,
> +				       compositor, NULL);
> +}
> +
> +WL_EXPORT void
> +weston_pointer_gestures_init(struct weston_compositor *ec)
> +{
> +	wl_global_create(ec->wl_display, &_wl_pointer_gestures_interface, 1,
> +			 ec, bind_pointer_gestures);
> +}
> diff --git a/src/libinput-device.c b/src/libinput-device.c
> index 2cbfb88..60a8b5f 100644
> --- a/src/libinput-device.c
> +++ b/src/libinput-device.c
> @@ -39,6 +39,7 @@
>  #include "compositor.h"
>  #include "libinput-device.h"
>  #include "shared/helpers.h"
> +#include "protocol/pointer-gestures-server-protocol.h"
>  
>  #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10)
>  
> @@ -287,6 +288,122 @@ handle_touch_frame(struct libinput_device *libinput_device,
>  	notify_touch_frame(seat);
>  }
>  
> +static void
> +handle_pointer_swipe_begin(struct libinput_device *libinput_device,
> +			   struct libinput_event_gesture *gesture_event)
> +{
> +	struct evdev_device *device =
> +		libinput_device_get_user_data(libinput_device);
> +	struct weston_seat *seat = device->seat;
> +	uint32_t time, fingers;
> +
> +	time = libinput_event_gesture_get_time(gesture_event);
> +	fingers = libinput_event_gesture_get_finger_count(gesture_event);
> +	notify_pointer_swipe(seat, time, 0, fingers, 0, 0,
> +			     _WL_POINTER_GESTURE_SWIPE_BEGIN);
> +}
> +
> +static void
> +handle_pointer_swipe_update(struct libinput_device *libinput_device,
> +			   struct libinput_event_gesture *gesture_event)
> +{
> +	struct evdev_device *device =
> +		libinput_device_get_user_data(libinput_device);
> +	struct weston_seat *seat = device->seat;
> +	uint32_t time, fingers;
> +	double dx, dy;
> +
> +	time = libinput_event_gesture_get_time(gesture_event);
> +	fingers = libinput_event_gesture_get_finger_count(gesture_event);
> +	dx = libinput_event_gesture_get_dx(gesture_event);
> +	dy = libinput_event_gesture_get_dx(gesture_event);
> +
> +	notify_pointer_swipe(seat, time, 0, fingers,
> +			     wl_fixed_from_double(dx),
> +			     wl_fixed_from_double(dy),
> +			     _WL_POINTER_GESTURE_SWIPE_UPDATE);
> +}
> +
> +static void
> +handle_pointer_swipe_end(struct libinput_device *libinput_device,
> +			   struct libinput_event_gesture *gesture_event)
> +{
> +	struct evdev_device *device =
> +		libinput_device_get_user_data(libinput_device);
> +	struct weston_seat *seat = device->seat;
> +	uint32_t time, fingers, cancelled;
> +
> +	time = libinput_event_gesture_get_time(gesture_event);
> +	fingers = libinput_event_gesture_get_finger_count(gesture_event);
> +	cancelled = libinput_event_gesture_get_cancelled(gesture_event);
> +
> +	notify_pointer_swipe(seat, time, cancelled, fingers, 0, 0,
> +			     _WL_POINTER_GESTURE_SWIPE_END);
> +}
> +
> +static void
> +handle_pointer_pinch_begin(struct libinput_device *libinput_device,
> +			   struct libinput_event_gesture *gesture_event)
> +{
> +	struct evdev_device *device =
> +		libinput_device_get_user_data(libinput_device);
> +	struct weston_seat *seat = device->seat;
> +	uint32_t time, fingers;
> +	double scale;
> +
> +	time = libinput_event_gesture_get_time(gesture_event);
> +	fingers = libinput_event_gesture_get_finger_count(gesture_event);
> +	scale = libinput_event_gesture_get_scale(gesture_event);
> +
> +	notify_pointer_pinch(seat, time, 0, fingers, 0, 0, scale, 0,
> +			     _WL_POINTER_GESTURE_PINCH_BEGIN);
> +}
> +
> +static void
> +handle_pointer_pinch_update(struct libinput_device *libinput_device,
> +			   struct libinput_event_gesture *gesture_event)
> +{
> +	struct evdev_device *device =
> +		libinput_device_get_user_data(libinput_device);
> +	struct weston_seat *seat = device->seat;
> +	double scale, angle_delta, dx, dy;
> +	uint32_t time, fingers;
> +
> +	time = libinput_event_gesture_get_time(gesture_event);
> +	fingers = libinput_event_gesture_get_finger_count(gesture_event);
> +	scale = libinput_event_gesture_get_scale(gesture_event);
> +	angle_delta = libinput_event_gesture_get_angle_delta(gesture_event);
> +	dx = libinput_event_gesture_get_dx(gesture_event);
> +	dy = libinput_event_gesture_get_dx(gesture_event);
> +
> +	notify_pointer_pinch(seat, time, 0, fingers,
> +			     wl_fixed_from_double(dx),
> +			     wl_fixed_from_double(dy),
> +			     wl_fixed_from_double(scale),
> +			     wl_fixed_from_double(angle_delta),
> +			     _WL_POINTER_GESTURE_PINCH_UPDATE);
> +}
> +
> +static void
> +handle_pointer_pinch_end(struct libinput_device *libinput_device,
> +			 struct libinput_event_gesture *gesture_event)
> +{
> +	struct evdev_device *device =
> +		libinput_device_get_user_data(libinput_device);
> +	struct weston_seat *seat = device->seat;
> +	uint32_t time, fingers, cancelled;
> +	double scale;
> +
> +	time = libinput_event_gesture_get_time(gesture_event);
> +	fingers = libinput_event_gesture_get_finger_count(gesture_event);
> +	cancelled = libinput_event_gesture_get_cancelled(gesture_event);
> +	scale = libinput_event_gesture_get_scale(gesture_event);
> +
> +	notify_pointer_pinch(seat, time, cancelled, fingers,
> +			     0, 0, wl_fixed_from_double(scale), 0,
> +			     _WL_POINTER_GESTURE_PINCH_END);
> +}
> +
>  int
>  evdev_device_process_event(struct libinput_event *event)
>  {
> @@ -332,6 +449,30 @@ evdev_device_process_event(struct libinput_event *event)
>  		handle_touch_frame(libinput_device,
>  				   libinput_event_get_touch_event(event));
>  		break;
> +	case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
> +		handle_pointer_swipe_begin(libinput_device,
> +					   libinput_event_get_gesture_event(event));
> +		break;
> +	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
> +		handle_pointer_swipe_update(libinput_device,
> +					    libinput_event_get_gesture_event(event));
> +		break;
> +	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
> +		handle_pointer_swipe_end(libinput_device,
> +					 libinput_event_get_gesture_event(event));
> +		break;
> +	case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
> +		handle_pointer_pinch_begin(libinput_device,
> +					   libinput_event_get_gesture_event(event));
> +		break;
> +	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
> +		handle_pointer_pinch_update(libinput_device,
> +					    libinput_event_get_gesture_event(event));
> +		break;
> +	case LIBINPUT_EVENT_GESTURE_PINCH_END:
> +		handle_pointer_pinch_end(libinput_device,
> +					 libinput_event_get_gesture_event(event));
> +		break;
>  	default:
>  		handled = 0;
>  		weston_log("unknown libinput event %d\n",
> -- 
> 2.4.3
> 
> _______________________________________________
> 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