[gtk+/wip/garnacho/touchpad-gestures: 105/105] wayland: Implement touchpad gesture events
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/garnacho/touchpad-gestures: 105/105] wayland: Implement touchpad gesture events
- Date: Mon, 3 Aug 2015 17:04:49 +0000 (UTC)
commit 850e738bf36600b9408c1aef156d45b455c0c1c0
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Jul 9 19:36:30 2015 +0200
wayland: Implement touchpad gesture events
On wayland, the gestures protocol defines a wl_pointer_gestures global
object, that will match in number with wl_seats, swipe and pinch
interfaces can be obtained from it, which events are translated into
GdkEventTouchpadSwipe/Pinch events.
gdk/wayland/gdkdevice-wayland.c | 245 ++++++++++++++++++++++++++++++++++++++
gdk/wayland/gdkdisplay-wayland.c | 6 +
gdk/wayland/gdkdisplay-wayland.h | 1 +
3 files changed, 252 insertions(+), 0 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 7fb27c1..9b190f2 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -29,6 +29,7 @@
#include "gdkkeysyms.h"
#include "gdkdeviceprivate.h"
#include "gdkdevicemanagerprivate.h"
+#include "pointer-gestures-client-protocol.h"
#include <xkbcommon/xkbcommon.h>
@@ -54,6 +55,8 @@ struct _GdkWaylandDeviceData
struct wl_pointer *wl_pointer;
struct wl_keyboard *wl_keyboard;
struct wl_touch *wl_touch;
+ struct _wl_pointer_gesture_swipe *wl_pointer_gesture_swipe;
+ struct _wl_pointer_gesture_pinch *wl_pointer_gesture_pinch;
GdkDisplay *display;
GdkDeviceManager *device_manager;
@@ -99,6 +102,10 @@ struct _GdkWaylandDeviceData
/* Source/dest for non-local dnd */
GdkWindow *foreign_dnd_window;
+
+ /* Some tracking on gesture events */
+ guint gesture_n_fingers;
+ gdouble gesture_scale;
};
struct _GdkWaylandDevice
@@ -1653,6 +1660,213 @@ touch_handle_cancel (void *data,
GDK_NOTE (EVENTS, g_message ("touch cancel"));
}
+static void
+emit_gesture_swipe_event (GdkWaylandDeviceData *device,
+ GdkTouchpadGesturePhase phase,
+ guint32 _time,
+ guint32 n_fingers,
+ gdouble dx,
+ gdouble dy)
+{
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
+ GdkEvent *event;
+
+ if (!device->pointer_focus)
+ return;
+
+ device->time = _time;
+
+ event = gdk_event_new (GDK_TOUCHPAD_SWIPE);
+ event->touchpad_swipe.phase = phase;
+ event->touchpad_swipe.window = g_object_ref (device->pointer_focus);
+ gdk_event_set_device (event, device->master_pointer);
+ gdk_event_set_source_device (event, device->pointer);
+ event->touchpad_swipe.time = _time;
+ event->touchpad_swipe.state = device->button_modifiers | device->key_modifiers;
+ gdk_event_set_screen (event, display->screen);
+ event->touchpad_swipe.dx = dx;
+ event->touchpad_swipe.dy = dy;
+ event->touchpad_swipe.n_fingers = n_fingers;
+
+ get_coordinates (device,
+ &event->touchpad_swipe.x,
+ &event->touchpad_swipe.y,
+ &event->touchpad_swipe.x_root,
+ &event->touchpad_swipe.y_root);
+
+ GDK_NOTE (EVENTS,
+ g_message ("swipe event %d, coords: %f %f, device %p state %d",
+ event->type, event->touchpad_swipe.x,
+ event->touchpad_swipe.y, device,
+ event->touchpad_swipe.state));
+
+ _gdk_wayland_display_deliver_event (device->display, event);
+}
+
+static void
+gesture_swipe_begin (void *data,
+ struct _wl_pointer_gesture_swipe *swipe,
+ uint32_t serial,
+ uint32_t time,
+ struct wl_surface *surface,
+ uint32_t fingers)
+{
+ GdkWaylandDeviceData *device = data;
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
+
+ _gdk_wayland_display_update_serial (display, serial);
+
+ emit_gesture_swipe_event (device,
+ GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
+ time, fingers, 0, 0);
+ device->gesture_n_fingers = fingers;
+}
+
+static void
+gesture_swipe_update (void *data,
+ struct _wl_pointer_gesture_swipe *swipe,
+ uint32_t time,
+ wl_fixed_t dx,
+ wl_fixed_t dy)
+{
+ GdkWaylandDeviceData *device = data;
+
+ emit_gesture_swipe_event (device,
+ GDK_TOUCHPAD_GESTURE_PHASE_UPDATE,
+ time,
+ device->gesture_n_fingers,
+ wl_fixed_to_double (dx),
+ wl_fixed_to_double (dy));
+}
+
+static void
+gesture_swipe_end (void *data,
+ struct _wl_pointer_gesture_swipe *swipe,
+ uint32_t serial,
+ uint32_t time,
+ int32_t cancelled)
+{
+ GdkWaylandDeviceData *device = data;
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
+ GdkTouchpadGesturePhase phase;
+
+ _gdk_wayland_display_update_serial (display, serial);
+
+ phase = (cancelled) ?
+ GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
+ GDK_TOUCHPAD_GESTURE_PHASE_END;
+
+ emit_gesture_swipe_event (device, phase, time,
+ device->gesture_n_fingers, 0, 0);
+}
+
+static void
+emit_gesture_pinch_event (GdkWaylandDeviceData *device,
+ GdkTouchpadGesturePhase phase,
+ guint32 _time,
+ guint n_fingers,
+ gdouble dx,
+ gdouble dy,
+ gdouble scale,
+ gdouble angle_delta)
+{
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
+ GdkEvent *event;
+
+ if (!device->pointer_focus)
+ return;
+
+ device->time = _time;
+
+ event = gdk_event_new (GDK_TOUCHPAD_PINCH);
+ event->touchpad_pinch.phase = phase;
+ event->touchpad_pinch.window = g_object_ref (device->pointer_focus);
+ gdk_event_set_device (event, device->master_pointer);
+ gdk_event_set_source_device (event, device->pointer);
+ event->touchpad_pinch.time = _time;
+ event->touchpad_pinch.state = device->button_modifiers | device->key_modifiers;
+ gdk_event_set_screen (event, display->screen);
+ event->touchpad_pinch.dx = dx;
+ event->touchpad_pinch.dy = dy;
+ event->touchpad_pinch.scale = scale;
+ event->touchpad_pinch.angle_delta = angle_delta * G_PI / 180;
+ event->touchpad_pinch.n_fingers = n_fingers;
+
+ get_coordinates (device,
+ &event->touchpad_pinch.x,
+ &event->touchpad_pinch.y,
+ &event->touchpad_pinch.x_root,
+ &event->touchpad_pinch.y_root);
+
+ GDK_NOTE (EVENTS,
+ g_message ("pinch event %d, coords: %f %f, device %p state %d",
+ event->type, event->touchpad_pinch.x,
+ event->touchpad_pinch.y, device,
+ event->touchpad_pinch.state));
+
+ _gdk_wayland_display_deliver_event (device->display, event);
+}
+
+static void
+gesture_pinch_begin (void *data,
+ struct _wl_pointer_gesture_pinch *pinch,
+ uint32_t serial,
+ uint32_t time,
+ struct wl_surface *surface,
+ uint32_t fingers)
+{
+ GdkWaylandDeviceData *device = data;
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
+
+ _gdk_wayland_display_update_serial (display, serial);
+ emit_gesture_pinch_event (device,
+ GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
+ time, fingers, 0, 0, 1, 0);
+ device->gesture_n_fingers = fingers;
+}
+
+static void
+gesture_pinch_update (void *data,
+ struct _wl_pointer_gesture_pinch *pinch,
+ uint32_t time,
+ wl_fixed_t dx,
+ wl_fixed_t dy,
+ wl_fixed_t scale,
+ wl_fixed_t rotation)
+{
+ GdkWaylandDeviceData *device = data;
+
+ emit_gesture_pinch_event (device,
+ GDK_TOUCHPAD_GESTURE_PHASE_UPDATE, time,
+ device->gesture_n_fingers,
+ wl_fixed_to_double (dx),
+ wl_fixed_to_double (dy),
+ wl_fixed_to_double (scale),
+ wl_fixed_to_double (rotation));
+}
+
+static void
+gesture_pinch_end (void *data,
+ struct _wl_pointer_gesture_pinch *pinch,
+ uint32_t serial,
+ uint32_t time,
+ int32_t cancelled)
+{
+ GdkWaylandDeviceData *device = data;
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
+ GdkTouchpadGesturePhase phase;
+
+ _gdk_wayland_display_update_serial (display, serial);
+
+ phase = (cancelled) ?
+ GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
+ GDK_TOUCHPAD_GESTURE_PHASE_END;
+
+ emit_gesture_pinch_event (device, phase,
+ time, device->gesture_n_fingers,
+ 0, 0, 1, 0);
+}
+
static const struct wl_pointer_listener pointer_listener = {
pointer_handle_enter,
pointer_handle_leave,
@@ -1678,6 +1892,18 @@ static const struct wl_touch_listener touch_listener = {
touch_handle_cancel
};
+static const struct _wl_pointer_gesture_swipe_listener gesture_swipe_listener = {
+ gesture_swipe_begin,
+ gesture_swipe_update,
+ gesture_swipe_end
+};
+
+static const struct _wl_pointer_gesture_pinch_listener gesture_pinch_listener = {
+ gesture_pinch_begin,
+ gesture_pinch_update,
+ gesture_pinch_end
+};
+
static void
seat_handle_capabilities (void *data,
struct wl_seat *seat,
@@ -1685,6 +1911,7 @@ seat_handle_capabilities (void *data,
{
GdkWaylandDeviceData *device = data;
GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (device->device_manager);
+ GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (device->display);
GDK_NOTE (MISC,
g_message ("seat %p with %s%s%s", seat,
@@ -1715,6 +1942,24 @@ seat_handle_capabilities (void *data,
device->drop_context = _gdk_wayland_drop_context_new (device->master_pointer,
device->data_device);
+ if (wayland_display->pointer_gestures)
+ {
+ device->wl_pointer_gesture_swipe =
+ _wl_pointer_gestures_get_swipe_gesture (wayland_display->pointer_gestures,
+ device->wl_pointer);
+ _wl_pointer_gesture_swipe_set_user_data (device->wl_pointer_gesture_swipe,
+ device);
+ _wl_pointer_gesture_swipe_add_listener (device->wl_pointer_gesture_swipe,
+ &gesture_swipe_listener, device);
+
+ device->wl_pointer_gesture_pinch =
+ _wl_pointer_gestures_get_pinch_gesture (wayland_display->pointer_gestures,
+ device->wl_pointer);
+ _wl_pointer_gesture_pinch_set_user_data (device->wl_pointer_gesture_pinch,
+ device);
+ _wl_pointer_gesture_pinch_add_listener (device->wl_pointer_gesture_pinch,
+ &gesture_pinch_listener, device);
+ }
g_signal_emit_by_name (device_manager, "device-added", device->pointer);
}
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index a0a5d0c..491d4ef 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -35,6 +35,7 @@
#include "gdkkeysprivate.h"
#include "gdkprivate-wayland.h"
#include "gdkglcontext-wayland.h"
+#include "gestures-client-protocol.h"
/**
* SECTION:wayland_interaction
@@ -357,6 +358,11 @@ gdk_registry_handle_global (void *data,
display_wayland->subcompositor =
wl_registry_bind (display_wayland->wl_registry, id, &wl_subcompositor_interface, 1);
}
+ else if (strcmp (interface, "_wl_pointer_gestures") == 0)
+ {
+ display_wayland->pointer_gestures =
+ wl_registry_bind (display_wayland->wl_registry, id, &_wl_pointer_gestures_interface, 1);
+ }
else
handled = FALSE;
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index d6e6b06..b834fd7 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -71,6 +71,7 @@ struct _GdkWaylandDisplay
struct wl_input_device *input_device;
struct wl_data_device_manager *data_device_manager;
struct wl_subcompositor *subcompositor;
+ struct _wl_pointer_gestures *pointer_gestures;
GList *async_roundtrips;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]