forked from AuroraMiddleware/gtk
xi2: Translate touch events
Translate XI_TouchBegin/Update/End to GDK_TOUCH_BEGIN/UPDATE/END events. At the same time, set pointer-emulated flags on button events with XIPointerEmulated and on touch events emulating the pointer.
This commit is contained in:
parent
7f35708cee
commit
f7b7cc22e6
@ -386,6 +386,7 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||
GdkDisplay *display;
|
||||
XIEventMask mask;
|
||||
Window xwindow;
|
||||
@ -393,6 +394,7 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
||||
gint status;
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
|
||||
|
||||
/* FIXME: confine_to is actually unused */
|
||||
|
||||
@ -407,7 +409,9 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
||||
}
|
||||
|
||||
mask.deviceid = device_xi2->device_id;
|
||||
mask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &mask.mask_len);
|
||||
mask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
|
||||
event_mask,
|
||||
&mask.mask_len);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
|
||||
@ -623,10 +627,17 @@ gdk_x11_device_xi2_select_window_events (GdkDevice *device,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||
GdkDisplay *display;
|
||||
XIEventMask evmask;
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
|
||||
|
||||
evmask.deviceid = device_xi2->device_id;
|
||||
evmask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &evmask.mask_len);
|
||||
evmask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
|
||||
event_mask,
|
||||
&evmask.mask_len);
|
||||
|
||||
XISelectEvents (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
@ -636,10 +647,14 @@ gdk_x11_device_xi2_select_window_events (GdkDevice *device,
|
||||
}
|
||||
|
||||
guchar *
|
||||
_gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
||||
gint *len)
|
||||
_gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
|
||||
GdkEventMask event_mask,
|
||||
gint *len)
|
||||
{
|
||||
guchar *mask;
|
||||
gint minor;
|
||||
|
||||
g_object_get (device_manager_xi2, "minor", &minor, NULL);
|
||||
|
||||
*len = XIMaskLen (XI_LASTEVENT);
|
||||
mask = g_new0 (guchar, *len);
|
||||
@ -688,6 +703,17 @@ _gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
||||
XISetMask (mask, XI_FocusOut);
|
||||
}
|
||||
|
||||
#ifdef XINPUT_2_2
|
||||
/* XInput 2.2 includes multitouch support */
|
||||
if (minor >= 2 &&
|
||||
event_mask & GDK_TOUCH_MASK)
|
||||
{
|
||||
XISetMask (mask, XI_TouchBegin);
|
||||
XISetMask (mask, XI_TouchUpdate);
|
||||
XISetMask (mask, XI_TouchEnd);
|
||||
}
|
||||
#endif /* XINPUT_2_2 */
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,11 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
||||
int major, minor;
|
||||
|
||||
major = 2;
|
||||
#ifdef XINPUT_2_2
|
||||
minor = 2;
|
||||
#else
|
||||
minor = 0;
|
||||
#endif /* XINPUT_2_2 */
|
||||
|
||||
if (!_gdk_disable_multidevice &&
|
||||
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#ifdef XINPUT_2
|
||||
|
||||
@ -164,8 +165,10 @@ _gdk_x11_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
|
||||
static void
|
||||
translate_valuator_class (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
XIValuatorClassInfo *info,
|
||||
gint n_valuator)
|
||||
Atom valuator_label,
|
||||
gdouble min,
|
||||
gdouble max,
|
||||
gdouble resolution)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
|
||||
@ -186,24 +189,19 @@ translate_valuator_class (GdkDisplay *display,
|
||||
|
||||
for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++)
|
||||
{
|
||||
if (label_atoms[i] == info->label)
|
||||
if (label_atoms[i] == valuator_label)
|
||||
{
|
||||
use = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->label != None)
|
||||
label = gdk_x11_xatom_to_atom_for_display (display, info->label);
|
||||
if (valuator_label != None)
|
||||
label = gdk_x11_xatom_to_atom_for_display (display, valuator_label);
|
||||
else
|
||||
label = GDK_NONE;
|
||||
|
||||
_gdk_device_add_axis (device,
|
||||
label,
|
||||
use,
|
||||
info->min,
|
||||
info->max,
|
||||
info->resolution);
|
||||
_gdk_device_add_axis (device, label, use, min, max, resolution);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -212,7 +210,7 @@ translate_device_classes (GdkDisplay *display,
|
||||
XIAnyClassInfo **classes,
|
||||
guint n_classes)
|
||||
{
|
||||
gint i, n_valuator = 0;
|
||||
gint i;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (device));
|
||||
|
||||
@ -234,10 +232,14 @@ translate_device_classes (GdkDisplay *display,
|
||||
}
|
||||
break;
|
||||
case XIValuatorClass:
|
||||
translate_valuator_class (display, device,
|
||||
(XIValuatorClassInfo *) class_info,
|
||||
n_valuator);
|
||||
n_valuator++;
|
||||
{
|
||||
XIValuatorClassInfo *valuator_info = (XIValuatorClassInfo *) class_info;
|
||||
translate_valuator_class (display, device,
|
||||
valuator_info->label,
|
||||
valuator_info->min,
|
||||
valuator_info->max,
|
||||
valuator_info->resolution);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Ignore */
|
||||
@ -893,6 +895,11 @@ get_event_window (GdkEventTranslator *translator,
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_Motion:
|
||||
#ifdef XINPUT_2_2
|
||||
case XI_TouchUpdate:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
#endif /* XINPUT_2_2 */
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
|
||||
@ -1117,51 +1124,39 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
GdkDevice *source_device;
|
||||
|
||||
switch (xev->detail)
|
||||
if (ev->evtype == XI_ButtonPress &&
|
||||
(xev->detail >= 4 && xev->detail <= 7))
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
/* Button presses of button 4-7 are scroll events */
|
||||
if (ev->evtype == XI_ButtonPress)
|
||||
{
|
||||
event->scroll.type = GDK_SCROLL;
|
||||
/* Button presses of button 4-7 are scroll events */
|
||||
event->scroll.type = GDK_SCROLL;
|
||||
|
||||
if (xev->detail == 4)
|
||||
event->scroll.direction = GDK_SCROLL_UP;
|
||||
else if (xev->detail == 5)
|
||||
event->scroll.direction = GDK_SCROLL_DOWN;
|
||||
else if (xev->detail == 6)
|
||||
event->scroll.direction = GDK_SCROLL_LEFT;
|
||||
else
|
||||
event->scroll.direction = GDK_SCROLL_RIGHT;
|
||||
if (xev->detail == 4)
|
||||
event->scroll.direction = GDK_SCROLL_UP;
|
||||
else if (xev->detail == 5)
|
||||
event->scroll.direction = GDK_SCROLL_DOWN;
|
||||
else if (xev->detail == 6)
|
||||
event->scroll.direction = GDK_SCROLL_LEFT;
|
||||
else
|
||||
event->scroll.direction = GDK_SCROLL_RIGHT;
|
||||
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xev->time;
|
||||
event->scroll.x = (gdouble) xev->event_x;
|
||||
event->scroll.y = (gdouble) xev->event_y;
|
||||
event->scroll.x_root = (gdouble) xev->root_x;
|
||||
event->scroll.y_root = (gdouble) xev->root_y;
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xev->time;
|
||||
event->scroll.x = (gdouble) xev->event_x;
|
||||
event->scroll.y = (gdouble) xev->event_y;
|
||||
event->scroll.x_root = (gdouble) xev->root_x;
|
||||
event->scroll.y_root = (gdouble) xev->root_y;
|
||||
|
||||
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
||||
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
break;
|
||||
}
|
||||
/* Button presses of button 4-7 are scroll events, so ignore the release */
|
||||
else if (ev->evtype == XI_ButtonRelease)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
/* else (XI_ButtonRelease) fall thru */
|
||||
default:
|
||||
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
}
|
||||
else
|
||||
{
|
||||
event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
|
||||
|
||||
event->button.window = window;
|
||||
@ -1194,9 +1189,13 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
}
|
||||
|
||||
event->button.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
event->button.button = xev->detail;
|
||||
}
|
||||
|
||||
if (xev->flags & (XIPointerEmulated | XITouchEmulatingPointer))
|
||||
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||
|
||||
if (return_val == FALSE)
|
||||
break;
|
||||
|
||||
@ -1211,15 +1210,14 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case XI_Motion:
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
GdkDevice *source_device;
|
||||
|
||||
event->motion.type = GDK_MOTION_NOTIFY;
|
||||
|
||||
event->motion.window = window;
|
||||
|
||||
event->motion.time = xev->time;
|
||||
event->motion.x = (gdouble) xev->event_x;
|
||||
event->motion.y = (gdouble) xev->event_y;
|
||||
@ -1235,6 +1233,9 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->motion.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
if (xev->flags & (XIPointerEmulated | XITouchEmulatingPointer))
|
||||
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||
|
||||
/* There doesn't seem to be motion hints in XI */
|
||||
event->motion.is_hint = FALSE;
|
||||
|
||||
@ -1254,6 +1255,124 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef XINPUT_2_2
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
GdkDevice *source_device;
|
||||
|
||||
if (ev->evtype == XI_TouchBegin)
|
||||
event->touch.type = GDK_TOUCH_BEGIN;
|
||||
else if (ev->evtype == XI_TouchEnd)
|
||||
event->touch.type = GDK_TOUCH_END;
|
||||
|
||||
event->touch.window = window;
|
||||
event->touch.time = xev->time;
|
||||
event->touch.x = (gdouble) xev->event_x;
|
||||
event->touch.y = (gdouble) xev->event_y;
|
||||
event->touch.x_root = (gdouble) xev->root_x;
|
||||
event->touch.y_root = (gdouble) xev->root_y;
|
||||
|
||||
event->touch.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
||||
event->touch.axes = translate_axes (event->touch.device,
|
||||
event->touch.x,
|
||||
event->touch.y,
|
||||
event->touch.window,
|
||||
&xev->valuators);
|
||||
|
||||
if (gdk_device_get_mode (event->touch.device) == GDK_MODE_WINDOW)
|
||||
{
|
||||
GdkDevice *device = event->touch.device;
|
||||
|
||||
/* Update event coordinates from axes */
|
||||
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_X, &event->touch.x);
|
||||
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
|
||||
}
|
||||
|
||||
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
if (ev->evtype == XI_TouchBegin)
|
||||
event->touch.state |= GDK_BUTTON1_MASK;
|
||||
|
||||
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||
|
||||
if (xev->flags & XITouchEmulatingPointer)
|
||||
{
|
||||
event->touch.emulating_pointer = TRUE;
|
||||
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||
}
|
||||
|
||||
if (return_val == FALSE)
|
||||
break;
|
||||
|
||||
if (!set_screen_from_root (display, event, xev->root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ev->evtype == XI_TouchBegin)
|
||||
set_user_time (event);
|
||||
}
|
||||
break;
|
||||
|
||||
case XI_TouchUpdate:
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
GdkDevice *source_device;
|
||||
|
||||
event->touch.window = window;
|
||||
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||
event->touch.type = GDK_TOUCH_UPDATE;
|
||||
event->touch.time = xev->time;
|
||||
event->touch.x = (gdouble) xev->event_x;
|
||||
event->touch.y = (gdouble) xev->event_y;
|
||||
event->touch.x_root = (gdouble) xev->root_x;
|
||||
event->touch.y_root = (gdouble) xev->root_y;
|
||||
|
||||
event->touch.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GINT_TO_POINTER (xev->deviceid));
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
||||
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
event->touch.state |= GDK_BUTTON1_MASK;
|
||||
|
||||
if (xev->flags & XITouchEmulatingPointer)
|
||||
{
|
||||
event->touch.emulating_pointer = TRUE;
|
||||
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||
}
|
||||
|
||||
event->touch.axes = translate_axes (event->touch.device,
|
||||
event->touch.x,
|
||||
event->touch.y,
|
||||
event->touch.window,
|
||||
&xev->valuators);
|
||||
|
||||
if (gdk_device_get_mode (event->touch.device) == GDK_MODE_WINDOW)
|
||||
{
|
||||
GdkDevice *device = event->touch.device;
|
||||
|
||||
/* Update event coordinates from axes */
|
||||
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_X, &event->touch.x);
|
||||
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
{
|
||||
@ -1350,7 +1469,8 @@ gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
|
||||
GDK_BUTTON2_MOTION_MASK |
|
||||
GDK_BUTTON3_MOTION_MASK |
|
||||
GDK_BUTTON_MOTION_MASK |
|
||||
GDK_FOCUS_CHANGE_MASK);
|
||||
GDK_FOCUS_CHANGE_MASK |
|
||||
GDK_TOUCH_MASK);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1364,7 +1484,9 @@ gdk_x11_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
|
||||
device_manager = GDK_DEVICE_MANAGER (translator);
|
||||
|
||||
event_mask.deviceid = XIAllMasterDevices;
|
||||
event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (evmask, &event_mask.mask_len);
|
||||
event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
|
||||
evmask,
|
||||
&event_mask.mask_len);
|
||||
|
||||
_gdk_x11_device_manager_xi2_select_events (device_manager, window, &event_mask);
|
||||
g_free (event_mask.mask);
|
||||
|
@ -245,8 +245,9 @@ void _gdk_x11_device_xi_translate_axes (GdkDevice *device,
|
||||
#endif
|
||||
|
||||
#ifdef XINPUT_2
|
||||
guchar * _gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
||||
gint *len);
|
||||
guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
|
||||
GdkEventMask event_mask,
|
||||
gint *len);
|
||||
guint _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
||||
XIButtonState *buttons_state,
|
||||
XIGroupState *group_state);
|
||||
|
Loading…
Reference in New Issue
Block a user