1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3 *
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.
8 *
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.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include "gdkx11devicemanager-xi2.h"
21 #include "gdkx11device-xi2.h"
22
23 #include "gdkdevicemanagerprivate-core.h"
24 #include "gdkdeviceprivate.h"
25 #include "gdkdevicetoolprivate.h"
26 #include "gdkdisplayprivate.h"
27 #include "gdkeventtranslator.h"
28 #include "gdkprivate-x11.h"
29 #include "gdkintl.h"
30 #include "gdkkeysyms.h"
31 #include "gdkinternals.h"
32 #include "gdkseatdefaultprivate.h"
33
34 #include <X11/Xlib.h>
35 #include <X11/Xutil.h>
36 #include <X11/extensions/XInput2.h>
37 #include <X11/Xatom.h>
38
39 #include <string.h>
40
41 static const char *wacom_type_atoms[] = {
42 "STYLUS",
43 "CURSOR",
44 "ERASER",
45 "PAD",
46 "TOUCH"
47 };
48 #define N_WACOM_TYPE_ATOMS G_N_ELEMENTS (wacom_type_atoms)
49
50 enum {
51 WACOM_TYPE_STYLUS,
52 WACOM_TYPE_CURSOR,
53 WACOM_TYPE_ERASER,
54 WACOM_TYPE_PAD,
55 WACOM_TYPE_TOUCH,
56 };
57
58 struct _GdkX11DeviceManagerXI2
59 {
60 GdkX11DeviceManagerCore parent_object;
61
62 GHashTable *id_table;
63
64 GList *devices;
65
66 gint opcode;
67 gint major;
68 gint minor;
69 };
70
71 struct _GdkX11DeviceManagerXI2Class
72 {
73 GdkDeviceManagerClass parent_class;
74 };
75
76 static void gdk_x11_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface);
77
78 G_DEFINE_TYPE_WITH_CODE (GdkX11DeviceManagerXI2, gdk_x11_device_manager_xi2, GDK_TYPE_X11_DEVICE_MANAGER_CORE,
79 G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
80 gdk_x11_device_manager_xi2_event_translator_init))
81
82 static void gdk_x11_device_manager_xi2_constructed (GObject *object);
83 static void gdk_x11_device_manager_xi2_dispose (GObject *object);
84 static void gdk_x11_device_manager_xi2_set_property (GObject *object,
85 guint prop_id,
86 const GValue *value,
87 GParamSpec *pspec);
88 static void gdk_x11_device_manager_xi2_get_property (GObject *object,
89 guint prop_id,
90 GValue *value,
91 GParamSpec *pspec);
92
93 static GList * gdk_x11_device_manager_xi2_list_devices (GdkDeviceManager *device_manager,
94 GdkDeviceType type);
95 static GdkDevice * gdk_x11_device_manager_xi2_get_client_pointer (GdkDeviceManager *device_manager);
96
97 static gboolean gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
98 GdkDisplay *display,
99 GdkEvent *event,
100 XEvent *xevent);
101 static GdkEventMask gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator);
102 static void gdk_x11_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
103 Window window,
104 GdkEventMask event_mask);
105 static GdkWindow * gdk_x11_device_manager_xi2_get_window (GdkEventTranslator *translator,
106 XEvent *xevent);
107
108 enum {
109 PROP_0,
110 PROP_OPCODE,
111 PROP_MAJOR,
112 PROP_MINOR
113 };
114
115 static void
gdk_x11_device_manager_xi2_class_init(GdkX11DeviceManagerXI2Class * klass)116 gdk_x11_device_manager_xi2_class_init (GdkX11DeviceManagerXI2Class *klass)
117 {
118 GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
119 GObjectClass *object_class = G_OBJECT_CLASS (klass);
120
121 object_class->constructed = gdk_x11_device_manager_xi2_constructed;
122 object_class->dispose = gdk_x11_device_manager_xi2_dispose;
123 object_class->set_property = gdk_x11_device_manager_xi2_set_property;
124 object_class->get_property = gdk_x11_device_manager_xi2_get_property;
125
126 device_manager_class->list_devices = gdk_x11_device_manager_xi2_list_devices;
127 device_manager_class->get_client_pointer = gdk_x11_device_manager_xi2_get_client_pointer;
128
129 g_object_class_install_property (object_class,
130 PROP_OPCODE,
131 g_param_spec_int ("opcode",
132 P_("Opcode"),
133 P_("Opcode for XInput2 requests"),
134 0, G_MAXINT, 0,
135 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
136 g_object_class_install_property (object_class,
137 PROP_MAJOR,
138 g_param_spec_int ("major",
139 P_("Major"),
140 P_("Major version number"),
141 0, G_MAXINT, 0,
142 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
143 g_object_class_install_property (object_class,
144 PROP_MINOR,
145 g_param_spec_int ("minor",
146 P_("Minor"),
147 P_("Minor version number"),
148 0, G_MAXINT, 0,
149 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
150 }
151
152 static void
gdk_x11_device_manager_xi2_init(GdkX11DeviceManagerXI2 * device_manager)153 gdk_x11_device_manager_xi2_init (GdkX11DeviceManagerXI2 *device_manager)
154 {
155 device_manager->id_table = g_hash_table_new_full (g_direct_hash,
156 g_direct_equal,
157 NULL,
158 (GDestroyNotify) g_object_unref);
159 }
160
161 static void
_gdk_x11_device_manager_xi2_select_events(GdkDeviceManager * device_manager,Window xwindow,XIEventMask * event_mask)162 _gdk_x11_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
163 Window xwindow,
164 XIEventMask *event_mask)
165 {
166 GdkDisplay *display;
167 Display *xdisplay;
168
169 display = gdk_device_manager_get_display (device_manager);
170 xdisplay = GDK_DISPLAY_XDISPLAY (display);
171
172 XISelectEvents (xdisplay, xwindow, event_mask, 1);
173 }
174
175 static void
translate_valuator_class(GdkDisplay * display,GdkDevice * device,Atom valuator_label,gdouble min,gdouble max,gdouble resolution)176 translate_valuator_class (GdkDisplay *display,
177 GdkDevice *device,
178 Atom valuator_label,
179 gdouble min,
180 gdouble max,
181 gdouble resolution)
182 {
183 static gboolean initialized = FALSE;
184 static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
185 GdkAxisUse use = GDK_AXIS_IGNORE;
186 GdkAtom label;
187 gint i;
188
189 if (!initialized)
190 {
191 label_atoms [GDK_AXIS_X] = gdk_x11_get_xatom_by_name_for_display (display, "Abs X");
192 label_atoms [GDK_AXIS_Y] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Y");
193 label_atoms [GDK_AXIS_PRESSURE] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Pressure");
194 label_atoms [GDK_AXIS_XTILT] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Tilt X");
195 label_atoms [GDK_AXIS_YTILT] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Tilt Y");
196 label_atoms [GDK_AXIS_WHEEL] = gdk_x11_get_xatom_by_name_for_display (display, "Abs Wheel");
197 initialized = TRUE;
198 }
199
200 for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++)
201 {
202 if (label_atoms[i] == valuator_label)
203 {
204 use = i;
205 break;
206 }
207 }
208
209 if (valuator_label != None)
210 label = gdk_x11_xatom_to_atom_for_display (display, valuator_label);
211 else
212 label = GDK_NONE;
213
214 _gdk_device_add_axis (device, label, use, min, max, resolution);
215 GDK_NOTE (INPUT, g_message ("\n\taxis: %s %s", gdk_atom_name (label), use == GDK_AXIS_IGNORE ? "(ignored)" : "(used)"));
216 }
217
218 static void
translate_device_classes(GdkDisplay * display,GdkDevice * device,XIAnyClassInfo ** classes,guint n_classes)219 translate_device_classes (GdkDisplay *display,
220 GdkDevice *device,
221 XIAnyClassInfo **classes,
222 guint n_classes)
223 {
224 gint i;
225
226 g_object_freeze_notify (G_OBJECT (device));
227
228 for (i = 0; i < n_classes; i++)
229 {
230 XIAnyClassInfo *class_info = classes[i];
231
232 switch (class_info->type)
233 {
234 case XIKeyClass:
235 {
236 XIKeyClassInfo *key_info = (XIKeyClassInfo *) class_info;
237 gint j;
238
239 _gdk_device_set_keys (device, key_info->num_keycodes);
240
241 for (j = 0; j < key_info->num_keycodes; j++)
242 gdk_device_set_key (device, j, key_info->keycodes[j], 0);
243 }
244 break;
245 case XIValuatorClass:
246 {
247 XIValuatorClassInfo *valuator_info = (XIValuatorClassInfo *) class_info;
248 translate_valuator_class (display, device,
249 valuator_info->label,
250 valuator_info->min,
251 valuator_info->max,
252 valuator_info->resolution);
253 }
254 break;
255 #ifdef XINPUT_2_2
256 case XIScrollClass:
257 {
258 XIScrollClassInfo *scroll_info = (XIScrollClassInfo *) class_info;
259 GdkScrollDirection direction;
260
261 if (scroll_info->scroll_type == XIScrollTypeVertical)
262 direction = GDK_SCROLL_DOWN;
263 else
264 direction = GDK_SCROLL_RIGHT;
265
266 GDK_NOTE (INPUT,
267 g_message ("\n\tscroll valuator %d: %s, increment %f",
268 scroll_info->number,
269 scroll_info->scroll_type == XIScrollTypeVertical
270 ? "vertical"
271 : "horizontal",
272 scroll_info->increment));
273
274 _gdk_x11_device_xi2_add_scroll_valuator (GDK_X11_DEVICE_XI2 (device),
275 scroll_info->number,
276 direction,
277 scroll_info->increment);
278 }
279 #endif /* XINPUT_2_2 */
280 default:
281 /* Ignore */
282 break;
283 }
284 }
285
286 g_object_thaw_notify (G_OBJECT (device));
287 }
288
289 static gboolean
is_touch_device(XIAnyClassInfo ** classes,guint n_classes,GdkInputSource * device_type,gint * num_touches)290 is_touch_device (XIAnyClassInfo **classes,
291 guint n_classes,
292 GdkInputSource *device_type,
293 gint *num_touches)
294 {
295 #ifdef XINPUT_2_2
296 guint i;
297
298 for (i = 0; i < n_classes; i++)
299 {
300 XITouchClassInfo *class = (XITouchClassInfo *) classes[i];
301
302 if (class->type != XITouchClass)
303 continue;
304
305 if (class->num_touches > 0)
306 {
307 if (class->mode == XIDirectTouch)
308 *device_type = GDK_SOURCE_TOUCHSCREEN;
309 else if (class->mode == XIDependentTouch)
310 *device_type = GDK_SOURCE_TOUCHPAD;
311 else
312 continue;
313
314 *num_touches = class->num_touches;
315
316 return TRUE;
317 }
318 }
319 #endif
320
321 return FALSE;
322 }
323
324 static gboolean
has_abs_axes(GdkDisplay * display,XIAnyClassInfo ** classes,guint n_classes)325 has_abs_axes (GdkDisplay *display,
326 XIAnyClassInfo **classes,
327 guint n_classes)
328 {
329 gboolean has_x = FALSE, has_y = FALSE;
330 Atom abs_x, abs_y;
331 guint i;
332
333 abs_x = gdk_x11_get_xatom_by_name_for_display (display, "Abs X");
334 abs_y = gdk_x11_get_xatom_by_name_for_display (display, "Abs Y");
335
336 for (i = 0; i < n_classes; i++)
337 {
338 XIValuatorClassInfo *class = (XIValuatorClassInfo *) classes[i];
339
340 if (class->type != XIValuatorClass)
341 continue;
342 if (class->mode != XIModeAbsolute)
343 continue;
344
345 if (class->label == abs_x)
346 has_x = TRUE;
347 else if (class->label == abs_y)
348 has_y = TRUE;
349
350 if (has_x && has_y)
351 break;
352 }
353
354 return (has_x && has_y);
355 }
356
357 static gboolean
get_device_ids(GdkDisplay * display,XIDeviceInfo * info,gchar ** vendor_id,gchar ** product_id)358 get_device_ids (GdkDisplay *display,
359 XIDeviceInfo *info,
360 gchar **vendor_id,
361 gchar **product_id)
362 {
363 gulong nitems, bytes_after;
364 guint32 *data;
365 int rc, format;
366 Atom prop, type;
367
368 gdk_x11_display_error_trap_push (display);
369
370 prop = XInternAtom (GDK_DISPLAY_XDISPLAY (display), "Device Product ID", True);
371
372 if (prop == None)
373 {
374 gdk_x11_display_error_trap_pop_ignored (display);
375 return 0;
376 }
377
378 rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display),
379 info->deviceid, prop,
380 0, 2, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
381 (guchar **) &data);
382 gdk_x11_display_error_trap_pop_ignored (display);
383
384 if (rc != Success || type != XA_INTEGER || format != 32 || nitems != 2)
385 return FALSE;
386
387 if (vendor_id)
388 *vendor_id = g_strdup_printf ("%.4x", data[0]);
389 if (product_id)
390 *product_id = g_strdup_printf ("%.4x", data[1]);
391
392 XFree (data);
393
394 return TRUE;
395 }
396
397 static gboolean
is_touchpad_device(GdkDisplay * display,XIDeviceInfo * info)398 is_touchpad_device (GdkDisplay *display,
399 XIDeviceInfo *info)
400 {
401 gulong nitems, bytes_after;
402 guint32 *data;
403 int rc, format;
404 Atom type;
405
406 gdk_x11_display_error_trap_push (display);
407
408 rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display),
409 info->deviceid,
410 gdk_x11_get_xatom_by_name_for_display (display, "libinput Tapping Enabled"),
411 0, 1, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
412 (guchar **) &data);
413 gdk_x11_display_error_trap_pop_ignored (display);
414
415 if (rc != Success || type != XA_INTEGER || format != 8 || nitems != 1)
416 return FALSE;
417
418 XFree (data);
419
420 return TRUE;
421 }
422
423 static GdkDevice *
create_device(GdkDeviceManager * device_manager,GdkDisplay * display,XIDeviceInfo * dev)424 create_device (GdkDeviceManager *device_manager,
425 GdkDisplay *display,
426 XIDeviceInfo *dev)
427 {
428 GdkInputSource input_source;
429 GdkInputSource touch_source;
430 GdkDeviceType type;
431 GdkDevice *device;
432 GdkInputMode mode;
433 gint num_touches = 0;
434 gchar *vendor_id = NULL, *product_id = NULL;
435
436 if (dev->use == XIMasterKeyboard || dev->use == XISlaveKeyboard)
437 input_source = GDK_SOURCE_KEYBOARD;
438 else if (is_touchpad_device (display, dev))
439 input_source = GDK_SOURCE_TOUCHPAD;
440 else if (dev->use == XISlavePointer &&
441 is_touch_device (dev->classes, dev->num_classes, &touch_source, &num_touches))
442 input_source = touch_source;
443 else
444 {
445 gchar *tmp_name;
446
447 tmp_name = g_ascii_strdown (dev->name, -1);
448
449 if (strstr (tmp_name, "eraser"))
450 input_source = GDK_SOURCE_ERASER;
451 else if (strstr (tmp_name, "cursor"))
452 input_source = GDK_SOURCE_CURSOR;
453 else if (strstr (tmp_name, " pad"))
454 input_source = GDK_SOURCE_TABLET_PAD;
455 else if (strstr (tmp_name, "wacom") ||
456 strstr (tmp_name, "pen"))
457 input_source = GDK_SOURCE_PEN;
458 else if (!strstr (tmp_name, "mouse") &&
459 !strstr (tmp_name, "pointer") &&
460 !strstr (tmp_name, "qemu usb tablet") &&
461 !strstr (tmp_name, "spice vdagent tablet") &&
462 !strstr (tmp_name, "virtualbox usb tablet") &&
463 has_abs_axes (display, dev->classes, dev->num_classes))
464 input_source = GDK_SOURCE_TOUCHSCREEN;
465 else if (strstr (tmp_name, "trackpoint") ||
466 strstr (tmp_name, "dualpoint stick"))
467 input_source = GDK_SOURCE_TRACKPOINT;
468 else
469 input_source = GDK_SOURCE_MOUSE;
470
471 g_free (tmp_name);
472 }
473
474 switch (dev->use)
475 {
476 case XIMasterKeyboard:
477 case XIMasterPointer:
478 type = GDK_DEVICE_TYPE_MASTER;
479 mode = GDK_MODE_SCREEN;
480 break;
481 case XISlaveKeyboard:
482 case XISlavePointer:
483 type = GDK_DEVICE_TYPE_SLAVE;
484 mode = GDK_MODE_DISABLED;
485 break;
486 case XIFloatingSlave:
487 default:
488 type = GDK_DEVICE_TYPE_FLOATING;
489 mode = GDK_MODE_DISABLED;
490 break;
491 }
492
493 GDK_NOTE (INPUT,
494 ({
495 const gchar *type_names[] = { "master", "slave", "floating" };
496 const gchar *source_names[] = { "mouse", "pen", "eraser", "cursor", "keyboard", "direct touch", "indirect touch", "trackpoint", "pad" };
497 const gchar *mode_names[] = { "disabled", "screen", "window" };
498 g_message ("input device:\n\tname: %s\n\ttype: %s\n\tsource: %s\n\tmode: %s\n\thas cursor: %d\n\ttouches: %d",
499 dev->name,
500 type_names[type],
501 source_names[input_source],
502 mode_names[mode],
503 dev->use == XIMasterPointer,
504 num_touches);
505 }));
506
507 if (dev->use != XIMasterKeyboard &&
508 dev->use != XIMasterPointer)
509 get_device_ids (display, dev, &vendor_id, &product_id);
510
511 device = g_object_new (GDK_TYPE_X11_DEVICE_XI2,
512 "name", dev->name,
513 "type", type,
514 "input-source", input_source,
515 "input-mode", mode,
516 "has-cursor", (dev->use == XIMasterPointer),
517 "display", display,
518 "device-manager", device_manager,
519 "device-id", dev->deviceid,
520 "vendor-id", vendor_id,
521 "product-id", product_id,
522 "num-touches", num_touches,
523 NULL);
524
525 translate_device_classes (display, device, dev->classes, dev->num_classes);
526 g_free (vendor_id);
527 g_free (product_id);
528
529 return device;
530 }
531
532 static void
ensure_seat_for_device_pair(GdkX11DeviceManagerXI2 * device_manager,GdkDevice * device1,GdkDevice * device2)533 ensure_seat_for_device_pair (GdkX11DeviceManagerXI2 *device_manager,
534 GdkDevice *device1,
535 GdkDevice *device2)
536 {
537 GdkDevice *pointer, *keyboard;
538 GdkDisplay *display;
539 GdkSeat *seat;
540
541 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
542 seat = gdk_device_get_seat (device1);
543
544 if (!seat)
545 {
546 if (gdk_device_get_source (device1) == GDK_SOURCE_KEYBOARD)
547 {
548 keyboard = device1;
549 pointer = device2;
550 }
551 else
552 {
553 pointer = device1;
554 keyboard = device2;
555 }
556
557 seat = gdk_seat_default_new_for_master_pair (pointer, keyboard);
558 gdk_display_add_seat (display, seat);
559 g_object_unref (seat);
560 }
561 }
562
563 static GdkDevice *
add_device(GdkX11DeviceManagerXI2 * device_manager,XIDeviceInfo * dev,gboolean emit_signal)564 add_device (GdkX11DeviceManagerXI2 *device_manager,
565 XIDeviceInfo *dev,
566 gboolean emit_signal)
567 {
568 GdkDisplay *display;
569 GdkDevice *device;
570
571 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
572 device = create_device (GDK_DEVICE_MANAGER (device_manager), display, dev);
573
574 g_hash_table_replace (device_manager->id_table,
575 GINT_TO_POINTER (dev->deviceid),
576 g_object_ref (device));
577
578 device_manager->devices = g_list_append (device_manager->devices, device);
579
580 if (emit_signal)
581 {
582 if (dev->use == XISlavePointer || dev->use == XISlaveKeyboard)
583 {
584 GdkDevice *master;
585 GdkSeat *seat;
586
587 /* The device manager is already constructed, then
588 * keep the hierarchy coherent for the added device.
589 */
590 master = g_hash_table_lookup (device_manager->id_table,
591 GINT_TO_POINTER (dev->attachment));
592
593 _gdk_device_set_associated_device (device, master);
594 _gdk_device_add_slave (master, device);
595
596 seat = gdk_device_get_seat (master);
597 gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), device);
598 }
599 else if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
600 {
601 GdkDevice *relative;
602
603 relative = g_hash_table_lookup (device_manager->id_table,
604 GINT_TO_POINTER (dev->attachment));
605
606 if (relative)
607 {
608 _gdk_device_set_associated_device (device, relative);
609 _gdk_device_set_associated_device (relative, device);
610 ensure_seat_for_device_pair (device_manager, device, relative);
611 }
612 }
613 }
614
615 g_signal_emit_by_name (device_manager, "device-added", device);
616
617 return device;
618 }
619
620 static void
detach_from_seat(GdkDevice * device)621 detach_from_seat (GdkDevice *device)
622 {
623 GdkSeat *seat = gdk_device_get_seat (device);
624
625 if (!seat)
626 return;
627
628 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER)
629 gdk_display_remove_seat (gdk_device_get_display (device), seat);
630 else if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_SLAVE)
631 gdk_seat_default_remove_slave (GDK_SEAT_DEFAULT (seat), device);
632 }
633
634 static void
remove_device(GdkX11DeviceManagerXI2 * device_manager,gint device_id)635 remove_device (GdkX11DeviceManagerXI2 *device_manager,
636 gint device_id)
637 {
638 GdkDevice *device;
639
640 device = g_hash_table_lookup (device_manager->id_table,
641 GINT_TO_POINTER (device_id));
642
643 if (device)
644 {
645 detach_from_seat (device);
646
647 g_hash_table_remove (device_manager->id_table,
648 GINT_TO_POINTER (device_id));
649
650 device_manager->devices = g_list_remove (device_manager->devices, device);
651 g_signal_emit_by_name (device_manager, "device-removed", device);
652 g_object_run_dispose (G_OBJECT (device));
653 g_object_unref (device);
654 }
655 }
656
657 static void
relate_masters(gpointer key,gpointer value,gpointer user_data)658 relate_masters (gpointer key,
659 gpointer value,
660 gpointer user_data)
661 {
662 GdkX11DeviceManagerXI2 *device_manager;
663 GdkDevice *device, *relative;
664
665 device_manager = user_data;
666 device = g_hash_table_lookup (device_manager->id_table, key);
667 relative = g_hash_table_lookup (device_manager->id_table, value);
668
669 _gdk_device_set_associated_device (device, relative);
670 _gdk_device_set_associated_device (relative, device);
671 ensure_seat_for_device_pair (device_manager, device, relative);
672 }
673
674 static void
relate_slaves(gpointer key,gpointer value,gpointer user_data)675 relate_slaves (gpointer key,
676 gpointer value,
677 gpointer user_data)
678 {
679 GdkX11DeviceManagerXI2 *device_manager;
680 GdkDevice *slave, *master;
681 GdkSeat *seat;
682
683 device_manager = user_data;
684 slave = g_hash_table_lookup (device_manager->id_table, key);
685 master = g_hash_table_lookup (device_manager->id_table, value);
686
687 _gdk_device_set_associated_device (slave, master);
688 _gdk_device_add_slave (master, slave);
689
690 seat = gdk_device_get_seat (master);
691 gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), slave);
692 }
693
694 static void
gdk_x11_device_manager_xi2_constructed(GObject * object)695 gdk_x11_device_manager_xi2_constructed (GObject *object)
696 {
697 GdkX11DeviceManagerXI2 *device_manager;
698 GdkDisplay *display;
699 GdkScreen *screen;
700 GHashTable *masters, *slaves;
701 Display *xdisplay;
702 XIDeviceInfo *info, *dev;
703 int ndevices, i;
704 XIEventMask event_mask;
705 unsigned char mask[2] = { 0 };
706
707 G_OBJECT_CLASS (gdk_x11_device_manager_xi2_parent_class)->constructed (object);
708
709 device_manager = GDK_X11_DEVICE_MANAGER_XI2 (object);
710 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
711 xdisplay = GDK_DISPLAY_XDISPLAY (display);
712
713 g_assert (device_manager->major == 2);
714
715 masters = g_hash_table_new (NULL, NULL);
716 slaves = g_hash_table_new (NULL, NULL);
717
718 info = XIQueryDevice (xdisplay, XIAllDevices, &ndevices);
719
720 /* Initialize devices list */
721 for (i = 0; i < ndevices; i++)
722 {
723 dev = &info[i];
724
725 if (!dev->enabled)
726 continue;
727
728 add_device (device_manager, dev, FALSE);
729
730 if (dev->use == XIMasterPointer ||
731 dev->use == XIMasterKeyboard)
732 {
733 g_hash_table_insert (masters,
734 GINT_TO_POINTER (dev->deviceid),
735 GINT_TO_POINTER (dev->attachment));
736 }
737 else if (dev->use == XISlavePointer ||
738 dev->use == XISlaveKeyboard)
739 {
740 g_hash_table_insert (slaves,
741 GINT_TO_POINTER (dev->deviceid),
742 GINT_TO_POINTER (dev->attachment));
743 }
744 }
745
746 XIFreeDeviceInfo (info);
747
748 /* Stablish relationships between devices */
749 g_hash_table_foreach (masters, relate_masters, object);
750 g_hash_table_destroy (masters);
751
752 g_hash_table_foreach (slaves, relate_slaves, object);
753 g_hash_table_destroy (slaves);
754
755 /* Connect to hierarchy change events */
756 screen = gdk_display_get_default_screen (display);
757 XISetMask (mask, XI_HierarchyChanged);
758 XISetMask (mask, XI_DeviceChanged);
759 XISetMask (mask, XI_PropertyEvent);
760
761 event_mask.deviceid = XIAllDevices;
762 event_mask.mask_len = sizeof (mask);
763 event_mask.mask = mask;
764
765 _gdk_x11_device_manager_xi2_select_events (GDK_DEVICE_MANAGER (object),
766 GDK_WINDOW_XID (gdk_screen_get_root_window (screen)),
767 &event_mask);
768 }
769
770 static void
gdk_x11_device_manager_xi2_dispose(GObject * object)771 gdk_x11_device_manager_xi2_dispose (GObject *object)
772 {
773 GdkX11DeviceManagerXI2 *device_manager;
774
775 device_manager = GDK_X11_DEVICE_MANAGER_XI2 (object);
776
777 g_list_free_full (device_manager->devices, g_object_unref);
778 device_manager->devices = NULL;
779
780 if (device_manager->id_table)
781 {
782 g_hash_table_destroy (device_manager->id_table);
783 device_manager->id_table = NULL;
784 }
785
786 G_OBJECT_CLASS (gdk_x11_device_manager_xi2_parent_class)->dispose (object);
787 }
788
789 static GList *
gdk_x11_device_manager_xi2_list_devices(GdkDeviceManager * device_manager,GdkDeviceType type)790 gdk_x11_device_manager_xi2_list_devices (GdkDeviceManager *device_manager,
791 GdkDeviceType type)
792 {
793 GdkX11DeviceManagerXI2 *device_manager_xi2;
794 GList *cur, *list = NULL;
795
796 device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (device_manager);
797
798 for (cur = device_manager_xi2->devices; cur; cur = cur->next)
799 {
800 GdkDevice *dev = cur->data;
801
802 if (type == gdk_device_get_device_type (dev))
803 list = g_list_prepend (list, dev);
804 }
805
806 return list;
807 }
808
809 static GdkDevice *
gdk_x11_device_manager_xi2_get_client_pointer(GdkDeviceManager * device_manager)810 gdk_x11_device_manager_xi2_get_client_pointer (GdkDeviceManager *device_manager)
811 {
812 GdkX11DeviceManagerXI2 *device_manager_xi2;
813 GdkDisplay *display;
814 int device_id;
815
816 device_manager_xi2 = (GdkX11DeviceManagerXI2 *) device_manager;
817 display = gdk_device_manager_get_display (device_manager);
818
819 XIGetClientPointer (GDK_DISPLAY_XDISPLAY (display),
820 None, &device_id);
821
822 return g_hash_table_lookup (device_manager_xi2->id_table,
823 GINT_TO_POINTER (device_id));
824 }
825
826 static void
gdk_x11_device_manager_xi2_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)827 gdk_x11_device_manager_xi2_set_property (GObject *object,
828 guint prop_id,
829 const GValue *value,
830 GParamSpec *pspec)
831 {
832 GdkX11DeviceManagerXI2 *device_manager;
833
834 device_manager = GDK_X11_DEVICE_MANAGER_XI2 (object);
835
836 switch (prop_id)
837 {
838 case PROP_OPCODE:
839 device_manager->opcode = g_value_get_int (value);
840 break;
841 case PROP_MAJOR:
842 device_manager->major = g_value_get_int (value);
843 break;
844 case PROP_MINOR:
845 device_manager->minor = g_value_get_int (value);
846 break;
847 default:
848 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
849 break;
850 }
851 }
852
853 static void
gdk_x11_device_manager_xi2_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)854 gdk_x11_device_manager_xi2_get_property (GObject *object,
855 guint prop_id,
856 GValue *value,
857 GParamSpec *pspec)
858 {
859 GdkX11DeviceManagerXI2 *device_manager;
860
861 device_manager = GDK_X11_DEVICE_MANAGER_XI2 (object);
862
863 switch (prop_id)
864 {
865 case PROP_OPCODE:
866 g_value_set_int (value, device_manager->opcode);
867 break;
868 case PROP_MAJOR:
869 g_value_set_int (value, device_manager->major);
870 break;
871 case PROP_MINOR:
872 g_value_set_int (value, device_manager->minor);
873 break;
874 default:
875 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
876 break;
877 }
878 }
879
880 static void
gdk_x11_device_manager_xi2_event_translator_init(GdkEventTranslatorIface * iface)881 gdk_x11_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface)
882 {
883 iface->translate_event = gdk_x11_device_manager_xi2_translate_event;
884 iface->get_handled_events = gdk_x11_device_manager_xi2_get_handled_events;
885 iface->select_window_events = gdk_x11_device_manager_xi2_select_window_events;
886 iface->get_window = gdk_x11_device_manager_xi2_get_window;
887 }
888
889 static void
handle_hierarchy_changed(GdkX11DeviceManagerXI2 * device_manager,XIHierarchyEvent * ev)890 handle_hierarchy_changed (GdkX11DeviceManagerXI2 *device_manager,
891 XIHierarchyEvent *ev)
892 {
893 GdkDisplay *display;
894 Display *xdisplay;
895 XIDeviceInfo *info;
896 int ndevices;
897 gint i;
898
899 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
900 xdisplay = GDK_DISPLAY_XDISPLAY (display);
901
902 for (i = 0; i < ev->num_info; i++)
903 {
904 if (ev->info[i].flags & XIDeviceEnabled)
905 {
906 gdk_x11_display_error_trap_push (display);
907 info = XIQueryDevice (xdisplay, ev->info[i].deviceid, &ndevices);
908 gdk_x11_display_error_trap_pop_ignored (display);
909 if (info)
910 {
911 add_device (device_manager, &info[0], TRUE);
912 XIFreeDeviceInfo (info);
913 }
914 }
915 else if (ev->info[i].flags & XIDeviceDisabled)
916 remove_device (device_manager, ev->info[i].deviceid);
917 else if (ev->info[i].flags & XISlaveAttached ||
918 ev->info[i].flags & XISlaveDetached)
919 {
920 GdkDevice *master, *slave;
921 GdkSeat *seat;
922
923 slave = g_hash_table_lookup (device_manager->id_table,
924 GINT_TO_POINTER (ev->info[i].deviceid));
925
926 if (!slave)
927 continue;
928
929 /* Remove old master info */
930 master = gdk_device_get_associated_device (slave);
931
932 if (master)
933 {
934 _gdk_device_remove_slave (master, slave);
935 _gdk_device_set_associated_device (slave, NULL);
936
937 g_signal_emit_by_name (device_manager, "device-changed", master);
938
939 seat = gdk_device_get_seat (master);
940 gdk_seat_default_remove_slave (GDK_SEAT_DEFAULT (seat), slave);
941 }
942
943 /* Add new master if it's an attachment event */
944 if (ev->info[i].flags & XISlaveAttached)
945 {
946 gdk_x11_display_error_trap_push (display);
947 info = XIQueryDevice (xdisplay, ev->info[i].deviceid, &ndevices);
948 gdk_x11_display_error_trap_pop_ignored (display);
949 if (info)
950 {
951 master = g_hash_table_lookup (device_manager->id_table,
952 GINT_TO_POINTER (info->attachment));
953 XIFreeDeviceInfo (info);
954 }
955
956 if (master)
957 {
958 _gdk_device_set_associated_device (slave, master);
959 _gdk_device_add_slave (master, slave);
960
961 seat = gdk_device_get_seat (master);
962 gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), slave);
963
964 g_signal_emit_by_name (device_manager, "device-changed", master);
965 }
966 }
967
968 g_signal_emit_by_name (device_manager, "device-changed", slave);
969 }
970 }
971 }
972
973 static void
handle_device_changed(GdkX11DeviceManagerXI2 * device_manager,XIDeviceChangedEvent * ev)974 handle_device_changed (GdkX11DeviceManagerXI2 *device_manager,
975 XIDeviceChangedEvent *ev)
976 {
977 GdkDisplay *display;
978 GdkDevice *device, *source_device;
979
980 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
981 device = g_hash_table_lookup (device_manager->id_table,
982 GUINT_TO_POINTER (ev->deviceid));
983 source_device = g_hash_table_lookup (device_manager->id_table,
984 GUINT_TO_POINTER (ev->sourceid));
985
986 if (device)
987 {
988 _gdk_device_reset_axes (device);
989 _gdk_device_xi2_unset_scroll_valuators ((GdkX11DeviceXI2 *) device);
990 gdk_x11_device_xi2_store_axes (GDK_X11_DEVICE_XI2 (device), NULL, 0);
991 translate_device_classes (display, device, ev->classes, ev->num_classes);
992
993 g_signal_emit_by_name (G_OBJECT (device), "changed");
994 }
995
996 if (source_device)
997 _gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
998 }
999
1000 static gboolean
device_get_tool_serial_and_id(GdkDevice * device,guint * serial_id,guint * id)1001 device_get_tool_serial_and_id (GdkDevice *device,
1002 guint *serial_id,
1003 guint *id)
1004 {
1005 GdkDisplay *display;
1006 gulong nitems, bytes_after;
1007 guint32 *data;
1008 int rc, format;
1009 Atom type;
1010
1011 display = gdk_device_get_display (device);
1012
1013 gdk_x11_display_error_trap_push (display);
1014
1015 rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display),
1016 gdk_x11_device_get_id (device),
1017 gdk_x11_get_xatom_by_name_for_display (display, "Wacom Serial IDs"),
1018 0, 5, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
1019 (guchar **) &data);
1020 gdk_x11_display_error_trap_pop_ignored (display);
1021
1022 if (rc != Success)
1023 return FALSE;
1024
1025 if (type == XA_INTEGER && format == 32)
1026 {
1027 if (nitems >= 4)
1028 *serial_id = data[3];
1029 if (nitems >= 5)
1030 *id = data[4];
1031 }
1032
1033 XFree (data);
1034
1035 return TRUE;
1036 }
1037
1038 static GdkDeviceToolType
device_get_tool_type(GdkDevice * device)1039 device_get_tool_type (GdkDevice *device)
1040 {
1041 GdkDisplay *display;
1042 gulong nitems, bytes_after;
1043 guint32 *data;
1044 int rc, format;
1045 Atom type;
1046 Atom device_type;
1047 Atom types[N_WACOM_TYPE_ATOMS];
1048 GdkDeviceToolType tool_type = GDK_DEVICE_TOOL_TYPE_UNKNOWN;
1049
1050 display = gdk_device_get_display (device);
1051 gdk_x11_display_error_trap_push (display);
1052
1053 rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display),
1054 gdk_x11_device_get_id (device),
1055 gdk_x11_get_xatom_by_name_for_display (display, "Wacom Tool Type"),
1056 0, 1, False, XA_ATOM, &type, &format, &nitems, &bytes_after,
1057 (guchar **) &data);
1058 gdk_x11_display_error_trap_pop_ignored (display);
1059
1060 if (rc != Success)
1061 return GDK_DEVICE_TOOL_TYPE_UNKNOWN;
1062
1063 if (type != XA_ATOM || format != 32 || nitems != 1)
1064 {
1065 XFree (data);
1066 return GDK_DEVICE_TOOL_TYPE_UNKNOWN;
1067 }
1068
1069 device_type = *data;
1070 XFree (data);
1071
1072 if (device_type == 0)
1073 return GDK_DEVICE_TOOL_TYPE_UNKNOWN;
1074
1075 gdk_x11_display_error_trap_push (display);
1076 rc = XInternAtoms (GDK_DISPLAY_XDISPLAY (display),
1077 (char **) wacom_type_atoms,
1078 N_WACOM_TYPE_ATOMS,
1079 False,
1080 types);
1081 gdk_x11_display_error_trap_pop_ignored (display);
1082
1083 if (rc == 0)
1084 return GDK_DEVICE_TOOL_TYPE_UNKNOWN;
1085
1086 if (device_type == types[WACOM_TYPE_STYLUS])
1087 tool_type = GDK_DEVICE_TOOL_TYPE_PEN;
1088 else if (device_type == types[WACOM_TYPE_CURSOR])
1089 tool_type = GDK_DEVICE_TOOL_TYPE_MOUSE;
1090 else if (device_type == types[WACOM_TYPE_ERASER])
1091 tool_type = GDK_DEVICE_TOOL_TYPE_ERASER;
1092 else if (device_type == types[WACOM_TYPE_TOUCH])
1093 tool_type = GDK_DEVICE_TOOL_TYPE_UNKNOWN;
1094
1095 return tool_type;
1096 }
1097
1098 static void
handle_property_change(GdkX11DeviceManagerXI2 * device_manager,XIPropertyEvent * ev)1099 handle_property_change (GdkX11DeviceManagerXI2 *device_manager,
1100 XIPropertyEvent *ev)
1101 {
1102 GdkDevice *device;
1103
1104 device = g_hash_table_lookup (device_manager->id_table,
1105 GUINT_TO_POINTER (ev->deviceid));
1106
1107 if (device != NULL &&
1108 ev->property == gdk_x11_get_xatom_by_name ("Wacom Serial IDs"))
1109 {
1110 GdkDeviceTool *tool = NULL;
1111 guint serial_id = 0, tool_id = 0;
1112 GdkSeat *seat;
1113
1114 if (ev->what != XIPropertyDeleted &&
1115 device_get_tool_serial_and_id (device, &serial_id, &tool_id))
1116 {
1117 seat = gdk_device_get_seat (device);
1118 tool = gdk_seat_get_tool (seat, serial_id, tool_id);
1119
1120 if (!tool && serial_id > 0)
1121 {
1122 GdkDeviceToolType tool_type;
1123
1124 tool_type = device_get_tool_type (device);
1125 if (tool_type != GDK_DEVICE_TOOL_TYPE_UNKNOWN)
1126 {
1127 tool = gdk_device_tool_new (serial_id, tool_id, tool_type, 0);
1128 gdk_seat_default_add_tool (GDK_SEAT_DEFAULT (seat), tool);
1129 }
1130 }
1131 }
1132
1133 gdk_device_update_tool (device, tool);
1134 }
1135 }
1136
1137 static GdkCrossingMode
translate_crossing_mode(gint mode)1138 translate_crossing_mode (gint mode)
1139 {
1140 switch (mode)
1141 {
1142 case XINotifyNormal:
1143 return GDK_CROSSING_NORMAL;
1144 case XINotifyGrab:
1145 case XINotifyPassiveGrab:
1146 return GDK_CROSSING_GRAB;
1147 case XINotifyUngrab:
1148 case XINotifyPassiveUngrab:
1149 return GDK_CROSSING_UNGRAB;
1150 case XINotifyWhileGrabbed:
1151 /* Fall through, unexpected in pointer crossing events */
1152 default:
1153 g_assert_not_reached ();
1154 }
1155 }
1156
1157 static GdkNotifyType
translate_notify_type(gint detail)1158 translate_notify_type (gint detail)
1159 {
1160 switch (detail)
1161 {
1162 case NotifyInferior:
1163 return GDK_NOTIFY_INFERIOR;
1164 case NotifyAncestor:
1165 return GDK_NOTIFY_ANCESTOR;
1166 case NotifyVirtual:
1167 return GDK_NOTIFY_VIRTUAL;
1168 case NotifyNonlinear:
1169 return GDK_NOTIFY_NONLINEAR;
1170 case NotifyNonlinearVirtual:
1171 return GDK_NOTIFY_NONLINEAR_VIRTUAL;
1172 default:
1173 g_assert_not_reached ();
1174 }
1175 }
1176
1177 static gboolean
set_screen_from_root(GdkDisplay * display,GdkEvent * event,Window xrootwin)1178 set_screen_from_root (GdkDisplay *display,
1179 GdkEvent *event,
1180 Window xrootwin)
1181 {
1182 GdkScreen *screen;
1183
1184 screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
1185
1186 if (screen)
1187 {
1188 gdk_event_set_screen (event, screen);
1189
1190 return TRUE;
1191 }
1192
1193 return FALSE;
1194 }
1195
1196 static void
set_user_time(GdkEvent * event)1197 set_user_time (GdkEvent *event)
1198 {
1199 GdkWindow *window;
1200 guint32 time;
1201
1202 window = gdk_window_get_toplevel (event->any.window);
1203 g_return_if_fail (GDK_IS_WINDOW (window));
1204
1205 time = gdk_event_get_time (event);
1206
1207 /* If an event doesn't have a valid timestamp, we shouldn't use it
1208 * to update the latest user interaction time.
1209 */
1210 if (time != GDK_CURRENT_TIME)
1211 gdk_x11_window_set_user_time (window, time);
1212 }
1213
1214 static gdouble *
translate_axes(GdkDevice * device,gdouble x,gdouble y,GdkWindow * window,XIValuatorState * valuators)1215 translate_axes (GdkDevice *device,
1216 gdouble x,
1217 gdouble y,
1218 GdkWindow *window,
1219 XIValuatorState *valuators)
1220 {
1221 guint n_axes, i;
1222 gdouble *axes;
1223 gdouble *vals;
1224
1225 g_object_get (device, "n-axes", &n_axes, NULL);
1226
1227 axes = g_new0 (gdouble, n_axes);
1228 vals = valuators->values;
1229
1230 for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++)
1231 {
1232 GdkAxisUse use;
1233 gdouble val;
1234
1235 if (!XIMaskIsSet (valuators->mask, i))
1236 {
1237 axes[i] = gdk_x11_device_xi2_get_last_axis_value (GDK_X11_DEVICE_XI2 (device), i);
1238 continue;
1239 }
1240
1241 use = gdk_device_get_axis_use (device, i);
1242 val = *vals++;
1243
1244 switch (use)
1245 {
1246 case GDK_AXIS_X:
1247 case GDK_AXIS_Y:
1248 if (gdk_device_get_mode (device) == GDK_MODE_WINDOW)
1249 _gdk_device_translate_window_coord (device, window, i, val, &axes[i]);
1250 else
1251 {
1252 if (use == GDK_AXIS_X)
1253 axes[i] = x;
1254 else
1255 axes[i] = y;
1256 }
1257 break;
1258 default:
1259 _gdk_device_translate_axis (device, i, val, &axes[i]);
1260 break;
1261 }
1262 }
1263
1264 gdk_x11_device_xi2_store_axes (GDK_X11_DEVICE_XI2 (device), axes, n_axes);
1265
1266 return axes;
1267 }
1268
1269 static gboolean
is_parent_of(GdkWindow * parent,GdkWindow * child)1270 is_parent_of (GdkWindow *parent,
1271 GdkWindow *child)
1272 {
1273 GdkWindow *w;
1274
1275 w = child;
1276 while (w != NULL)
1277 {
1278 if (w == parent)
1279 return TRUE;
1280
1281 w = gdk_window_get_parent (w);
1282 }
1283
1284 return FALSE;
1285 }
1286
1287 static gboolean
get_event_window(GdkEventTranslator * translator,XIEvent * ev,GdkWindow ** window_p)1288 get_event_window (GdkEventTranslator *translator,
1289 XIEvent *ev,
1290 GdkWindow **window_p)
1291 {
1292 GdkDisplay *display;
1293 GdkWindow *window = NULL;
1294 gboolean should_have_window = TRUE;
1295
1296 display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (translator));
1297
1298 switch (ev->evtype)
1299 {
1300 case XI_KeyPress:
1301 case XI_KeyRelease:
1302 case XI_ButtonPress:
1303 case XI_ButtonRelease:
1304 case XI_Motion:
1305 #ifdef XINPUT_2_2
1306 case XI_TouchUpdate:
1307 case XI_TouchBegin:
1308 case XI_TouchEnd:
1309 #endif /* XINPUT_2_2 */
1310 {
1311 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
1312
1313 window = gdk_x11_window_lookup_for_display (display, xev->event);
1314
1315 /* Apply keyboard grabs to non-native windows */
1316 if (ev->evtype == XI_KeyPress || ev->evtype == XI_KeyRelease)
1317 {
1318 GdkDeviceGrabInfo *info;
1319 GdkDevice *device;
1320 gulong serial;
1321
1322 device = g_hash_table_lookup (GDK_X11_DEVICE_MANAGER_XI2 (translator)->id_table,
1323 GUINT_TO_POINTER (((XIDeviceEvent *) ev)->deviceid));
1324
1325 serial = _gdk_display_get_next_serial (display);
1326 info = _gdk_display_has_device_grab (display, device, serial);
1327
1328 if (info &&
1329 (!is_parent_of (info->window, window) ||
1330 !info->owner_events))
1331 {
1332 /* Report key event against grab window */
1333 window = info->window;
1334 }
1335 }
1336 }
1337 break;
1338 #ifdef XINPUT_2_4
1339 case XI_GesturePinchBegin:
1340 case XI_GesturePinchUpdate:
1341 case XI_GesturePinchEnd:
1342 {
1343 XIGesturePinchEvent *xev = (XIGesturePinchEvent *) ev;
1344
1345 window = gdk_x11_window_lookup_for_display (display, xev->event);
1346 }
1347 break;
1348 case XI_GestureSwipeBegin:
1349 case XI_GestureSwipeUpdate:
1350 case XI_GestureSwipeEnd:
1351 {
1352 XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
1353
1354 window = gdk_x11_window_lookup_for_display (display, xev->event);
1355 }
1356 break;
1357 #endif /* XINPUT_2_4 */
1358 case XI_Enter:
1359 case XI_Leave:
1360 case XI_FocusIn:
1361 case XI_FocusOut:
1362 {
1363 XIEnterEvent *xev = (XIEnterEvent *) ev;
1364
1365 window = gdk_x11_window_lookup_for_display (display, xev->event);
1366 }
1367 break;
1368 default:
1369 should_have_window = FALSE;
1370 break;
1371 }
1372
1373 *window_p = window;
1374
1375 if (should_have_window && !window)
1376 return FALSE;
1377
1378 return TRUE;
1379 }
1380
1381 static gboolean
gdk_x11_device_manager_xi2_translate_core_event(GdkEventTranslator * translator,GdkDisplay * display,GdkEvent * event,XEvent * xevent)1382 gdk_x11_device_manager_xi2_translate_core_event (GdkEventTranslator *translator,
1383 GdkDisplay *display,
1384 GdkEvent *event,
1385 XEvent *xevent)
1386 {
1387 GdkEventTranslatorIface *parent_iface;
1388 gboolean keyboard = FALSE;
1389 GdkDevice *device;
1390
1391 if ((xevent->type == KeyPress || xevent->type == KeyRelease) &&
1392 (xevent->xkey.keycode == 0 || xevent->xkey.serial == 0))
1393 {
1394 /* The X input methods (when triggered via XFilterEvent)
1395 * generate a core key press event with keycode 0 to signal the
1396 * end of a key sequence. We use the core translate_event
1397 * implementation to translate this event.
1398 *
1399 * Other less educated IM modules like to filter every keypress,
1400 * only to have these replaced by their own homegrown events,
1401 * these events oddly have serial=0, so we try to catch these.
1402 *
1403 * This is just a bandaid fix to keep xim working with a single
1404 * keyboard until XFilterEvent learns about XI2.
1405 */
1406 keyboard = TRUE;
1407 }
1408 else if (xevent->xany.send_event)
1409 {
1410 /* If another process sends us core events, process them; we
1411 * assume that it won't send us redundant core and XI2 events.
1412 * (At the moment, it's not possible to send XI2 events anyway.
1413 * In the future, an app that was trying to decide whether to
1414 * send core or XI2 events could look at the event mask on the
1415 * window to see which kind we are listening to.)
1416 */
1417 switch (xevent->type)
1418 {
1419 case KeyPress:
1420 case KeyRelease:
1421 case FocusIn:
1422 case FocusOut:
1423 keyboard = TRUE;
1424 break;
1425
1426 case ButtonPress:
1427 case ButtonRelease:
1428 case MotionNotify:
1429 case EnterNotify:
1430 case LeaveNotify:
1431 break;
1432
1433 default:
1434 return FALSE;
1435 }
1436 }
1437 else
1438 return FALSE;
1439
1440 parent_iface = g_type_interface_peek_parent (GDK_EVENT_TRANSLATOR_GET_IFACE (translator));
1441 if (!parent_iface->translate_event (translator, display, event, xevent))
1442 return FALSE;
1443
1444 /* The core device manager sets a core device on the event.
1445 * We need to override that with an XI2 device, since we are
1446 * using XI2.
1447 */
1448 device = gdk_x11_device_manager_xi2_get_client_pointer ((GdkDeviceManager *)translator);
1449 if (keyboard)
1450 device = gdk_device_get_associated_device (device);
1451 gdk_event_set_device (event, device);
1452
1453 return TRUE;
1454 }
1455
1456 static gboolean
scroll_valuators_changed(GdkX11DeviceXI2 * device,XIValuatorState * valuators,gdouble * dx,gdouble * dy)1457 scroll_valuators_changed (GdkX11DeviceXI2 *device,
1458 XIValuatorState *valuators,
1459 gdouble *dx,
1460 gdouble *dy)
1461 {
1462 gboolean has_scroll_valuators = FALSE;
1463 GdkScrollDirection direction;
1464 guint n_axes, i, n_val;
1465 gdouble *vals;
1466
1467 n_axes = gdk_device_get_n_axes (GDK_DEVICE (device));
1468 vals = valuators->values;
1469 *dx = *dy = 0;
1470 n_val = 0;
1471
1472 for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++)
1473 {
1474 gdouble delta;
1475
1476 if (!XIMaskIsSet (valuators->mask, i))
1477 continue;
1478
1479 if (_gdk_x11_device_xi2_get_scroll_delta (device, i, vals[n_val],
1480 &direction, &delta))
1481 {
1482 has_scroll_valuators = TRUE;
1483
1484 if (direction == GDK_SCROLL_UP ||
1485 direction == GDK_SCROLL_DOWN)
1486 *dy = delta;
1487 else
1488 *dx = delta;
1489 }
1490
1491 n_val++;
1492 }
1493
1494 return has_scroll_valuators;
1495 }
1496
1497 static gboolean
gdk_x11_device_manager_xi2_translate_event(GdkEventTranslator * translator,GdkDisplay * display,GdkEvent * event,XEvent * xevent)1498 gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
1499 GdkDisplay *display,
1500 GdkEvent *event,
1501 XEvent *xevent)
1502 {
1503 GdkX11DeviceManagerXI2 *device_manager;
1504 XGenericEventCookie *cookie;
1505 GdkDevice *device, *source_device;
1506 gboolean return_val = TRUE;
1507 GdkWindow *window;
1508 GdkWindowImplX11 *impl;
1509 int scale;
1510 XIEvent *ev;
1511
1512 device_manager = (GdkX11DeviceManagerXI2 *) translator;
1513 cookie = &xevent->xcookie;
1514
1515 if (xevent->type != GenericEvent)
1516 return gdk_x11_device_manager_xi2_translate_core_event (translator, display, event, xevent);
1517 else if (cookie->extension != device_manager->opcode)
1518 return FALSE;
1519
1520 ev = (XIEvent *) cookie->data;
1521
1522 if (!ev)
1523 return FALSE;
1524
1525 if (!get_event_window (translator, ev, &window))
1526 return FALSE;
1527
1528 if (window && GDK_WINDOW_DESTROYED (window))
1529 return FALSE;
1530
1531 scale = 1;
1532 if (window)
1533 {
1534 impl = GDK_WINDOW_IMPL_X11 (window->impl);
1535 scale = impl->window_scale;
1536 }
1537
1538 if (ev->evtype == XI_Motion ||
1539 ev->evtype == XI_ButtonRelease)
1540 {
1541 if (_gdk_x11_moveresize_handle_event (xevent))
1542 return FALSE;
1543 }
1544
1545 switch (ev->evtype)
1546 {
1547 case XI_HierarchyChanged:
1548 handle_hierarchy_changed (device_manager,
1549 (XIHierarchyEvent *) ev);
1550 return_val = FALSE;
1551 break;
1552 case XI_DeviceChanged:
1553 handle_device_changed (device_manager,
1554 (XIDeviceChangedEvent *) ev);
1555 return_val = FALSE;
1556 break;
1557 case XI_PropertyEvent:
1558 handle_property_change (device_manager,
1559 (XIPropertyEvent *) ev);
1560 return_val = FALSE;
1561 break;
1562 case XI_KeyPress:
1563 case XI_KeyRelease:
1564 {
1565 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
1566 GdkKeymap *keymap = gdk_keymap_get_for_display (display);
1567 GdkModifierType consumed, state;
1568
1569 GDK_NOTE (EVENTS,
1570 g_message ("key %s:\twindow %ld\n"
1571 "\tdevice:%u\n"
1572 "\tsource device:%u\n"
1573 "\tkey number: %u\n",
1574 (ev->evtype == XI_KeyPress) ? "press" : "release",
1575 xev->event,
1576 xev->deviceid,
1577 xev->sourceid,
1578 xev->detail));
1579
1580 event->key.type = xev->evtype == XI_KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
1581
1582 event->key.window = window;
1583
1584 event->key.time = xev->time;
1585 event->key.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
1586 event->key.group = xev->group.effective;
1587
1588 event->key.hardware_keycode = xev->detail;
1589 gdk_event_set_scancode (event, xev->detail);
1590 event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
1591
1592 device = g_hash_table_lookup (device_manager->id_table,
1593 GUINT_TO_POINTER (xev->deviceid));
1594 gdk_event_set_device (event, device);
1595
1596 source_device = g_hash_table_lookup (device_manager->id_table,
1597 GUINT_TO_POINTER (xev->sourceid));
1598 gdk_event_set_source_device (event, source_device);
1599 gdk_event_set_seat (event, gdk_device_get_seat (device));
1600
1601 event->key.keyval = GDK_KEY_VoidSymbol;
1602
1603 gdk_keymap_translate_keyboard_state (keymap,
1604 event->key.hardware_keycode,
1605 event->key.state,
1606 event->key.group,
1607 &event->key.keyval,
1608 NULL, NULL, &consumed);
1609
1610 state = event->key.state & ~consumed;
1611 _gdk_x11_keymap_add_virt_mods (keymap, &state);
1612 event->key.state |= state;
1613
1614 _gdk_x11_event_translate_keyboard_string (&event->key);
1615
1616 if (ev->evtype == XI_KeyPress)
1617 set_user_time (event);
1618
1619 /* FIXME: emulate autorepeat on key
1620 * release? XI2 seems attached to Xkb.
1621 */
1622 }
1623
1624 break;
1625 case XI_ButtonPress:
1626 case XI_ButtonRelease:
1627 {
1628 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
1629
1630 GDK_NOTE (EVENTS,
1631 g_message ("button %s:\twindow %ld\n"
1632 "\tdevice:%u\n"
1633 "\tsource device:%u\n"
1634 "\tbutton number: %u\n"
1635 "\tx,y: %.2f %.2f",
1636 (ev->evtype == XI_ButtonPress) ? "press" : "release",
1637 xev->event,
1638 xev->deviceid,
1639 xev->sourceid,
1640 xev->detail,
1641 xev->event_x, xev->event_y));
1642
1643 if (ev->evtype == XI_ButtonRelease &&
1644 (xev->detail >= 4 && xev->detail <= 7))
1645 return FALSE;
1646 else if (ev->evtype == XI_ButtonPress &&
1647 (xev->detail >= 4 && xev->detail <= 7))
1648 {
1649 /* Button presses of button 4-7 are scroll events */
1650 event->scroll.type = GDK_SCROLL;
1651
1652 if (xev->detail == 4)
1653 event->scroll.direction = GDK_SCROLL_UP;
1654 else if (xev->detail == 5)
1655 event->scroll.direction = GDK_SCROLL_DOWN;
1656 else if (xev->detail == 6)
1657 event->scroll.direction = GDK_SCROLL_LEFT;
1658 else
1659 event->scroll.direction = GDK_SCROLL_RIGHT;
1660
1661 event->scroll.window = window;
1662 event->scroll.time = xev->time;
1663 event->scroll.x = (gdouble) xev->event_x / scale;
1664 event->scroll.y = (gdouble) xev->event_y / scale;
1665 event->scroll.x_root = (gdouble) xev->root_x / scale;
1666 event->scroll.y_root = (gdouble) xev->root_y / scale;
1667 event->scroll.delta_x = 0;
1668 event->scroll.delta_y = 0;
1669
1670 device = g_hash_table_lookup (device_manager->id_table,
1671 GUINT_TO_POINTER (xev->deviceid));
1672 gdk_event_set_device (event, device);
1673
1674 source_device = g_hash_table_lookup (device_manager->id_table,
1675 GUINT_TO_POINTER (xev->sourceid));
1676 gdk_event_set_source_device (event, source_device);
1677 gdk_event_set_seat (event, gdk_device_get_seat (device));
1678
1679 event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
1680
1681 #ifdef XINPUT_2_2
1682 if (xev->flags & XIPointerEmulated)
1683 gdk_event_set_pointer_emulated (event, TRUE);
1684 #endif
1685 }
1686 else
1687 {
1688 event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
1689
1690 event->button.window = window;
1691 event->button.time = xev->time;
1692 event->button.x = (gdouble) xev->event_x / scale;
1693 event->button.y = (gdouble) xev->event_y / scale;
1694 event->button.x_root = (gdouble) xev->root_x / scale;
1695 event->button.y_root = (gdouble) xev->root_y / scale;
1696
1697 device = g_hash_table_lookup (device_manager->id_table,
1698 GUINT_TO_POINTER (xev->deviceid));
1699 gdk_event_set_device (event, device);
1700
1701 source_device = g_hash_table_lookup (device_manager->id_table,
1702 GUINT_TO_POINTER (xev->sourceid));
1703 gdk_event_set_source_device (event, source_device);
1704 gdk_event_set_seat (event, gdk_device_get_seat (device));
1705 gdk_event_set_device_tool (event, source_device->last_tool);
1706
1707 event->button.axes = translate_axes (event->button.device,
1708 event->button.x,
1709 event->button.y,
1710 event->button.window,
1711 &xev->valuators);
1712
1713 if (gdk_device_get_mode (event->button.device) == GDK_MODE_WINDOW)
1714 {
1715 GdkDevice *device = event->button.device;
1716
1717 /* Update event coordinates from axes */
1718 gdk_device_get_axis (device, event->button.axes, GDK_AXIS_X, &event->button.x);
1719 gdk_device_get_axis (device, event->button.axes, GDK_AXIS_Y, &event->button.y);
1720 }
1721
1722 event->button.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
1723
1724 event->button.button = xev->detail;
1725 }
1726
1727 #ifdef XINPUT_2_2
1728 if (xev->flags & XIPointerEmulated)
1729 gdk_event_set_pointer_emulated (event, TRUE);
1730 #endif
1731
1732 if (return_val == FALSE)
1733 break;
1734
1735 if (!set_screen_from_root (display, event, xev->root))
1736 {
1737 return_val = FALSE;
1738 break;
1739 }
1740
1741 if (ev->evtype == XI_ButtonPress)
1742 set_user_time (event);
1743
1744 break;
1745 }
1746
1747 case XI_Motion:
1748 {
1749 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
1750 gdouble delta_x, delta_y;
1751
1752 source_device = g_hash_table_lookup (device_manager->id_table,
1753 GUINT_TO_POINTER (xev->sourceid));
1754 device = g_hash_table_lookup (device_manager->id_table,
1755 GUINT_TO_POINTER (xev->deviceid));
1756
1757 /* When scrolling, X might send events twice here; once with both the
1758 * device and the source device set to the physical device, and once
1759 * with the device set to the master device.
1760 * Since we are only interested in the latter, and
1761 * scroll_valuators_changed() updates the valuator cache for the
1762 * source device, we need to explicitly ignore the first event in
1763 * order to get the correct delta for the second.
1764 */
1765 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE &&
1766 scroll_valuators_changed (GDK_X11_DEVICE_XI2 (source_device),
1767 &xev->valuators, &delta_x, &delta_y))
1768 {
1769 event->scroll.type = GDK_SCROLL;
1770 event->scroll.direction = GDK_SCROLL_SMOOTH;
1771
1772 if (delta_x == 0.0 && delta_y == 0.0)
1773 event->scroll.is_stop = TRUE;
1774
1775 GDK_NOTE(EVENTS,
1776 g_message ("smooth scroll: %s\n\tdevice: %u\n\tsource device: %u\n\twindow %ld\n\tdeltas: %f %f",
1777 #ifdef XINPUT_2_2
1778 (xev->flags & XIPointerEmulated) ? "emulated" : "",
1779 #else
1780 "",
1781 #endif
1782 xev->deviceid, xev->sourceid,
1783 xev->event, delta_x, delta_y));
1784
1785
1786 event->scroll.window = window;
1787 event->scroll.time = xev->time;
1788 event->scroll.x = (gdouble) xev->event_x / scale;
1789 event->scroll.y = (gdouble) xev->event_y / scale;
1790 event->scroll.x_root = (gdouble) xev->root_x / scale;
1791 event->scroll.y_root = (gdouble) xev->root_y / scale;
1792 event->scroll.delta_x = delta_x;
1793 event->scroll.delta_y = delta_y;
1794
1795 event->scroll.device = device;
1796 gdk_event_set_source_device (event, source_device);
1797 gdk_event_set_seat (event, gdk_device_get_seat (device));
1798
1799 event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
1800 break;
1801 }
1802
1803 event->motion.type = GDK_MOTION_NOTIFY;
1804 event->motion.window = window;
1805 event->motion.time = xev->time;
1806 event->motion.x = (gdouble) xev->event_x / scale;
1807 event->motion.y = (gdouble) xev->event_y / scale;
1808 event->motion.x_root = (gdouble) xev->root_x / scale;
1809 event->motion.y_root = (gdouble) xev->root_y / scale;
1810
1811 event->motion.device = device;
1812 gdk_event_set_source_device (event, source_device);
1813 gdk_event_set_seat (event, gdk_device_get_seat (device));
1814 gdk_event_set_device_tool (event, source_device->last_tool);
1815
1816 event->motion.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
1817
1818 #ifdef XINPUT_2_2
1819 if (xev->flags & XIPointerEmulated)
1820 gdk_event_set_pointer_emulated (event, TRUE);
1821 #endif
1822
1823 /* There doesn't seem to be motion hints in XI */
1824 event->motion.is_hint = FALSE;
1825
1826 event->motion.axes = translate_axes (event->motion.device,
1827 event->motion.x,
1828 event->motion.y,
1829 event->motion.window,
1830 &xev->valuators);
1831
1832 if (gdk_device_get_mode (event->motion.device) == GDK_MODE_WINDOW)
1833 {
1834 /* Update event coordinates from axes */
1835 gdk_device_get_axis (event->motion.device, event->motion.axes, GDK_AXIS_X, &event->motion.x);
1836 gdk_device_get_axis (event->motion.device, event->motion.axes, GDK_AXIS_Y, &event->motion.y);
1837 }
1838 }
1839 break;
1840
1841 #ifdef XINPUT_2_2
1842 case XI_TouchBegin:
1843 case XI_TouchEnd:
1844 {
1845 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
1846
1847 GDK_NOTE(EVENTS,
1848 g_message ("touch %s:\twindow %ld\n\ttouch id: %u\n\tpointer emulating: %s",
1849 ev->evtype == XI_TouchBegin ? "begin" : "end",
1850 xev->event,
1851 xev->detail,
1852 xev->flags & XITouchEmulatingPointer ? "true" : "false"));
1853
1854 if (ev->evtype == XI_TouchBegin)
1855 event->touch.type = GDK_TOUCH_BEGIN;
1856 else if (ev->evtype == XI_TouchEnd)
1857 event->touch.type = GDK_TOUCH_END;
1858
1859 event->touch.window = window;
1860 event->touch.time = xev->time;
1861 event->touch.x = (gdouble) xev->event_x / scale;
1862 event->touch.y = (gdouble) xev->event_y / scale;
1863 event->touch.x_root = (gdouble) xev->root_x / scale;
1864 event->touch.y_root = (gdouble) xev->root_y / scale;
1865
1866 device = g_hash_table_lookup (device_manager->id_table,
1867 GUINT_TO_POINTER (xev->deviceid));
1868 gdk_event_set_device (event, device);
1869
1870 source_device = g_hash_table_lookup (device_manager->id_table,
1871 GUINT_TO_POINTER (xev->sourceid));
1872 gdk_event_set_source_device (event, source_device);
1873 gdk_event_set_seat (event, gdk_device_get_seat (device));
1874
1875 event->touch.axes = translate_axes (event->touch.device,
1876 event->touch.x,
1877 event->touch.y,
1878 event->touch.window,
1879 &xev->valuators);
1880
1881 if (gdk_device_get_mode (event->touch.device) == GDK_MODE_WINDOW)
1882 {
1883 GdkDevice *device = event->touch.device;
1884
1885 /* Update event coordinates from axes */
1886 gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_X, &event->touch.x);
1887 gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
1888 }
1889
1890 event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
1891
1892 if (ev->evtype == XI_TouchBegin)
1893 event->touch.state |= GDK_BUTTON1_MASK;
1894
1895 event->touch.sequence = GUINT_TO_POINTER (xev->detail);
1896
1897 if (xev->flags & XITouchEmulatingPointer)
1898 {
1899 event->touch.emulating_pointer = TRUE;
1900 gdk_event_set_pointer_emulated (event, TRUE);
1901 }
1902
1903 if (return_val == FALSE)
1904 break;
1905
1906 if (!set_screen_from_root (display, event, xev->root))
1907 {
1908 return_val = FALSE;
1909 break;
1910 }
1911
1912 if (ev->evtype == XI_TouchBegin)
1913 set_user_time (event);
1914 }
1915 break;
1916
1917 case XI_TouchUpdate:
1918 {
1919 XIDeviceEvent *xev = (XIDeviceEvent *) ev;
1920
1921 GDK_NOTE(EVENTS,
1922 g_message ("touch update:\twindow %ld\n\ttouch id: %u\n\tpointer emulating: %s",
1923 xev->event,
1924 xev->detail,
1925 xev->flags & XITouchEmulatingPointer ? "true" : "false"));
1926
1927 event->touch.window = window;
1928 event->touch.sequence = GUINT_TO_POINTER (xev->detail);
1929 event->touch.type = GDK_TOUCH_UPDATE;
1930 event->touch.time = xev->time;
1931 event->touch.x = (gdouble) xev->event_x / scale;
1932 event->touch.y = (gdouble) xev->event_y / scale;
1933 event->touch.x_root = (gdouble) xev->root_x / scale;
1934 event->touch.y_root = (gdouble) xev->root_y / scale;
1935
1936 device = g_hash_table_lookup (device_manager->id_table,
1937 GINT_TO_POINTER (xev->deviceid));
1938 gdk_event_set_device (event, device);
1939
1940 source_device = g_hash_table_lookup (device_manager->id_table,
1941 GUINT_TO_POINTER (xev->sourceid));
1942 gdk_event_set_source_device (event, source_device);
1943 gdk_event_set_seat (event, gdk_device_get_seat (device));
1944
1945 event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
1946
1947 event->touch.state |= GDK_BUTTON1_MASK;
1948
1949 if (xev->flags & XITouchEmulatingPointer)
1950 {
1951 event->touch.emulating_pointer = TRUE;
1952 gdk_event_set_pointer_emulated (event, TRUE);
1953 }
1954
1955 event->touch.axes = translate_axes (event->touch.device,
1956 event->touch.x,
1957 event->touch.y,
1958 event->touch.window,
1959 &xev->valuators);
1960
1961 if (gdk_device_get_mode (event->touch.device) == GDK_MODE_WINDOW)
1962 {
1963 GdkDevice *device = event->touch.device;
1964
1965 /* Update event coordinates from axes */
1966 gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_X, &event->touch.x);
1967 gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
1968 }
1969 }
1970 break;
1971 #endif /* XINPUT_2_2 */
1972
1973 #ifdef XINPUT_2_4
1974 case XI_GesturePinchBegin:
1975 case XI_GesturePinchUpdate:
1976 case XI_GesturePinchEnd:
1977 {
1978 XIGesturePinchEvent *xev = (XIGesturePinchEvent *) ev;
1979
1980 #ifdef G_ENABLE_DEBUG
1981 const char* event_name = "";
1982 switch (xev->evtype)
1983 {
1984 case XI_GesturePinchBegin:
1985 event_name = "begin";
1986 break;
1987 case XI_GesturePinchUpdate:
1988 event_name = "update";
1989 break;
1990 case XI_GesturePinchEnd:
1991 event_name = "end";
1992 break;
1993 }
1994 #endif
1995
1996 GDK_NOTE(EVENTS,
1997 g_message ("pinch gesture %s:\twindow %ld\n\tfinger_count: %u%s",
1998 event_name,
1999 xev->event,
2000 xev->detail,
2001 xev->flags & XIGesturePinchEventCancelled ? "\n\tcancelled" : ""));
2002
2003 event->touchpad_pinch.type = GDK_TOUCHPAD_PINCH;
2004 event->touchpad_pinch.phase =
2005 _gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
2006 event->touchpad_pinch.window = window;
2007 event->touchpad_pinch.time = xev->time;
2008 event->touchpad_pinch.x = (gdouble) xev->event_x / scale;
2009 event->touchpad_pinch.y = (gdouble) xev->event_y / scale;
2010 event->touchpad_pinch.x_root = (gdouble) xev->root_x / scale;
2011 event->touchpad_pinch.y_root = (gdouble) xev->root_y / scale;
2012 event->touchpad_pinch.dx = xev->delta_x;
2013 event->touchpad_pinch.dy = xev->delta_y;
2014 event->touchpad_pinch.scale = xev->scale;
2015 event->touchpad_pinch.angle_delta = xev->delta_angle * G_PI / 180;
2016 event->touchpad_pinch.n_fingers = xev->detail;
2017
2018 device = g_hash_table_lookup (device_manager->id_table,
2019 GUINT_TO_POINTER (xev->deviceid));
2020 gdk_event_set_device (event, device);
2021
2022 source_device = g_hash_table_lookup (device_manager->id_table,
2023 GUINT_TO_POINTER (xev->sourceid));
2024 gdk_event_set_source_device (event, source_device);
2025 gdk_event_set_seat (event, gdk_device_get_seat (device));
2026
2027 event->touchpad_pinch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
2028
2029 if (xev->evtype == XI_GesturePinchBegin || xev->evtype == XI_GesturePinchEnd)
2030 {
2031 if (!set_screen_from_root (display, event, xev->root))
2032 {
2033 return_val = FALSE;
2034 break;
2035 }
2036 }
2037
2038 if (ev->evtype == XI_GesturePinchBegin)
2039 set_user_time (event);
2040 }
2041 break;
2042
2043 case XI_GestureSwipeBegin:
2044 case XI_GestureSwipeUpdate:
2045 case XI_GestureSwipeEnd:
2046 {
2047 XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
2048
2049 #ifdef G_ENABLE_DEBUG
2050 const char* event_name = "";
2051 switch (xev->evtype)
2052 {
2053 case XI_GestureSwipeBegin:
2054 event_name = "begin";
2055 break;
2056 case XI_GestureSwipeUpdate:
2057 event_name = "update";
2058 break;
2059 case XI_GestureSwipeEnd:
2060 event_name = "end";
2061 break;
2062 }
2063 #endif
2064
2065 GDK_NOTE(EVENTS,
2066 g_message ("swipe gesture %s:\twindow %ld\n\tfinger_count: %u%s",
2067 event_name,
2068 xev->event,
2069 xev->detail,
2070 xev->flags & XIGestureSwipeEventCancelled ? "\n\tcancelled" : ""));
2071
2072 event->touchpad_swipe.type = GDK_TOUCHPAD_SWIPE;
2073 event->touchpad_pinch.phase =
2074 _gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
2075 event->touchpad_swipe.window = window;
2076 event->touchpad_swipe.time = xev->time;
2077 event->touchpad_swipe.x = (gdouble) xev->event_x / scale;
2078 event->touchpad_swipe.y = (gdouble) xev->event_y / scale;
2079 event->touchpad_swipe.x_root = (gdouble) xev->root_x / scale;
2080 event->touchpad_swipe.y_root = (gdouble) xev->root_y / scale;
2081 event->touchpad_swipe.dx = xev->delta_x;
2082 event->touchpad_swipe.dy = xev->delta_y;
2083 event->touchpad_swipe.n_fingers = xev->detail;
2084
2085 device = g_hash_table_lookup (device_manager->id_table,
2086 GUINT_TO_POINTER (xev->deviceid));
2087 gdk_event_set_device (event, device);
2088
2089 source_device = g_hash_table_lookup (device_manager->id_table,
2090 GUINT_TO_POINTER (xev->sourceid));
2091 gdk_event_set_source_device (event, source_device);
2092 gdk_event_set_seat (event, gdk_device_get_seat (device));
2093
2094 event->touchpad_swipe.state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
2095
2096 if (xev->evtype == XI_GestureSwipeBegin || xev->evtype == XI_GestureSwipeEnd)
2097 {
2098 if (!set_screen_from_root (display, event, xev->root))
2099 {
2100 return_val = FALSE;
2101 break;
2102 }
2103 }
2104
2105 if (ev->evtype == XI_GestureSwipeBegin)
2106 set_user_time (event);
2107 }
2108 break;
2109 #endif /* XINPUT_2_4 */
2110
2111 case XI_Enter:
2112 case XI_Leave:
2113 {
2114 XIEnterEvent *xev = (XIEnterEvent *) ev;
2115
2116 GDK_NOTE (EVENTS,
2117 g_message ("%s notify:\twindow %ld\n\tsubwindow:%ld\n"
2118 "\tdevice: %u\n\tsource device: %u\n"
2119 "\tnotify type: %u\n\tcrossing mode: %u",
2120 (ev->evtype == XI_Enter) ? "enter" : "leave",
2121 xev->event, xev->child,
2122 xev->deviceid, xev->sourceid,
2123 xev->detail, xev->mode));
2124
2125 event->crossing.type = (ev->evtype == XI_Enter) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY;
2126
2127 event->crossing.x = (gdouble) xev->event_x / scale;
2128 event->crossing.y = (gdouble) xev->event_y / scale;
2129 event->crossing.x_root = (gdouble) xev->root_x / scale;
2130 event->crossing.y_root = (gdouble) xev->root_y / scale;
2131 event->crossing.time = xev->time;
2132 event->crossing.focus = xev->focus;
2133
2134 event->crossing.window = window;
2135 event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xev->child);
2136
2137 device = g_hash_table_lookup (device_manager->id_table,
2138 GINT_TO_POINTER (xev->deviceid));
2139 gdk_event_set_device (event, device);
2140
2141 source_device = g_hash_table_lookup (device_manager->id_table,
2142 GUINT_TO_POINTER (xev->sourceid));
2143 gdk_event_set_source_device (event, source_device);
2144 gdk_event_set_seat (event, gdk_device_get_seat (device));
2145
2146 if (ev->evtype == XI_Enter &&
2147 xev->detail != XINotifyInferior && xev->mode != XINotifyPassiveUngrab &&
2148 gdk_window_get_window_type (window) == GDK_WINDOW_TOPLEVEL)
2149 {
2150 if (gdk_device_get_device_type (source_device) != GDK_DEVICE_TYPE_MASTER)
2151 _gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
2152 else
2153 {
2154 GList *slaves, *l;
2155
2156 slaves = gdk_device_list_slave_devices (source_device);
2157
2158 for (l = slaves; l; l = l->next)
2159 _gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
2160
2161 g_list_free (slaves);
2162 }
2163 }
2164
2165 event->crossing.mode = translate_crossing_mode (xev->mode);
2166 event->crossing.detail = translate_notify_type (xev->detail);
2167 event->crossing.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
2168 }
2169 break;
2170 case XI_FocusIn:
2171 case XI_FocusOut:
2172 {
2173 if (window)
2174 {
2175 XIEnterEvent *xev = (XIEnterEvent *) ev;
2176
2177 device = g_hash_table_lookup (device_manager->id_table,
2178 GINT_TO_POINTER (xev->deviceid));
2179
2180 source_device = g_hash_table_lookup (device_manager->id_table,
2181 GUINT_TO_POINTER (xev->sourceid));
2182
2183 _gdk_device_manager_core_handle_focus (window,
2184 xev->event,
2185 device,
2186 source_device,
2187 (ev->evtype == XI_FocusIn) ? TRUE : FALSE,
2188 xev->detail,
2189 xev->mode);
2190 }
2191
2192 return_val = FALSE;
2193 }
2194 break;
2195 default:
2196 return_val = FALSE;
2197 break;
2198 }
2199
2200 event->any.send_event = cookie->send_event;
2201
2202 if (return_val)
2203 {
2204 if (event->any.window)
2205 g_object_ref (event->any.window);
2206
2207 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2208 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2209 (event->crossing.subwindow != NULL))
2210 g_object_ref (event->crossing.subwindow);
2211 }
2212 else
2213 {
2214 /* Mark this event as having no resources to be freed */
2215 event->any.window = NULL;
2216 event->any.type = GDK_NOTHING;
2217 }
2218
2219 return return_val;
2220 }
2221
2222 static GdkEventMask
gdk_x11_device_manager_xi2_get_handled_events(GdkEventTranslator * translator)2223 gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
2224 {
2225 return (GDK_KEY_PRESS_MASK |
2226 GDK_KEY_RELEASE_MASK |
2227 GDK_BUTTON_PRESS_MASK |
2228 GDK_BUTTON_RELEASE_MASK |
2229 GDK_SCROLL_MASK |
2230 GDK_ENTER_NOTIFY_MASK |
2231 GDK_LEAVE_NOTIFY_MASK |
2232 GDK_POINTER_MOTION_MASK |
2233 GDK_POINTER_MOTION_HINT_MASK |
2234 GDK_BUTTON1_MOTION_MASK |
2235 GDK_BUTTON2_MOTION_MASK |
2236 GDK_BUTTON3_MOTION_MASK |
2237 GDK_BUTTON_MOTION_MASK |
2238 GDK_FOCUS_CHANGE_MASK |
2239 GDK_TOUCH_MASK |
2240 GDK_TOUCHPAD_GESTURE_MASK);
2241 }
2242
2243 static void
gdk_x11_device_manager_xi2_select_window_events(GdkEventTranslator * translator,Window window,GdkEventMask evmask)2244 gdk_x11_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
2245 Window window,
2246 GdkEventMask evmask)
2247 {
2248 GdkDeviceManager *device_manager;
2249 XIEventMask event_mask;
2250
2251 device_manager = GDK_DEVICE_MANAGER (translator);
2252
2253 event_mask.deviceid = XIAllMasterDevices;
2254 event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
2255 evmask,
2256 &event_mask.mask_len);
2257
2258 _gdk_x11_device_manager_xi2_select_events (device_manager, window, &event_mask);
2259 g_free (event_mask.mask);
2260 }
2261
2262 static GdkWindow *
gdk_x11_device_manager_xi2_get_window(GdkEventTranslator * translator,XEvent * xevent)2263 gdk_x11_device_manager_xi2_get_window (GdkEventTranslator *translator,
2264 XEvent *xevent)
2265 {
2266 GdkX11DeviceManagerXI2 *device_manager;
2267 XIEvent *ev;
2268 GdkWindow *window = NULL;
2269
2270 device_manager = (GdkX11DeviceManagerXI2 *) translator;
2271
2272 if (xevent->type != GenericEvent ||
2273 xevent->xcookie.extension != device_manager->opcode)
2274 return NULL;
2275
2276 ev = (XIEvent *) xevent->xcookie.data;
2277 if (!ev)
2278 return NULL;
2279
2280 get_event_window (translator, ev, &window);
2281 return window;
2282 }
2283
2284 GdkDevice *
_gdk_x11_device_manager_xi2_lookup(GdkX11DeviceManagerXI2 * device_manager_xi2,gint device_id)2285 _gdk_x11_device_manager_xi2_lookup (GdkX11DeviceManagerXI2 *device_manager_xi2,
2286 gint device_id)
2287 {
2288 return g_hash_table_lookup (device_manager_xi2->id_table,
2289 GINT_TO_POINTER (device_id));
2290 }
2291