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 <unistd.h>
21#include <fcntl.h>
22#include <errno.h>
23
24#include <string.h>
25#include <gdk/gdkwindow.h>
26#include <gdk/gdktypes.h>
27#include "gdkprivate-wayland.h"
28#include "gdkseat-wayland.h"
29#include "gdkwayland.h"
30#include "gdkkeysyms.h"
31#include "gdkdeviceprivate.h"
32#include "gdkdevicetoolprivate.h"
33#include "gdkdevicemanagerprivate.h"
34#include "gdkseatprivate.h"
35#include "pointer-gestures-unstable-v1-client-protocol.h"
36#include "tablet-unstable-v1-client-protocol.h"
37
38#include <xkbcommon/xkbcommon.h>
39
40#include <linux/input.h>
41
42#include <sys/time.h>
43#include <sys/mman.h>
44#include <linux/input.h>
45
46#define BUTTON_BASE (BTN_LEFT - 1) /* Used to translate to 1-indexed buttons */
47
48typedef struct _GdkWaylandTouchData GdkWaylandTouchData;
49typedef struct _GdkWaylandPointerFrameData GdkWaylandPointerFrameData;
50typedef struct _GdkWaylandPointerData GdkWaylandPointerData;
51typedef struct _GdkWaylandTabletData GdkWaylandTabletData;
52typedef struct _GdkWaylandTabletToolData GdkWaylandTabletToolData;
53
54struct _GdkWaylandTouchData
55{
56 uint32_t id;
57 gdouble x;
58 gdouble y;
59 GdkWindow *window;
60 uint32_t touch_down_serial;
61 guint initial_touch : 1;
62};
63
64struct _GdkWaylandPointerFrameData
65{
66 GdkEvent *event;
67
68 /* Specific to the scroll event */
69 gdouble delta_x, delta_y;
70 int32_t discrete_x, discrete_y;
71 gint8 is_scroll_stop;
72 enum wl_pointer_axis_source source;
73};
74
75struct _GdkWaylandPointerData {
76 GdkWindow *focus;
77
78 double surface_x, surface_y;
79
80 GdkModifierType button_modifiers;
81
82 uint32_t time;
83 uint32_t enter_serial;
84 uint32_t press_serial;
85
86 GdkWindow *grab_window;
87 uint32_t grab_time;
88
89 struct wl_surface *pointer_surface;
90 GdkCursor *cursor;
91 guint cursor_timeout_id;
92 guint cursor_image_index;
93 guint cursor_image_delay;
94
95 guint current_output_scale;
96 GSList *pointer_surface_outputs;
97
98 /* Accumulated event data for a pointer frame */
99 GdkWaylandPointerFrameData frame;
100};
101
102struct _GdkWaylandTabletToolData
103{
104 GdkSeat *seat;
105 struct zwp_tablet_tool_v1 *wp_tablet_tool;
106 GdkAxisFlags axes;
107 GdkDeviceToolType type;
108 guint64 hardware_serial;
109 guint64 hardware_id_wacom;
110
111 GdkDeviceTool *tool;
112 GdkWaylandTabletData *current_tablet;
113};
114
115struct _GdkWaylandTabletData
116{
117 struct zwp_tablet_v1 *wp_tablet;
118 gchar *name;
119 gchar *path;
120 uint32_t vid;
121 uint32_t pid;
122
123 GdkDevice *master;
124 GdkDevice *stylus_device;
125 GdkDevice *eraser_device;
126 GdkDevice *current_device;
127 GdkSeat *seat;
128 GdkWaylandPointerData pointer_info;
129
130 GdkWaylandTabletToolData *current_tool;
131
132 gint axis_indices[GDK_AXIS_LAST];
133 gdouble *axes;
134};
135
136struct _GdkWaylandSeat
137{
138 GdkSeat parent_instance;
139
140 guint32 id;
141 struct wl_seat *wl_seat;
142 struct wl_pointer *wl_pointer;
143 struct wl_keyboard *wl_keyboard;
144 struct wl_touch *wl_touch;
145 struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe;
146 struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch;
147 struct zwp_tablet_seat_v1 *wp_tablet_seat;
148
149 GdkDisplay *display;
150 GdkDeviceManager *device_manager;
151
152 GdkDevice *master_pointer;
153 GdkDevice *master_keyboard;
154 GdkDevice *pointer;
155 GdkDevice *wheel_scrolling;
156 GdkDevice *finger_scrolling;
157 GdkDevice *continuous_scrolling;
158 GdkDevice *keyboard;
159 GdkDevice *touch_master;
160 GdkDevice *touch;
161 GdkCursor *cursor;
162 GdkKeymap *keymap;
163
164 GHashTable *touches;
165 GList *tablets;
166 GList *tablet_tools;
167
168 GdkWaylandPointerData pointer_info;
169 GdkWaylandPointerData touch_info;
170
171 GdkModifierType key_modifiers;
172 GdkWindow *keyboard_focus;
173 GdkAtom pending_selection;
174 GdkWindow *grab_window;
175 uint32_t grab_time;
176 gboolean have_server_repeat;
177 uint32_t server_repeat_rate;
178 uint32_t server_repeat_delay;
179
180 struct wl_callback *repeat_callback;
181 guint32 repeat_timer;
182 guint32 repeat_key;
183 guint32 repeat_count;
184 gint64 repeat_deadline;
185 GSettings *keyboard_settings;
186 uint32_t keyboard_time;
187
188 struct gtk_primary_selection_device *primary_data_device;
189 struct wl_data_device *data_device;
190 GdkDragContext *drop_context;
191
192 /* Source/dest for non-local dnd */
193 GdkWindow *foreign_dnd_window;
194
195 /* Some tracking on gesture events */
196 guint gesture_n_fingers;
197 gdouble gesture_scale;
198
199 GdkCursor *grab_cursor;
200};
201
202G_DEFINE_TYPE (GdkWaylandSeat, gdk_wayland_seat, GDK_TYPE_SEAT)
203
204struct _GdkWaylandDevice
205{
206 GdkDevice parent_instance;
207 GdkWaylandTouchData *emulating_touch; /* Only used on wd->touch_master */
208 GdkWaylandPointerData *pointer;
209};
210
211struct _GdkWaylandDeviceClass
212{
213 GdkDeviceClass parent_class;
214};
215
216G_DEFINE_TYPE (GdkWaylandDevice, gdk_wayland_device, GDK_TYPE_DEVICE)
217
218#define GDK_TYPE_WAYLAND_DEVICE_MANAGER (gdk_wayland_device_manager_get_type ())
219#define GDK_WAYLAND_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManager))
220#define GDK_WAYLAND_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManagerClass))
221#define GDK_IS_WAYLAND_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER))
222#define GDK_IS_WAYLAND_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_WAYLAND_DEVICE_MANAGER))
223#define GDK_WAYLAND_DEVICE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManagerClass))
224
225#define GDK_SLOT_TO_EVENT_SEQUENCE(s) ((GdkEventSequence *) GUINT_TO_POINTER((s) + 1))
226#define GDK_EVENT_SEQUENCE_TO_SLOT(s) (GPOINTER_TO_UINT(s) - 1)
227
228typedef struct _GdkWaylandDeviceManager GdkWaylandDeviceManager;
229typedef struct _GdkWaylandDeviceManagerClass GdkWaylandDeviceManagerClass;
230
231struct _GdkWaylandDeviceManager
232{
233 GdkDeviceManager parent_object;
234 GList *devices;
235};
236
237struct _GdkWaylandDeviceManagerClass
238{
239 GdkDeviceManagerClass parent_class;
240};
241
242static void deliver_key_event (GdkWaylandSeat *seat,
243 uint32_t time_,
244 uint32_t key,
245 uint32_t state);
246GType gdk_wayland_device_manager_get_type (void);
247
248G_DEFINE_TYPE (GdkWaylandDeviceManager,
249 gdk_wayland_device_manager, GDK_TYPE_DEVICE_MANAGER)
250
251static gboolean
252gdk_wayland_device_get_history (GdkDevice *device,
253 GdkWindow *window,
254 guint32 start,
255 guint32 stop,
256 GdkTimeCoord ***events,
257 gint *n_events)
258{
259 return FALSE;
260}
261
262static void
263gdk_wayland_device_get_state (GdkDevice *device,
264 GdkWindow *window,
265 gdouble *axes,
266 GdkModifierType *mask)
267{
268 gdouble x, y;
269
270 gdk_window_get_device_position_double (window, device, &x, &y, mask);
271
272 if (axes)
273 {
274 axes[0] = x;
275 axes[1] = y;
276 }
277}
278
279static void
280gdk_wayland_pointer_stop_cursor_animation (GdkWaylandPointerData *pointer)
281{
282 if (pointer->cursor_timeout_id > 0)
283 {
284 g_source_remove (pointer->cursor_timeout_id);
285 pointer->cursor_timeout_id = 0;
286 }
287
288 pointer->cursor_image_index = 0;
289}
290
291static GdkWaylandTabletData *
292gdk_wayland_device_manager_find_tablet (GdkWaylandSeat *seat,
293 GdkDevice *device)
294{
295 GList *l;
296
297 for (l = seat->tablets; l; l = l->next)
298 {
299 GdkWaylandTabletData *tablet = l->data;
300
301 if (tablet->master == device ||
302 tablet->stylus_device == device ||
303 tablet->eraser_device == device)
304 return tablet;
305 }
306
307 return NULL;
308}
309
310static gboolean
311gdk_wayland_device_update_window_cursor (GdkDevice *device)
312{
313 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
314 GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
315 struct wl_buffer *buffer;
316 int x, y, w, h, scale;
317 guint next_image_index, next_image_delay;
318 gboolean retval = G_SOURCE_REMOVE;
319 GdkWaylandTabletData *tablet;
320
321 tablet = gdk_wayland_device_manager_find_tablet (seat, device);
322
323 if (pointer->cursor)
324 {
325 buffer = _gdk_wayland_cursor_get_buffer (pointer->cursor,
326 pointer->cursor_image_index,
327 &x, &y, &w, &h, &scale);
328 }
329 else
330 {
331 pointer->cursor_timeout_id = 0;
332 return TRUE;
333 }
334
335 if (tablet)
336 {
337 if (!tablet->current_tool)
338 return retval;
339
340 zwp_tablet_tool_v1_set_cursor (tablet->current_tool->wp_tablet_tool,
341 pointer->enter_serial,
342 pointer->pointer_surface,
343 x, y);
344 }
345 else if (seat->wl_pointer)
346 {
347 wl_pointer_set_cursor (seat->wl_pointer,
348 pointer->enter_serial,
349 pointer->pointer_surface,
350 x, y);
351 }
352 else
353 return retval;
354
355 if (buffer)
356 {
357 wl_surface_attach (pointer->pointer_surface, buffer, 0, 0);
358 wl_surface_set_buffer_scale (pointer->pointer_surface, scale);
359 wl_surface_damage (pointer->pointer_surface, 0, 0, w, h);
360 wl_surface_commit (pointer->pointer_surface);
361 }
362 else
363 {
364 wl_surface_attach (pointer->pointer_surface, NULL, 0, 0);
365 wl_surface_commit (pointer->pointer_surface);
366 }
367
368 next_image_index =
369 _gdk_wayland_cursor_get_next_image_index (pointer->cursor,
370 pointer->cursor_image_index,
371 &next_image_delay);
372
373 if (next_image_index != pointer->cursor_image_index)
374 {
375 if (next_image_delay != pointer->cursor_image_delay)
376 {
377 guint id;
378
379 gdk_wayland_pointer_stop_cursor_animation (pointer);
380
381 /* Queue timeout for next frame */
382 id = g_timeout_add (next_image_delay,
383 (GSourceFunc) gdk_wayland_device_update_window_cursor,
384 device);
385 g_source_set_name_by_id (id, "[gtk+] gdk_wayland_device_update_window_cursor");
386 pointer->cursor_timeout_id = id;
387 }
388 else
389 retval = G_SOURCE_CONTINUE;
390
391 pointer->cursor_image_index = next_image_index;
392 pointer->cursor_image_delay = next_image_delay;
393 }
394 else
395 gdk_wayland_pointer_stop_cursor_animation (pointer);
396
397 return retval;
398}
399
400static void
401gdk_wayland_device_set_window_cursor (GdkDevice *device,
402 GdkWindow *window,
403 GdkCursor *cursor)
404{
405 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
406 GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
407
408 if (device == seat->touch_master)
409 return;
410
411 if (seat->grab_cursor)
412 cursor = seat->grab_cursor;
413
414 /* Setting the cursor to NULL means that we should use
415 * the default cursor
416 */
417 if (!cursor)
418 {
419 guint scale = pointer->current_output_scale;
420 cursor =
421 _gdk_wayland_display_get_cursor_for_type_with_scale (seat->display,
422 GDK_LEFT_PTR,
423 scale);
424 }
425 else
426 _gdk_wayland_cursor_set_scale (cursor, pointer->current_output_scale);
427
428 if (cursor == pointer->cursor)
429 return;
430
431 gdk_wayland_pointer_stop_cursor_animation (pointer);
432
433 if (pointer->cursor)
434 g_object_unref (pointer->cursor);
435
436 pointer->cursor = g_object_ref (cursor);
437
438 gdk_wayland_device_update_window_cursor (device);
439}
440
441static void
442gdk_wayland_device_warp (GdkDevice *device,
443 GdkScreen *screen,
444 gdouble x,
445 gdouble y)
446{
447}
448
449static void
450get_coordinates (GdkDevice *device,
451 double *x,
452 double *y,
453 double *x_root,
454 double *y_root)
455{
456 GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
457 int root_x, root_y;
458
459 if (x)
460 *x = pointer->surface_x;
461 if (y)
462 *y = pointer->surface_y;
463
464 if (pointer->focus)
465 {
466 gdk_window_get_root_coords (pointer->focus,
467 pointer->surface_x,
468 pointer->surface_y,
469 &root_x, &root_y);
470 }
471 else
472 {
473 root_x = pointer->surface_x;
474 root_y = pointer->surface_y;
475 }
476
477 if (x_root)
478 *x_root = root_x;
479 if (y_root)
480 *y_root = root_y;
481}
482
483static GdkModifierType
484device_get_modifiers (GdkDevice *device)
485{
486 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
487 GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
488 GdkModifierType mask;
489
490 mask = seat->key_modifiers;
491
492 if (pointer)
493 mask |= pointer->button_modifiers;
494
495 return mask;
496}
497
498static void
499gdk_wayland_device_query_state (GdkDevice *device,
500 GdkWindow *window,
501 GdkWindow **root_window,
502 GdkWindow **child_window,
503 gdouble *root_x,
504 gdouble *root_y,
505 gdouble *win_x,
506 gdouble *win_y,
507 GdkModifierType *mask)
508{
509 GdkWaylandSeat *seat;
510 GdkWaylandPointerData *pointer;
511 GdkScreen *default_screen;
512
513 seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
514 pointer = GDK_WAYLAND_DEVICE (device)->pointer;
515 default_screen = gdk_display_get_default_screen (seat->display);
516
517 if (root_window)
518 *root_window = gdk_screen_get_root_window (default_screen);
519 if (child_window)
520 *child_window = pointer->focus;
521 if (mask)
522 *mask = device_get_modifiers (device);
523
524 get_coordinates (device, win_x, win_y, root_x, root_y);
525}
526
527static void
528emulate_crossing (GdkWindow *window,
529 GdkWindow *subwindow,
530 GdkDevice *device,
531 GdkEventType type,
532 GdkCrossingMode mode,
533 guint32 time_)
534{
535 GdkEvent *event;
536
537 event = gdk_event_new (type);
538 event->crossing.window = window ? g_object_ref (window) : NULL;
539 event->crossing.subwindow = subwindow ? g_object_ref (subwindow) : NULL;
540 event->crossing.time = time_;
541 event->crossing.mode = mode;
542 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
543 gdk_event_set_device (event, device);
544 gdk_event_set_source_device (event, device);
545 gdk_event_set_seat (event, gdk_device_get_seat (device));
546
547 gdk_window_get_device_position_double (window, device,
548 &event->crossing.x, &event->crossing.y,
549 &event->crossing.state);
550 event->crossing.x_root = event->crossing.x;
551 event->crossing.y_root = event->crossing.y;
552
553 _gdk_wayland_display_deliver_event (gdk_window_get_display (window), event);
554}
555
556static void
557emulate_touch_crossing (GdkWindow *window,
558 GdkWindow *subwindow,
559 GdkDevice *device,
560 GdkDevice *source,
561 GdkWaylandTouchData *touch,
562 GdkEventType type,
563 GdkCrossingMode mode,
564 guint32 time_)
565{
566 GdkEvent *event;
567
568 event = gdk_event_new (type);
569 event->crossing.window = window ? g_object_ref (window) : NULL;
570 event->crossing.subwindow = subwindow ? g_object_ref (subwindow) : NULL;
571 event->crossing.time = time_;
572 event->crossing.mode = mode;
573 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
574 gdk_event_set_device (event, device);
575 gdk_event_set_source_device (event, source);
576 gdk_event_set_seat (event, gdk_device_get_seat (device));
577
578 event->crossing.x = touch->x;
579 event->crossing.y = touch->y;
580 event->crossing.x_root = event->crossing.x;
581 event->crossing.y_root = event->crossing.y;
582
583 _gdk_wayland_display_deliver_event (gdk_window_get_display (window), event);
584}
585
586static void
587emulate_focus (GdkWindow *window,
588 GdkDevice *device,
589 gboolean focus_in,
590 guint32 time_)
591{
592 GdkEvent *event;
593
594 event = gdk_event_new (GDK_FOCUS_CHANGE);
595 event->focus_change.window = g_object_ref (window);
596 event->focus_change.in = focus_in;
597 gdk_event_set_device (event, device);
598 gdk_event_set_source_device (event, device);
599 gdk_event_set_seat (event, gdk_device_get_seat (device));
600
601 _gdk_wayland_display_deliver_event (gdk_window_get_display (window), event);
602}
603
604static void
605device_emit_grab_crossing (GdkDevice *device,
606 GdkWindow *from,
607 GdkWindow *to,
608 GdkCrossingMode mode,
609 guint32 time_)
610{
611 if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
612 {
613 if (from)
614 emulate_focus (from, device, FALSE, time_);
615 if (to)
616 emulate_focus (to, device, TRUE, time_);
617 }
618 else
619 {
620 if (from)
621 emulate_crossing (from, to, device, GDK_LEAVE_NOTIFY, mode, time_);
622 if (to)
623 emulate_crossing (to, from, device, GDK_ENTER_NOTIFY, mode, time_);
624 }
625}
626
627static GdkWindow *
628gdk_wayland_device_get_focus (GdkDevice *device)
629{
630 GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
631 GdkWaylandPointerData *pointer;
632
633 if (device == wayland_seat->master_keyboard)
634 return wayland_seat->keyboard_focus;
635 else
636 {
637 pointer = GDK_WAYLAND_DEVICE (device)->pointer;
638
639 if (pointer)
640 return pointer->focus;
641 }
642
643 return NULL;
644}
645
646static GdkGrabStatus
647gdk_wayland_device_grab (GdkDevice *device,
648 GdkWindow *window,
649 gboolean owner_events,
650 GdkEventMask event_mask,
651 GdkWindow *confine_to,
652 GdkCursor *cursor,
653 guint32 time_)
654{
655 GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
656 GdkWindow *prev_focus = gdk_wayland_device_get_focus (device);
657 GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
658
659 if (prev_focus != window)
660 device_emit_grab_crossing (device, prev_focus, window, GDK_CROSSING_GRAB, time_);
661
662 if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
663 {
664 /* Device is a keyboard */
665 return GDK_GRAB_SUCCESS;
666 }
667 else
668 {
669 /* Device is a pointer */
670 if (pointer->grab_window != NULL &&
671 time_ != 0 && pointer->grab_time > time_)
672 {
673 return GDK_GRAB_ALREADY_GRABBED;
674 }
675
676 if (time_ == 0)
677 time_ = pointer->time;
678
679 pointer->grab_window = window;
680 pointer->grab_time = time_;
681 _gdk_wayland_window_set_grab_seat (window, GDK_SEAT (wayland_seat));
682
683 g_clear_object (&wayland_seat->cursor);
684
685 if (cursor)
686 wayland_seat->cursor = g_object_ref (cursor);
687
688 gdk_wayland_device_update_window_cursor (device);
689 }
690
691 return GDK_GRAB_SUCCESS;
692}
693
694static void
695gdk_wayland_device_ungrab (GdkDevice *device,
696 guint32 time_)
697{
698 GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
699 GdkDisplay *display;
700 GdkDeviceGrabInfo *grab;
701 GdkWindow *focus, *prev_focus = NULL;
702
703 display = gdk_device_get_display (device);
704
705 grab = _gdk_display_get_last_device_grab (display, device);
706
707 if (grab)
708 {
709 grab->serial_end = grab->serial_start;
710 prev_focus = grab->window;
711 }
712
713 focus = gdk_wayland_device_get_focus (device);
714
715 if (focus != prev_focus)
716 device_emit_grab_crossing (device, prev_focus, focus, GDK_CROSSING_UNGRAB, time_);
717
718 if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
719 {
720 /* Device is a keyboard */
721 }
722 else
723 {
724 /* Device is a pointer */
725 gdk_wayland_device_update_window_cursor (device);
726
727 if (pointer->grab_window)
728 _gdk_wayland_window_set_grab_seat (pointer->grab_window,
729 NULL);
730 }
731}
732
733static GdkWindow *
734gdk_wayland_device_window_at_position (GdkDevice *device,
735 gdouble *win_x,
736 gdouble *win_y,
737 GdkModifierType *mask,
738 gboolean get_toplevel)
739{
740 GdkWaylandPointerData *pointer;
741
742 pointer = GDK_WAYLAND_DEVICE(device)->pointer;
743
744 if (!pointer)
745 return NULL;
746
747 if (win_x)
748 *win_x = pointer->surface_x;
749 if (win_y)
750 *win_y = pointer->surface_y;
751 if (mask)
752 *mask = device_get_modifiers (device);
753
754 return pointer->focus;
755}
756
757static void
758gdk_wayland_device_select_window_events (GdkDevice *device,
759 GdkWindow *window,
760 GdkEventMask event_mask)
761{
762}
763
764static void
765gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass)
766{
767 GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
768
769 device_class->get_history = gdk_wayland_device_get_history;
770 device_class->get_state = gdk_wayland_device_get_state;
771 device_class->set_window_cursor = gdk_wayland_device_set_window_cursor;
772 device_class->warp = gdk_wayland_device_warp;
773 device_class->query_state = gdk_wayland_device_query_state;
774 device_class->grab = gdk_wayland_device_grab;
775 device_class->ungrab = gdk_wayland_device_ungrab;
776 device_class->window_at_position = gdk_wayland_device_window_at_position;
777 device_class->select_window_events = gdk_wayland_device_select_window_events;
778}
779
780static void
781gdk_wayland_device_init (GdkWaylandDevice *device_core)
782{
783 GdkDevice *device;
784
785 device = GDK_DEVICE (device_core);
786
787 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
788 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
789}
790
791/**
792 * gdk_wayland_device_get_wl_seat:
793 * @device: (type GdkWaylandDevice): a #GdkDevice
794 *
795 * Returns the Wayland wl_seat of a #GdkDevice.
796 *
797 * Returns: (transfer none): a Wayland wl_seat
798 *
799 * Since: 3.10
800 */
801struct wl_seat *
802gdk_wayland_device_get_wl_seat (GdkDevice *device)
803{
804 GdkWaylandSeat *seat;
805
806 g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
807
808 seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
809 return seat->wl_seat;
810}
811
812/**
813 * gdk_wayland_device_get_wl_pointer:
814 * @device: (type GdkWaylandDevice): a #GdkDevice
815 *
816 * Returns the Wayland wl_pointer of a #GdkDevice.
817 *
818 * Returns: (transfer none): a Wayland wl_pointer
819 *
820 * Since: 3.10
821 */
822struct wl_pointer *
823gdk_wayland_device_get_wl_pointer (GdkDevice *device)
824{
825 GdkWaylandSeat *seat;
826
827 g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
828
829 seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
830 return seat->wl_pointer;
831}
832
833/**
834 * gdk_wayland_device_get_wl_keyboard:
835 * @device: (type GdkWaylandDevice): a #GdkDevice
836 *
837 * Returns the Wayland wl_keyboard of a #GdkDevice.
838 *
839 * Returns: (transfer none): a Wayland wl_keyboard
840 *
841 * Since: 3.10
842 */
843struct wl_keyboard *
844gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
845{
846 GdkWaylandSeat *seat;
847
848 g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
849
850 seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
851 return seat->wl_keyboard;
852}
853
854GdkKeymap *
855_gdk_wayland_device_get_keymap (GdkDevice *device)
856{
857 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
858 return seat->keymap;
859}
860
861static void
862emit_selection_owner_change (GdkWindow *window,
863 GdkAtom atom)
864{
865 GdkEvent *event;
866
867 event = gdk_event_new (GDK_OWNER_CHANGE);
868 event->owner_change.window = g_object_ref (window);
869 event->owner_change.owner = NULL;
870 event->owner_change.reason = GDK_OWNER_CHANGE_NEW_OWNER;
871 event->owner_change.selection = atom;
872 event->owner_change.time = GDK_CURRENT_TIME;
873 event->owner_change.selection_time = GDK_CURRENT_TIME;
874
875 gdk_event_put (event);
876 gdk_event_free (event);
877}
878
879static void
880data_device_data_offer (void *data,
881 struct wl_data_device *data_device,
882 struct wl_data_offer *offer)
883{
884 GdkWaylandSeat *seat = data;
885
886 GDK_NOTE (EVENTS,
887 g_message ("data device data offer, data device %p, offer %p",
888 data_device, offer));
889
890 gdk_wayland_selection_ensure_offer (seat->display, offer);
891}
892
893static void
894data_device_enter (void *data,
895 struct wl_data_device *data_device,
896 uint32_t serial,
897 struct wl_surface *surface,
898 wl_fixed_t x,
899 wl_fixed_t y,
900 struct wl_data_offer *offer)
901{
902 GdkWaylandSeat *seat = data;
903 GdkWindow *dest_window, *dnd_owner;
904 GdkAtom selection;
905
906 dest_window = wl_surface_get_user_data (surface);
907
908 if (!GDK_IS_WINDOW (dest_window))
909 return;
910
911 GDK_NOTE (EVENTS,
912 g_message ("data device enter, data device %p serial %u, surface %p, x %f y %f, offer %p",
913 data_device, serial, surface, wl_fixed_to_double (x), wl_fixed_to_double (y), offer));
914
915 /* Update pointer state, so device state queries work during DnD */
916 seat->pointer_info.focus = g_object_ref (dest_window);
917 seat->pointer_info.surface_x = wl_fixed_to_double (x);
918 seat->pointer_info.surface_y = wl_fixed_to_double (y);
919
920 gdk_wayland_drop_context_update_targets (seat->drop_context);
921
922 selection = gdk_drag_get_selection (seat->drop_context);
923 dnd_owner = gdk_selection_owner_get_for_display (seat->display, selection);
924
925 if (!dnd_owner)
926 dnd_owner = seat->foreign_dnd_window;
927
928 _gdk_wayland_drag_context_set_source_window (seat->drop_context, dnd_owner);
929
930 _gdk_wayland_drag_context_set_dest_window (seat->drop_context,
931 dest_window, serial);
932 _gdk_wayland_drag_context_set_coords (seat->drop_context,
933 wl_fixed_to_double (x),
934 wl_fixed_to_double (y));
935 _gdk_wayland_drag_context_emit_event (seat->drop_context, GDK_DRAG_ENTER,
936 GDK_CURRENT_TIME);
937
938 gdk_wayland_selection_set_offer (seat->display, selection, offer);
939
940 emit_selection_owner_change (dest_window, selection);
941}
942
943static void
944data_device_leave (void *data,
945 struct wl_data_device *data_device)
946{
947 GdkWaylandSeat *seat = data;
948
949 GDK_NOTE (EVENTS,
950 g_message ("data device leave, data device %p", data_device));
951
952 if (!gdk_drag_context_get_dest_window (seat->drop_context))
953 return;
954
955 g_object_unref (seat->pointer_info.focus);
956 seat->pointer_info.focus = NULL;
957
958 _gdk_wayland_drag_context_set_coords (seat->drop_context, -1, -1);
959 _gdk_wayland_drag_context_emit_event (seat->drop_context, GDK_DRAG_LEAVE,
960 GDK_CURRENT_TIME);
961 _gdk_wayland_drag_context_set_dest_window (seat->drop_context, NULL, 0);
962}
963
964static void
965data_device_motion (void *data,
966 struct wl_data_device *data_device,
967 uint32_t time,
968 wl_fixed_t x,
969 wl_fixed_t y)
970{
971 GdkWaylandSeat *seat = data;
972
973 g_debug (G_STRLOC ": %s data_device = %p, time = %d, x = %f, y = %f",
974 G_STRFUNC, data_device, time, wl_fixed_to_double (x), wl_fixed_to_double (y));
975
976 if (!gdk_drag_context_get_dest_window (seat->drop_context))
977 return;
978
979 /* Update pointer state, so device state queries work during DnD */
980 seat->pointer_info.surface_x = wl_fixed_to_double (x);
981 seat->pointer_info.surface_y = wl_fixed_to_double (y);
982
983 gdk_wayland_drop_context_update_targets (seat->drop_context);
984 _gdk_wayland_drag_context_set_coords (seat->drop_context,
985 wl_fixed_to_double (x),
986 wl_fixed_to_double (y));
987 _gdk_wayland_drag_context_emit_event (seat->drop_context,
988 GDK_DRAG_MOTION, time);
989}
990
991static void
992data_device_drop (void *data,
993 struct wl_data_device *data_device)
994{
995 GdkWaylandSeat *seat = data;
996
997 GDK_NOTE (EVENTS,
998 g_message ("data device drop, data device %p", data_device));
999
1000 _gdk_wayland_drag_context_emit_event (seat->drop_context,
1001 GDK_DROP_START, GDK_CURRENT_TIME);
1002}
1003
1004static void
1005data_device_selection (void *data,
1006 struct wl_data_device *wl_data_device,
1007 struct wl_data_offer *offer)
1008{
1009 GdkWaylandSeat *seat = data;
1010 GdkAtom selection;
1011
1012 GDK_NOTE (EVENTS,
1013 g_message ("data device selection, data device %p, data offer %p",
1014 wl_data_device, offer));
1015
1016 selection = gdk_atom_intern_static_string ("CLIPBOARD");
1017 gdk_wayland_selection_set_offer (seat->display, selection, offer);
1018
1019 /* If we already have keyboard focus, the selection was targeted at the
1020 * focused surface. If we don't we will receive keyboard focus directly after
1021 * this, so lets wait and find out what window will get the focus before
1022 * emitting the owner-changed event.
1023 */
1024 if (seat->keyboard_focus)
1025 emit_selection_owner_change (seat->keyboard_focus, selection);
1026 else
1027 seat->pending_selection = selection;
1028}
1029
1030static const struct wl_data_device_listener data_device_listener = {
1031 data_device_data_offer,
1032 data_device_enter,
1033 data_device_leave,
1034 data_device_motion,
1035 data_device_drop,
1036 data_device_selection
1037};
1038
1039static void
1040primary_selection_data_offer (void *data,
1041 struct gtk_primary_selection_device *gtk_primary_selection_device,
1042 struct gtk_primary_selection_offer *gtk_primary_offer)
1043{
1044 GdkWaylandSeat *seat = data;
1045
1046 GDK_NOTE (EVENTS,
1047 g_message ("primary selection offer, device %p, data offer %p",
1048 gtk_primary_selection_device, gtk_primary_offer));
1049
1050 gdk_wayland_selection_ensure_primary_offer (seat->display, gtk_primary_offer);
1051}
1052
1053static void
1054primary_selection_selection (void *data,
1055 struct gtk_primary_selection_device *gtk_primary_selection_device,
1056 struct gtk_primary_selection_offer *gtk_primary_offer)
1057{
1058 GdkWaylandSeat *seat = data;
1059 GdkAtom selection;
1060
1061 GDK_NOTE (EVENTS,
1062 g_message ("primary selection selection, device %p, data offer %p",
1063 gtk_primary_selection_device, gtk_primary_offer));
1064
1065 selection = gdk_atom_intern_static_string ("PRIMARY");
1066 gdk_wayland_selection_set_offer (seat->display, selection, gtk_primary_offer);
1067 emit_selection_owner_change (seat->keyboard_focus, selection);
1068}
1069
1070static const struct gtk_primary_selection_device_listener primary_selection_device_listener = {
1071 primary_selection_data_offer,
1072 primary_selection_selection,
1073};
1074
1075static GdkDevice * get_scroll_device (GdkWaylandSeat *seat,
1076 enum wl_pointer_axis_source source);
1077
1078static GdkEvent *
1079create_scroll_event (GdkWaylandSeat *seat,
1080 gboolean emulated)
1081{
1082 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1083 GdkEvent *event;
1084
1085 event = gdk_event_new (GDK_SCROLL);
1086 event->scroll.window = g_object_ref (seat->pointer_info.focus);
1087 gdk_event_set_device (event, seat->master_pointer);
1088 gdk_event_set_source_device (event, get_scroll_device (seat, seat->pointer_info.frame.source));
1089 event->scroll.time = seat->pointer_info.time;
1090 event->scroll.state = device_get_modifiers (seat->master_pointer);
1091 gdk_event_set_screen (event, display->screen);
1092
1093 gdk_event_set_pointer_emulated (event, emulated);
1094
1095 get_coordinates (seat->master_pointer,
1096 &event->scroll.x,
1097 &event->scroll.y,
1098 &event->scroll.x_root,
1099 &event->scroll.y_root);
1100
1101 return event;
1102}
1103
1104static void
1105flush_discrete_scroll_event (GdkWaylandSeat *seat,
1106 GdkScrollDirection direction)
1107{
1108 GdkEvent *event;
1109
1110 event = create_scroll_event (seat, TRUE);
1111 event->scroll.direction = direction;
1112
1113 _gdk_wayland_display_deliver_event (seat->display, event);
1114}
1115
1116static void
1117flush_smooth_scroll_event (GdkWaylandSeat *seat,
1118 gdouble delta_x,
1119 gdouble delta_y,
1120 gboolean is_stop)
1121{
1122 GdkEvent *event;
1123
1124 event = create_scroll_event (seat, FALSE);
1125 event->scroll.direction = GDK_SCROLL_SMOOTH;
1126 event->scroll.delta_x = delta_x;
1127 event->scroll.delta_y = delta_y;
1128 event->scroll.is_stop = is_stop;
1129
1130 _gdk_wayland_display_deliver_event (seat->display, event);
1131}
1132
1133static void
1134flush_scroll_event (GdkWaylandSeat *seat,
1135 GdkWaylandPointerFrameData *pointer_frame)
1136{
1137 gboolean is_stop = FALSE;
1138
1139 if (pointer_frame->discrete_x || pointer_frame->discrete_y)
1140 {
1141 GdkScrollDirection direction;
1142
1143 if (pointer_frame->discrete_x > 0)
1144 direction = GDK_SCROLL_LEFT;
1145 else if (pointer_frame->discrete_x < 0)
1146 direction = GDK_SCROLL_RIGHT;
1147 else if (pointer_frame->discrete_y > 0)
1148 direction = GDK_SCROLL_DOWN;
1149 else
1150 direction = GDK_SCROLL_UP;
1151
1152 flush_discrete_scroll_event (seat, direction);
1153 pointer_frame->discrete_x = 0;
1154 pointer_frame->discrete_y = 0;
1155 }
1156
1157 if (pointer_frame->is_scroll_stop ||
1158 pointer_frame->delta_x != 0 ||
1159 pointer_frame->delta_y != 0)
1160 {
1161 /* Axes can stop independently, if we stop on one axis but have a
1162 * delta on the other, we don't count it as a stop event.
1163 */
1164 if (pointer_frame->is_scroll_stop &&
1165 pointer_frame->delta_x == 0 &&
1166 pointer_frame->delta_y == 0)
1167 is_stop = TRUE;
1168
1169 flush_smooth_scroll_event (seat,
1170 pointer_frame->delta_x,
1171 pointer_frame->delta_y,
1172 is_stop);
1173
1174 pointer_frame->delta_x = 0;
1175 pointer_frame->delta_y = 0;
1176 pointer_frame->is_scroll_stop = FALSE;
1177 }
1178}
1179
1180static void
1181gdk_wayland_seat_flush_frame_event (GdkWaylandSeat *seat)
1182{
1183 if (seat->pointer_info.frame.event)
1184 {
1185 _gdk_wayland_display_deliver_event (gdk_seat_get_display (GDK_SEAT (seat)),
1186 seat->pointer_info.frame.event);
1187 seat->pointer_info.frame.event = NULL;
1188 }
1189 else
1190 {
1191 flush_scroll_event (seat, &seat->pointer_info.frame);
1192 seat->pointer_info.frame.source = 0;
1193 }
1194}
1195
1196static GdkEvent *
1197gdk_wayland_seat_get_frame_event (GdkWaylandSeat *seat,
1198 GdkEventType evtype)
1199{
1200 if (seat->pointer_info.frame.event &&
1201 seat->pointer_info.frame.event->type != evtype)
1202 gdk_wayland_seat_flush_frame_event (seat);
1203
1204 seat->pointer_info.frame.event = gdk_event_new (evtype);
1205 return seat->pointer_info.frame.event;
1206}
1207
1208static void
1209pointer_handle_enter (void *data,
1210 struct wl_pointer *pointer,
1211 uint32_t serial,
1212 struct wl_surface *surface,
1213 wl_fixed_t sx,
1214 wl_fixed_t sy)
1215{
1216 GdkWaylandSeat *seat = data;
1217 GdkEvent *event;
1218 GdkWaylandDisplay *display_wayland =
1219 GDK_WAYLAND_DISPLAY (seat->display);
1220
1221 if (!surface)
1222 return;
1223
1224 if (!GDK_IS_WINDOW (wl_surface_get_user_data (surface)))
1225 return;
1226
1227 _gdk_wayland_display_update_serial (display_wayland, serial);
1228
1229 seat->pointer_info.focus = wl_surface_get_user_data (surface);
1230 g_object_ref (seat->pointer_info.focus);
1231
1232 seat->pointer_info.button_modifiers = 0;
1233
1234 seat->pointer_info.surface_x = wl_fixed_to_double (sx);
1235 seat->pointer_info.surface_y = wl_fixed_to_double (sy);
1236 seat->pointer_info.enter_serial = serial;
1237
1238 event = gdk_wayland_seat_get_frame_event (seat, GDK_ENTER_NOTIFY);
1239 event->crossing.window = g_object_ref (seat->pointer_info.focus);
1240 gdk_event_set_device (event, seat->master_pointer);
1241 gdk_event_set_source_device (event, seat->pointer);
1242 gdk_event_set_seat (event, gdk_device_get_seat (seat->master_pointer));
1243 event->crossing.subwindow = NULL;
1244 event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
1245 event->crossing.mode = GDK_CROSSING_NORMAL;
1246 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1247 event->crossing.focus = TRUE;
1248 event->crossing.state = 0;
1249
1250 gdk_wayland_device_update_window_cursor (seat->master_pointer);
1251
1252 get_coordinates (seat->master_pointer,
1253 &event->crossing.x,
1254 &event->crossing.y,
1255 &event->crossing.x_root,
1256 &event->crossing.y_root);
1257
1258 GDK_NOTE (EVENTS,
1259 g_message ("enter, seat %p surface %p",
1260 seat, seat->pointer_info.focus));
1261
1262 if (display_wayland->seat_version < WL_POINTER_HAS_FRAME)
1263 gdk_wayland_seat_flush_frame_event (seat);
1264}
1265
1266static void
1267pointer_handle_leave (void *data,
1268 struct wl_pointer *pointer,
1269 uint32_t serial,
1270 struct wl_surface *surface)
1271{
1272 GdkWaylandSeat *seat = data;
1273 GdkEvent *event;
1274 GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
1275
1276 if (!surface)
1277 return;
1278
1279 if (!GDK_IS_WINDOW (wl_surface_get_user_data (surface)))
1280 return;
1281
1282 if (!seat->pointer_info.focus)
1283 return;
1284
1285 _gdk_wayland_display_update_serial (display_wayland, serial);
1286
1287 event = gdk_wayland_seat_get_frame_event (seat, GDK_LEAVE_NOTIFY);
1288 event->crossing.window = g_object_ref (seat->pointer_info.focus);
1289 gdk_event_set_device (event, seat->master_pointer);
1290 gdk_event_set_source_device (event, seat->pointer);
1291 gdk_event_set_seat (event, GDK_SEAT (seat));
1292 event->crossing.subwindow = NULL;
1293 event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
1294 event->crossing.mode = GDK_CROSSING_NORMAL;
1295 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1296 event->crossing.focus = TRUE;
1297 event->crossing.state = 0;
1298
1299 gdk_wayland_device_update_window_cursor (seat->master_pointer);
1300
1301 get_coordinates (seat->master_pointer,
1302 &event->crossing.x,
1303 &event->crossing.y,
1304 &event->crossing.x_root,
1305 &event->crossing.y_root);
1306
1307 GDK_NOTE (EVENTS,
1308 g_message ("leave, seat %p surface %p",
1309 seat, seat->pointer_info.focus));
1310
1311 g_object_unref (seat->pointer_info.focus);
1312 seat->pointer_info.focus = NULL;
1313 if (seat->cursor)
1314 gdk_wayland_pointer_stop_cursor_animation (&seat->pointer_info);
1315
1316 seat->pointer_info.focus = NULL;
1317
1318 if (display_wayland->seat_version < WL_POINTER_HAS_FRAME)
1319 gdk_wayland_seat_flush_frame_event (seat);
1320}
1321
1322static void
1323pointer_handle_motion (void *data,
1324 struct wl_pointer *pointer,
1325 uint32_t time,
1326 wl_fixed_t sx,
1327 wl_fixed_t sy)
1328{
1329 GdkWaylandSeat *seat = data;
1330 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1331 GdkEvent *event;
1332
1333 if (!seat->pointer_info.focus)
1334 return;
1335
1336 seat->pointer_info.time = time;
1337 seat->pointer_info.surface_x = wl_fixed_to_double (sx);
1338 seat->pointer_info.surface_y = wl_fixed_to_double (sy);
1339
1340 event = gdk_wayland_seat_get_frame_event (seat, GDK_MOTION_NOTIFY);
1341 event->motion.window = g_object_ref (seat->pointer_info.focus);
1342 gdk_event_set_device (event, seat->master_pointer);
1343 gdk_event_set_source_device (event, seat->pointer);
1344 gdk_event_set_seat (event, gdk_device_get_seat (seat->master_pointer));
1345 event->motion.time = time;
1346 event->motion.axes = NULL;
1347 event->motion.state = device_get_modifiers (seat->master_pointer);
1348 event->motion.is_hint = 0;
1349 gdk_event_set_screen (event, display->screen);
1350
1351 get_coordinates (seat->master_pointer,
1352 &event->motion.x,
1353 &event->motion.y,
1354 &event->motion.x_root,
1355 &event->motion.y_root);
1356
1357 GDK_NOTE (EVENTS,
1358 g_message ("motion %f %f, seat %p state %d",
1359 wl_fixed_to_double (sx), wl_fixed_to_double (sy),
1360 seat, event->motion.state));
1361
1362 if (display->seat_version < WL_POINTER_HAS_FRAME)
1363 gdk_wayland_seat_flush_frame_event (seat);
1364}
1365
1366static void
1367pointer_handle_button (void *data,
1368 struct wl_pointer *pointer,
1369 uint32_t serial,
1370 uint32_t time,
1371 uint32_t button,
1372 uint32_t state)
1373{
1374 GdkWaylandSeat *seat = data;
1375 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1376 GdkEvent *event;
1377 uint32_t modifier;
1378 int gdk_button;
1379
1380 if (!seat->pointer_info.focus)
1381 return;
1382
1383 _gdk_wayland_display_update_serial (display, serial);
1384
1385 switch (button)
1386 {
1387 case BTN_LEFT:
1388 gdk_button = GDK_BUTTON_PRIMARY;
1389 break;
1390 case BTN_MIDDLE:
1391 gdk_button = GDK_BUTTON_MIDDLE;
1392 break;
1393 case BTN_RIGHT:
1394 gdk_button = GDK_BUTTON_SECONDARY;
1395 break;
1396 default:
1397 /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */
1398 gdk_button = button - BUTTON_BASE + 4;
1399 break;
1400 }
1401
1402 seat->pointer_info.time = time;
1403 if (state)
1404 seat->pointer_info.press_serial = serial;
1405
1406 event = gdk_wayland_seat_get_frame_event (seat,
1407 state ? GDK_BUTTON_PRESS :
1408 GDK_BUTTON_RELEASE);
1409 event->button.window = g_object_ref (seat->pointer_info.focus);
1410 gdk_event_set_device (event, seat->master_pointer);
1411 gdk_event_set_source_device (event, seat->pointer);
1412 gdk_event_set_seat (event, gdk_device_get_seat (seat->master_pointer));
1413 event->button.time = time;
1414 event->button.axes = NULL;
1415 event->button.state = device_get_modifiers (seat->master_pointer);
1416 event->button.button = gdk_button;
1417 gdk_event_set_screen (event, display->screen);
1418
1419 get_coordinates (seat->master_pointer,
1420 &event->button.x,
1421 &event->button.y,
1422 &event->button.x_root,
1423 &event->button.y_root);
1424
1425 modifier = 1 << (8 + gdk_button - 1);
1426 if (state)
1427 seat->pointer_info.button_modifiers |= modifier;
1428 else
1429 seat->pointer_info.button_modifiers &= ~modifier;
1430
1431 GDK_NOTE (EVENTS,
1432 g_message ("button %d %s, seat %p state %d",
1433 event->button.button,
1434 state ? "press" : "release",
1435 seat,
1436 event->button.state));
1437
1438 if (display->seat_version < WL_POINTER_HAS_FRAME)
1439 gdk_wayland_seat_flush_frame_event (seat);
1440}
1441
1442#ifdef G_ENABLE_DEBUG
1443
1444const char *
1445get_axis_name (uint32_t axis)
1446{
1447 switch (axis)
1448 {
1449 case WL_POINTER_AXIS_VERTICAL_SCROLL:
1450 return "horizontal";
1451 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
1452 return "vertical";
1453 default:
1454 return "unknown";
1455 }
1456}
1457
1458#endif
1459
1460static void
1461pointer_handle_axis (void *data,
1462 struct wl_pointer *pointer,
1463 uint32_t time,
1464 uint32_t axis,
1465 wl_fixed_t value)
1466{
1467 GdkWaylandSeat *seat = data;
1468 GdkWaylandPointerFrameData *pointer_frame = &seat->pointer_info.frame;
1469 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1470
1471 if (!seat->pointer_info.focus)
1472 return;
1473
1474 /* get the delta and convert it into the expected range */
1475 switch (axis)
1476 {
1477 case WL_POINTER_AXIS_VERTICAL_SCROLL:
1478 pointer_frame->delta_y = wl_fixed_to_double (value) / 10.0;
1479 break;
1480 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
1481 pointer_frame->delta_x = wl_fixed_to_double (value) / 10.0;
1482 break;
1483 default:
1484 g_return_if_reached ();
1485 }
1486
1487 seat->pointer_info.time = time;
1488
1489 GDK_NOTE (EVENTS,
1490 g_message ("scroll, axis %s, value %f, seat %p",
1491 get_axis_name (axis), wl_fixed_to_double (value) / 10.0,
1492 seat));
1493
1494 if (display->seat_version < WL_POINTER_HAS_FRAME)
1495 gdk_wayland_seat_flush_frame_event (seat);
1496}
1497
1498static void
1499pointer_handle_frame (void *data,
1500 struct wl_pointer *pointer)
1501{
1502 GdkWaylandSeat *seat = data;
1503
1504 GDK_NOTE (EVENTS,
1505 g_message ("frame, seat %p", seat));
1506
1507 gdk_wayland_seat_flush_frame_event (seat);
1508}
1509
1510#ifdef G_ENABLE_DEBUG
1511
1512static const char *
1513get_axis_source_name (enum wl_pointer_axis_source source)
1514{
1515 switch (source)
1516 {
1517 case WL_POINTER_AXIS_SOURCE_WHEEL:
1518 return "wheel";
1519 case WL_POINTER_AXIS_SOURCE_FINGER:
1520 return "finger";
1521 case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
1522 return "continuous";
1523 default:
1524 return "unknown";
1525 }
1526}
1527
1528#endif
1529
1530static void
1531pointer_handle_axis_source (void *data,
1532 struct wl_pointer *pointer,
1533 enum wl_pointer_axis_source source)
1534{
1535 GdkWaylandSeat *seat = data;
1536 GdkWaylandPointerFrameData *pointer_frame = &seat->pointer_info.frame;
1537
1538 if (!seat->pointer_info.focus)
1539 return;
1540
1541 pointer_frame->source = source;
1542
1543 GDK_NOTE (EVENTS,
1544 g_message ("axis source %s, seat %p", get_axis_source_name (source), seat));
1545}
1546
1547static void
1548pointer_handle_axis_stop (void *data,
1549 struct wl_pointer *pointer,
1550 uint32_t time,
1551 uint32_t axis)
1552{
1553 GdkWaylandSeat *seat = data;
1554 GdkWaylandPointerFrameData *pointer_frame = &seat->pointer_info.frame;
1555
1556 if (!seat->pointer_info.focus)
1557 return;
1558
1559 seat->pointer_info.time = time;
1560
1561 switch (axis)
1562 {
1563 case WL_POINTER_AXIS_VERTICAL_SCROLL:
1564 pointer_frame->delta_y = 0;
1565 break;
1566 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
1567 pointer_frame->delta_x = 0;
1568 break;
1569 default:
1570 g_return_if_reached ();
1571 }
1572
1573 pointer_frame->is_scroll_stop = TRUE;
1574
1575 GDK_NOTE (EVENTS,
1576 g_message ("axis %s stop, seat %p", get_axis_name (axis), seat));
1577}
1578
1579static void
1580pointer_handle_axis_discrete (void *data,
1581 struct wl_pointer *pointer,
1582 uint32_t axis,
1583 int32_t value)
1584{
1585 GdkWaylandSeat *seat = data;
1586 GdkWaylandPointerFrameData *pointer_frame = &seat->pointer_info.frame;
1587
1588 if (!seat->pointer_info.focus)
1589 return;
1590
1591 switch (axis)
1592 {
1593 case WL_POINTER_AXIS_VERTICAL_SCROLL:
1594 pointer_frame->discrete_y = value;
1595 break;
1596 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
1597 pointer_frame->discrete_x = value;
1598 break;
1599 default:
1600 g_return_if_reached ();
1601 }
1602
1603 GDK_NOTE (EVENTS,
1604 g_message ("discrete scroll, axis %s, value %d, seat %p",
1605 get_axis_name (axis), value, seat));
1606}
1607
1608static void
1609keyboard_handle_keymap (void *data,
1610 struct wl_keyboard *keyboard,
1611 uint32_t format,
1612 int fd,
1613 uint32_t size)
1614{
1615 GdkWaylandSeat *seat = data;
1616 PangoDirection direction;
1617
1618 direction = gdk_keymap_get_direction (seat->keymap);
1619
1620 _gdk_wayland_keymap_update_from_fd (seat->keymap, format, fd, size);
1621
1622 g_signal_emit_by_name (seat->keymap, "keys-changed");
1623 g_signal_emit_by_name (seat->keymap, "state-changed");
1624
1625 if (direction != gdk_keymap_get_direction (seat->keymap))
1626 g_signal_emit_by_name (seat->keymap, "direction-changed");
1627}
1628
1629static void
1630keyboard_handle_enter (void *data,
1631 struct wl_keyboard *keyboard,
1632 uint32_t serial,
1633 struct wl_surface *surface,
1634 struct wl_array *keys)
1635{
1636 GdkWaylandSeat *seat = data;
1637 GdkEvent *event;
1638 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1639
1640 if (!surface)
1641 return;
1642
1643 if (!GDK_IS_WINDOW (wl_surface_get_user_data (surface)))
1644 return;
1645
1646 _gdk_wayland_display_update_serial (display, serial);
1647
1648 seat->keyboard_focus = wl_surface_get_user_data (surface);
1649 g_object_ref (seat->keyboard_focus);
1650
1651 event = gdk_event_new (GDK_FOCUS_CHANGE);
1652 event->focus_change.window = g_object_ref (seat->keyboard_focus);
1653 event->focus_change.send_event = FALSE;
1654 event->focus_change.in = TRUE;
1655 gdk_event_set_device (event, seat->master_keyboard);
1656 gdk_event_set_source_device (event, seat->keyboard);
1657 gdk_event_set_seat (event, gdk_device_get_seat (seat->master_pointer));
1658
1659 GDK_NOTE (EVENTS,
1660 g_message ("focus in, seat %p surface %p",
1661 seat, seat->keyboard_focus));
1662
1663 _gdk_wayland_display_deliver_event (seat->display, event);
1664
1665 if (seat->pending_selection != GDK_NONE)
1666 {
1667 emit_selection_owner_change (seat->keyboard_focus,
1668 seat->pending_selection);
1669 seat->pending_selection = GDK_NONE;
1670 }
1671}
1672
1673static void stop_key_repeat (GdkWaylandSeat *seat);
1674
1675static void
1676keyboard_handle_leave (void *data,
1677 struct wl_keyboard *keyboard,
1678 uint32_t serial,
1679 struct wl_surface *surface)
1680{
1681 GdkWaylandSeat *seat = data;
1682 GdkEvent *event;
1683 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1684
1685 if (!seat->keyboard_focus)
1686 return;
1687
1688 /* gdk_window_is_destroyed() might already return TRUE for
1689 * seat->keyboard_focus here, which would happen if we destroyed the
1690 * window before loosing keyboard focus.
1691 */
1692 stop_key_repeat (seat);
1693
1694 _gdk_wayland_display_update_serial (display, serial);
1695
1696 event = gdk_event_new (GDK_FOCUS_CHANGE);
1697 event->focus_change.window = g_object_ref (seat->keyboard_focus);
1698 event->focus_change.send_event = FALSE;
1699 event->focus_change.in = FALSE;
1700 gdk_event_set_device (event, seat->master_keyboard);
1701 gdk_event_set_source_device (event, seat->keyboard);
1702 gdk_event_set_seat (event, gdk_device_get_seat (seat->master_keyboard));
1703
1704 g_object_unref (seat->keyboard_focus);
1705 seat->keyboard_focus = NULL;
1706
1707 GDK_NOTE (EVENTS,
1708 g_message ("focus out, seat %p surface %p",
1709 seat, seat->keyboard_focus));
1710
1711 _gdk_wayland_display_deliver_event (seat->display, event);
1712}
1713
1714static gboolean keyboard_repeat (gpointer data);
1715
1716static void
1717translate_keyboard_string (GdkEventKey *event)
1718{
1719 gunichar c = 0;
1720 gchar buf[7];
1721
1722 /* Fill in event->string crudely, since various programs
1723 * depend on it.
1724 */
1725 event->string = NULL;
1726
1727 if (event->keyval != GDK_KEY_VoidSymbol)
1728 c = gdk_keyval_to_unicode (event->keyval);
1729
1730 if (c)
1731 {
1732 gsize bytes_written;
1733 gint len;
1734
1735 /* Apply the control key - Taken from Xlib */
1736 if (event->state & GDK_CONTROL_MASK)
1737 {
1738 if ((c >= '@' && c < '\177') || c == ' ')
1739 c &= 0x1F;
1740 else if (c == '2')
1741 {
1742 event->string = g_memdup ("\0\0", 2);
1743 event->length = 1;
1744 buf[0] = '\0';
1745 return;
1746 }
1747 else if (c >= '3' && c <= '7')
1748 c -= ('3' - '\033');
1749 else if (c == '8')
1750 c = '\177';
1751 else if (c == '/')
1752 c = '_' & 0x1F;
1753 }
1754
1755 len = g_unichar_to_utf8 (c, buf);
1756 buf[len] = '\0';
1757
1758 event->string = g_locale_from_utf8 (buf, len,
1759 NULL, &bytes_written,
1760 NULL);
1761 if (event->string)
1762 event->length = bytes_written;
1763 }
1764 else if (event->keyval == GDK_KEY_Escape)
1765 {
1766 event->length = 1;
1767 event->string = g_strdup ("\033");
1768 }
1769 else if (event->keyval == GDK_KEY_Return ||
1770 event->keyval == GDK_KEY_KP_Enter)
1771 {
1772 event->length = 1;
1773 event->string = g_strdup ("\r");
1774 }
1775
1776 if (!event->string)
1777 {
1778 event->length = 0;
1779 event->string = g_strdup ("");
1780 }
1781}
1782
1783static GSettings *
1784get_keyboard_settings (GdkWaylandSeat *seat)
1785{
1786 if (!seat->keyboard_settings)
1787 {
1788 GSettingsSchemaSource *source;
1789 GSettingsSchema *schema;
1790
1791 source = g_settings_schema_source_get_default ();
1792 schema = g_settings_schema_source_lookup (source, "org.gnome.settings-daemon.peripherals.keyboard", FALSE);
1793 if (schema != NULL)
1794 {
1795 seat->keyboard_settings = g_settings_new_full (schema, NULL, NULL);
1796 g_settings_schema_unref (schema);
1797 }
1798 }
1799
1800 return seat->keyboard_settings;
1801}
1802
1803static gboolean
1804get_key_repeat (GdkWaylandSeat *seat,
1805 guint *delay,
1806 guint *interval)
1807{
1808 gboolean repeat;
1809
1810 if (seat->have_server_repeat)
1811 {
1812 if (seat->server_repeat_rate > 0)
1813 {
1814 repeat = TRUE;
1815 *delay = seat->server_repeat_delay;
1816 *interval = (1000 / seat->server_repeat_rate);
1817 }
1818 else
1819 {
1820 repeat = FALSE;
1821 }
1822 }
1823 else
1824 {
1825 GSettings *keyboard_settings = get_keyboard_settings (seat);
1826
1827 if (keyboard_settings)
1828 {
1829 repeat = g_settings_get_boolean (keyboard_settings, "repeat");
1830 *delay = g_settings_get_uint (keyboard_settings, "delay");
1831 *interval = g_settings_get_uint (keyboard_settings, "repeat-interval");
1832 }
1833 else
1834 {
1835 repeat = TRUE;
1836 *delay = 400;
1837 *interval = 80;
1838 }
1839 }
1840
1841 return repeat;
1842}
1843
1844static void
1845stop_key_repeat (GdkWaylandSeat *seat)
1846{
1847 if (seat->repeat_timer)
1848 {
1849 g_source_remove (seat->repeat_timer);
1850 seat->repeat_timer = 0;
1851 }
1852
1853 g_clear_pointer (&seat->repeat_callback, wl_callback_destroy);
1854}
1855
1856static void
1857deliver_key_event (GdkWaylandSeat *seat,
1858 uint32_t time_,
1859 uint32_t key,
1860 uint32_t state)
1861{
1862 GdkEvent *event;
1863 struct xkb_state *xkb_state;
1864 struct xkb_keymap *xkb_keymap;
1865 GdkKeymap *keymap;
1866 xkb_keysym_t sym;
1867 guint delay, interval, timeout;
1868 gint64 begin_time, now;
1869
1870 begin_time = g_get_monotonic_time ();
1871
1872 stop_key_repeat (seat);
1873
1874 keymap = seat->keymap;
1875 xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
1876 xkb_keymap = _gdk_wayland_keymap_get_xkb_keymap (keymap);
1877
1878 sym = xkb_state_key_get_one_sym (xkb_state, key);
1879 if (sym == XKB_KEY_NoSymbol)
1880 return;
1881
1882 seat->pointer_info.time = time_;
1883 seat->key_modifiers = gdk_keymap_get_modifier_state (keymap);
1884
1885 event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
1886 event->key.window = seat->keyboard_focus ? g_object_ref (seat->keyboard_focus) : NULL;
1887 gdk_event_set_device (event, seat->master_keyboard);
1888 gdk_event_set_source_device (event, seat->keyboard);
1889 gdk_event_set_seat (event, GDK_SEAT (seat));
1890 event->key.time = time_;
1891 event->key.state = device_get_modifiers (seat->master_pointer);
1892 event->key.group = 0;
1893 event->key.hardware_keycode = key;
1894 gdk_event_set_scancode (event, key);
1895 event->key.keyval = sym;
1896 event->key.is_modifier = _gdk_wayland_keymap_key_is_modifier (keymap, key);
1897
1898 translate_keyboard_string (&event->key);
1899
1900 _gdk_wayland_display_deliver_event (seat->display, event);
1901
1902 GDK_NOTE (EVENTS,
1903 g_message ("keyboard event, code %d, sym %d, "
1904 "string %s, mods 0x%x",
1905 event->key.hardware_keycode, event->key.keyval,
1906 event->key.string, event->key.state));
1907
1908 if (state == 0)
1909 return;
1910
1911 if (!xkb_keymap_key_repeats (xkb_keymap, key))
1912 return;
1913
1914 if (!get_key_repeat (seat, &delay, &interval))
1915 return;
1916
1917 seat->repeat_count++;
1918 seat->repeat_key = key;
1919
1920 interval *= 1000L;
1921 delay *= 1000L;
1922
1923 now = g_get_monotonic_time ();
1924
1925 if (seat->repeat_count == 1)
1926 seat->repeat_deadline = begin_time + delay;
1927 else if (seat->repeat_deadline + interval > now)
1928 seat->repeat_deadline += interval;
1929 else
1930 /* frame delay caused us to miss repeat deadline */
1931 seat->repeat_deadline = now;
1932
1933 timeout = (seat->repeat_deadline - now) / 1000L;
1934
1935 seat->repeat_timer =
1936 gdk_threads_add_timeout (timeout, keyboard_repeat, seat);
1937 g_source_set_name_by_id (seat->repeat_timer, "[gtk+] keyboard_repeat");
1938}
1939
1940static void
1941sync_after_repeat_callback (void *data,
1942 struct wl_callback *callback,
1943 uint32_t time)
1944{
1945 GdkWaylandSeat *seat = data;
1946
1947 g_clear_pointer (&seat->repeat_callback, wl_callback_destroy);
1948
1949 deliver_key_event (seat, seat->keyboard_time, seat->repeat_key, 1);
1950}
1951
1952static const struct wl_callback_listener sync_after_repeat_callback_listener = {
1953 sync_after_repeat_callback
1954};
1955
1956static gboolean
1957keyboard_repeat (gpointer data)
1958{
1959 GdkWaylandSeat *seat = data;
1960 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1961
1962 /* Ping the server and wait for the timeout. We won't process
1963 * key repeat until it responds, since a hung server could lead
1964 * to a delayed key release event. We don't want to generate
1965 * repeat events long after the user released the key, just because
1966 * the server is tardy in telling us the user released the key.
1967 */
1968 seat->repeat_callback = wl_display_sync (display->wl_display);
1969
1970 wl_callback_add_listener (seat->repeat_callback,
1971 &sync_after_repeat_callback_listener,
1972 seat);
1973
1974 seat->repeat_timer = 0;
1975 return G_SOURCE_REMOVE;
1976}
1977
1978static void
1979keyboard_handle_key (void *data,
1980 struct wl_keyboard *keyboard,
1981 uint32_t serial,
1982 uint32_t time,
1983 uint32_t key,
1984 uint32_t state_w)
1985{
1986 GdkWaylandSeat *seat = data;
1987 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
1988
1989 if (!seat->keyboard_focus)
1990 return;
1991
1992 seat->keyboard_time = time;
1993 seat->repeat_count = 0;
1994 _gdk_wayland_display_update_serial (display, serial);
1995 deliver_key_event (data, time, key + 8, state_w);
1996}
1997
1998static void
1999keyboard_handle_modifiers (void *data,
2000 struct wl_keyboard *keyboard,
2001 uint32_t serial,
2002 uint32_t mods_depressed,
2003 uint32_t mods_latched,
2004 uint32_t mods_locked,
2005 uint32_t group)
2006{
2007 GdkWaylandSeat *seat = data;
2008 GdkKeymap *keymap;
2009 struct xkb_state *xkb_state;
2010 PangoDirection direction;
2011
2012 keymap = seat->keymap;
2013 direction = gdk_keymap_get_direction (keymap);
2014 xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
2015 seat->key_modifiers = mods_depressed | mods_latched | mods_locked;
2016
2017 xkb_state_update_mask (xkb_state, mods_depressed, mods_latched, mods_locked, group, 0, 0);
2018
2019 g_signal_emit_by_name (keymap, "state-changed");
2020 if (direction != gdk_keymap_get_direction (keymap))
2021 g_signal_emit_by_name (keymap, "direction-changed");
2022}
2023
2024static void
2025keyboard_handle_repeat_info (void *data,
2026 struct wl_keyboard *keyboard,
2027 int32_t rate,
2028 int32_t delay)
2029{
2030 GdkWaylandSeat *seat = data;
2031
2032 seat->have_server_repeat = TRUE;
2033 seat->server_repeat_rate = rate;
2034 seat->server_repeat_delay = delay;
2035}
2036
2037static GdkWaylandTouchData *
2038gdk_wayland_seat_add_touch (GdkWaylandSeat *seat,
2039 uint32_t id,
2040 struct wl_surface *surface)
2041{
2042 GdkWaylandTouchData *touch;
2043
2044 touch = g_new0 (GdkWaylandTouchData, 1);
2045 touch->id = id;
2046 touch->window = wl_surface_get_user_data (surface);
2047 touch->initial_touch = (g_hash_table_size (seat->touches) == 0);
2048
2049 g_hash_table_insert (seat->touches, GUINT_TO_POINTER (id), touch);
2050
2051 return touch;
2052}
2053
2054static GdkWaylandTouchData *
2055gdk_wayland_seat_get_touch (GdkWaylandSeat *seat,
2056 uint32_t id)
2057{
2058 return g_hash_table_lookup (seat->touches, GUINT_TO_POINTER (id));
2059}
2060
2061static void
2062gdk_wayland_seat_remove_touch (GdkWaylandSeat *seat,
2063 uint32_t id)
2064{
2065 g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
2066}
2067
2068static GdkEvent *
2069_create_touch_event (GdkWaylandSeat *seat,
2070 GdkWaylandTouchData *touch,
2071 GdkEventType evtype,
2072 uint32_t time)
2073{
2074 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2075 gint x_root, y_root;
2076 GdkEvent *event;
2077
2078 event = gdk_event_new (evtype);
2079 event->touch.window = g_object_ref (touch->window);
2080 gdk_event_set_device (event, seat->touch_master);
2081 gdk_event_set_source_device (event, seat->touch);
2082 gdk_event_set_seat (event, GDK_SEAT (seat));
2083 event->touch.time = time;
2084 event->touch.state = device_get_modifiers (seat->touch_master);
2085 gdk_event_set_screen (event, display->screen);
2086 event->touch.sequence = GDK_SLOT_TO_EVENT_SEQUENCE (touch->id);
2087
2088 if (touch->initial_touch)
2089 {
2090 gdk_event_set_pointer_emulated (event, TRUE);
2091 event->touch.emulating_pointer = TRUE;
2092 }
2093
2094 gdk_window_get_root_coords (touch->window,
2095 touch->x, touch->y,
2096 &x_root, &y_root);
2097
2098 event->touch.x = touch->x;
2099 event->touch.y = touch->y;
2100 event->touch.x_root = x_root;
2101 event->touch.y_root = y_root;
2102
2103 return event;
2104}
2105
2106static void
2107mimic_pointer_emulating_touch_info (GdkDevice *device,
2108 GdkWaylandTouchData *touch)
2109{
2110 GdkWaylandPointerData *pointer;
2111
2112 pointer = GDK_WAYLAND_DEVICE (device)->pointer;
2113 g_set_object (&pointer->focus, touch->window);
2114 pointer->press_serial = pointer->enter_serial = touch->touch_down_serial;
2115 pointer->surface_x = touch->x;
2116 pointer->surface_y = touch->y;
2117}
2118
2119static void
2120touch_handle_master_pointer_crossing (GdkWaylandSeat *seat,
2121 GdkWaylandTouchData *touch,
2122 uint32_t time)
2123{
2124 GdkWaylandPointerData *pointer;
2125
2126 pointer = GDK_WAYLAND_DEVICE (seat->touch_master)->pointer;
2127
2128 if (pointer->focus == touch->window)
2129 return;
2130
2131 if (pointer->focus)
2132 {
2133 emulate_touch_crossing (pointer->focus, NULL,
2134 seat->touch_master, seat->touch, touch,
2135 GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, time);
2136 }
2137
2138 if (touch->window)
2139 {
2140 emulate_touch_crossing (touch->window, NULL,
2141 seat->touch_master, seat->touch, touch,
2142 GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, time);
2143 }
2144}
2145
2146static void
2147touch_handle_down (void *data,
2148 struct wl_touch *wl_touch,
2149 uint32_t serial,
2150 uint32_t time,
2151 struct wl_surface *wl_surface,
2152 int32_t id,
2153 wl_fixed_t x,
2154 wl_fixed_t y)
2155{
2156 GdkWaylandSeat *seat = data;
2157 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2158 GdkWaylandTouchData *touch;
2159 GdkEvent *event;
2160
2161 _gdk_wayland_display_update_serial (display, serial);
2162
2163 touch = gdk_wayland_seat_add_touch (seat, id, wl_surface);
2164 touch->x = wl_fixed_to_double (x);
2165 touch->y = wl_fixed_to_double (y);
2166 touch->touch_down_serial = serial;
2167
2168 event = _create_touch_event (seat, touch, GDK_TOUCH_BEGIN, time);
2169
2170 if (touch->initial_touch)
2171 {
2172 touch_handle_master_pointer_crossing (seat, touch, time);
2173 GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = touch;
2174 mimic_pointer_emulating_touch_info (seat->touch_master, touch);
2175 }
2176
2177 GDK_NOTE (EVENTS,
2178 g_message ("touch begin %f %f", event->touch.x, event->touch.y));
2179
2180 _gdk_wayland_display_deliver_event (seat->display, event);
2181}
2182
2183static void
2184touch_handle_up (void *data,
2185 struct wl_touch *wl_touch,
2186 uint32_t serial,
2187 uint32_t time,
2188 int32_t id)
2189{
2190 GdkWaylandSeat *seat = data;
2191 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2192 GdkWaylandTouchData *touch;
2193 GdkEvent *event;
2194
2195 _gdk_wayland_display_update_serial (display, serial);
2196
2197 touch = gdk_wayland_seat_get_touch (seat, id);
2198 event = _create_touch_event (seat, touch, GDK_TOUCH_END, time);
2199
2200 GDK_NOTE (EVENTS,
2201 g_message ("touch end %f %f", event->touch.x, event->touch.y));
2202
2203 _gdk_wayland_display_deliver_event (seat->display, event);
2204
2205 if (touch->initial_touch)
2206 GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = NULL;
2207
2208 gdk_wayland_seat_remove_touch (seat, id);
2209}
2210
2211static void
2212touch_handle_motion (void *data,
2213 struct wl_touch *wl_touch,
2214 uint32_t time,
2215 int32_t id,
2216 wl_fixed_t x,
2217 wl_fixed_t y)
2218{
2219 GdkWaylandSeat *seat = data;
2220 GdkWaylandTouchData *touch;
2221 GdkEvent *event;
2222
2223 touch = gdk_wayland_seat_get_touch (seat, id);
2224 touch->x = wl_fixed_to_double (x);
2225 touch->y = wl_fixed_to_double (y);
2226
2227 if (touch->initial_touch)
2228 mimic_pointer_emulating_touch_info (seat->touch_master, touch);
2229
2230 event = _create_touch_event (seat, touch, GDK_TOUCH_UPDATE, time);
2231
2232 GDK_NOTE (EVENTS,
2233 g_message ("touch update %f %f", event->touch.x, event->touch.y));
2234
2235 _gdk_wayland_display_deliver_event (seat->display, event);
2236}
2237
2238static void
2239touch_handle_frame (void *data,
2240 struct wl_touch *wl_touch)
2241{
2242}
2243
2244static void
2245touch_handle_cancel (void *data,
2246 struct wl_touch *wl_touch)
2247{
2248 GdkWaylandSeat *wayland_seat = data;
2249 GdkWaylandTouchData *touch;
2250 GHashTableIter iter;
2251 GdkEvent *event;
2252
2253 if (GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch)
2254 {
2255 touch = GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch;
2256 GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch = NULL;
2257 }
2258
2259 g_hash_table_iter_init (&iter, wayland_seat->touches);
2260
2261 while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch))
2262 {
2263 event = _create_touch_event (wayland_seat, touch, GDK_TOUCH_CANCEL,
2264 GDK_CURRENT_TIME);
2265 _gdk_wayland_display_deliver_event (wayland_seat->display, event);
2266 g_hash_table_iter_remove (&iter);
2267 }
2268
2269 GDK_NOTE (EVENTS, g_message ("touch cancel"));
2270}
2271
2272static void
2273emit_gesture_swipe_event (GdkWaylandSeat *seat,
2274 GdkTouchpadGesturePhase phase,
2275 guint32 _time,
2276 guint32 n_fingers,
2277 gdouble dx,
2278 gdouble dy)
2279{
2280 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2281 GdkEvent *event;
2282
2283 if (!seat->pointer_info.focus)
2284 return;
2285
2286 seat->pointer_info.time = _time;
2287
2288 event = gdk_event_new (GDK_TOUCHPAD_SWIPE);
2289 event->touchpad_swipe.phase = phase;
2290 event->touchpad_swipe.window = g_object_ref (seat->pointer_info.focus);
2291 gdk_event_set_device (event, seat->master_pointer);
2292 gdk_event_set_source_device (event, seat->pointer);
2293 gdk_event_set_seat (event, GDK_SEAT (seat));
2294 event->touchpad_swipe.time = _time;
2295 event->touchpad_swipe.state = device_get_modifiers (seat->master_pointer);
2296 gdk_event_set_screen (event, display->screen);
2297 event->touchpad_swipe.dx = dx;
2298 event->touchpad_swipe.dy = dy;
2299 event->touchpad_swipe.n_fingers = n_fingers;
2300
2301 get_coordinates (seat->master_pointer,
2302 &event->touchpad_swipe.x,
2303 &event->touchpad_swipe.y,
2304 &event->touchpad_swipe.x_root,
2305 &event->touchpad_swipe.y_root);
2306
2307 GDK_NOTE (EVENTS,
2308 g_message ("swipe event %d, coords: %f %f, seat %p state %d",
2309 event->type, event->touchpad_swipe.x,
2310 event->touchpad_swipe.y, seat,
2311 event->touchpad_swipe.state));
2312
2313 _gdk_wayland_display_deliver_event (seat->display, event);
2314}
2315
2316static void
2317gesture_swipe_begin (void *data,
2318 struct zwp_pointer_gesture_swipe_v1 *swipe,
2319 uint32_t serial,
2320 uint32_t time,
2321 struct wl_surface *surface,
2322 uint32_t fingers)
2323{
2324 GdkWaylandSeat *seat = data;
2325 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2326
2327 _gdk_wayland_display_update_serial (display, serial);
2328
2329 emit_gesture_swipe_event (seat,
2330 GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
2331 time, fingers, 0, 0);
2332 seat->gesture_n_fingers = fingers;
2333}
2334
2335static void
2336gesture_swipe_update (void *data,
2337 struct zwp_pointer_gesture_swipe_v1 *swipe,
2338 uint32_t time,
2339 wl_fixed_t dx,
2340 wl_fixed_t dy)
2341{
2342 GdkWaylandSeat *seat = data;
2343
2344 emit_gesture_swipe_event (seat,
2345 GDK_TOUCHPAD_GESTURE_PHASE_UPDATE,
2346 time,
2347 seat->gesture_n_fingers,
2348 wl_fixed_to_double (dx),
2349 wl_fixed_to_double (dy));
2350}
2351
2352static void
2353gesture_swipe_end (void *data,
2354 struct zwp_pointer_gesture_swipe_v1 *swipe,
2355 uint32_t serial,
2356 uint32_t time,
2357 int32_t cancelled)
2358{
2359 GdkWaylandSeat *seat = data;
2360 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2361 GdkTouchpadGesturePhase phase;
2362
2363 _gdk_wayland_display_update_serial (display, serial);
2364
2365 phase = (cancelled) ?
2366 GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
2367 GDK_TOUCHPAD_GESTURE_PHASE_END;
2368
2369 emit_gesture_swipe_event (seat, phase, time,
2370 seat->gesture_n_fingers, 0, 0);
2371}
2372
2373static void
2374emit_gesture_pinch_event (GdkWaylandSeat *seat,
2375 GdkTouchpadGesturePhase phase,
2376 guint32 _time,
2377 guint n_fingers,
2378 gdouble dx,
2379 gdouble dy,
2380 gdouble scale,
2381 gdouble angle_delta)
2382{
2383 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2384 GdkEvent *event;
2385
2386 if (!seat->pointer_info.focus)
2387 return;
2388
2389 seat->pointer_info.time = _time;
2390
2391 event = gdk_event_new (GDK_TOUCHPAD_PINCH);
2392 event->touchpad_pinch.phase = phase;
2393 event->touchpad_pinch.window = g_object_ref (seat->pointer_info.focus);
2394 gdk_event_set_device (event, seat->master_pointer);
2395 gdk_event_set_source_device (event, seat->pointer);
2396 gdk_event_set_seat (event, GDK_SEAT (seat));
2397 event->touchpad_pinch.time = _time;
2398 event->touchpad_pinch.state = device_get_modifiers (seat->master_pointer);
2399 gdk_event_set_screen (event, display->screen);
2400 event->touchpad_pinch.dx = dx;
2401 event->touchpad_pinch.dy = dy;
2402 event->touchpad_pinch.scale = scale;
2403 event->touchpad_pinch.angle_delta = angle_delta * G_PI / 180;
2404 event->touchpad_pinch.n_fingers = n_fingers;
2405
2406 get_coordinates (seat->master_pointer,
2407 &event->touchpad_pinch.x,
2408 &event->touchpad_pinch.y,
2409 &event->touchpad_pinch.x_root,
2410 &event->touchpad_pinch.y_root);
2411
2412 GDK_NOTE (EVENTS,
2413 g_message ("pinch event %d, coords: %f %f, seat %p state %d",
2414 event->type, event->touchpad_pinch.x,
2415 event->touchpad_pinch.y, seat,
2416 event->touchpad_pinch.state));
2417
2418 _gdk_wayland_display_deliver_event (seat->display, event);
2419}
2420
2421static void
2422gesture_pinch_begin (void *data,
2423 struct zwp_pointer_gesture_pinch_v1 *pinch,
2424 uint32_t serial,
2425 uint32_t time,
2426 struct wl_surface *surface,
2427 uint32_t fingers)
2428{
2429 GdkWaylandSeat *seat = data;
2430 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2431
2432 _gdk_wayland_display_update_serial (display, serial);
2433 emit_gesture_pinch_event (seat,
2434 GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
2435 time, fingers, 0, 0, 1, 0);
2436 seat->gesture_n_fingers = fingers;
2437}
2438
2439static void
2440gesture_pinch_update (void *data,
2441 struct zwp_pointer_gesture_pinch_v1 *pinch,
2442 uint32_t time,
2443 wl_fixed_t dx,
2444 wl_fixed_t dy,
2445 wl_fixed_t scale,
2446 wl_fixed_t rotation)
2447{
2448 GdkWaylandSeat *seat = data;
2449
2450 emit_gesture_pinch_event (seat,
2451 GDK_TOUCHPAD_GESTURE_PHASE_UPDATE, time,
2452 seat->gesture_n_fingers,
2453 wl_fixed_to_double (dx),
2454 wl_fixed_to_double (dy),
2455 wl_fixed_to_double (scale),
2456 wl_fixed_to_double (rotation));
2457}
2458
2459static void
2460gesture_pinch_end (void *data,
2461 struct zwp_pointer_gesture_pinch_v1 *pinch,
2462 uint32_t serial,
2463 uint32_t time,
2464 int32_t cancelled)
2465{
2466 GdkWaylandSeat *seat = data;
2467 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
2468 GdkTouchpadGesturePhase phase;
2469
2470 _gdk_wayland_display_update_serial (display, serial);
2471
2472 phase = (cancelled) ?
2473 GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
2474 GDK_TOUCHPAD_GESTURE_PHASE_END;
2475
2476 emit_gesture_pinch_event (seat, phase,
2477 time, seat->gesture_n_fingers,
2478 0, 0, 1, 0);
2479}
2480
2481static GdkDevice *
2482tablet_select_device_for_tool (GdkWaylandTabletData *tablet,
2483 GdkDeviceTool *tool)
2484{
2485 GdkDevice *device;
2486
2487 if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
2488 device = tablet->eraser_device;
2489 else
2490 device = tablet->stylus_device;
2491
2492 return device;
2493}
2494
2495static void
2496_gdk_wayland_seat_remove_tool (GdkWaylandSeat *seat,
2497 GdkWaylandTabletToolData *tool)
2498{
2499 seat->tablet_tools = g_list_remove (seat->tablet_tools, tool);
2500
2501 gdk_seat_tool_removed (GDK_SEAT (seat), tool->tool);
2502
2503 zwp_tablet_tool_v1_destroy (tool->wp_tablet_tool);
2504 g_object_unref (tool->tool);
2505 g_free (tool);
2506}
2507
2508static void
2509_gdk_wayland_seat_remove_tablet (GdkWaylandSeat *seat,
2510 GdkWaylandTabletData *tablet)
2511{
2512 GdkWaylandDeviceManager *device_manager =
2513 GDK_WAYLAND_DEVICE_MANAGER (seat->device_manager);
2514
2515 seat->tablets = g_list_remove (seat->tablets, tablet);
2516
2517 zwp_tablet_v1_destroy (tablet->wp_tablet);
2518
2519 device_manager->devices =
2520 g_list_remove (device_manager->devices, tablet->master);
2521 device_manager->devices =
2522 g_list_remove (device_manager->devices, tablet->stylus_device);
2523 device_manager->devices =
2524 g_list_remove (device_manager->devices, tablet->eraser_device);
2525
2526 g_signal_emit_by_name (device_manager, "device-removed",
2527 tablet->stylus_device);
2528 g_signal_emit_by_name (device_manager, "device-removed",
2529 tablet->eraser_device);
2530 g_signal_emit_by_name (device_manager, "device-removed",
2531 tablet->master);
2532
2533 _gdk_device_set_associated_device (tablet->master, NULL);
2534 _gdk_device_set_associated_device (tablet->stylus_device, NULL);
2535 _gdk_device_set_associated_device (tablet->eraser_device, NULL);
2536
2537 if (tablet->pointer_info.focus)
2538 g_object_unref (tablet->pointer_info.focus);
2539
2540 if (tablet->axes)
2541 g_free (tablet->axes);
2542
2543 wl_surface_destroy (tablet->pointer_info.pointer_surface);
2544 g_object_unref (tablet->master);
2545 g_object_unref (tablet->stylus_device);
2546 g_object_unref (tablet->eraser_device);
2547 g_free (tablet);
2548}
2549
2550static void
2551tablet_handle_name (void *data,
2552 struct zwp_tablet_v1 *wp_tablet,
2553 const char *name)
2554{
2555 GdkWaylandTabletData *tablet = data;
2556
2557 tablet->name = g_strdup (name);
2558}
2559
2560static void
2561tablet_handle_id (void *data,
2562 struct zwp_tablet_v1 *wp_tablet,
2563 uint32_t vid,
2564 uint32_t pid)
2565{
2566 GdkWaylandTabletData *tablet = data;
2567
2568 tablet->vid = vid;
2569 tablet->pid = pid;
2570}
2571
2572static void
2573tablet_handle_path (void *data,
2574 struct zwp_tablet_v1 *wp_tablet,
2575 const char *path)
2576{
2577 GdkWaylandTabletData *tablet = data;
2578
2579 tablet->path = g_strdup (path);
2580}
2581
2582static void
2583tablet_handle_done (void *data,
2584 struct zwp_tablet_v1 *wp_tablet)
2585{
2586 GdkWaylandTabletData *tablet = data;
2587 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
2588 GdkDisplay *display = gdk_seat_get_display (GDK_SEAT (seat));
2589 GdkWaylandDeviceManager *device_manager =
2590 GDK_WAYLAND_DEVICE_MANAGER (seat->device_manager);
2591 GdkDevice *master, *stylus_device, *eraser_device;
2592 gchar *master_name, *eraser_name;
2593
2594 master_name = g_strdup_printf ("Master pointer for %s", tablet->name);
2595 master = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2596 "name", master_name,
2597 "type", GDK_DEVICE_TYPE_MASTER,
2598 "input-source", GDK_SOURCE_MOUSE,
2599 "input-mode", GDK_MODE_SCREEN,
2600 "has-cursor", TRUE,
2601 "display", display,
2602 "device-manager", device_manager,
2603 "seat", seat,
2604 NULL);
2605 GDK_WAYLAND_DEVICE (master)->pointer = &tablet->pointer_info;
2606
2607 eraser_name = g_strconcat (tablet->name, " (Eraser)", NULL);
2608
2609 stylus_device = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2610 "name", tablet->name,
2611 "type", GDK_DEVICE_TYPE_SLAVE,
2612 "input-source", GDK_SOURCE_PEN,
2613 "input-mode", GDK_MODE_SCREEN,
2614 "has-cursor", FALSE,
2615 "display", display,
2616 "device-manager", device_manager,
2617 "seat", seat,
2618 NULL);
2619
2620 eraser_device = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2621 "name", eraser_name,
2622 "type", GDK_DEVICE_TYPE_SLAVE,
2623 "input-source", GDK_SOURCE_ERASER,
2624 "input-mode", GDK_MODE_SCREEN,
2625 "has-cursor", FALSE,
2626 "display", display,
2627 "device-manager", device_manager,
2628 "seat", seat,
2629 NULL);
2630
2631 tablet->master = master;
2632 device_manager->devices =
2633 g_list_prepend (device_manager->devices, tablet->master);
2634 g_signal_emit_by_name (device_manager, "device-added", master);
2635
2636 tablet->stylus_device = stylus_device;
2637 device_manager->devices =
2638 g_list_prepend (device_manager->devices, tablet->stylus_device);
2639 g_signal_emit_by_name (device_manager, "device-added", stylus_device);
2640
2641 tablet->eraser_device = eraser_device;
2642 device_manager->devices =
2643 g_list_prepend (device_manager->devices, tablet->eraser_device);
2644 g_signal_emit_by_name (device_manager, "device-added", eraser_device);
2645
2646 _gdk_device_set_associated_device (master, seat->master_keyboard);
2647 _gdk_device_set_associated_device (stylus_device, master);
2648 _gdk_device_set_associated_device (eraser_device, master);
2649
2650 g_free (eraser_name);
2651 g_free (master_name);
2652}
2653
2654static void
2655tablet_handle_removed (void *data,
2656 struct zwp_tablet_v1 *wp_tablet)
2657{
2658 GdkWaylandTabletData *tablet = data;
2659
2660 _gdk_wayland_seat_remove_tablet (GDK_WAYLAND_SEAT (tablet->seat), tablet);
2661}
2662
2663static const struct wl_pointer_listener pointer_listener = {
2664 pointer_handle_enter,
2665 pointer_handle_leave,
2666 pointer_handle_motion,
2667 pointer_handle_button,
2668 pointer_handle_axis,
2669 pointer_handle_frame,
2670 pointer_handle_axis_source,
2671 pointer_handle_axis_stop,
2672 pointer_handle_axis_discrete,
2673};
2674
2675static const struct wl_keyboard_listener keyboard_listener = {
2676 keyboard_handle_keymap,
2677 keyboard_handle_enter,
2678 keyboard_handle_leave,
2679 keyboard_handle_key,
2680 keyboard_handle_modifiers,
2681 keyboard_handle_repeat_info,
2682};
2683
2684static const struct wl_touch_listener touch_listener = {
2685 touch_handle_down,
2686 touch_handle_up,
2687 touch_handle_motion,
2688 touch_handle_frame,
2689 touch_handle_cancel
2690};
2691
2692static const struct zwp_pointer_gesture_swipe_v1_listener gesture_swipe_listener = {
2693 gesture_swipe_begin,
2694 gesture_swipe_update,
2695 gesture_swipe_end
2696};
2697
2698static const struct zwp_pointer_gesture_pinch_v1_listener gesture_pinch_listener = {
2699 gesture_pinch_begin,
2700 gesture_pinch_update,
2701 gesture_pinch_end
2702};
2703
2704static const struct zwp_tablet_v1_listener tablet_listener = {
2705 tablet_handle_name,
2706 tablet_handle_id,
2707 tablet_handle_path,
2708 tablet_handle_done,
2709 tablet_handle_removed,
2710};
2711
2712static void
2713seat_handle_capabilities (void *data,
2714 struct wl_seat *wl_seat,
2715 enum wl_seat_capability caps)
2716{
2717 GdkWaylandSeat *seat = data;
2718 GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (seat->device_manager);
2719 GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
2720
2721 GDK_NOTE (MISC,
2722 g_message ("seat %p with %s%s%s", wl_seat,
2723 (caps & WL_SEAT_CAPABILITY_POINTER) ? " pointer, " : "",
2724 (caps & WL_SEAT_CAPABILITY_KEYBOARD) ? " keyboard, " : "",
2725 (caps & WL_SEAT_CAPABILITY_TOUCH) ? " touch" : ""));
2726
2727 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !seat->wl_pointer)
2728 {
2729 seat->wl_pointer = wl_seat_get_pointer (wl_seat);
2730 wl_pointer_set_user_data (seat->wl_pointer, seat);
2731 wl_pointer_add_listener (seat->wl_pointer, &pointer_listener, seat);
2732
2733 seat->pointer = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2734 "name", "Wayland Pointer",
2735 "type", GDK_DEVICE_TYPE_SLAVE,
2736 "input-source", GDK_SOURCE_MOUSE,
2737 "input-mode", GDK_MODE_SCREEN,
2738 "has-cursor", TRUE,
2739 "display", seat->display,
2740 "device-manager", seat->device_manager,
2741 "seat", seat,
2742 NULL);
2743 _gdk_device_set_associated_device (seat->pointer, seat->master_pointer);
2744
2745 device_manager->devices =
2746 g_list_prepend (device_manager->devices, seat->pointer);
2747
2748 if (display_wayland->pointer_gestures)
2749 {
2750 seat->wp_pointer_gesture_swipe =
2751 zwp_pointer_gestures_v1_get_swipe_gesture (display_wayland->pointer_gestures,
2752 seat->wl_pointer);
2753 zwp_pointer_gesture_swipe_v1_set_user_data (seat->wp_pointer_gesture_swipe,
2754 seat);
2755 zwp_pointer_gesture_swipe_v1_add_listener (seat->wp_pointer_gesture_swipe,
2756 &gesture_swipe_listener, seat);
2757
2758 seat->wp_pointer_gesture_pinch =
2759 zwp_pointer_gestures_v1_get_pinch_gesture (display_wayland->pointer_gestures,
2760 seat->wl_pointer);
2761 zwp_pointer_gesture_pinch_v1_set_user_data (seat->wp_pointer_gesture_pinch,
2762 seat);
2763 zwp_pointer_gesture_pinch_v1_add_listener (seat->wp_pointer_gesture_pinch,
2764 &gesture_pinch_listener, seat);
2765 }
2766
2767 g_signal_emit_by_name (device_manager, "device-added", seat->pointer);
2768 }
2769 else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer)
2770 {
2771 wl_pointer_release (seat->wl_pointer);
2772 seat->wl_pointer = NULL;
2773 _gdk_device_set_associated_device (seat->pointer, NULL);
2774
2775 device_manager->devices =
2776 g_list_remove (device_manager->devices, seat->pointer);
2777
2778 g_signal_emit_by_name (device_manager, "device-removed", seat->pointer);
2779 g_clear_object (&seat->pointer);
2780
2781 if (seat->wheel_scrolling)
2782 {
2783 _gdk_device_set_associated_device (seat->wheel_scrolling, NULL);
2784
2785 device_manager->devices =
2786 g_list_remove (device_manager->devices, seat->wheel_scrolling);
2787
2788 g_signal_emit_by_name (device_manager, "device-removed", seat->wheel_scrolling);
2789 g_clear_object (&seat->wheel_scrolling);
2790 }
2791
2792 if (seat->finger_scrolling)
2793 {
2794 _gdk_device_set_associated_device (seat->finger_scrolling, NULL);
2795
2796 device_manager->devices =
2797 g_list_remove (device_manager->devices, seat->finger_scrolling);
2798
2799 g_signal_emit_by_name (device_manager, "device-removed", seat->finger_scrolling);
2800 g_clear_object (&seat->finger_scrolling);
2801 }
2802
2803 if (seat->continuous_scrolling)
2804 {
2805 _gdk_device_set_associated_device (seat->continuous_scrolling, NULL);
2806
2807 device_manager->devices =
2808 g_list_remove (device_manager->devices, seat->continuous_scrolling);
2809
2810 g_signal_emit_by_name (device_manager, "device-removed", seat->continuous_scrolling);
2811 g_clear_object (&seat->continuous_scrolling);
2812 }
2813 }
2814
2815 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !seat->wl_keyboard)
2816 {
2817 seat->wl_keyboard = wl_seat_get_keyboard (wl_seat);
2818 wl_keyboard_set_user_data (seat->wl_keyboard, seat);
2819 wl_keyboard_add_listener (seat->wl_keyboard, &keyboard_listener, seat);
2820
2821 seat->keyboard = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2822 "name", "Wayland Keyboard",
2823 "type", GDK_DEVICE_TYPE_SLAVE,
2824 "input-source", GDK_SOURCE_KEYBOARD,
2825 "input-mode", GDK_MODE_SCREEN,
2826 "has-cursor", FALSE,
2827 "display", seat->display,
2828 "device-manager", seat->device_manager,
2829 "seat", seat,
2830 NULL);
2831 _gdk_device_reset_axes (seat->keyboard);
2832 _gdk_device_set_associated_device (seat->keyboard, seat->master_keyboard);
2833
2834 device_manager->devices =
2835 g_list_prepend (device_manager->devices, seat->keyboard);
2836
2837 g_signal_emit_by_name (device_manager, "device-added", seat->keyboard);
2838 }
2839 else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->wl_keyboard)
2840 {
2841 wl_keyboard_release (seat->wl_keyboard);
2842 seat->wl_keyboard = NULL;
2843 _gdk_device_set_associated_device (seat->keyboard, NULL);
2844
2845 device_manager->devices =
2846 g_list_remove (device_manager->devices, seat->keyboard);
2847
2848 g_signal_emit_by_name (device_manager, "device-removed", seat->keyboard);
2849 g_clear_object (&seat->keyboard);
2850 }
2851
2852 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !seat->wl_touch)
2853 {
2854 seat->wl_touch = wl_seat_get_touch (wl_seat);
2855 wl_touch_set_user_data (seat->wl_touch, seat);
2856 wl_touch_add_listener (seat->wl_touch, &touch_listener, seat);
2857
2858 seat->touch_master = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2859 "name", "Wayland Touch Master Pointer",
2860 "type", GDK_DEVICE_TYPE_MASTER,
2861 "input-source", GDK_SOURCE_MOUSE,
2862 "input-mode", GDK_MODE_SCREEN,
2863 "has-cursor", TRUE,
2864 "display", seat->display,
2865 "device-manager", seat->device_manager,
2866 "seat", seat,
2867 NULL);
2868 GDK_WAYLAND_DEVICE (seat->touch_master)->pointer = &seat->touch_info;
2869 _gdk_device_set_associated_device (seat->touch_master, seat->master_keyboard);
2870
2871 device_manager->devices =
2872 g_list_prepend (device_manager->devices, seat->touch_master);
2873 g_signal_emit_by_name (device_manager, "device-added", seat->touch_master);
2874
2875 seat->touch = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2876 "name", "Wayland Touch",
2877 "type", GDK_DEVICE_TYPE_SLAVE,
2878 "input-source", GDK_SOURCE_TOUCHSCREEN,
2879 "input-mode", GDK_MODE_SCREEN,
2880 "has-cursor", FALSE,
2881 "display", seat->display,
2882 "device-manager", seat->device_manager,
2883 "seat", seat,
2884 NULL);
2885 _gdk_device_set_associated_device (seat->touch, seat->touch_master);
2886
2887 device_manager->devices =
2888 g_list_prepend (device_manager->devices, seat->touch);
2889
2890 g_signal_emit_by_name (device_manager, "device-added", seat->touch);
2891 }
2892 else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch)
2893 {
2894 wl_touch_release (seat->wl_touch);
2895 seat->wl_touch = NULL;
2896 _gdk_device_set_associated_device (seat->touch_master, NULL);
2897 _gdk_device_set_associated_device (seat->touch, NULL);
2898
2899 device_manager->devices =
2900 g_list_remove (device_manager->devices, seat->touch_master);
2901 device_manager->devices =
2902 g_list_remove (device_manager->devices, seat->touch);
2903
2904 g_signal_emit_by_name (device_manager, "device-removed", seat->touch_master);
2905 g_signal_emit_by_name (device_manager, "device-removed", seat->touch);
2906 g_clear_object (&seat->touch_master);
2907 g_clear_object (&seat->touch);
2908 }
2909
2910 if (seat->master_pointer)
2911 gdk_drag_context_set_device (seat->drop_context, seat->master_pointer);
2912 else if (seat->touch_master)
2913 gdk_drag_context_set_device (seat->drop_context, seat->touch_master);
2914}
2915
2916static GdkDevice *
2917get_scroll_device (GdkWaylandSeat *seat,
2918 enum wl_pointer_axis_source source)
2919{
2920 GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (seat->device_manager);
2921
2922 if (!seat->pointer)
2923 return NULL;
2924
2925 switch (source)
2926 {
2927 case WL_POINTER_AXIS_SOURCE_WHEEL:
2928 if (seat->wheel_scrolling == NULL)
2929 {
2930 seat->wheel_scrolling = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2931 "name", "Wayland Wheel Scrolling",
2932 "type", GDK_DEVICE_TYPE_SLAVE,
2933 "input-source", GDK_SOURCE_MOUSE,
2934 "input-mode", GDK_MODE_SCREEN,
2935 "has-cursor", TRUE,
2936 "display", seat->display,
2937 "device-manager", seat->device_manager,
2938 "seat", seat,
2939 NULL);
2940 _gdk_device_set_associated_device (seat->wheel_scrolling, seat->master_pointer);
2941
2942 device_manager->devices =
2943 g_list_append (device_manager->devices, seat->wheel_scrolling);
2944
2945 g_signal_emit_by_name (device_manager, "device-added", seat->wheel_scrolling);
2946 }
2947 return seat->wheel_scrolling;
2948
2949 case WL_POINTER_AXIS_SOURCE_FINGER:
2950 if (seat->finger_scrolling == NULL)
2951 {
2952 seat->finger_scrolling = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2953 "name", "Wayland Finger Scrolling",
2954 "type", GDK_DEVICE_TYPE_SLAVE,
2955 "input-source", GDK_SOURCE_TOUCHPAD,
2956 "input-mode", GDK_MODE_SCREEN,
2957 "has-cursor", TRUE,
2958 "display", seat->display,
2959 "device-manager", seat->device_manager,
2960 "seat", seat,
2961 NULL);
2962 _gdk_device_set_associated_device (seat->finger_scrolling, seat->master_pointer);
2963
2964 device_manager->devices =
2965 g_list_append (device_manager->devices, seat->finger_scrolling);
2966
2967 g_signal_emit_by_name (device_manager, "device-added", seat->finger_scrolling);
2968 }
2969 return seat->finger_scrolling;
2970
2971 case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
2972 if (seat->continuous_scrolling == NULL)
2973 {
2974 seat->continuous_scrolling = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
2975 "name", "Wayland Continuous Scrolling",
2976 "type", GDK_DEVICE_TYPE_SLAVE,
2977 "input-source", GDK_SOURCE_TRACKPOINT,
2978 "input-mode", GDK_MODE_SCREEN,
2979 "has-cursor", TRUE,
2980 "display", seat->display,
2981 "device-manager", seat->device_manager,
2982 "seat", seat,
2983 NULL);
2984 _gdk_device_set_associated_device (seat->continuous_scrolling, seat->master_pointer);
2985
2986 device_manager->devices =
2987 g_list_append (device_manager->devices, seat->continuous_scrolling);
2988
2989 g_signal_emit_by_name (device_manager, "device-added", seat->continuous_scrolling);
2990 }
2991 return seat->continuous_scrolling;
2992
2993 default:
2994 return seat->pointer;
2995 }
2996}
2997
2998static void
2999seat_handle_name (void *data,
3000 struct wl_seat *seat,
3001 const char *name)
3002{
3003 /* We don't care about the name. */
3004 GDK_NOTE (MISC,
3005 g_message ("seat %p name %s", seat, name));
3006}
3007
3008static const struct wl_seat_listener seat_listener = {
3009 seat_handle_capabilities,
3010 seat_handle_name,
3011};
3012
3013static void
3014tablet_tool_handle_type (void *data,
3015 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3016 uint32_t tool_type)
3017{
3018 GdkWaylandTabletToolData *tool = data;
3019
3020 switch (tool_type)
3021 {
3022 case ZWP_TABLET_TOOL_V1_TYPE_PEN:
3023 tool->type = GDK_DEVICE_TOOL_TYPE_PEN;
3024 break;
3025 case ZWP_TABLET_TOOL_V1_TYPE_BRUSH:
3026 tool->type = GDK_DEVICE_TOOL_TYPE_BRUSH;
3027 break;
3028 case ZWP_TABLET_TOOL_V1_TYPE_AIRBRUSH:
3029 tool->type = GDK_DEVICE_TOOL_TYPE_AIRBRUSH;
3030 break;
3031 case ZWP_TABLET_TOOL_V1_TYPE_PENCIL:
3032 tool->type = GDK_DEVICE_TOOL_TYPE_PENCIL;
3033 break;
3034 case ZWP_TABLET_TOOL_V1_TYPE_ERASER:
3035 tool->type = GDK_DEVICE_TOOL_TYPE_ERASER;
3036 break;
3037 case ZWP_TABLET_TOOL_V1_TYPE_MOUSE:
3038 tool->type = GDK_DEVICE_TOOL_TYPE_MOUSE;
3039 break;
3040 case ZWP_TABLET_TOOL_V1_TYPE_LENS:
3041 tool->type = GDK_DEVICE_TOOL_TYPE_LENS;
3042 break;
3043 default:
3044 tool->type = GDK_DEVICE_TOOL_TYPE_UNKNOWN;
3045 break;
3046 };
3047}
3048
3049static void
3050tablet_tool_handle_hardware_serial (void *data,
3051 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3052 uint32_t serial_hi,
3053 uint32_t serial_lo)
3054{
3055 GdkWaylandTabletToolData *tool = data;
3056
3057 tool->hardware_serial = ((guint64) serial_hi) << 32 | serial_lo;
3058}
3059
3060static void
3061tablet_tool_handle_hardware_id_wacom (void *data,
3062 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3063 uint32_t id_hi,
3064 uint32_t id_lo)
3065{
3066 GdkWaylandTabletToolData *tool = data;
3067
3068 tool->hardware_id_wacom = ((guint64) id_hi) << 32 | id_lo;
3069}
3070
3071static void
3072tablet_tool_handle_capability (void *data,
3073 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3074 uint32_t capability)
3075{
3076 GdkWaylandTabletToolData *tool = data;
3077
3078 switch (capability)
3079 {
3080 case ZWP_TABLET_TOOL_V1_CAPABILITY_TILT:
3081 tool->axes |= GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT;
3082 break;
3083 case ZWP_TABLET_TOOL_V1_CAPABILITY_PRESSURE:
3084 tool->axes |= GDK_AXIS_FLAG_PRESSURE;
3085 break;
3086 case ZWP_TABLET_TOOL_V1_CAPABILITY_DISTANCE:
3087 tool->axes |= GDK_AXIS_FLAG_DISTANCE;
3088 break;
3089 case ZWP_TABLET_TOOL_V1_CAPABILITY_ROTATION:
3090 tool->axes |= GDK_AXIS_FLAG_ROTATION;
3091 break;
3092 case ZWP_TABLET_TOOL_V1_CAPABILITY_SLIDER:
3093 tool->axes |= GDK_AXIS_FLAG_SLIDER;
3094 break;
3095 }
3096}
3097
3098static void
3099tablet_tool_handle_done (void *data,
3100 struct zwp_tablet_tool_v1 *wp_tablet_tool)
3101{
3102 GdkWaylandTabletToolData *tool = data;
3103
3104 tool->tool = gdk_device_tool_new (tool->hardware_serial, tool->type, tool->axes);
3105 gdk_seat_tool_added (tool->seat, tool->tool);
3106}
3107
3108static void
3109tablet_tool_handle_removed (void *data,
3110 struct zwp_tablet_tool_v1 *wp_tablet_tool)
3111{
3112 GdkWaylandTabletToolData *tool = data;
3113
3114 _gdk_wayland_seat_remove_tool (GDK_WAYLAND_SEAT (tool->seat), tool);
3115}
3116
3117static void
3118gdk_wayland_tablet_flush_frame_event (GdkWaylandTabletData *tablet,
3119 guint32 time)
3120{
3121 GdkEvent *event;
3122
3123 event = tablet->pointer_info.frame.event;
3124 tablet->pointer_info.frame.event = NULL;
3125
3126 if (!event)
3127 return;
3128
3129 switch (event->type)
3130 {
3131 case GDK_MOTION_NOTIFY:
3132 event->motion.time = time;
3133 event->motion.axes =
3134 g_memdup (tablet->axes,
3135 sizeof (gdouble) *
3136 gdk_device_get_n_axes (tablet->current_device));
3137 break;
3138 case GDK_BUTTON_PRESS:
3139 case GDK_BUTTON_RELEASE:
3140 event->button.time = time;
3141 event->button.axes =
3142 g_memdup (tablet->axes,
3143 sizeof (gdouble) *
3144 gdk_device_get_n_axes (tablet->current_device));
3145 break;
3146 case GDK_PROXIMITY_IN:
3147 case GDK_PROXIMITY_OUT:
3148 event->proximity.time = time;
3149 break;
3150 default:
3151 return;
3152 }
3153
3154 if (event->type == GDK_PROXIMITY_OUT)
3155 emulate_crossing (event->proximity.window, NULL,
3156 tablet->master, GDK_LEAVE_NOTIFY,
3157 GDK_CROSSING_NORMAL, time);
3158
3159 _gdk_wayland_display_deliver_event (gdk_seat_get_display (tablet->seat),
3160 event);
3161
3162 if (event->type == GDK_PROXIMITY_IN)
3163 emulate_crossing (event->proximity.window, NULL,
3164 tablet->master, GDK_ENTER_NOTIFY,
3165 GDK_CROSSING_NORMAL, time);
3166}
3167
3168static GdkEvent *
3169gdk_wayland_tablet_get_frame_event (GdkWaylandTabletData *tablet,
3170 GdkEventType evtype)
3171{
3172 if (tablet->pointer_info.frame.event &&
3173 tablet->pointer_info.frame.event->type != evtype)
3174 gdk_wayland_tablet_flush_frame_event (tablet, GDK_CURRENT_TIME);
3175
3176 tablet->pointer_info.frame.event = gdk_event_new (evtype);
3177 return tablet->pointer_info.frame.event;
3178}
3179
3180static void
3181gdk_wayland_device_tablet_clone_tool_axes (GdkWaylandTabletData *tablet,
3182 GdkDeviceTool *tool)
3183{
3184 gint axis_pos;
3185
3186 g_object_freeze_notify (G_OBJECT (tablet->current_device));
3187 _gdk_device_reset_axes (tablet->current_device);
3188
3189 _gdk_device_add_axis (tablet->current_device, GDK_NONE, GDK_AXIS_X, 0, 0, 0);
3190 _gdk_device_add_axis (tablet->current_device, GDK_NONE, GDK_AXIS_Y, 0, 0, 0);
3191
3192 if (tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
3193 {
3194 axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
3195 GDK_AXIS_XTILT, -9000, 9000, 0);
3196 tablet->axis_indices[GDK_AXIS_XTILT] = axis_pos;
3197
3198 axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
3199 GDK_AXIS_YTILT, -9000, 9000, 0);
3200 tablet->axis_indices[GDK_AXIS_YTILT] = axis_pos;
3201 }
3202 if (tool->tool_axes & GDK_AXIS_FLAG_DISTANCE)
3203 {
3204 axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
3205 GDK_AXIS_DISTANCE, 0, 65535, 0);
3206 tablet->axis_indices[GDK_AXIS_DISTANCE] = axis_pos;
3207 }
3208 if (tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
3209 {
3210 axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
3211 GDK_AXIS_PRESSURE, 0, 65535, 0);
3212 tablet->axis_indices[GDK_AXIS_PRESSURE] = axis_pos;
3213 }
3214
3215 if (tool->tool_axes & GDK_AXIS_FLAG_ROTATION)
3216 {
3217 axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
3218 GDK_AXIS_ROTATION, 0, 36000, 0);
3219 tablet->axis_indices[GDK_AXIS_ROTATION] = axis_pos;
3220 }
3221
3222 if (tool->tool_axes & GDK_AXIS_FLAG_SLIDER)
3223 {
3224 axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
3225 GDK_AXIS_SLIDER, -65535, 65535, 0);
3226 tablet->axis_indices[GDK_AXIS_SLIDER] = axis_pos;
3227 }
3228
3229 if (tablet->axes)
3230 g_free (tablet->axes);
3231
3232 tablet->axes =
3233 g_new0 (gdouble, gdk_device_get_n_axes (tablet->current_device));
3234
3235 g_object_thaw_notify (G_OBJECT (tablet->current_device));
3236}
3237
3238static void
3239gdk_wayland_mimic_device_axes (GdkDevice *master,
3240 GdkDevice *slave)
3241{
3242 gdouble axis_min, axis_max, axis_resolution;
3243 GdkAtom axis_label;
3244 GdkAxisUse axis_use;
3245 gint axis_count;
3246 gint i;
3247
3248 g_object_freeze_notify (G_OBJECT (master));
3249 _gdk_device_reset_axes (master);
3250 axis_count = gdk_device_get_n_axes (slave);
3251
3252 for (i = 0; i < axis_count; i++)
3253 {
3254 _gdk_device_get_axis_info (slave, i, &axis_label, &axis_use, &axis_min,
3255 &axis_max, &axis_resolution);
3256 _gdk_device_add_axis (master, axis_label, axis_use, axis_min,
3257 axis_max, axis_resolution);
3258 }
3259
3260 g_object_thaw_notify (G_OBJECT (master));
3261}
3262
3263static void
3264tablet_tool_handle_proximity_in (void *data,
3265 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3266 uint32_t serial,
3267 struct zwp_tablet_v1 *wp_tablet,
3268 struct wl_surface *surface)
3269{
3270 GdkWaylandTabletToolData *tool = data;
3271 GdkWaylandTabletData *tablet = zwp_tablet_v1_get_user_data (wp_tablet);
3272 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
3273 GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
3274 GdkWindow *window = wl_surface_get_user_data (surface);
3275 GdkEvent *event;
3276
3277 if (!surface)
3278 return;
3279 if (!GDK_IS_WINDOW (window))
3280 return;
3281
3282 tool->current_tablet = tablet;
3283 tablet->current_tool = tool;
3284
3285 _gdk_wayland_display_update_serial (display_wayland, serial);
3286 tablet->pointer_info.enter_serial = serial;
3287
3288 tablet->pointer_info.focus = g_object_ref (window);
3289 tablet->current_device =
3290 tablet_select_device_for_tool (tablet, tool->tool);
3291
3292 gdk_device_update_tool (tablet->current_device, tool->tool);
3293 gdk_wayland_device_tablet_clone_tool_axes (tablet, tool->tool);
3294 gdk_wayland_mimic_device_axes (tablet->master, tablet->current_device);
3295
3296 event = gdk_wayland_tablet_get_frame_event (tablet, GDK_PROXIMITY_IN);
3297 event->proximity.window = g_object_ref (tablet->pointer_info.focus);
3298 gdk_event_set_device (event, tablet->master);
3299 gdk_event_set_source_device (event, tablet->current_device);
3300 gdk_event_set_device_tool (event, tool->tool);
3301
3302 GDK_NOTE (EVENTS,
3303 g_message ("proximity in, seat %p surface %p tool %d",
3304 seat, tablet->pointer_info.focus,
3305 gdk_device_tool_get_tool_type (tool->tool)));
3306}
3307
3308static void
3309tablet_tool_handle_proximity_out (void *data,
3310 struct zwp_tablet_tool_v1 *wp_tablet_tool)
3311{
3312 GdkWaylandTabletToolData *tool = data;
3313 GdkWaylandTabletData *tablet = tool->current_tablet;
3314 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
3315 GdkEvent *event;
3316
3317 GDK_NOTE (EVENTS,
3318 g_message ("proximity out, seat %p, tool %d", seat,
3319 gdk_device_tool_get_tool_type (tool->tool)));
3320
3321 event = gdk_wayland_tablet_get_frame_event (tablet, GDK_PROXIMITY_OUT);
3322 event->proximity.window = g_object_ref (tablet->pointer_info.focus);
3323 gdk_event_set_device (event, tablet->master);
3324 gdk_event_set_source_device (event, tablet->current_device);
3325 gdk_event_set_device_tool (event, tool->tool);
3326
3327 gdk_wayland_pointer_stop_cursor_animation (&tablet->pointer_info);
3328
3329 gdk_wayland_device_update_window_cursor (tablet->master);
3330 g_object_unref (tablet->pointer_info.focus);
3331 tablet->pointer_info.focus = NULL;
3332
3333 gdk_device_update_tool (tablet->current_device, NULL);
3334}
3335
3336static void
3337tablet_create_button_event_frame (GdkWaylandTabletData *tablet,
3338 GdkEventType evtype,
3339 guint button)
3340{
3341 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
3342 GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
3343 GdkEvent *event;
3344
3345 event = gdk_wayland_tablet_get_frame_event (tablet, evtype);
3346 event->button.window = g_object_ref (tablet->pointer_info.focus);
3347 gdk_event_set_device (event, tablet->master);
3348 gdk_event_set_source_device (event, tablet->current_device);
3349 gdk_event_set_device_tool (event, tablet->current_tool->tool);
3350 event->button.time = tablet->pointer_info.time;
3351 event->button.state = device_get_modifiers (tablet->master);
3352 event->button.button = button;
3353 gdk_event_set_screen (event, display_wayland->screen);
3354
3355 get_coordinates (tablet->master,
3356 &event->button.x,
3357 &event->button.y,
3358 &event->button.x_root,
3359 &event->button.y_root);
3360}
3361
3362static void
3363tablet_tool_handle_down (void *data,
3364 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3365 uint32_t serial)
3366{
3367 GdkWaylandTabletToolData *tool = data;
3368 GdkWaylandTabletData *tablet = tool->current_tablet;
3369 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
3370 GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
3371
3372 if (!tablet->pointer_info.focus)
3373 return;
3374
3375 _gdk_wayland_display_update_serial (display_wayland, serial);
3376 tablet->pointer_info.press_serial = serial;
3377
3378 tablet_create_button_event_frame (tablet, GDK_BUTTON_PRESS, GDK_BUTTON_PRIMARY);
3379 tablet->pointer_info.button_modifiers |= GDK_BUTTON1_MASK;
3380}
3381
3382static void
3383tablet_tool_handle_up (void *data,
3384 struct zwp_tablet_tool_v1 *wp_tablet_tool)
3385{
3386 GdkWaylandTabletToolData *tool = data;
3387 GdkWaylandTabletData *tablet = tool->current_tablet;
3388
3389 if (!tablet->pointer_info.focus)
3390 return;
3391
3392 tablet_create_button_event_frame (tablet, GDK_BUTTON_RELEASE, GDK_BUTTON_PRIMARY);
3393 tablet->pointer_info.button_modifiers &= ~GDK_BUTTON1_MASK;
3394}
3395
3396static void
3397tablet_tool_handle_motion (void *data,
3398 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3399 wl_fixed_t sx,
3400 wl_fixed_t sy)
3401{
3402 GdkWaylandTabletToolData *tool = data;
3403 GdkWaylandTabletData *tablet = tool->current_tablet;
3404 GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
3405 GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
3406 GdkEvent *event;
3407
3408 tablet->pointer_info.surface_x = wl_fixed_to_double (sx);
3409 tablet->pointer_info.surface_y = wl_fixed_to_double (sy);
3410
3411 GDK_NOTE (EVENTS,
3412 g_message ("tablet motion %f %f",
3413 tablet->pointer_info.surface_x,
3414 tablet->pointer_info.surface_y));
3415
3416 event = gdk_wayland_tablet_get_frame_event (tablet, GDK_MOTION_NOTIFY);
3417 event->motion.window = g_object_ref (tablet->pointer_info.focus);
3418 gdk_event_set_device (event, tablet->master);
3419 gdk_event_set_source_device (event, tablet->current_device);
3420 gdk_event_set_device_tool (event, tool->tool);
3421 event->motion.time = tablet->pointer_info.time;
3422 event->motion.state = device_get_modifiers (tablet->master);
3423 event->motion.is_hint = FALSE;
3424 gdk_event_set_screen (event, display->screen);
3425
3426 get_coordinates (tablet->master,
3427 &event->motion.x,
3428 &event->motion.y,
3429 &event->motion.x_root,
3430 &event->motion.y_root);
3431}
3432
3433static void
3434tablet_tool_handle_pressure (void *data,
3435 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3436 uint32_t pressure)
3437{
3438 GdkWaylandTabletToolData *tool = data;
3439 GdkWaylandTabletData *tablet = tool->current_tablet;
3440 gint axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
3441
3442 _gdk_device_translate_axis (tablet->current_device, axis_index,
3443 pressure, &tablet->axes[axis_index]);
3444
3445 GDK_NOTE (EVENTS,
3446 g_message ("tablet tool %d pressure %d",
3447 gdk_device_tool_get_tool_type (tool->tool), pressure));
3448}
3449
3450static void
3451tablet_tool_handle_distance (void *data,
3452 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3453 uint32_t distance)
3454{
3455 GdkWaylandTabletToolData *tool = data;
3456 GdkWaylandTabletData *tablet = tool->current_tablet;
3457 gint axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
3458
3459 _gdk_device_translate_axis (tablet->current_device, axis_index,
3460 distance, &tablet->axes[axis_index]);
3461
3462 GDK_NOTE (EVENTS,
3463 g_message ("tablet tool %d distance %d",
3464 gdk_device_tool_get_tool_type (tool->tool), distance));
3465}
3466
3467static void
3468tablet_tool_handle_tilt (void *data,
3469 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3470 int32_t xtilt,
3471 int32_t ytilt)
3472{
3473 GdkWaylandTabletToolData *tool = data;
3474 GdkWaylandTabletData *tablet = tool->current_tablet;
3475 gint xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
3476 gint ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
3477
3478 _gdk_device_translate_axis (tablet->current_device, xtilt_axis_index,
3479 xtilt, &tablet->axes[xtilt_axis_index]);
3480 _gdk_device_translate_axis (tablet->current_device, ytilt_axis_index,
3481 ytilt, &tablet->axes[ytilt_axis_index]);
3482
3483 GDK_NOTE (EVENTS,
3484 g_message ("tablet tool %d tilt %d/%d",
3485 gdk_device_tool_get_tool_type (tool->tool),
3486 xtilt, ytilt));
3487}
3488
3489static void
3490tablet_tool_handle_button (void *data,
3491 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3492 uint32_t serial,
3493 uint32_t button,
3494 uint32_t state)
3495{
3496 GdkWaylandTabletToolData *tool = data;
3497 GdkWaylandTabletData *tablet = tool->current_tablet;
3498 GdkEventType evtype;
3499 guint n_button;
3500
3501 if (!tablet->pointer_info.focus)
3502 return;
3503
3504 tablet->pointer_info.press_serial = serial;
3505
3506 if (button == BTN_STYLUS)
3507 n_button = GDK_BUTTON_SECONDARY;
3508 else if (button == BTN_STYLUS2)
3509 n_button = GDK_BUTTON_MIDDLE;
3510 else
3511 return;
3512
3513 if (state == ZWP_TABLET_TOOL_V1_BUTTON_STATE_PRESSED)
3514 evtype = GDK_BUTTON_PRESS;
3515 else if (state == ZWP_TABLET_TOOL_V1_BUTTON_STATE_RELEASED)
3516 evtype = GDK_BUTTON_RELEASE;
3517 else
3518 return;
3519
3520 tablet_create_button_event_frame (tablet, evtype, n_button);
3521}
3522
3523static void
3524tablet_tool_handle_rotation (void *data,
3525 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3526 int32_t degrees)
3527{
3528 GdkWaylandTabletToolData *tool = data;
3529 GdkWaylandTabletData *tablet = tool->current_tablet;
3530 gint axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
3531
3532 _gdk_device_translate_axis (tablet->current_device, axis_index,
3533 degrees, &tablet->axes[axis_index]);
3534
3535 GDK_NOTE (EVENTS,
3536 g_message ("tablet tool %d rotation %d",
3537 gdk_device_tool_get_tool_type (tool->tool), degrees));
3538}
3539
3540static void
3541tablet_tool_handle_slider (void *data,
3542 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3543 int32_t position)
3544{
3545 GdkWaylandTabletToolData *tool = data;
3546 GdkWaylandTabletData *tablet = tool->current_tablet;
3547 gint axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
3548
3549 _gdk_device_translate_axis (tablet->current_device, axis_index,
3550 position, &tablet->axes[axis_index]);
3551
3552 GDK_NOTE (EVENTS,
3553 g_message ("tablet tool %d slider %d",
3554 gdk_device_tool_get_tool_type (tool->tool), position));
3555}
3556
3557static void
3558tablet_tool_handle_wheel (void *data,
3559 struct zwp_tablet_tool_v1 *wp_tablet_tool,
3560 int32_t degrees,
3561 int32_t clicks)
3562{
3563 /* FIXME: Handle wheel */
3564}
3565
3566static void
3567tablet_tool_handle_frame (void *data,
3568 struct zwp_tablet_tool_v1 *wl_tablet_tool,
3569 uint32_t time)
3570{
3571 GdkWaylandTabletToolData *tool = data;
3572 GdkWaylandTabletData *tablet = tool->current_tablet;
3573 GdkEvent *frame_event;
3574
3575 GDK_NOTE (EVENTS,
3576 g_message ("tablet frame, time %d", time));
3577
3578 frame_event = tablet->pointer_info.frame.event;
3579
3580 if (frame_event && frame_event->type == GDK_PROXIMITY_OUT)
3581 {
3582 tool->current_tablet = NULL;
3583 tablet->current_tool = NULL;
3584 }
3585
3586 tablet->pointer_info.time = time;
3587 gdk_wayland_tablet_flush_frame_event (tablet, time);
3588}
3589
3590static const struct zwp_tablet_tool_v1_listener tablet_tool_listener = {
3591 tablet_tool_handle_type,
3592 tablet_tool_handle_hardware_serial,
3593 tablet_tool_handle_hardware_id_wacom,
3594 tablet_tool_handle_capability,
3595 tablet_tool_handle_done,
3596 tablet_tool_handle_removed,
3597 tablet_tool_handle_proximity_in,
3598 tablet_tool_handle_proximity_out,
3599 tablet_tool_handle_down,
3600 ta