[gtk: 2/3] gdk/x11: Implement XI2.4 touchpad gesture support
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 2/3] gdk/x11: Implement XI2.4 touchpad gesture support
- Date: Thu, 28 Oct 2021 16:44:53 +0000 (UTC)
commit 68bd94fa254ec4488e746d6e0616719a4896ef0d
Author: Povilas Kanapickas <povilas radix lt>
Date: Mon Sep 6 01:32:16 2021 +0300
gdk/x11: Implement XI2.4 touchpad gesture support
gdk/gdkseatdefault.c | 3 +-
gdk/x11/gdkdevice-xi2.c | 44 +++++++++++++
gdk/x11/gdkdevicemanager-x11.c | 2 +-
gdk/x11/gdkdevicemanager-xi2.c | 143 ++++++++++++++++++++++++++++++++++++++++-
gdk/x11/gdkprivate-x11.h | 1 +
meson.build | 7 ++
6 files changed, 197 insertions(+), 3 deletions(-)
---
diff --git a/gdk/gdkseatdefault.c b/gdk/gdkseatdefault.c
index ce47df8230..18d44662ec 100644
--- a/gdk/gdkseatdefault.c
+++ b/gdk/gdkseatdefault.c
@@ -43,7 +43,8 @@ struct _GdkSeatDefaultPrivate
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK | \
GDK_PROXIMITY_IN_MASK | \
- GDK_PROXIMITY_OUT_MASK)
+ GDK_PROXIMITY_OUT_MASK | \
+ GDK_TOUCHPAD_GESTURE_MASK)
G_DEFINE_TYPE_WITH_PRIVATE (GdkSeatDefault, gdk_seat_default, GDK_TYPE_SEAT)
diff --git a/gdk/x11/gdkdevice-xi2.c b/gdk/x11/gdkdevice-xi2.c
index 5976dfafc4..7062a7330a 100644
--- a/gdk/x11/gdkdevice-xi2.c
+++ b/gdk/x11/gdkdevice-xi2.c
@@ -619,6 +619,20 @@ _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager
}
#endif /* XINPUT_2_2 */
+#ifdef XINPUT_2_4
+ /* XInput 2.4 includes touchpad gesture support */
+ if (minor >= 4 &&
+ event_mask & GDK_TOUCHPAD_GESTURE_MASK)
+ {
+ XISetMask (mask, XI_GesturePinchBegin);
+ XISetMask (mask, XI_GesturePinchUpdate);
+ XISetMask (mask, XI_GesturePinchEnd);
+ XISetMask (mask, XI_GestureSwipeBegin);
+ XISetMask (mask, XI_GestureSwipeUpdate);
+ XISetMask (mask, XI_GestureSwipeEnd);
+ }
+#endif
+
return mask;
}
@@ -667,6 +681,36 @@ _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
return state;
}
+#ifdef XINPUT_2_4
+guint
+_gdk_x11_device_xi2_gesture_type_to_phase (int evtype, int flags)
+{
+ switch (evtype)
+ {
+ case XI_GesturePinchBegin:
+ case XI_GestureSwipeBegin:
+ return GDK_TOUCHPAD_GESTURE_PHASE_BEGIN;
+
+ case XI_GesturePinchUpdate:
+ case XI_GestureSwipeUpdate:
+ return GDK_TOUCHPAD_GESTURE_PHASE_UPDATE;
+
+ case XI_GesturePinchEnd:
+ if (flags & XIGesturePinchEventCancelled)
+ return GDK_TOUCHPAD_GESTURE_PHASE_CANCEL;
+ return GDK_TOUCHPAD_GESTURE_PHASE_END;
+
+ case XI_GestureSwipeEnd:
+ if (flags & XIGestureSwipeEventCancelled)
+ return GDK_TOUCHPAD_GESTURE_PHASE_CANCEL;
+ return GDK_TOUCHPAD_GESTURE_PHASE_END;
+ default:
+ g_assert_not_reached ();
+ return GDK_TOUCHPAD_GESTURE_PHASE_END;
+ }
+}
+#endif /* XINPUT_2_4 */
+
void
_gdk_x11_device_xi2_add_scroll_valuator (GdkX11DeviceXI2 *device,
guint n_valuator,
diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c
index d01a5db24b..27a7d2007b 100644
--- a/gdk/x11/gdkdevicemanager-x11.c
+++ b/gdk/x11/gdkdevicemanager-x11.c
@@ -41,7 +41,7 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
int major, minor;
major = 2;
- minor = 3;
+ minor = 4;
if (XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
{
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index e4114e5279..9eb4e9bc56 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1275,6 +1275,26 @@ get_event_surface (GdkEventTranslator *translator,
}
}
break;
+#ifdef XINPUT_2_4
+ case XI_GesturePinchBegin:
+ case XI_GesturePinchUpdate:
+ case XI_GesturePinchEnd:
+ {
+ XIGesturePinchEvent *xev = (XIGesturePinchEvent *) ev;
+
+ surface = gdk_x11_surface_lookup_for_display (display, xev->event);
+ }
+ break;
+ case XI_GestureSwipeBegin:
+ case XI_GestureSwipeUpdate:
+ case XI_GestureSwipeEnd:
+ {
+ XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
+
+ surface = gdk_x11_surface_lookup_for_display (display, xev->event);
+ }
+ break;
+#endif /* XINPUT_2_4 */
case XI_Enter:
case XI_Leave:
case XI_FocusIn:
@@ -1881,6 +1901,126 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
break;
#endif /* XINPUT_2_2 */
+#ifdef XINPUT_2_4
+ case XI_GesturePinchBegin:
+ case XI_GesturePinchUpdate:
+ case XI_GesturePinchEnd:
+ {
+ XIGesturePinchEvent *xev = (XIGesturePinchEvent *) ev;
+ GdkModifierType state;
+ GdkTouchpadGesturePhase phase;
+ double x, y;
+
+#ifdef G_ENABLE_DEBUG
+ const char *event_name = "";
+ switch (xev->evtype)
+ {
+ case XI_GesturePinchBegin:
+ event_name = "begin";
+ break;
+ case XI_GesturePinchUpdate:
+ event_name = "update";
+ break;
+ case XI_GesturePinchEnd:
+ event_name = "end";
+ break;
+ default:
+ break;
+ }
+#endif
+
+ GDK_NOTE (EVENTS,
+ g_message ("pinch gesture %s:\twindow %ld\n\tfinger_count: %u%s",
+ event_name,
+ xev->event,
+ xev->detail,
+ xev->flags & XIGesturePinchEventCancelled ? "\n\tcancelled" : ""));
+
+ device = g_hash_table_lookup (device_manager->id_table,
+ GINT_TO_POINTER (xev->deviceid));
+
+ state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
+ phase = _gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
+
+ x = (double) xev->event_x / scale;
+ y = (double) xev->event_y / scale;
+
+ event = gdk_touchpad_event_new_pinch (surface,
+ device,
+ xev->time,
+ state,
+ phase,
+ x, y,
+ xev->detail,
+ xev->delta_x,
+ xev->delta_y,
+ xev->scale,
+ xev->delta_angle * G_PI / 180);
+
+ if (ev->evtype == XI_GesturePinchBegin)
+ set_user_time (event);
+ }
+ break;
+
+ case XI_GestureSwipeBegin:
+ case XI_GestureSwipeUpdate:
+ case XI_GestureSwipeEnd:
+ {
+ XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
+ GdkModifierType state;
+ GdkTouchpadGesturePhase phase;
+ double x, y;
+
+#ifdef G_ENABLE_DEBUG
+ const char *event_name = "";
+ switch (xev->evtype)
+ {
+ case XI_GestureSwipeBegin:
+ event_name = "begin";
+ break;
+ case XI_GestureSwipeUpdate:
+ event_name = "update";
+ break;
+ case XI_GestureSwipeEnd:
+ event_name = "end";
+ break;
+ default:
+ break;
+ }
+#endif
+
+ GDK_NOTE (EVENTS,
+ g_message ("swipe gesture %s:\twindow %ld\n\tfinger_count: %u%s",
+ event_name,
+ xev->event,
+ xev->detail,
+ xev->flags & XIGestureSwipeEventCancelled ? "\n\tcancelled" : ""));
+
+ device = g_hash_table_lookup (device_manager->id_table,
+ GINT_TO_POINTER (xev->deviceid));
+
+ state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
+ phase = _gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
+
+ x = (double) xev->event_x / scale;
+ y = (double) xev->event_y / scale;
+
+ event = gdk_touchpad_event_new_swipe (surface,
+ device,
+ xev->time,
+ state,
+ phase,
+ x, y,
+ xev->detail,
+ xev->delta_x,
+ xev->delta_y);
+
+ if (ev->evtype == XI_GestureSwipeBegin)
+ set_user_time (event);
+ }
+ break;
+#endif /* XINPUT_2_4 */
+
case XI_Enter:
case XI_Leave:
{
@@ -1992,7 +2132,8 @@ gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
GDK_BUTTON3_MOTION_MASK |
GDK_BUTTON_MOTION_MASK |
GDK_FOCUS_CHANGE_MASK |
- GDK_TOUCH_MASK);
+ GDK_TOUCH_MASK |
+ GDK_TOUCHPAD_GESTURE_MASK);
}
static void
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 4461f15e6b..74a5155096 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -140,6 +140,7 @@ guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *devic
guint _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
XIButtonState *buttons_state,
XIGroupState *group_state);
+guint _gdk_x11_device_xi2_gesture_type_to_phase (int evtype, int flags);
int _gdk_x11_device_xi2_get_id (GdkX11DeviceXI2 *device);
void _gdk_device_xi2_unset_scroll_valuators (GdkX11DeviceXI2 *device);
diff --git a/meson.build b/meson.build
index e85daf88f5..0965a2f113 100644
--- a/meson.build
+++ b/meson.build
@@ -557,6 +557,13 @@ if x11_enabled
endif
cdata.set('XINPUT_2_2', 1)
+ has_gesture_pinch_event = cc.has_member('XIGesturePinchEvent', 'type', dependencies: xi_dep,
+ prefix: '''#include <X11/Xlib.h>
+ #include <X11/extensions/XInput2.h>''')
+ if has_gesture_pinch_event
+ cdata.set('XINPUT_2_4', 1)
+ endif
+
xinerama_dep = dependency('xinerama')
if not cc.has_header_symbol('X11/extensions/Xinerama.h', 'XineramaQueryExtension', dependencies:
xinerama_dep)
error('X11 backend enabled, but Xinerama extension does not work.')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]