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 */
|
/* Define to 1 if XInput 2.2 is available */
|
||||||
#mesondefine XINPUT_2_2
|
#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. */
|
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||||
# define _DARWIN_USE_64_BIT_INODE 1
|
# define _DARWIN_USE_64_BIT_INODE 1
|
||||||
|
@ -300,6 +300,9 @@
|
|||||||
/* Define to 1 if XInput 2.2 is available */
|
/* Define to 1 if XInput 2.2 is available */
|
||||||
/* #undef XINPUT_2_2 */
|
/* #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. */
|
/* Define to 1 if the X Window System is missing or not being used. */
|
||||||
/* #undef X_DISPLAY_MISSING */
|
/* #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]),
|
AC_DEFINE(XINPUT_2_2, 1, [Define to 1 if XInput 2.2 is available]),
|
||||||
have_xinput2_2=no,
|
have_xinput2_2=no,
|
||||||
[[#include <X11/extensions/XInput2.h>]])])
|
[[#include <X11/extensions/XInput2.h>]])])
|
||||||
LIBS="$gtk_save_LIBS"
|
|
||||||
|
|
||||||
if test "x$have_xinput2_2" = "xyes"; then
|
if test "x$have_xinput2_2" = "xyes"; then
|
||||||
X_EXTENSIONS="$X_EXTENSIONS XI2.2"
|
X_EXTENSIONS="$X_EXTENSIONS XI2.2"
|
||||||
else
|
else
|
||||||
X_EXTENSIONS="$X_EXTENSIONS XI2"
|
X_EXTENSIONS="$X_EXTENSIONS XI2"
|
||||||
fi
|
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
|
fi
|
||||||
|
|
||||||
AS_IF([test "x$have_xinput2" != "xyes"],
|
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_container_add (GTK_CONTAINER (window), drawing_area);
|
||||||
gtk_widget_add_events (drawing_area,
|
gtk_widget_add_events (drawing_area,
|
||||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
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_signal_connect (drawing_area, "draw",
|
||||||
G_CALLBACK (drawing_area_draw), NULL);
|
G_CALLBACK (drawing_area_draw), NULL);
|
||||||
|
@ -43,7 +43,8 @@ struct _GdkSeatDefaultPrivate
|
|||||||
GDK_ENTER_NOTIFY_MASK | \
|
GDK_ENTER_NOTIFY_MASK | \
|
||||||
GDK_LEAVE_NOTIFY_MASK | \
|
GDK_LEAVE_NOTIFY_MASK | \
|
||||||
GDK_PROXIMITY_IN_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)
|
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) ||
|
if (gdk_window_is_toplevel (private) ||
|
||||||
mask & GDK_BUTTON_PRESS_MASK)
|
mask & GDK_BUTTON_PRESS_MASK)
|
||||||
mask |=
|
mask |=
|
||||||
GDK_TOUCH_MASK |
|
GDK_TOUCH_MASK | GDK_TOUCHPAD_GESTURE_MASK |
|
||||||
GDK_POINTER_MOTION_MASK |
|
GDK_POINTER_MOTION_MASK |
|
||||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||||
GDK_SCROLL_MASK;
|
GDK_SCROLL_MASK;
|
||||||
|
@ -61,7 +61,6 @@ struct _GdkX11DeviceXI2Class
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GdkX11DeviceXI2, gdk_x11_device_xi2, GDK_TYPE_DEVICE)
|
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_finalize (GObject *object);
|
||||||
static void gdk_x11_device_xi2_get_property (GObject *object,
|
static void gdk_x11_device_xi2_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -762,6 +761,20 @@ _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager
|
|||||||
}
|
}
|
||||||
#endif /* XINPUT_2_2 */
|
#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;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,6 +823,36 @@ _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
|||||||
return 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
|
void
|
||||||
_gdk_x11_device_xi2_add_scroll_valuator (GdkX11DeviceXI2 *device,
|
_gdk_x11_device_xi2_add_scroll_valuator (GdkX11DeviceXI2 *device,
|
||||||
guint n_valuator,
|
guint n_valuator,
|
||||||
|
@ -48,7 +48,7 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
|||||||
int major, minor;
|
int major, minor;
|
||||||
|
|
||||||
major = 2;
|
major = 2;
|
||||||
minor = 3;
|
minor = 4;
|
||||||
|
|
||||||
if (!_gdk_disable_multidevice &&
|
if (!_gdk_disable_multidevice &&
|
||||||
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||||
|
@ -1335,6 +1335,26 @@ get_event_window (GdkEventTranslator *translator,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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_Enter:
|
||||||
case XI_Leave:
|
case XI_Leave:
|
||||||
case XI_FocusIn:
|
case XI_FocusIn:
|
||||||
@ -1950,6 +1970,144 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
|||||||
break;
|
break;
|
||||||
#endif /* XINPUT_2_2 */
|
#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_Enter:
|
||||||
case XI_Leave:
|
case XI_Leave:
|
||||||
{
|
{
|
||||||
@ -2078,7 +2236,8 @@ gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
|
|||||||
GDK_BUTTON3_MOTION_MASK |
|
GDK_BUTTON3_MOTION_MASK |
|
||||||
GDK_BUTTON_MOTION_MASK |
|
GDK_BUTTON_MOTION_MASK |
|
||||||
GDK_FOCUS_CHANGE_MASK |
|
GDK_FOCUS_CHANGE_MASK |
|
||||||
GDK_TOUCH_MASK);
|
GDK_TOUCH_MASK |
|
||||||
|
GDK_TOUCHPAD_GESTURE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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,
|
guint _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
||||||
XIButtonState *buttons_state,
|
XIButtonState *buttons_state,
|
||||||
XIGroupState *group_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);
|
gint _gdk_x11_device_xi2_get_id (GdkX11DeviceXI2 *device);
|
||||||
void _gdk_device_xi2_unset_scroll_valuators (GdkX11DeviceXI2 *device);
|
void _gdk_device_xi2_unset_scroll_valuators (GdkX11DeviceXI2 *device);
|
||||||
|
|
||||||
|
@ -629,6 +629,14 @@ if x11_enabled
|
|||||||
endif
|
endif
|
||||||
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')
|
enable_xinerama = get_option('xinerama')
|
||||||
if enable_xinerama != 'no'
|
if enable_xinerama != 'no'
|
||||||
want_xinerama = enable_xinerama == 'yes'
|
want_xinerama = enable_xinerama == 'yes'
|
||||||
|
Reference in New Issue
Block a user