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 <[email protected]> > --- > 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 <[email protected]> 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
