gdk/x11: Implement XI2.4 touchpad gesture support
This commit is contained in:
@@ -244,6 +244,9 @@
|
||||
/* Define to 1 if XInput 2.2 is available */
|
||||
#mesondefine XINPUT_2_2
|
||||
|
||||
/* Define to 1 if XInput 2.4 is available */
|
||||
#mesondefine XINPUT_2_4
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
|
||||
@@ -300,6 +300,9 @@
|
||||
/* Define to 1 if XInput 2.2 is available */
|
||||
/* #undef XINPUT_2_2 */
|
||||
|
||||
/* Define to 1 if XInput 2.4 is available */
|
||||
/* #undef XINPUT_2_4 */
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
/* #undef X_DISPLAY_MISSING */
|
||||
|
||||
|
||||
12
configure.ac
12
configure.ac
@@ -1167,13 +1167,23 @@ if test "x$enable_x11_backend" = xyes; then
|
||||
AC_DEFINE(XINPUT_2_2, 1, [Define to 1 if XInput 2.2 is available]),
|
||||
have_xinput2_2=no,
|
||||
[[#include <X11/extensions/XInput2.h>]])])
|
||||
LIBS="$gtk_save_LIBS"
|
||||
|
||||
if test "x$have_xinput2_2" = "xyes"; then
|
||||
X_EXTENSIONS="$X_EXTENSIONS XI2.2"
|
||||
else
|
||||
X_EXTENSIONS="$X_EXTENSIONS XI2"
|
||||
fi
|
||||
|
||||
AC_CHECK_MEMBER([XIGesturePinchEvent.type],
|
||||
have_xinput2_4=yes
|
||||
AC_DEFINE(XINPUT_2_4, 1, [Define to 1 if XInput 2.4 is available]),
|
||||
have_xinput2_4=no,
|
||||
[[#include <X11/extensions/XInput2.h>]])
|
||||
|
||||
if test "x$have_xinput2_4" = "xyes"; then
|
||||
X_EXTENSIONS="$X_EXTENSIONS XI2.4"
|
||||
fi
|
||||
LIBS="$gtk_save_LIBS"
|
||||
fi
|
||||
|
||||
AS_IF([test "x$have_xinput2" != "xyes"],
|
||||
|
||||
@@ -160,7 +160,7 @@ do_gestures (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (window), drawing_area);
|
||||
gtk_widget_add_events (drawing_area,
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK | GDK_TOUCH_MASK);
|
||||
GDK_POINTER_MOTION_MASK | GDK_TOUCH_MASK | GDK_TOUCHPAD_GESTURE_MASK);
|
||||
|
||||
g_signal_connect (drawing_area, "draw",
|
||||
G_CALLBACK (drawing_area_draw), NULL);
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -1286,7 +1286,7 @@ get_native_device_event_mask (GdkWindow *private,
|
||||
if (gdk_window_is_toplevel (private) ||
|
||||
mask & GDK_BUTTON_PRESS_MASK)
|
||||
mask |=
|
||||
GDK_TOUCH_MASK |
|
||||
GDK_TOUCH_MASK | GDK_TOUCHPAD_GESTURE_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_SCROLL_MASK;
|
||||
|
||||
@@ -61,7 +61,6 @@ struct _GdkX11DeviceXI2Class
|
||||
|
||||
G_DEFINE_TYPE (GdkX11DeviceXI2, gdk_x11_device_xi2, GDK_TYPE_DEVICE)
|
||||
|
||||
|
||||
static void gdk_x11_device_xi2_finalize (GObject *object);
|
||||
static void gdk_x11_device_xi2_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -762,6 +761,20 @@ _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager
|
||||
}
|
||||
#endif /* XINPUT_2_2 */
|
||||
|
||||
#ifdef XINPUT_2_4
|
||||
/* XInput 2.4 includes multitouch 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;
|
||||
}
|
||||
|
||||
@@ -810,6 +823,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,
|
||||
|
||||
@@ -48,7 +48,7 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
||||
int major, minor;
|
||||
|
||||
major = 2;
|
||||
minor = 3;
|
||||
minor = 4;
|
||||
|
||||
if (!_gdk_disable_multidevice &&
|
||||
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||
|
||||
@@ -1335,6 +1335,26 @@ get_event_window (GdkEventTranslator *translator,
|
||||
}
|
||||
}
|
||||
break;
|
||||
#ifdef XINPUT_2_4
|
||||
case XI_GesturePinchBegin:
|
||||
case XI_GesturePinchUpdate:
|
||||
case XI_GesturePinchEnd:
|
||||
{
|
||||
XIGesturePinchEvent *xev = (XIGesturePinchEvent *) ev;
|
||||
|
||||
window = gdk_x11_window_lookup_for_display (display, xev->event);
|
||||
}
|
||||
break;
|
||||
case XI_GestureSwipeBegin:
|
||||
case XI_GestureSwipeUpdate:
|
||||
case XI_GestureSwipeEnd:
|
||||
{
|
||||
XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
|
||||
|
||||
window = gdk_x11_window_lookup_for_display (display, xev->event);
|
||||
}
|
||||
break;
|
||||
#endif /* XINPUT_2_4 */
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
case XI_FocusIn:
|
||||
@@ -1950,6 +1970,144 @@ 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;
|
||||
|
||||
#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;
|
||||
}
|
||||
#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" : ""));
|
||||
|
||||
event->touchpad_pinch.type = GDK_TOUCHPAD_PINCH;
|
||||
event->touchpad_pinch.phase =
|
||||
_gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
|
||||
event->touchpad_pinch.window = window;
|
||||
event->touchpad_pinch.time = xev->time;
|
||||
event->touchpad_pinch.x = (gdouble) xev->event_x / scale;
|
||||
event->touchpad_pinch.y = (gdouble) xev->event_y / scale;
|
||||
event->touchpad_pinch.x_root = (gdouble) xev->root_x / scale;
|
||||
event->touchpad_pinch.y_root = (gdouble) xev->root_y / scale;
|
||||
event->touchpad_pinch.dx = xev->delta_x;
|
||||
event->touchpad_pinch.dy = xev->delta_y;
|
||||
event->touchpad_pinch.scale = xev->scale;
|
||||
event->touchpad_pinch.angle_delta = xev->delta_angle * G_PI / 180;
|
||||
event->touchpad_pinch.n_fingers = xev->detail;
|
||||
|
||||
device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
gdk_event_set_device (event, device);
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
event->touchpad_pinch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
|
||||
|
||||
if (xev->evtype == XI_GesturePinchBegin || xev->evtype == XI_GesturePinchEnd)
|
||||
{
|
||||
if (!set_screen_from_root (display, event, xev->root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->evtype == XI_GesturePinchBegin)
|
||||
set_user_time (event);
|
||||
}
|
||||
break;
|
||||
|
||||
case XI_GestureSwipeBegin:
|
||||
case XI_GestureSwipeUpdate:
|
||||
case XI_GestureSwipeEnd:
|
||||
{
|
||||
XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
|
||||
|
||||
#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;
|
||||
}
|
||||
#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" : ""));
|
||||
|
||||
event->touchpad_swipe.type = GDK_TOUCHPAD_SWIPE;
|
||||
event->touchpad_pinch.phase =
|
||||
_gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
|
||||
event->touchpad_swipe.window = window;
|
||||
event->touchpad_swipe.time = xev->time;
|
||||
event->touchpad_swipe.x = (gdouble) xev->event_x / scale;
|
||||
event->touchpad_swipe.y = (gdouble) xev->event_y / scale;
|
||||
event->touchpad_swipe.x_root = (gdouble) xev->root_x / scale;
|
||||
event->touchpad_swipe.y_root = (gdouble) xev->root_y / scale;
|
||||
event->touchpad_swipe.dx = xev->delta_x;
|
||||
event->touchpad_swipe.dy = xev->delta_y;
|
||||
event->touchpad_swipe.n_fingers = xev->detail;
|
||||
|
||||
device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
gdk_event_set_device (event, device);
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
event->touchpad_swipe.state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
|
||||
|
||||
if (xev->evtype == XI_GestureSwipeBegin || xev->evtype == XI_GestureSwipeEnd)
|
||||
{
|
||||
if (!set_screen_from_root (display, event, xev->root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->evtype == XI_GestureSwipeBegin)
|
||||
set_user_time (event);
|
||||
}
|
||||
break;
|
||||
#endif /* XINPUT_2_4 */
|
||||
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
{
|
||||
@@ -2078,7 +2236,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
|
||||
|
||||
@@ -230,6 +230,11 @@ 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);
|
||||
|
||||
#ifdef XINPUT_2_4
|
||||
guint _gdk_x11_device_xi2_gesture_type_to_phase (int evtype, int flags);
|
||||
#endif
|
||||
|
||||
gint _gdk_x11_device_xi2_get_id (GdkX11DeviceXI2 *device);
|
||||
void _gdk_device_xi2_unset_scroll_valuators (GdkX11DeviceXI2 *device);
|
||||
|
||||
|
||||
@@ -629,6 +629,14 @@ if x11_enabled
|
||||
endif
|
||||
endif
|
||||
|
||||
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
|
||||
|
||||
|
||||
enable_xinerama = get_option('xinerama')
|
||||
if enable_xinerama != 'no'
|
||||
want_xinerama = enable_xinerama == 'yes'
|
||||
|
||||
Reference in New Issue
Block a user