1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gdkdevicemanager-xi2.h"
24 #include <gdk/gdkdeviceprivate.h>
25 #include "gdkeventtranslator.h"
26 #include "gdkdevice-xi2.h"
27 #include "gdkkeysyms.h"
28 #include "gdkprivate-x11.h"
33 #define HAS_FOCUS(toplevel) ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
36 static void gdk_device_manager_xi2_constructed (GObject *object);
37 static void gdk_device_manager_xi2_dispose (GObject *object);
39 static GList * gdk_device_manager_xi2_list_devices (GdkDeviceManager *device_manager,
41 static GdkDevice * gdk_device_manager_xi2_get_client_pointer (GdkDeviceManager *device_manager);
43 static void gdk_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface);
45 static gboolean gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
49 static GdkEventMask gdk_device_manager_xi2_get_handled_events (GdkEventTranslator *translator);
50 static void gdk_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
52 GdkEventMask event_mask);
55 G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI2, gdk_device_manager_xi2, GDK_TYPE_DEVICE_MANAGER,
56 G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
57 gdk_device_manager_xi2_event_translator_init))
61 gdk_device_manager_xi2_class_init (GdkDeviceManagerXI2Class *klass)
63 GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
64 GObjectClass *object_class = G_OBJECT_CLASS (klass);
66 object_class->constructed = gdk_device_manager_xi2_constructed;
67 object_class->dispose = gdk_device_manager_xi2_dispose;
69 device_manager_class->list_devices = gdk_device_manager_xi2_list_devices;
70 device_manager_class->get_client_pointer = gdk_device_manager_xi2_get_client_pointer;
74 gdk_device_manager_xi2_init (GdkDeviceManagerXI2 *device_manager)
76 device_manager->id_table = g_hash_table_new_full (g_direct_hash,
79 (GDestroyNotify) g_object_unref);
83 _gdk_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
85 XIEventMask *event_mask)
90 display = gdk_device_manager_get_display (device_manager);
91 xdisplay = GDK_DISPLAY_XDISPLAY (display);
93 XISelectEvents (xdisplay, xwindow, event_mask, 1);
97 translate_valuator_class (GdkDisplay *display,
99 XIValuatorClassInfo *info,
102 static gboolean initialized = FALSE;
103 static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
104 GdkAxisUse use = GDK_AXIS_IGNORE;
110 label_atoms [GDK_AXIS_X] = gdk_x11_get_xatom_by_name_for_display (display, "Abs X");
111 label_atoms [GDK_AXIS_Y] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Y");
112 label_atoms [GDK_AXIS_PRESSURE] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Pressure");
113 label_atoms [GDK_AXIS_XTILT] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Tilt X");
114 label_atoms [GDK_AXIS_YTILT] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Tilt Y");
115 label_atoms [GDK_AXIS_WHEEL] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Wheel");
119 for (i = GDK_AXIS_IGNORE; i <= GDK_AXIS_LAST; i++)
121 if (label_atoms[i] == info->label)
128 if (info->label != None)
129 label = gdk_x11_xatom_to_atom_for_display (display, info->label);
133 _gdk_device_add_axis (device,
142 translate_device_classes (GdkDisplay *display,
144 XIAnyClassInfo **classes,
147 gint i, n_valuator = 0;
149 g_object_freeze_notify (G_OBJECT (device));
151 for (i = 0; i < n_classes; i++)
153 XIAnyClassInfo *class_info = classes[i];
155 switch (class_info->type)
159 XIKeyClassInfo *key_info = (XIKeyClassInfo *) class_info;
162 _gdk_device_set_keys (device, key_info->num_keycodes);
164 for (i = 0; i < key_info->num_keycodes; i++)
165 gdk_device_set_key (device, i, key_info->keycodes[i], 0);
168 case XIValuatorClass:
169 translate_valuator_class (display, device,
170 (XIValuatorClassInfo *) class_info,
180 g_object_thaw_notify (G_OBJECT (device));
184 create_device (GdkDeviceManager *device_manager,
188 GdkInputSource input_source;
193 if (dev->use == XIMasterKeyboard || dev->use == XISlaveKeyboard)
194 input_source = GDK_SOURCE_KEYBOARD;
199 tmp_name = g_ascii_strdown (dev->name, -1);
201 if (strstr (tmp_name, "eraser"))
202 input_source = GDK_SOURCE_ERASER;
203 else if (strstr (tmp_name, "cursor"))
204 input_source = GDK_SOURCE_CURSOR;
205 else if (strstr (tmp_name, "wacom") ||
206 strstr (tmp_name, "pen"))
207 input_source = GDK_SOURCE_PEN;
209 input_source = GDK_SOURCE_MOUSE;
216 case XIMasterKeyboard:
217 case XIMasterPointer:
218 type = GDK_DEVICE_TYPE_MASTER;
219 mode = GDK_MODE_SCREEN;
221 case XISlaveKeyboard:
223 type = GDK_DEVICE_TYPE_SLAVE;
224 mode = GDK_MODE_DISABLED;
226 case XIFloatingSlave:
228 type = GDK_DEVICE_TYPE_FLOATING;
229 mode = GDK_MODE_DISABLED;
233 device = g_object_new (GDK_TYPE_DEVICE_XI2,
236 "input-source", input_source,
238 "has-cursor", (dev->use == XIMasterPointer),
240 "device-manager", device_manager,
241 "device-id", dev->deviceid,
244 translate_device_classes (display, device, dev->classes, dev->num_classes);
250 add_device (GdkDeviceManagerXI2 *device_manager,
252 gboolean emit_signal)
257 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
258 device = create_device (GDK_DEVICE_MANAGER (device_manager), display, dev);
260 g_hash_table_replace (device_manager->id_table,
261 GINT_TO_POINTER (dev->deviceid),
262 g_object_ref (device));
264 if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
265 device_manager->master_devices = g_list_append (device_manager->master_devices, device);
266 else if (dev->use == XISlavePointer || dev->use == XISlaveKeyboard)
267 device_manager->slave_devices = g_list_append (device_manager->slave_devices, device);
268 else if (dev->use == XIFloatingSlave)
269 device_manager->floating_devices = g_list_append (device_manager->floating_devices, device);
271 g_warning ("Unhandled device: %s\n", gdk_device_get_name (device));
274 g_signal_emit_by_name (device_manager, "device-added", device);
280 remove_device (GdkDeviceManagerXI2 *device_manager,
285 device = g_hash_table_lookup (device_manager->id_table,
286 GINT_TO_POINTER (device_id));
290 device_manager->master_devices = g_list_remove (device_manager->master_devices, device);
291 device_manager->slave_devices = g_list_remove (device_manager->slave_devices, device);
292 device_manager->floating_devices = g_list_remove (device_manager->floating_devices, device);
294 g_signal_emit_by_name (device_manager, "device-removed", device);
296 g_object_run_dispose (G_OBJECT (device));
298 g_hash_table_remove (device_manager->id_table,
299 GINT_TO_POINTER (device_id));
304 relate_devices (gpointer key,
308 GdkDeviceManagerXI2 *device_manager;
309 GdkDevice *device, *relative;
311 device_manager = user_data;
312 device = g_hash_table_lookup (device_manager->id_table, key);
313 relative = g_hash_table_lookup (device_manager->id_table, value);
315 _gdk_device_set_associated_device (device, relative);
316 _gdk_device_set_associated_device (relative, device);
320 gdk_device_manager_xi2_constructed (GObject *object)
322 GdkDeviceManagerXI2 *device_manager_xi2;
325 GHashTable *relations;
327 XIDeviceInfo *info, *dev;
329 XIEventMask event_mask;
330 unsigned char mask[2] = { 0 };
332 device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (object);
333 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
334 xdisplay = GDK_DISPLAY_XDISPLAY (display);
335 relations = g_hash_table_new (NULL, NULL);
337 info = XIQueryDevice(xdisplay, XIAllDevices, &ndevices);
339 /* Initialize devices list */
340 for (i = 0; i < ndevices; i++)
345 device = add_device (device_manager_xi2, dev, FALSE);
347 if (dev->use == XIMasterPointer ||
348 dev->use == XIMasterKeyboard)
350 g_hash_table_insert (relations,
351 GINT_TO_POINTER (dev->deviceid),
352 GINT_TO_POINTER (dev->attachment));
356 XIFreeDeviceInfo(info);
358 /* Stablish relationships between devices */
359 g_hash_table_foreach (relations, relate_devices, object);
360 g_hash_table_destroy (relations);
362 /* Connect to hierarchy change events */
363 screen = gdk_display_get_default_screen (display);
364 XISetMask (mask, XI_HierarchyChanged);
365 XISetMask (mask, XI_DeviceChanged);
367 event_mask.deviceid = XIAllDevices;
368 event_mask.mask_len = sizeof (mask);
369 event_mask.mask = mask;
371 _gdk_device_manager_xi2_select_events (GDK_DEVICE_MANAGER (object),
372 GDK_WINDOW_XID (gdk_screen_get_root_window (screen)),
377 gdk_device_manager_xi2_dispose (GObject *object)
379 GdkDeviceManagerXI2 *device_manager_xi2;
381 device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (object);
383 g_list_foreach (device_manager_xi2->master_devices, (GFunc) g_object_unref, NULL);
384 g_list_free (device_manager_xi2->master_devices);
385 device_manager_xi2->master_devices = NULL;
387 g_list_foreach (device_manager_xi2->slave_devices, (GFunc) g_object_unref, NULL);
388 g_list_free (device_manager_xi2->slave_devices);
389 device_manager_xi2->slave_devices = NULL;
391 g_list_foreach (device_manager_xi2->floating_devices, (GFunc) g_object_unref, NULL);
392 g_list_free (device_manager_xi2->floating_devices);
393 device_manager_xi2->floating_devices = NULL;
395 if (device_manager_xi2->id_table)
397 g_hash_table_destroy (device_manager_xi2->id_table);
398 device_manager_xi2->id_table = NULL;
401 G_OBJECT_CLASS (gdk_device_manager_xi2_parent_class)->dispose (object);
405 gdk_device_manager_xi2_list_devices (GdkDeviceManager *device_manager,
408 GdkDeviceManagerXI2 *device_manager_xi2;
411 device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (device_manager);
415 case GDK_DEVICE_TYPE_MASTER:
416 list = device_manager_xi2->master_devices;
418 case GDK_DEVICE_TYPE_SLAVE:
419 list = device_manager_xi2->slave_devices;
421 case GDK_DEVICE_TYPE_FLOATING:
422 list = device_manager_xi2->floating_devices;
425 g_assert_not_reached ();
428 return g_list_copy (list);
432 gdk_device_manager_xi2_get_client_pointer (GdkDeviceManager *device_manager)
434 GdkDeviceManagerXI2 *device_manager_xi2;
438 device_manager_xi2 = (GdkDeviceManagerXI2 *) device_manager;
439 display = gdk_device_manager_get_display (device_manager);
441 XIGetClientPointer (GDK_DISPLAY_XDISPLAY (display),
444 return g_hash_table_lookup (device_manager_xi2->id_table,
445 GINT_TO_POINTER (device_id));
449 gdk_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface)
451 iface->translate_event = gdk_device_manager_xi2_translate_event;
452 iface->get_handled_events = gdk_device_manager_xi2_get_handled_events;
453 iface->select_window_events = gdk_device_manager_xi2_select_window_events;
457 handle_hierarchy_changed (GdkDeviceManagerXI2 *device_manager,
458 XIHierarchyEvent *ev)
463 /* We only care about enabled devices */
464 if (!(ev->flags & XIDeviceEnabled) &&
465 !(ev->flags & XIDeviceDisabled))
468 for (i = 0; i < ev->num_info; i++)
470 if (ev->info[i].flags & XIDeviceEnabled)
477 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
478 xdisplay = GDK_DISPLAY_XDISPLAY (display);
480 info = XIQueryDevice(xdisplay, ev->info[i].deviceid, &ndevices);
481 device = add_device (device_manager, &info[0], TRUE);
482 XIFreeDeviceInfo(info);
484 else if (ev->info[i].flags & XIDeviceDisabled)
485 remove_device (device_manager, ev->info[i].deviceid);
490 handle_device_changed (GdkDeviceManagerXI2 *device_manager,
491 XIDeviceChangedEvent *ev)
496 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
497 device = g_hash_table_lookup (device_manager->id_table,
498 GUINT_TO_POINTER (ev->deviceid));
500 _gdk_device_reset_axes (device);
501 translate_device_classes (display, device, ev->classes, ev->num_classes);
504 static GdkCrossingMode
505 translate_crossing_mode (int mode)
510 return GDK_CROSSING_NORMAL;
512 return GDK_CROSSING_GRAB;
514 return GDK_CROSSING_UNGRAB;
516 g_assert_not_reached ();
521 translate_notify_type (int detail)
526 return GDK_NOTIFY_INFERIOR;
528 return GDK_NOTIFY_ANCESTOR;
530 return GDK_NOTIFY_VIRTUAL;
531 case NotifyNonlinear:
532 return GDK_NOTIFY_NONLINEAR;
533 case NotifyNonlinearVirtual:
534 return GDK_NOTIFY_NONLINEAR_VIRTUAL;
536 g_assert_not_reached ();
541 set_screen_from_root (GdkDisplay *display,
547 screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
551 gdk_event_set_screen (event, screen);
560 set_user_time (GdkEvent *event)
565 window = gdk_window_get_toplevel (event->any.window);
566 g_return_if_fail (GDK_IS_WINDOW (window));
568 time = gdk_event_get_time (event);
570 /* If an event doesn't have a valid timestamp, we shouldn't use it
571 * to update the latest user interaction time.
573 if (time != GDK_CURRENT_TIME)
574 gdk_x11_window_set_user_time (window, time);
578 translate_keyboard_string (GdkEventKey *event)
583 /* Fill in event->string crudely, since various programs
586 event->string = NULL;
588 if (event->keyval != GDK_KEY_VoidSymbol)
589 c = gdk_keyval_to_unicode (event->keyval);
596 /* Apply the control key - Taken from Xlib
598 if (event->state & GDK_CONTROL_MASK)
600 if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
603 event->string = g_memdup ("\0\0", 2);
608 else if (c >= '3' && c <= '7') c -= ('3' - '\033');
609 else if (c == '8') c = '\177';
610 else if (c == '/') c = '_' & 0x1F;
613 len = g_unichar_to_utf8 (c, buf);
616 event->string = g_locale_from_utf8 (buf, len,
617 NULL, &bytes_written,
620 event->length = bytes_written;
622 else if (event->keyval == GDK_KEY_Escape)
625 event->string = g_strdup ("\033");
627 else if (event->keyval == GDK_KEY_Return ||
628 event->keyval == GDK_KEY_KP_Enter)
631 event->string = g_strdup ("\r");
637 event->string = g_strdup ("");
642 generate_focus_event (GdkWindow *window,
648 event = gdk_event_new (GDK_FOCUS_CHANGE);
649 event->focus_change.window = g_object_ref (window);
650 event->focus_change.send_event = FALSE;
651 event->focus_change.in = in;
652 gdk_event_set_device (event, device);
654 gdk_event_put (event);
655 gdk_event_free (event);
659 handle_focus_change (GdkWindow *window,
665 GdkToplevelX11 *toplevel;
668 toplevel = _gdk_x11_window_get_toplevel (window);
673 had_focus = HAS_FOCUS (toplevel);
679 /* When the focus moves from an ancestor of the window to
680 * the window or a descendent of the window, *and* the
681 * pointer is inside the window, then we were previously
682 * receiving keystroke events in the has_pointer_focus
683 * case and are now receiving them in the
684 * has_focus_window case.
686 if (toplevel->has_pointer &&
687 mode != NotifyGrab &&
688 mode != NotifyUngrab)
689 toplevel->has_pointer_focus = (in) ? FALSE : TRUE;
692 case NotifyNonlinear:
693 case NotifyNonlinearVirtual:
694 if (mode != NotifyGrab &&
695 mode != NotifyUngrab)
696 toplevel->has_focus_window = (in) ? TRUE : FALSE;
697 /* We pretend that the focus moves to the grab
698 * window, so we pay attention to NotifyGrab
699 * NotifyUngrab, and ignore NotifyWhileGrabbed
701 if (mode != NotifyWhileGrabbed)
702 toplevel->has_focus = (in) ? TRUE : FALSE;
705 /* The X server sends NotifyPointer/NotifyGrab,
706 * but the pointer focus is ignored while a
709 if (mode != NotifyGrab &&
710 mode != NotifyUngrab)
711 toplevel->has_pointer_focus = (in) ? TRUE :FALSE;
714 case NotifyPointerRoot:
715 case NotifyDetailNone:
719 if (HAS_FOCUS (toplevel) != had_focus)
720 generate_focus_event (window, device, (in) ? TRUE : FALSE);
724 translate_axes (GdkDevice *device,
728 XIValuatorState *valuators)
735 g_object_get (device, "n-axes", &n_axes, NULL);
737 axes = g_new0 (gdouble, n_axes);
738 vals = valuators->values;
740 width = gdk_window_get_width (window);
741 height = gdk_window_get_height (window);
743 for (i = 0; i < valuators->mask_len * 8; i++)
748 if (!XIMaskIsSet (valuators->mask, i))
751 use = _gdk_device_get_axis_use (device, i);
758 if (gdk_device_get_mode (device) == GDK_MODE_WINDOW)
759 _gdk_device_translate_window_coord (device, window, i, val, &axes[i]);
762 if (use == GDK_AXIS_X)
769 _gdk_device_translate_axis (device, i, val, &axes[i]);
778 is_parent_of (GdkWindow *parent,
789 w = gdk_window_get_parent (w);
796 get_event_window (GdkEventTranslator *translator,
800 GdkWindow *window = NULL;
802 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (translator));
809 case XI_ButtonRelease:
812 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
814 window = gdk_window_lookup_for_display (display, xev->event);
816 /* Apply keyboard grabs to non-native windows */
817 if (ev->evtype == XI_KeyPress || ev->evtype == XI_KeyRelease)
819 GdkDeviceGrabInfo *info;
823 device = g_hash_table_lookup (GDK_DEVICE_MANAGER_XI2 (translator)->id_table,
824 GUINT_TO_POINTER (((XIDeviceEvent *) ev)->deviceid));
826 serial = _gdk_windowing_window_get_next_serial (display);
827 info = _gdk_display_has_device_grab (display, device, serial);
830 (!is_parent_of (info->window, window) ||
831 !info->owner_events))
833 /* Report key event against grab window */
834 window = info->window;
844 XIEnterEvent *xev = (XIEnterEvent *) ev;
846 window = gdk_window_lookup_for_display (display, xev->event);
855 gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
860 GdkDeviceManagerXI2 *device_manager;
861 XGenericEventCookie *cookie;
862 gboolean return_val = TRUE;
867 dpy = GDK_DISPLAY_XDISPLAY (display);
868 device_manager = (GdkDeviceManagerXI2 *) translator;
869 cookie = &xevent->xcookie;
871 if (!XGetEventData (dpy, cookie))
874 if (cookie->type != GenericEvent ||
875 cookie->extension != device_manager->opcode)
877 XFreeEventData (dpy, cookie);
881 ev = (XIEvent *) cookie->data;
883 window = get_event_window (translator, ev);
885 if (window && GDK_WINDOW_DESTROYED (window))
887 XFreeEventData (dpy, cookie);
891 if (ev->evtype == XI_Motion ||
892 ev->evtype == XI_ButtonRelease)
894 if (_gdk_moveresize_handle_event (xevent))
896 XFreeEventData (dpy, cookie);
903 case XI_HierarchyChanged:
904 handle_hierarchy_changed (device_manager,
905 (XIHierarchyEvent *) ev);
908 case XI_DeviceChanged:
909 handle_device_changed (device_manager,
910 (XIDeviceChangedEvent *) ev);
916 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
917 GdkKeymap *keymap = gdk_keymap_get_for_display (display);
918 GdkModifierType consumed, state;
921 event->key.type = xev->evtype == XI_KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
923 event->key.window = window;
925 event->key.time = xev->time;
926 event->key.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
927 event->key.group = _gdk_x11_get_group_for_state (display, event->key.state);
929 event->key.hardware_keycode = xev->detail;
930 event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
932 device = g_hash_table_lookup (device_manager->id_table,
933 GUINT_TO_POINTER (xev->deviceid));
934 gdk_event_set_device (event, device);
936 event->key.keyval = GDK_KEY_VoidSymbol;
938 gdk_keymap_translate_keyboard_state (keymap,
939 event->key.hardware_keycode,
943 NULL, NULL, &consumed);
945 state = event->key.state & ~consumed;
946 _gdk_keymap_add_virtual_modifiers_compat (keymap, &state);
947 event->key.state |= state;
949 translate_keyboard_string ((GdkEventKey *) event);
951 if (ev->evtype == XI_KeyPress)
952 set_user_time (event);
954 /* FIXME: emulate autorepeat on key
955 * release? XI2 seems attached to Xkb.
961 case XI_ButtonRelease:
963 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
971 event->scroll.type = GDK_SCROLL;
973 if (xev->detail == 4)
974 event->scroll.direction = GDK_SCROLL_UP;
975 else if (xev->detail == 5)
976 event->scroll.direction = GDK_SCROLL_DOWN;
977 else if (xev->detail == 6)
978 event->scroll.direction = GDK_SCROLL_LEFT;
980 event->scroll.direction = GDK_SCROLL_RIGHT;
982 event->scroll.window = window;
983 event->scroll.time = xev->time;
984 event->scroll.x = (gdouble) xev->event_x;
985 event->scroll.y = (gdouble) xev->event_y;
986 event->scroll.x_root = (gdouble) xev->root_x;
987 event->scroll.y_root = (gdouble) xev->root_y;
989 event->scroll.device = g_hash_table_lookup (device_manager->id_table,
990 GUINT_TO_POINTER (xev->deviceid));
992 event->scroll.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
995 event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
997 event->button.window = window;
998 event->button.time = xev->time;
999 event->button.x = (gdouble) xev->event_x;
1000 event->button.y = (gdouble) xev->event_y;
1001 event->button.x_root = (gdouble) xev->root_x;
1002 event->button.y_root = (gdouble) xev->root_y;
1004 event->button.device = g_hash_table_lookup (device_manager->id_table,
1005 GUINT_TO_POINTER (xev->deviceid));
1007 event->button.axes = translate_axes (event->button.device,
1010 event->button.window,
1013 if (gdk_device_get_mode (event->button.device) == GDK_MODE_WINDOW)
1015 GdkDevice *device = event->button.device;
1017 /* Update event coordinates from axes */
1018 gdk_device_get_axis (device, event->button.axes, GDK_AXIS_X, &event->button.x);
1019 gdk_device_get_axis (device, event->button.axes, GDK_AXIS_Y, &event->button.y);
1022 event->button.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
1023 event->button.button = xev->detail;
1026 if (!set_screen_from_root (display, event, xev->root))
1032 set_user_time (event);
1038 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
1040 event->motion.type = GDK_MOTION_NOTIFY;
1042 event->motion.window = window;
1044 event->motion.time = xev->time;
1045 event->motion.x = (gdouble) xev->event_x;
1046 event->motion.y = (gdouble) xev->event_y;
1047 event->motion.x_root = (gdouble) xev->root_x;
1048 event->motion.y_root = (gdouble) xev->root_y;
1050 event->motion.device = g_hash_table_lookup (device_manager->id_table,
1051 GINT_TO_POINTER (xev->deviceid));
1053 event->motion.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
1055 /* There doesn't seem to be motion hints in XI */
1056 event->motion.is_hint = FALSE;
1058 event->motion.axes = translate_axes (event->motion.device,
1061 event->motion.window,
1064 if (gdk_device_get_mode (event->motion.device) == GDK_MODE_WINDOW)
1066 GdkDevice *device = event->motion.device;
1068 /* Update event coordinates from axes */
1069 gdk_device_get_axis (device, event->motion.axes, GDK_AXIS_X, &event->motion.x);
1070 gdk_device_get_axis (device, event->motion.axes, GDK_AXIS_Y, &event->motion.y);
1077 XIEnterEvent *xev = (XIEnterEvent *) ev;
1080 event->crossing.type = (ev->evtype == XI_Enter) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY;
1082 event->crossing.x = (gdouble) xev->event_x;
1083 event->crossing.y = (gdouble) xev->event_y;
1084 event->crossing.x_root = (gdouble) xev->root_x;
1085 event->crossing.y_root = (gdouble) xev->root_y;
1086 event->crossing.time = xev->time;
1087 event->crossing.focus = xev->focus;
1089 event->crossing.window = window;
1090 event->crossing.subwindow = gdk_window_lookup_for_display (display, xev->child);
1092 device = g_hash_table_lookup (device_manager->id_table,
1093 GINT_TO_POINTER (xev->deviceid));
1094 gdk_event_set_device (event, device);
1096 event->crossing.mode = translate_crossing_mode (xev->mode);
1097 event->crossing.detail = translate_notify_type (xev->detail);
1098 event->crossing.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
1104 XIEnterEvent *xev = (XIEnterEvent *) ev;
1107 device = g_hash_table_lookup (device_manager->id_table,
1108 GINT_TO_POINTER (xev->deviceid));
1110 handle_focus_change (window, device, xev->detail, xev->mode,
1111 (ev->evtype == XI_FocusIn) ? TRUE : FALSE);
1120 event->any.send_event = cookie->send_event;
1124 if (event->any.window)
1125 g_object_ref (event->any.window);
1127 if (((event->any.type == GDK_ENTER_NOTIFY) ||
1128 (event->any.type == GDK_LEAVE_NOTIFY)) &&
1129 (event->crossing.subwindow != NULL))
1130 g_object_ref (event->crossing.subwindow);
1134 /* Mark this event as having no resources to be freed */
1135 event->any.window = NULL;
1136 event->any.type = GDK_NOTHING;
1139 XFreeEventData (dpy, cookie);
1145 gdk_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
1147 return (GDK_KEY_PRESS_MASK |
1148 GDK_KEY_RELEASE_MASK |
1149 GDK_BUTTON_PRESS_MASK |
1150 GDK_BUTTON_RELEASE_MASK |
1152 GDK_ENTER_NOTIFY_MASK |
1153 GDK_LEAVE_NOTIFY_MASK |
1154 GDK_POINTER_MOTION_MASK |
1155 GDK_POINTER_MOTION_HINT_MASK |
1156 GDK_BUTTON1_MOTION_MASK |
1157 GDK_BUTTON2_MOTION_MASK |
1158 GDK_BUTTON3_MOTION_MASK |
1159 GDK_BUTTON_MOTION_MASK |
1160 GDK_FOCUS_CHANGE_MASK);
1164 gdk_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
1166 GdkEventMask evmask)
1168 GdkDeviceManager *device_manager;
1169 XIEventMask event_mask;
1171 device_manager = GDK_DEVICE_MANAGER (translator);
1173 event_mask.deviceid = XIAllMasterDevices;
1174 event_mask.mask = gdk_device_xi2_translate_event_mask (evmask, &event_mask.mask_len);
1176 _gdk_device_manager_xi2_select_events (device_manager, window, &event_mask);
1177 g_free (event_mask.mask);