1 /*
2  * Copyright © 2014 Intel Corporation
3  * Copyright © 2008 Kristian Høgsberg
4  *
5  * Permission to use, copy, modify, distribute, and sell this software
6  * and its documentation for any purpose is hereby granted without
7  * fee, provided that the above copyright notice appear in all copies
8  * and that both that copyright notice and this permission notice
9  * appear in supporting documentation, and that the name of the
10  * copyright holders not be used in advertising or publicity
11  * pertaining to distribution of the software without specific,
12  * written prior permission.  The copyright holders make no
13  * representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied
15  * warranty.
16  *
17  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
18  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
22  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24  * SOFTWARE.
25  */
26 
27 #include "xwayland.h"
28 
29 #include <linux/input.h>
30 
31 #include <sys/mman.h>
32 #include <xkbsrv.h>
33 #include <xserver-properties.h>
34 #include <inpututils.h>
35 #include <mipointer.h>
36 #include <mipointrst.h>
37 #include <misc.h>
38 #include "tablet-unstable-v2-client-protocol.h"
39 
40 struct axis_discrete_pending {
41     struct xorg_list l;
42     uint32_t axis;
43     int32_t discrete;
44 };
45 
46 struct sync_pending {
47     struct xorg_list l;
48     DeviceIntPtr pending_dev;
49 };
50 
51 static DevPrivateKeyRec xwl_tablet_private_key;
52 
53 static void
54 xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator *warp_emulator,
55                                         double dx,
56                                         double dy,
57                                         double dx_unaccel,
58                                         double dy_unaccel);
59 static void
60 xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator *warp_emulator,
61                                      struct xwl_window *xwl_window,
62                                      SpritePtr sprite,
63                                      int x, int y);
64 
65 static void
66 xwl_seat_destroy_confined_pointer(struct xwl_seat *xwl_seat);
67 
68 static void
69 init_tablet_manager_seat(struct xwl_screen *xwl_screen,
70                          struct xwl_seat *xwl_seat);
71 static void
72 release_tablet_manager_seat(struct xwl_seat *xwl_seat);
73 
74 static void
xwl_pointer_control(DeviceIntPtr device,PtrCtrl * ctrl)75 xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
76 {
77     /* Nothing to do, dix handles all settings */
78 }
79 
80 static Bool
init_pointer_buttons(DeviceIntPtr device)81 init_pointer_buttons(DeviceIntPtr device)
82 {
83 #define NBUTTONS 10
84     BYTE map[NBUTTONS + 1];
85     int i = 0;
86     Atom btn_labels[NBUTTONS] = { 0 };
87 
88     for (i = 1; i <= NBUTTONS; i++)
89         map[i] = i;
90 
91     btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
92     btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
93     btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
94     btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
95     btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
96     btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
97     btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
98     /* don't know about the rest */
99 
100     if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map))
101         return FALSE;
102 
103     return TRUE;
104 }
105 
106 static int
xwl_pointer_proc(DeviceIntPtr device,int what)107 xwl_pointer_proc(DeviceIntPtr device, int what)
108 {
109 #define NAXES 4
110     Atom axes_labels[NAXES] = { 0 };
111 
112     switch (what) {
113     case DEVICE_INIT:
114         device->public.on = FALSE;
115 
116         if (!init_pointer_buttons(device))
117             return BadValue;
118 
119         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
120         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
121         axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
122         axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
123 
124         if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
125                                            GetMotionHistorySize(), Absolute))
126             return BadValue;
127 
128         /* Valuators */
129         InitValuatorAxisStruct(device, 0, axes_labels[0],
130                                0, 0xFFFF, 10000, 0, 10000, Absolute);
131         InitValuatorAxisStruct(device, 1, axes_labels[1],
132                                0, 0xFFFF, 10000, 0, 10000, Absolute);
133         InitValuatorAxisStruct(device, 2, axes_labels[2],
134                                NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
135         InitValuatorAxisStruct(device, 3, axes_labels[3],
136                                NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
137 
138         SetScrollValuator(device, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
139         SetScrollValuator(device, 3, SCROLL_TYPE_VERTICAL, 1.0, SCROLL_FLAG_PREFERRED);
140 
141         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
142             return BadValue;
143 
144         return Success;
145 
146     case DEVICE_ON:
147         device->public.on = TRUE;
148         return Success;
149 
150     case DEVICE_OFF:
151     case DEVICE_CLOSE:
152         device->public.on = FALSE;
153         return Success;
154     }
155 
156     return BadMatch;
157 
158 #undef NBUTTONS
159 #undef NAXES
160 }
161 
162 static int
xwl_pointer_proc_relative(DeviceIntPtr device,int what)163 xwl_pointer_proc_relative(DeviceIntPtr device, int what)
164 {
165 #define NAXES 2
166     Atom axes_labels[NAXES] = { 0 };
167 
168     switch (what) {
169     case DEVICE_INIT:
170         device->public.on = FALSE;
171 
172         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
173         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
174 
175         /*
176          * We'll never send buttons, but XGetPointerMapping might in certain
177          * situations make the client think we have no buttons.
178          */
179         if (!init_pointer_buttons(device))
180             return BadValue;
181 
182         if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
183                                            GetMotionHistorySize(), Relative))
184             return BadValue;
185 
186         /* Valuators */
187         InitValuatorAxisStruct(device, 0, axes_labels[0],
188                                NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
189         InitValuatorAxisStruct(device, 1, axes_labels[1],
190                                NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
191 
192         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
193             return BadValue;
194 
195         return Success;
196 
197     case DEVICE_ON:
198         device->public.on = TRUE;
199         return Success;
200 
201     case DEVICE_OFF:
202     case DEVICE_CLOSE:
203         device->public.on = FALSE;
204         return Success;
205     }
206 
207     return BadMatch;
208 
209 #undef NAXES
210 }
211 
212 static void
xwl_keyboard_control(DeviceIntPtr device,KeybdCtrl * ctrl)213 xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl)
214 {
215 }
216 
217 static int
xwl_keyboard_proc(DeviceIntPtr device,int what)218 xwl_keyboard_proc(DeviceIntPtr device, int what)
219 {
220     struct xwl_seat *xwl_seat = device->public.devicePrivate;
221     int len;
222 
223     switch (what) {
224     case DEVICE_INIT:
225         device->public.on = FALSE;
226         if (xwl_seat->keymap)
227             len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size);
228         else
229             len = 0;
230         if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap,
231                                                 len,
232                                                 NULL, xwl_keyboard_control))
233             return BadValue;
234 
235         return Success;
236     case DEVICE_ON:
237         device->public.on = TRUE;
238         return Success;
239 
240     case DEVICE_OFF:
241     case DEVICE_CLOSE:
242         device->public.on = FALSE;
243         return Success;
244     }
245 
246     return BadMatch;
247 }
248 
249 static int
xwl_touch_proc(DeviceIntPtr device,int what)250 xwl_touch_proc(DeviceIntPtr device, int what)
251 {
252 #define NTOUCHPOINTS 20
253 #define NBUTTONS 1
254 #define NAXES 2
255     Atom btn_labels[NBUTTONS] = { 0 };
256     Atom axes_labels[NAXES] = { 0 };
257     BYTE map[NBUTTONS + 1] = { 0 };
258 
259     switch (what) {
260     case DEVICE_INIT:
261         device->public.on = FALSE;
262 
263         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X);
264         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y);
265 
266         if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
267                                            GetMotionHistorySize(), Absolute))
268             return BadValue;
269 
270         if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map))
271             return BadValue;
272 
273         if (!InitTouchClassDeviceStruct(device, NTOUCHPOINTS,
274                                         XIDirectTouch, NAXES))
275             return BadValue;
276 
277         /* Valuators */
278         InitValuatorAxisStruct(device, 0, axes_labels[0],
279                                0, 0xFFFF, 10000, 0, 10000, Absolute);
280         InitValuatorAxisStruct(device, 1, axes_labels[1],
281                                0, 0xFFFF, 10000, 0, 10000, Absolute);
282 
283         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
284             return BadValue;
285 
286         return Success;
287 
288     case DEVICE_ON:
289         device->public.on = TRUE;
290         return Success;
291 
292     case DEVICE_OFF:
293     case DEVICE_CLOSE:
294         device->public.on = FALSE;
295         return Success;
296     }
297 
298     return BadMatch;
299 #undef NAXES
300 #undef NBUTTONS
301 #undef NTOUCHPOINTS
302 }
303 
304 static int
xwl_tablet_proc(DeviceIntPtr device,int what)305 xwl_tablet_proc(DeviceIntPtr device, int what)
306 {
307 #define NBUTTONS 9
308 #define NAXES 6
309     Atom btn_labels[NBUTTONS] = { 0 };
310     Atom axes_labels[NAXES] = { 0 };
311     BYTE map[NBUTTONS + 1] = { 0 };
312     int i;
313 
314     switch (what) {
315     case DEVICE_INIT:
316         device->public.on = FALSE;
317 
318         for (i = 1; i <= NBUTTONS; i++)
319             map[i] = i;
320 
321         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
322         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
323         axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
324         axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
325         axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
326         axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL);
327 
328         if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
329                                            GetMotionHistorySize(), Absolute))
330             return BadValue;
331 
332         /* Valuators - match the xf86-input-wacom ranges */
333         InitValuatorAxisStruct(device, 0, axes_labels[0],
334                                0, 262143, 10000, 0, 10000, Absolute);
335         InitValuatorAxisStruct(device, 1, axes_labels[1],
336                                0, 262143, 10000, 0, 10000, Absolute);
337         /* pressure */
338         InitValuatorAxisStruct(device, 2, axes_labels[2],
339                                0, 65535, 1, 0, 1, Absolute);
340         /* tilt x */
341         InitValuatorAxisStruct(device, 3, axes_labels[3],
342                                -64, 63, 57, 0, 57, Absolute);
343         /* tilt y */
344         InitValuatorAxisStruct(device, 4, axes_labels[4],
345                                -64, 63, 57, 0, 57, Absolute);
346         /* abs wheel (airbrush) or rotation (artpen) */
347         InitValuatorAxisStruct(device, 5, axes_labels[5],
348                                -900, 899, 1, 0, 1, Absolute);
349 
350         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
351             return BadValue;
352 
353         if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map))
354             return BadValue;
355 
356         return Success;
357 
358     case DEVICE_ON:
359         device->public.on = TRUE;
360         return Success;
361 
362     case DEVICE_OFF:
363     case DEVICE_CLOSE:
364         device->public.on = FALSE;
365         return Success;
366     }
367 
368     return BadMatch;
369 #undef NAXES
370 #undef NBUTTONS
371 }
372 
373 static void
pointer_handle_enter(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface,wl_fixed_t sx_w,wl_fixed_t sy_w)374 pointer_handle_enter(void *data, struct wl_pointer *pointer,
375                      uint32_t serial, struct wl_surface *surface,
376                      wl_fixed_t sx_w, wl_fixed_t sy_w)
377 {
378     struct xwl_seat *xwl_seat = data;
379     DeviceIntPtr dev = xwl_seat->pointer;
380     DeviceIntPtr master;
381     int i;
382     int sx = wl_fixed_to_int(sx_w);
383     int sy = wl_fixed_to_int(sy_w);
384     int dx, dy;
385     ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
386     ValuatorMask mask;
387 
388     /* There's a race here where if we create and then immediately
389      * destroy a surface, we might end up in a state where the Wayland
390      * compositor sends us an event for a surface that doesn't exist.
391      *
392      * Don't process enter events in this case.
393      */
394     if (surface == NULL)
395         return;
396 
397     xwl_seat->xwl_screen->serial = serial;
398     xwl_seat->pointer_enter_serial = serial;
399 
400     xwl_seat->focus_window = wl_surface_get_user_data(surface);
401     dx = xwl_seat->focus_window->window->drawable.x;
402     dy = xwl_seat->focus_window->window->drawable.y;
403 
404     /* We just entered a new xwindow, forget about the old last xwindow */
405     xwl_seat->last_xwindow = NullWindow;
406 
407     master = GetMaster(dev, POINTER_OR_FLOAT);
408     (*pScreen->SetCursorPosition) (dev, pScreen, dx + sx, dy + sy, TRUE);
409 
410     miPointerInvalidateSprite(master);
411 
412     CheckMotion(NULL, master);
413 
414     /* Ideally, X clients shouldn't see these button releases.  When
415      * the pointer leaves a window with buttons down, it means that
416      * the wayland compositor has grabbed the pointer.  The button
417      * release event is consumed by whatever grab in the compositor
418      * and won't be sent to clients (the X server is a client).
419      * However, we need to reset X's idea of which buttons are up and
420      * down, and they're all up (by definition) when the pointer
421      * enters a window.  We should figure out a way to swallow these
422      * events, perhaps using an X grab whenever the pointer is not in
423      * any X window, but for now just send the events. */
424     valuator_mask_zero(&mask);
425     for (i = 0; i < dev->button->numButtons; i++)
426         if (BitIsOn(dev->button->down, i))
427             QueuePointerEvents(dev, ButtonRelease, i, 0, &mask);
428 
429     /* The last cursor frame we commited before the pointer left one
430      * of our surfaces might not have been shown. In that case we'll
431      * have a cursor surface frame callback pending which we need to
432      * clear so that we can continue submitting new cursor frames. */
433     if (xwl_seat->cursor.frame_cb) {
434         wl_callback_destroy(xwl_seat->cursor.frame_cb);
435         xwl_seat->cursor.frame_cb = NULL;
436         xwl_seat_set_cursor(xwl_seat);
437     }
438 
439     if (xwl_seat->pointer_warp_emulator) {
440         xwl_pointer_warp_emulator_maybe_lock(xwl_seat->pointer_warp_emulator,
441                                              xwl_seat->focus_window,
442                                              NULL, 0, 0);
443     }
444 }
445 
446 static void
pointer_handle_leave(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface)447 pointer_handle_leave(void *data, struct wl_pointer *pointer,
448                      uint32_t serial, struct wl_surface *surface)
449 {
450     struct xwl_seat *xwl_seat = data;
451     DeviceIntPtr dev = xwl_seat->pointer;
452 
453     xwl_seat->xwl_screen->serial = serial;
454 
455     /* The pointer has left a known xwindow, save it for a possible match
456      * in sprite_check_lost_focus()
457      */
458     if (xwl_seat->focus_window) {
459         xwl_seat->last_xwindow = xwl_seat->focus_window->window;
460         xwl_seat->focus_window = NULL;
461         CheckMotion(NULL, GetMaster(dev, POINTER_OR_FLOAT));
462     }
463 }
464 
465 static void
dispatch_pointer_motion_event(struct xwl_seat * xwl_seat)466 dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
467 {
468     ValuatorMask mask;
469 
470     if (xwl_seat->pointer_warp_emulator &&
471         xwl_seat->pending_pointer_event.has_relative) {
472         double dx;
473         double dy;
474         double dx_unaccel;
475         double dy_unaccel;
476 
477         dx = xwl_seat->pending_pointer_event.dx;
478         dy = xwl_seat->pending_pointer_event.dy;
479         dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
480         dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
481         xwl_pointer_warp_emulator_handle_motion(xwl_seat->pointer_warp_emulator,
482                                                 dx, dy,
483                                                 dx_unaccel, dy_unaccel);
484     } else if (xwl_seat->pending_pointer_event.has_absolute ||
485                xwl_seat->pending_pointer_event.has_relative) {
486         int x;
487         int y;
488 
489         if (xwl_seat->pending_pointer_event.has_absolute) {
490             int sx = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
491             int sy = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
492             int dx = xwl_seat->focus_window->window->drawable.x;
493             int dy = xwl_seat->focus_window->window->drawable.y;
494 
495             x = dx + sx;
496             y = dy + sy;
497         } else {
498             miPointerGetPosition(xwl_seat->pointer, &x, &y);
499         }
500 
501         valuator_mask_zero(&mask);
502         if (xwl_seat->pending_pointer_event.has_relative) {
503             double dx_unaccel;
504             double dy_unaccel;
505 
506             dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
507             dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
508             valuator_mask_set_absolute_unaccelerated(&mask, 0, x, dx_unaccel);
509             valuator_mask_set_absolute_unaccelerated(&mask, 1, y, dy_unaccel);
510         } else {
511             valuator_mask_set(&mask, 0, x);
512             valuator_mask_set(&mask, 1, y);
513         }
514 
515         QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
516                            POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
517     }
518 
519     xwl_seat->pending_pointer_event.has_absolute = FALSE;
520     xwl_seat->pending_pointer_event.has_relative = FALSE;
521 }
522 
523 static void
pointer_handle_motion(void * data,struct wl_pointer * pointer,uint32_t time,wl_fixed_t sx_w,wl_fixed_t sy_w)524 pointer_handle_motion(void *data, struct wl_pointer *pointer,
525                       uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
526 {
527     struct xwl_seat *xwl_seat = data;
528 
529     if (!xwl_seat->focus_window)
530         return;
531 
532     xwl_seat->pending_pointer_event.has_absolute = TRUE;
533     xwl_seat->pending_pointer_event.x = sx_w;
534     xwl_seat->pending_pointer_event.y = sy_w;
535 
536     if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
537         dispatch_pointer_motion_event(xwl_seat);
538 }
539 
540 static void
pointer_handle_button(void * data,struct wl_pointer * pointer,uint32_t serial,uint32_t time,uint32_t button,uint32_t state)541 pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
542                       uint32_t time, uint32_t button, uint32_t state)
543 {
544     struct xwl_seat *xwl_seat = data;
545     int index;
546     ValuatorMask mask;
547 
548     xwl_seat->xwl_screen->serial = serial;
549 
550     switch (button) {
551     case BTN_LEFT:
552         index = 1;
553         break;
554     case BTN_MIDDLE:
555         index = 2;
556         break;
557     case BTN_RIGHT:
558         index = 3;
559         break;
560     default:
561         /* Skip indexes 4-7: they are used for vertical and horizontal scroll.
562            The rest of the buttons go in order: BTN_SIDE becomes 8, etc. */
563         index = 8 + button - BTN_SIDE;
564         break;
565     }
566 
567     valuator_mask_zero(&mask);
568     QueuePointerEvents(xwl_seat->pointer,
569                        state ? ButtonPress : ButtonRelease, index, 0, &mask);
570 }
571 
572 static void
pointer_handle_axis(void * data,struct wl_pointer * pointer,uint32_t time,uint32_t axis,wl_fixed_t value)573 pointer_handle_axis(void *data, struct wl_pointer *pointer,
574                     uint32_t time, uint32_t axis, wl_fixed_t value)
575 {
576     struct xwl_seat *xwl_seat = data;
577     int index;
578     const int divisor = 10;
579     ValuatorMask mask;
580     struct axis_discrete_pending *pending = NULL;
581     struct axis_discrete_pending *iter;
582 
583     switch (axis) {
584     case WL_POINTER_AXIS_VERTICAL_SCROLL:
585         index = 3;
586         break;
587     case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
588         index = 2;
589         break;
590     default:
591         return;
592     }
593 
594     xorg_list_for_each_entry(iter, &xwl_seat->axis_discrete_pending, l) {
595         if (iter->axis == axis) {
596             pending = iter;
597             break;
598         }
599     }
600 
601     valuator_mask_zero(&mask);
602 
603     if (pending) {
604         valuator_mask_set(&mask, index, pending->discrete);
605         xorg_list_del(&pending->l);
606         free(pending);
607     } else {
608         valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
609     }
610     QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask);
611 }
612 
613 static void
pointer_handle_frame(void * data,struct wl_pointer * wl_pointer)614 pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
615 {
616     struct xwl_seat *xwl_seat = data;
617 
618     if (!xwl_seat->focus_window)
619         return;
620 
621     dispatch_pointer_motion_event(xwl_seat);
622 }
623 
624 static void
pointer_handle_axis_source(void * data,struct wl_pointer * wl_pointer,uint32_t axis_source)625 pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source)
626 {
627 }
628 
629 static void
pointer_handle_axis_stop(void * data,struct wl_pointer * wl_pointer,uint32_t time,uint32_t axis)630 pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer,
631                          uint32_t time, uint32_t axis)
632 {
633 }
634 
635 static void
pointer_handle_axis_discrete(void * data,struct wl_pointer * wl_pointer,uint32_t axis,int32_t discrete)636 pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer,
637                              uint32_t axis, int32_t discrete)
638 {
639     struct xwl_seat *xwl_seat = data;
640 
641     struct axis_discrete_pending *pending = malloc(sizeof *pending);
642     if (!pending)
643         return;
644 
645     pending->axis = axis;
646     pending->discrete = discrete;
647 
648     xorg_list_add(&pending->l, &xwl_seat->axis_discrete_pending);
649 }
650 
651 static const struct wl_pointer_listener pointer_listener = {
652     pointer_handle_enter,
653     pointer_handle_leave,
654     pointer_handle_motion,
655     pointer_handle_button,
656     pointer_handle_axis,
657     pointer_handle_frame,
658     pointer_handle_axis_source,
659     pointer_handle_axis_stop,
660     pointer_handle_axis_discrete,
661 };
662 
663 static void
relative_pointer_handle_relative_motion(void * data,struct zwp_relative_pointer_v1 * zwp_relative_pointer_v1,uint32_t utime_hi,uint32_t utime_lo,wl_fixed_t dxf,wl_fixed_t dyf,wl_fixed_t dx_unaccelf,wl_fixed_t dy_unaccelf)664 relative_pointer_handle_relative_motion(void *data,
665                                         struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
666                                         uint32_t utime_hi,
667                                         uint32_t utime_lo,
668                                         wl_fixed_t dxf,
669                                         wl_fixed_t dyf,
670                                         wl_fixed_t dx_unaccelf,
671                                         wl_fixed_t dy_unaccelf)
672 {
673     struct xwl_seat *xwl_seat = data;
674 
675     xwl_seat->pending_pointer_event.has_relative = TRUE;
676     xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf);
677     xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf);
678     xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf);
679     xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf);
680 
681     if (!xwl_seat->focus_window)
682         return;
683 
684     if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
685         dispatch_pointer_motion_event(xwl_seat);
686 }
687 
688 static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
689     relative_pointer_handle_relative_motion,
690 };
691 
692 static void
keyboard_handle_key(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state)693 keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
694                     uint32_t time, uint32_t key, uint32_t state)
695 {
696     struct xwl_seat *xwl_seat = data;
697     uint32_t *k, *end;
698 
699     xwl_seat->xwl_screen->serial = serial;
700 
701     end = (uint32_t *) ((char *) xwl_seat->keys.data + xwl_seat->keys.size);
702     for (k = xwl_seat->keys.data; k < end; k++) {
703         if (*k == key)
704             *k = *--end;
705     }
706     xwl_seat->keys.size = (char *) end - (char *) xwl_seat->keys.data;
707     if (state) {
708         k = wl_array_add(&xwl_seat->keys, sizeof *k);
709         *k = key;
710     }
711 
712     QueueKeyboardEvents(xwl_seat->keyboard,
713                         state ? KeyPress : KeyRelease, key + 8);
714 }
715 
716 static void
keyboard_handle_keymap(void * data,struct wl_keyboard * keyboard,uint32_t format,int fd,uint32_t size)717 keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
718                        uint32_t format, int fd, uint32_t size)
719 {
720     struct xwl_seat *xwl_seat = data;
721     DeviceIntPtr master;
722     XkbDescPtr xkb;
723     XkbChangesRec changes = { 0 };
724 
725     if (xwl_seat->keymap)
726         munmap(xwl_seat->keymap, xwl_seat->keymap_size);
727 
728     xwl_seat->keymap_size = size;
729     xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
730     if (xwl_seat->keymap == MAP_FAILED) {
731         xwl_seat->keymap_size = 0;
732         xwl_seat->keymap = NULL;
733         goto out;
734     }
735 
736     xkb = XkbCompileKeymapFromString(xwl_seat->keyboard, xwl_seat->keymap,
737                                      strnlen(xwl_seat->keymap,
738                                              xwl_seat->keymap_size));
739     if (!xkb)
740         goto out;
741 
742     XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes);
743 
744     if (xwl_seat->keyboard->key)
745         /* Keep the current controls */
746         XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc);
747 
748     XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb);
749 
750     master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
751     if (master)
752         XkbDeviceApplyKeymap(master, xkb);
753 
754     XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE);
755 
756  out:
757     close(fd);
758 }
759 
760 static void
keyboard_handle_enter(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)761 keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
762                       uint32_t serial,
763                       struct wl_surface *surface, struct wl_array *keys)
764 {
765     struct xwl_seat *xwl_seat = data;
766     uint32_t *k;
767 
768     xwl_seat->xwl_screen->serial = serial;
769     xwl_seat->keyboard_focus = surface;
770 
771     wl_array_copy(&xwl_seat->keys, keys);
772     wl_array_for_each(k, &xwl_seat->keys)
773         QueueKeyboardEvents(xwl_seat->keyboard, EnterNotify, *k + 8);
774 }
775 
776 static void
keyboard_handle_leave(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface)777 keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
778                       uint32_t serial, struct wl_surface *surface)
779 {
780     struct xwl_seat *xwl_seat = data;
781     uint32_t *k;
782 
783     xwl_seat->xwl_screen->serial = serial;
784 
785     wl_array_for_each(k, &xwl_seat->keys)
786         QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8);
787 
788     xwl_seat->keyboard_focus = NULL;
789 }
790 
791 static void
keyboard_handle_modifiers(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)792 keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
793                           uint32_t serial, uint32_t mods_depressed,
794                           uint32_t mods_latched, uint32_t mods_locked,
795                           uint32_t group)
796 {
797     struct xwl_seat *xwl_seat = data;
798     DeviceIntPtr dev;
799     XkbStateRec old_state, *new_state;
800     xkbStateNotify sn;
801     CARD16 changed;
802 
803     mieqProcessInputEvents();
804 
805     for (dev = inputInfo.devices; dev; dev = dev->next) {
806         if (dev != xwl_seat->keyboard &&
807             dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD))
808             continue;
809 
810         old_state = dev->key->xkbInfo->state;
811         new_state = &dev->key->xkbInfo->state;
812 
813         new_state->locked_group = group & XkbAllGroupsMask;
814         new_state->base_mods = mods_depressed & XkbAllModifiersMask;
815         new_state->locked_mods = mods_locked & XkbAllModifiersMask;
816         XkbLatchModifiers(dev, XkbAllModifiersMask,
817                           mods_latched & XkbAllModifiersMask);
818 
819         XkbComputeDerivedState(dev->key->xkbInfo);
820 
821         changed = XkbStateChangedFlags(&old_state, new_state);
822         if (!changed)
823             continue;
824 
825         sn.keycode = 0;
826         sn.eventType = 0;
827         sn.requestMajor = XkbReqCode;
828         sn.requestMinor = X_kbLatchLockState;   /* close enough */
829         sn.changed = changed;
830         XkbSendStateNotify(dev, &sn);
831     }
832 }
833 
834 static void
remove_sync_pending(DeviceIntPtr dev)835 remove_sync_pending(DeviceIntPtr dev)
836 {
837     struct xwl_seat *xwl_seat = dev->public.devicePrivate;
838     struct sync_pending *p, *npd;
839 
840     if (!xwl_seat)
841         return;
842 
843     xorg_list_for_each_entry_safe(p, npd, &xwl_seat->sync_pending, l) {
844         if (p->pending_dev == dev) {
845             xorg_list_del(&xwl_seat->sync_pending);
846             free (p);
847             return;
848         }
849     }
850 }
851 
852 static void
sync_callback(void * data,struct wl_callback * callback,uint32_t serial)853 sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
854 {
855     DeviceIntPtr dev = (DeviceIntPtr) data;
856 
857     remove_sync_pending(dev);
858     wl_callback_destroy(callback);
859 }
860 
861 static const struct wl_callback_listener sync_listener = {
862    sync_callback
863 };
864 
865 static Bool
keyboard_check_repeat(DeviceIntPtr dev,XkbSrvInfoPtr xkbi,unsigned key)866 keyboard_check_repeat (DeviceIntPtr dev, XkbSrvInfoPtr xkbi, unsigned key)
867 {
868     struct xwl_seat *xwl_seat = dev->public.devicePrivate;
869     struct xwl_screen *xwl_screen;
870     struct wl_callback *callback;
871     struct sync_pending *p;
872 
873     if (!xwl_seat)
874         return FALSE;
875 
876     /* Make sure we didn't miss a possible reply from the compositor */
877     xwl_screen = xwl_seat->xwl_screen;
878     xwl_sync_events (xwl_screen);
879 
880     xorg_list_for_each_entry(p, &xwl_seat->sync_pending, l) {
881         if (p->pending_dev == dev) {
882             ErrorF("Key repeat discarded, Wayland compositor doesn't "
883                    "seem to be processing events fast enough!\n");
884 
885             return FALSE;
886         }
887     }
888 
889     p = xnfalloc(sizeof(struct sync_pending));
890     p->pending_dev = dev;
891     callback = wl_display_sync (xwl_screen->display);
892     xorg_list_add(&p->l, &xwl_seat->sync_pending);
893 
894     wl_callback_add_listener(callback, &sync_listener, dev);
895 
896     return TRUE;
897 }
898 
899 static void
keyboard_handle_repeat_info(void * data,struct wl_keyboard * keyboard,int32_t rate,int32_t delay)900 keyboard_handle_repeat_info (void *data, struct wl_keyboard *keyboard,
901                              int32_t rate, int32_t delay)
902 {
903     struct xwl_seat *xwl_seat = data;
904     DeviceIntPtr dev;
905     XkbControlsPtr ctrl;
906 
907     if (rate < 0 || delay < 0) {
908         ErrorF("Wrong rate/delay: %d, %d\n", rate, delay);
909         return;
910     }
911 
912     for (dev = inputInfo.devices; dev; dev = dev->next) {
913         if (dev != xwl_seat->keyboard &&
914             dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD))
915             continue;
916 
917         if (rate != 0) {
918             ctrl = dev->key->xkbInfo->desc->ctrls;
919             ctrl->repeat_delay = delay;
920             /* rate is number of keys per second */
921             ctrl->repeat_interval = 1000 / rate;
922 
923             XkbSetRepeatKeys(dev, -1, AutoRepeatModeOn);
924         } else
925             XkbSetRepeatKeys(dev, -1, AutoRepeatModeOff);
926     }
927 }
928 
929 static const struct wl_keyboard_listener keyboard_listener = {
930     keyboard_handle_keymap,
931     keyboard_handle_enter,
932     keyboard_handle_leave,
933     keyboard_handle_key,
934     keyboard_handle_modifiers,
935     keyboard_handle_repeat_info,
936 };
937 
938 static struct xwl_touch *
xwl_seat_lookup_touch(struct xwl_seat * xwl_seat,int32_t id)939 xwl_seat_lookup_touch(struct xwl_seat *xwl_seat, int32_t id)
940 {
941     struct xwl_touch *xwl_touch, *next_xwl_touch;
942 
943     xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
944                                   &xwl_seat->touches, link_touch) {
945         if (xwl_touch->id == id)
946             return xwl_touch;
947     }
948 
949     return NULL;
950 }
951 
952 static void
xwl_touch_send_event(struct xwl_touch * xwl_touch,struct xwl_seat * xwl_seat,int type)953 xwl_touch_send_event(struct xwl_touch *xwl_touch,
954                      struct xwl_seat *xwl_seat, int type)
955 {
956     double dx, dy, x, y;
957     ValuatorMask mask;
958 
959     dx = xwl_touch->window->window->drawable.x;
960     dy = xwl_touch->window->window->drawable.y;
961 
962     x = (dx + xwl_touch->x) * 0xFFFF / xwl_seat->xwl_screen->width;
963     y = (dy + xwl_touch->y) * 0xFFFF / xwl_seat->xwl_screen->height;
964 
965     valuator_mask_zero(&mask);
966     valuator_mask_set_double(&mask, 0, x);
967     valuator_mask_set_double(&mask, 1, y);
968     QueueTouchEvents(xwl_seat->touch, type, xwl_touch->id, 0, &mask);
969 }
970 
971 static void
touch_handle_down(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,struct wl_surface * surface,int32_t id,wl_fixed_t sx_w,wl_fixed_t sy_w)972 touch_handle_down(void *data, struct wl_touch *wl_touch,
973                   uint32_t serial, uint32_t time,
974                   struct wl_surface *surface,
975                   int32_t id, wl_fixed_t sx_w, wl_fixed_t sy_w)
976 {
977     struct xwl_seat *xwl_seat = data;
978     struct xwl_touch *xwl_touch;
979 
980     if (surface == NULL)
981         return;
982 
983     xwl_touch = calloc(1, sizeof *xwl_touch);
984     if (xwl_touch == NULL) {
985         ErrorF("%s: ENOMEM\n", __func__);
986         return;
987     }
988 
989     xwl_touch->window = wl_surface_get_user_data(surface);
990     xwl_touch->id = id;
991     xwl_touch->x = wl_fixed_to_int(sx_w);
992     xwl_touch->y = wl_fixed_to_int(sy_w);
993     xorg_list_add(&xwl_touch->link_touch, &xwl_seat->touches);
994 
995     xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchBegin);
996 }
997 
998 static void
touch_handle_up(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,int32_t id)999 touch_handle_up(void *data, struct wl_touch *wl_touch,
1000                 uint32_t serial, uint32_t time, int32_t id)
1001 {
1002     struct xwl_touch *xwl_touch;
1003     struct xwl_seat *xwl_seat = data;
1004 
1005     xwl_touch = xwl_seat_lookup_touch(xwl_seat, id);
1006 
1007     if (!xwl_touch)
1008         return;
1009 
1010     xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchEnd);
1011     xorg_list_del(&xwl_touch->link_touch);
1012     free(xwl_touch);
1013 }
1014 
1015 static void
touch_handle_motion(void * data,struct wl_touch * wl_touch,uint32_t time,int32_t id,wl_fixed_t sx_w,wl_fixed_t sy_w)1016 touch_handle_motion(void *data, struct wl_touch *wl_touch,
1017                     uint32_t time, int32_t id,
1018                     wl_fixed_t sx_w, wl_fixed_t sy_w)
1019 {
1020     struct xwl_seat *xwl_seat = data;
1021     struct xwl_touch *xwl_touch;
1022 
1023     xwl_touch = xwl_seat_lookup_touch(xwl_seat, id);
1024 
1025     if (!xwl_touch)
1026         return;
1027 
1028     xwl_touch->x = wl_fixed_to_int(sx_w);
1029     xwl_touch->y = wl_fixed_to_int(sy_w);
1030     xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchUpdate);
1031 }
1032 
1033 static void
touch_handle_frame(void * data,struct wl_touch * wl_touch)1034 touch_handle_frame(void *data, struct wl_touch *wl_touch)
1035 {
1036 }
1037 
1038 static void
touch_handle_cancel(void * data,struct wl_touch * wl_touch)1039 touch_handle_cancel(void *data, struct wl_touch *wl_touch)
1040 {
1041     struct xwl_seat *xwl_seat = data;
1042     struct xwl_touch *xwl_touch, *next_xwl_touch;
1043 
1044     xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
1045                                   &xwl_seat->touches, link_touch) {
1046         /* We can't properly notify of cancellation to the X client
1047          * once it thinks it has the ownership, send at least a
1048          * TouchEnd event.
1049          */
1050         xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchEnd);
1051         xorg_list_del(&xwl_touch->link_touch);
1052         free(xwl_touch);
1053     }
1054 }
1055 
1056 static const struct wl_touch_listener touch_listener = {
1057     touch_handle_down,
1058     touch_handle_up,
1059     touch_handle_motion,
1060     touch_handle_frame,
1061     touch_handle_cancel
1062 };
1063 
1064 static struct xwl_seat *
find_matching_seat(DeviceIntPtr device)1065 find_matching_seat(DeviceIntPtr device)
1066 {
1067     DeviceIntPtr dev;
1068 
1069     for (dev = inputInfo.devices; dev; dev = dev->next)
1070         if (dev->deviceProc == xwl_keyboard_proc &&
1071             device == GetMaster(dev, MASTER_KEYBOARD))
1072                 return (struct xwl_seat *) dev->public.devicePrivate;
1073 
1074     return NULL;
1075 }
1076 
1077 static void
release_grab(struct xwl_seat * xwl_seat)1078 release_grab(struct xwl_seat *xwl_seat)
1079 {
1080     if (xwl_seat->keyboard_grab)
1081         zwp_xwayland_keyboard_grab_v1_destroy(xwl_seat->keyboard_grab);
1082     xwl_seat->keyboard_grab = NULL;
1083 }
1084 
1085 static void
set_grab(struct xwl_seat * xwl_seat,struct xwl_window * xwl_window)1086 set_grab(struct xwl_seat *xwl_seat, struct xwl_window *xwl_window)
1087 {
1088     struct xwl_screen *xwl_screen;
1089 
1090     if (!xwl_window)
1091         return;
1092 
1093     /* We already have a grab */
1094     if (xwl_seat->keyboard_grab)
1095         release_grab (xwl_seat);
1096 
1097     xwl_screen = xwl_seat->xwl_screen;
1098     xwl_seat->keyboard_grab =
1099         zwp_xwayland_keyboard_grab_manager_v1_grab_keyboard(xwl_screen->wp_grab,
1100                                                             xwl_window->surface,
1101                                                             xwl_seat->seat);
1102 }
1103 
1104 static void
xwl_keyboard_activate_grab(DeviceIntPtr device,GrabPtr grab,TimeStamp time,Bool passive)1105 xwl_keyboard_activate_grab(DeviceIntPtr device, GrabPtr grab, TimeStamp time, Bool passive)
1106 {
1107     struct xwl_seat *xwl_seat = device->public.devicePrivate;
1108 
1109     /* We are not interested in passive grabs */
1110     if (!passive) {
1111         /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
1112         if (xwl_seat == NULL)
1113             xwl_seat = find_matching_seat(device);
1114         if (xwl_seat)
1115             set_grab(xwl_seat, xwl_window_from_window(grab->window));
1116     }
1117 
1118     ActivateKeyboardGrab(device, grab, time, passive);
1119 }
1120 
1121 static void
xwl_keyboard_deactivate_grab(DeviceIntPtr device)1122 xwl_keyboard_deactivate_grab(DeviceIntPtr device)
1123 {
1124     struct xwl_seat *xwl_seat = device->public.devicePrivate;
1125 
1126     /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
1127     if (xwl_seat == NULL)
1128         xwl_seat = find_matching_seat(device);
1129     if (xwl_seat)
1130         release_grab (xwl_seat);
1131 
1132     DeactivateKeyboardGrab(device);
1133 }
1134 
1135 static void
setup_keyboard_grab_handler(DeviceIntPtr device)1136 setup_keyboard_grab_handler (DeviceIntPtr device)
1137 {
1138     device->deviceGrab.ActivateGrab = xwl_keyboard_activate_grab;
1139     device->deviceGrab.DeactivateGrab = xwl_keyboard_deactivate_grab;
1140 }
1141 
1142 static DeviceIntPtr
add_device(struct xwl_seat * xwl_seat,const char * driver,DeviceProc device_proc)1143 add_device(struct xwl_seat *xwl_seat,
1144            const char *driver, DeviceProc device_proc)
1145 {
1146     DeviceIntPtr dev = NULL;
1147     static Atom type_atom;
1148     char name[32];
1149 
1150     dev = AddInputDevice(serverClient, device_proc, TRUE);
1151     if (dev == NULL)
1152         return NULL;
1153 
1154     if (type_atom == None)
1155         type_atom = MakeAtom(driver, strlen(driver), TRUE);
1156     snprintf(name, sizeof name, "%s:%d", driver, xwl_seat->id);
1157     AssignTypeAndName(dev, type_atom, name);
1158     dev->public.devicePrivate = xwl_seat;
1159     dev->type = SLAVE;
1160     dev->spriteInfo->spriteOwner = FALSE;
1161 
1162     return dev;
1163 }
1164 
1165 static void
disable_device(DeviceIntPtr dev)1166 disable_device(DeviceIntPtr dev)
1167 {
1168     DisableDevice(dev, TRUE);
1169     dev->public.devicePrivate = NULL;
1170 }
1171 
1172 static void
enable_device(struct xwl_seat * xwl_seat,DeviceIntPtr dev)1173 enable_device(struct xwl_seat *xwl_seat, DeviceIntPtr dev)
1174 {
1175     dev->public.devicePrivate = xwl_seat;
1176     EnableDevice(dev, TRUE);
1177 }
1178 
1179 
1180 static void
init_pointer(struct xwl_seat * xwl_seat)1181 init_pointer(struct xwl_seat *xwl_seat)
1182 {
1183     xwl_seat->wl_pointer = wl_seat_get_pointer(xwl_seat->seat);
1184     wl_pointer_add_listener(xwl_seat->wl_pointer,
1185                             &pointer_listener, xwl_seat);
1186 
1187     if (xwl_seat->pointer == NULL) {
1188         xwl_seat_set_cursor(xwl_seat);
1189         xwl_seat->pointer =
1190             add_device(xwl_seat, "xwayland-pointer", xwl_pointer_proc);
1191         ActivateDevice(xwl_seat->pointer, TRUE);
1192     }
1193     enable_device(xwl_seat, xwl_seat->pointer);
1194 }
1195 
1196 static void
release_pointer(struct xwl_seat * xwl_seat)1197 release_pointer(struct xwl_seat *xwl_seat)
1198 {
1199     wl_pointer_release(xwl_seat->wl_pointer);
1200     xwl_seat->wl_pointer = NULL;
1201 
1202     if (xwl_seat->pointer)
1203         disable_device(xwl_seat->pointer);
1204 }
1205 
1206 static void
init_relative_pointer(struct xwl_seat * xwl_seat)1207 init_relative_pointer(struct xwl_seat *xwl_seat)
1208 {
1209     struct zwp_relative_pointer_manager_v1 *relative_pointer_manager =
1210         xwl_seat->xwl_screen->relative_pointer_manager;
1211 
1212     if (relative_pointer_manager) {
1213         xwl_seat->wp_relative_pointer =
1214             zwp_relative_pointer_manager_v1_get_relative_pointer(
1215                 relative_pointer_manager, xwl_seat->wl_pointer);
1216         zwp_relative_pointer_v1_add_listener(xwl_seat->wp_relative_pointer,
1217                                              &relative_pointer_listener,
1218                                              xwl_seat);
1219     }
1220 
1221     if (xwl_seat->relative_pointer == NULL) {
1222         xwl_seat->relative_pointer =
1223             add_device(xwl_seat, "xwayland-relative-pointer",
1224                        xwl_pointer_proc_relative);
1225         ActivateDevice(xwl_seat->relative_pointer, TRUE);
1226     }
1227     enable_device(xwl_seat, xwl_seat->relative_pointer);
1228 }
1229 
1230 static void
release_relative_pointer(struct xwl_seat * xwl_seat)1231 release_relative_pointer(struct xwl_seat *xwl_seat)
1232 {
1233     if (xwl_seat->wp_relative_pointer) {
1234         zwp_relative_pointer_v1_destroy(xwl_seat->wp_relative_pointer);
1235         xwl_seat->wp_relative_pointer = NULL;
1236     }
1237 
1238     if (xwl_seat->relative_pointer)
1239         disable_device(xwl_seat->relative_pointer);
1240 }
1241 
1242 static void
init_keyboard(struct xwl_seat * xwl_seat)1243 init_keyboard(struct xwl_seat *xwl_seat)
1244 {
1245     DeviceIntPtr master;
1246 
1247     xwl_seat->wl_keyboard = wl_seat_get_keyboard(xwl_seat->seat);
1248     wl_keyboard_add_listener(xwl_seat->wl_keyboard,
1249                              &keyboard_listener, xwl_seat);
1250 
1251     if (xwl_seat->keyboard == NULL) {
1252         xwl_seat->keyboard =
1253             add_device(xwl_seat, "xwayland-keyboard", xwl_keyboard_proc);
1254         ActivateDevice(xwl_seat->keyboard, TRUE);
1255     }
1256     enable_device(xwl_seat, xwl_seat->keyboard);
1257     xwl_seat->keyboard->key->xkbInfo->checkRepeat = keyboard_check_repeat;
1258 
1259     if (xwl_seat->xwl_screen->wp_grab) {
1260         /* We have Xwayland grab protocol supported by the compositor */
1261         master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
1262         if (master)
1263             setup_keyboard_grab_handler(master);
1264     }
1265 }
1266 
1267 static void
release_keyboard(struct xwl_seat * xwl_seat)1268 release_keyboard(struct xwl_seat *xwl_seat)
1269 {
1270     release_grab(xwl_seat);
1271     wl_keyboard_release(xwl_seat->wl_keyboard);
1272     xwl_seat->wl_keyboard = NULL;
1273 
1274     if (xwl_seat->keyboard) {
1275         remove_sync_pending(xwl_seat->keyboard);
1276         disable_device(xwl_seat->keyboard);
1277     }
1278 }
1279 
1280 static void
init_touch(struct xwl_seat * xwl_seat)1281 init_touch(struct xwl_seat *xwl_seat)
1282 {
1283     xwl_seat->wl_touch = wl_seat_get_touch(xwl_seat->seat);
1284     wl_touch_add_listener(xwl_seat->wl_touch,
1285                           &touch_listener, xwl_seat);
1286 
1287     if (xwl_seat->touch == NULL) {
1288         xwl_seat->touch =
1289             add_device(xwl_seat, "xwayland-touch", xwl_touch_proc);
1290         ActivateDevice(xwl_seat->touch, TRUE);
1291     }
1292     enable_device(xwl_seat, xwl_seat->touch);
1293 }
1294 
1295 static void
release_touch(struct xwl_seat * xwl_seat)1296 release_touch(struct xwl_seat *xwl_seat)
1297 {
1298     wl_touch_release(xwl_seat->wl_touch);
1299     xwl_seat->wl_touch = NULL;
1300 
1301     if (xwl_seat->touch)
1302         disable_device(xwl_seat->touch);
1303 }
1304 
1305 static void
seat_handle_capabilities(void * data,struct wl_seat * seat,enum wl_seat_capability caps)1306 seat_handle_capabilities(void *data, struct wl_seat *seat,
1307                          enum wl_seat_capability caps)
1308 {
1309     struct xwl_seat *xwl_seat = data;
1310 
1311     if (caps & WL_SEAT_CAPABILITY_POINTER && xwl_seat->wl_pointer == NULL) {
1312         init_pointer(xwl_seat);
1313         init_relative_pointer(xwl_seat);
1314     } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && xwl_seat->wl_pointer) {
1315         release_pointer(xwl_seat);
1316         release_relative_pointer(xwl_seat);
1317     }
1318 
1319     if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->wl_keyboard == NULL) {
1320         init_keyboard(xwl_seat);
1321     } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && xwl_seat->wl_keyboard) {
1322         release_keyboard(xwl_seat);
1323     }
1324 
1325     if (caps & WL_SEAT_CAPABILITY_TOUCH && xwl_seat->wl_touch == NULL) {
1326         init_touch(xwl_seat);
1327     } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && xwl_seat->wl_touch) {
1328         release_touch(xwl_seat);
1329     }
1330 
1331     xwl_seat->xwl_screen->expecting_event--;
1332 }
1333 
1334 static void
seat_handle_name(void * data,struct wl_seat * seat,const char * name)1335 seat_handle_name(void *data, struct wl_seat *seat,
1336                  const char *name)
1337 {
1338 
1339 }
1340 
1341 static const struct wl_seat_listener seat_listener = {
1342     seat_handle_capabilities,
1343     seat_handle_name
1344 };
1345 
1346 static void
xwl_cursor_init(struct xwl_cursor * xwl_cursor,struct xwl_screen * xwl_screen,void (* update_proc)(struct xwl_cursor *))1347 xwl_cursor_init(struct xwl_cursor *xwl_cursor, struct xwl_screen *xwl_screen,
1348                 void (* update_proc)(struct xwl_cursor *))
1349 {
1350     xwl_cursor->surface = wl_compositor_create_surface(xwl_screen->compositor);
1351     xwl_cursor->update_proc = update_proc;
1352     xwl_cursor->frame_cb = NULL;
1353     xwl_cursor->needs_update = FALSE;
1354 }
1355 
1356 static void
xwl_cursor_release(struct xwl_cursor * xwl_cursor)1357 xwl_cursor_release(struct xwl_cursor *xwl_cursor)
1358 {
1359     wl_surface_destroy(xwl_cursor->surface);
1360     if (xwl_cursor->frame_cb)
1361         wl_callback_destroy(xwl_cursor->frame_cb);
1362 }
1363 
1364 static void
xwl_seat_update_cursor(struct xwl_cursor * xwl_cursor)1365 xwl_seat_update_cursor(struct xwl_cursor *xwl_cursor)
1366 {
1367     struct xwl_seat *xwl_seat = wl_container_of(xwl_cursor, xwl_seat, cursor);
1368     xwl_seat_set_cursor(xwl_seat);
1369 }
1370 
1371 static void
create_input_device(struct xwl_screen * xwl_screen,uint32_t id,uint32_t version)1372 create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version)
1373 {
1374     struct xwl_seat *xwl_seat;
1375 
1376     xwl_seat = calloc(1, sizeof *xwl_seat);
1377     if (xwl_seat == NULL) {
1378         ErrorF("%s: ENOMEM\n", __func__);
1379         return;
1380     }
1381 
1382     xwl_seat->xwl_screen = xwl_screen;
1383     xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
1384 
1385     xwl_seat->seat =
1386         wl_registry_bind(xwl_screen->registry, id,
1387                          &wl_seat_interface, min(version, 5));
1388     xwl_seat->id = id;
1389 
1390     xwl_cursor_init(&xwl_seat->cursor, xwl_seat->xwl_screen,
1391                     xwl_seat_update_cursor);
1392     wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat);
1393 
1394     init_tablet_manager_seat(xwl_screen, xwl_seat);
1395 
1396     wl_array_init(&xwl_seat->keys);
1397 
1398     xorg_list_init(&xwl_seat->touches);
1399     xorg_list_init(&xwl_seat->axis_discrete_pending);
1400     xorg_list_init(&xwl_seat->sync_pending);
1401 }
1402 
1403 void
xwl_seat_destroy(struct xwl_seat * xwl_seat)1404 xwl_seat_destroy(struct xwl_seat *xwl_seat)
1405 {
1406     struct xwl_touch *xwl_touch, *next_xwl_touch;
1407     struct sync_pending *p, *npd;
1408     struct axis_discrete_pending *ad, *ad_next;
1409 
1410     xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
1411                                   &xwl_seat->touches, link_touch) {
1412         xorg_list_del(&xwl_touch->link_touch);
1413         free(xwl_touch);
1414     }
1415 
1416     xorg_list_for_each_entry_safe(p, npd, &xwl_seat->sync_pending, l) {
1417         xorg_list_del(&xwl_seat->sync_pending);
1418         free (p);
1419     }
1420 
1421     xorg_list_for_each_entry_safe(ad, ad_next, &xwl_seat->axis_discrete_pending, l) {
1422         xorg_list_del(&ad->l);
1423         free(ad);
1424     }
1425 
1426     release_tablet_manager_seat(xwl_seat);
1427 
1428     release_grab(xwl_seat);
1429     wl_seat_destroy(xwl_seat->seat);
1430     xwl_cursor_release(&xwl_seat->cursor);
1431     wl_array_release(&xwl_seat->keys);
1432     free(xwl_seat);
1433 }
1434 
1435 static void
tablet_handle_name(void * data,struct zwp_tablet_v2 * tablet,const char * name)1436 tablet_handle_name(void *data, struct zwp_tablet_v2 *tablet, const char *name)
1437 {
1438 }
1439 
1440 static void
tablet_handle_id(void * data,struct zwp_tablet_v2 * tablet,uint32_t vid,uint32_t pid)1441 tablet_handle_id(void *data, struct zwp_tablet_v2 *tablet, uint32_t vid,
1442                   uint32_t pid)
1443 {
1444 }
1445 
1446 static void
tablet_handle_path(void * data,struct zwp_tablet_v2 * tablet,const char * path)1447 tablet_handle_path(void *data, struct zwp_tablet_v2 *tablet, const char *path)
1448 {
1449 }
1450 
1451 static void
tablet_handle_done(void * data,struct zwp_tablet_v2 * tablet)1452 tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet)
1453 {
1454     struct xwl_tablet *xwl_tablet = data;
1455     struct xwl_seat *xwl_seat = xwl_tablet->seat;
1456 
1457     if (xwl_seat->stylus == NULL) {
1458         xwl_seat->stylus = add_device(xwl_seat, "xwayland-stylus", xwl_tablet_proc);
1459         ActivateDevice(xwl_seat->stylus, TRUE);
1460     }
1461     enable_device(xwl_seat, xwl_seat->stylus);
1462 
1463     if (xwl_seat->eraser == NULL) {
1464         xwl_seat->eraser = add_device(xwl_seat, "xwayland-eraser", xwl_tablet_proc);
1465         ActivateDevice(xwl_seat->eraser, TRUE);
1466     }
1467     enable_device(xwl_seat, xwl_seat->eraser);
1468 
1469     if (xwl_seat->puck == NULL) {
1470         xwl_seat->puck = add_device(xwl_seat, "xwayland-cursor", xwl_tablet_proc);
1471         ActivateDevice(xwl_seat->puck, TRUE);
1472     }
1473     enable_device(xwl_seat, xwl_seat->puck);
1474 }
1475 
1476 static void
tablet_handle_removed(void * data,struct zwp_tablet_v2 * tablet)1477 tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet)
1478 {
1479     struct xwl_tablet *xwl_tablet = data;
1480     struct xwl_seat *xwl_seat = xwl_tablet->seat;
1481 
1482     xorg_list_del(&xwl_tablet->link);
1483 
1484     /* The tablet is merely disabled, not removed. The next tablet
1485        will re-use the same X devices */
1486     if (xorg_list_is_empty(&xwl_seat->tablets)) {
1487         if (xwl_seat->stylus)
1488             disable_device(xwl_seat->stylus);
1489         if (xwl_seat->eraser)
1490             disable_device(xwl_seat->eraser);
1491         if (xwl_seat->puck)
1492             disable_device(xwl_seat->puck);
1493         /* pads are removed separately */
1494     }
1495 
1496     zwp_tablet_v2_destroy(tablet);
1497     free(xwl_tablet);
1498 }
1499 
1500 static const struct zwp_tablet_v2_listener tablet_listener = {
1501     tablet_handle_name,
1502     tablet_handle_id,
1503     tablet_handle_path,
1504     tablet_handle_done,
1505     tablet_handle_removed
1506 };
1507 
1508 static void
tablet_tool_receive_type(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t type)1509 tablet_tool_receive_type(void *data, struct zwp_tablet_tool_v2 *tool,
1510                          uint32_t type)
1511 {
1512     struct xwl_tablet_tool *xwl_tablet_tool = data;
1513     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1514 
1515     switch (type) {
1516         case ZWP_TABLET_TOOL_V2_TYPE_ERASER:
1517             xwl_tablet_tool->xdevice = xwl_seat->eraser;
1518             break;
1519         case ZWP_TABLET_TOOL_V2_TYPE_MOUSE:
1520         case ZWP_TABLET_TOOL_V2_TYPE_LENS:
1521             xwl_tablet_tool->xdevice = xwl_seat->puck;
1522             break;
1523         default:
1524             xwl_tablet_tool->xdevice = xwl_seat->stylus;
1525             break;
1526     }
1527 }
1528 
1529 static void
tablet_tool_receive_hardware_serial(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t hi,uint32_t low)1530 tablet_tool_receive_hardware_serial(void *data, struct zwp_tablet_tool_v2 *tool,
1531                                     uint32_t hi, uint32_t low)
1532 {
1533 }
1534 
1535 static void
tablet_tool_receive_hardware_id_wacom(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t hi,uint32_t low)1536 tablet_tool_receive_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *tool,
1537                                       uint32_t hi, uint32_t low)
1538 {
1539 }
1540 
1541 static void
tablet_tool_receive_capability(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t capability)1542 tablet_tool_receive_capability(void *data, struct zwp_tablet_tool_v2 *tool,
1543                                uint32_t capability)
1544 {
1545 }
1546 
1547 static void
tablet_tool_receive_done(void * data,struct zwp_tablet_tool_v2 * tool)1548 tablet_tool_receive_done(void *data, struct zwp_tablet_tool_v2 *tool)
1549 {
1550 }
1551 
1552 static void
tablet_tool_receive_removed(void * data,struct zwp_tablet_tool_v2 * tool)1553 tablet_tool_receive_removed(void *data, struct zwp_tablet_tool_v2 *tool)
1554 {
1555     struct xwl_tablet_tool *xwl_tablet_tool = data;
1556 
1557     xorg_list_del(&xwl_tablet_tool->link);
1558     xwl_cursor_release(&xwl_tablet_tool->cursor);
1559     zwp_tablet_tool_v2_destroy(tool);
1560     free(xwl_tablet_tool);
1561 }
1562 
1563 static void
tablet_tool_proximity_in(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t serial,struct zwp_tablet_v2 * tablet,struct wl_surface * wl_surface)1564 tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool,
1565                          uint32_t serial, struct zwp_tablet_v2 *tablet,
1566                          struct wl_surface *wl_surface)
1567 {
1568     struct xwl_tablet_tool *xwl_tablet_tool = data;
1569     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1570 
1571     /* There's a race here where if we create and then immediately
1572      * destroy a surface, we might end up in a state where the Wayland
1573      * compositor sends us an event for a surface that doesn't exist.
1574      *
1575      * Don't process enter events in this case.
1576      *
1577      * see pointer_handle_enter()
1578      */
1579     if (wl_surface == NULL)
1580         return;
1581 
1582     xwl_tablet_tool->proximity_in_serial = serial;
1583     xwl_seat->tablet_focus_window = wl_surface_get_user_data(wl_surface);
1584 
1585     xwl_tablet_tool_set_cursor(xwl_tablet_tool);
1586 }
1587 
1588 static void
tablet_tool_proximity_out(void * data,struct zwp_tablet_tool_v2 * tool)1589 tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool)
1590 {
1591     struct xwl_tablet_tool *xwl_tablet_tool = data;
1592     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1593 
1594     xwl_tablet_tool->proximity_in_serial = 0;
1595     xwl_seat->tablet_focus_window = NULL;
1596 
1597     xwl_tablet_tool->pressure = 0;
1598     xwl_tablet_tool->tilt_x = 0;
1599     xwl_tablet_tool->tilt_y = 0;
1600     xwl_tablet_tool->rotation = 0;
1601     xwl_tablet_tool->slider = 0;
1602 }
1603 
1604 static void
tablet_tool_down(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t serial)1605 tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial)
1606 {
1607     struct xwl_tablet_tool *xwl_tablet_tool = data;
1608     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1609     ValuatorMask mask;
1610 
1611     xwl_seat->xwl_screen->serial = serial;
1612 
1613     valuator_mask_zero(&mask);
1614     QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonPress, 1, 0, &mask);
1615 }
1616 
1617 static void
tablet_tool_up(void * data,struct zwp_tablet_tool_v2 * tool)1618 tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool)
1619 {
1620     struct xwl_tablet_tool *xwl_tablet_tool = data;
1621     ValuatorMask mask;
1622 
1623     valuator_mask_zero(&mask);
1624     QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonRelease, 1, 0, &mask);
1625 }
1626 
1627 static void
tablet_tool_motion(void * data,struct zwp_tablet_tool_v2 * tool,wl_fixed_t x,wl_fixed_t y)1628 tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
1629                    wl_fixed_t x, wl_fixed_t y)
1630 {
1631     struct xwl_tablet_tool *xwl_tablet_tool = data;
1632     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1633     int32_t dx, dy;
1634     double sx = wl_fixed_to_double(x);
1635     double sy = wl_fixed_to_double(y);
1636 
1637     if (!xwl_seat->tablet_focus_window)
1638         return;
1639 
1640     dx = xwl_seat->tablet_focus_window->window->drawable.x;
1641     dy = xwl_seat->tablet_focus_window->window->drawable.y;
1642 
1643     xwl_tablet_tool->x = (double) dx + sx;
1644     xwl_tablet_tool->y = (double) dy + sy;
1645 }
1646 
1647 static void
tablet_tool_pressure(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t pressure)1648 tablet_tool_pressure(void *data, struct zwp_tablet_tool_v2 *tool,
1649                      uint32_t pressure)
1650 {
1651     struct xwl_tablet_tool *xwl_tablet_tool = data;
1652     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1653 
1654     if (!xwl_seat->tablet_focus_window)
1655         return;
1656 
1657     /* normalized to 65535 already */
1658     xwl_tablet_tool->pressure = pressure;
1659 }
1660 
1661 static void
tablet_tool_distance(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t distance_raw)1662 tablet_tool_distance(void *data, struct zwp_tablet_tool_v2 *tool,
1663                      uint32_t distance_raw)
1664 {
1665 }
1666 
1667 static void
tablet_tool_tilt(void * data,struct zwp_tablet_tool_v2 * tool,wl_fixed_t tilt_x,wl_fixed_t tilt_y)1668 tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *tool,
1669                  wl_fixed_t tilt_x, wl_fixed_t tilt_y)
1670 {
1671     struct xwl_tablet_tool *xwl_tablet_tool = data;
1672     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1673 
1674     if (!xwl_seat->tablet_focus_window)
1675         return;
1676 
1677     xwl_tablet_tool->tilt_x = wl_fixed_to_double(tilt_x);
1678     xwl_tablet_tool->tilt_y = wl_fixed_to_double(tilt_y);
1679 }
1680 
1681 static void
tablet_tool_rotation(void * data,struct zwp_tablet_tool_v2 * tool,wl_fixed_t angle)1682 tablet_tool_rotation(void *data, struct zwp_tablet_tool_v2 *tool,
1683                      wl_fixed_t angle)
1684 {
1685     struct xwl_tablet_tool *xwl_tablet_tool = data;
1686     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1687     double rotation = wl_fixed_to_double(angle);
1688 
1689     if (!xwl_seat->tablet_focus_window)
1690         return;
1691 
1692     /* change origin (buttons facing right [libinput +90 degrees]) and
1693      * scaling (5 points per degree) to match wacom driver behavior
1694      */
1695     rotation = remainderf(rotation + 90.0f, 360.0f);
1696     rotation *= 5.0f;
1697     xwl_tablet_tool->rotation = rotation;
1698 }
1699 
1700 static void
tablet_tool_slider(void * data,struct zwp_tablet_tool_v2 * tool,int32_t position_raw)1701 tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *tool,
1702                    int32_t position_raw)
1703 {
1704     struct xwl_tablet_tool *xwl_tablet_tool = data;
1705     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1706     float position = position_raw / 65535.0;
1707 
1708     if (!xwl_seat->tablet_focus_window)
1709         return;
1710 
1711     xwl_tablet_tool->slider = (position * 1799.0f) - 900.0f;
1712 }
1713 
1714 static void
tablet_tool_wheel(void * data,struct zwp_tablet_tool_v2 * tool,wl_fixed_t degrees,int32_t clicks)1715 tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool,
1716                   wl_fixed_t degrees, int32_t clicks)
1717 {
1718     struct xwl_tablet_tool *xwl_tablet_tool = data;
1719     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1720 
1721     if (!xwl_seat->tablet_focus_window)
1722         return;
1723 
1724     xwl_tablet_tool->wheel_clicks = clicks;
1725 }
1726 
1727 static void
tablet_tool_button_state(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t serial,uint32_t button,uint32_t state)1728 tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool,
1729                          uint32_t serial, uint32_t button, uint32_t state)
1730 {
1731     struct xwl_tablet_tool *xwl_tablet_tool = data;
1732     struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
1733     uint32_t *mask = &xwl_tablet_tool->buttons_now;
1734     int xbtn = 0;
1735 
1736     /* BTN_0 .. BTN_9 */
1737     if (button >= 0x100 && button <= 0x109) {
1738         xbtn = button - 0x100 + 1;
1739     }
1740     /* BTN_A .. BTN_Z */
1741     else if (button >= 0x130 && button <= 0x135) {
1742         xbtn = button - 0x130 + 10;
1743     }
1744     /* BTN_BASE .. BTN_BASE6 */
1745     else if (button >= 0x126 && button <= 0x12b) {
1746         xbtn = button - 0x126 + 16;
1747     }
1748     else {
1749         switch (button) {
1750         case 0x110: /* BTN_LEFT    */
1751         case 0x14a: /* BTN_TOUCH   */
1752             xbtn = 1;
1753             break;
1754 
1755         case 0x112: /* BTN_MIDDLE  */
1756         case 0x14b: /* BTN_STYLUS  */
1757             xbtn = 2;
1758             break;
1759 
1760         case 0x111: /* BTN_RIGHT   */
1761         case 0x14c: /* BTN_STYLUS2 */
1762             xbtn = 3;
1763             break;
1764 
1765         case 0x113: /* BTN_SIDE    */
1766         case 0x116: /* BTN_BACK    */
1767         case 0x149: /* BTN_STYLUS3 */
1768             xbtn = 8;
1769             break;
1770 
1771         case 0x114: /* BTN_EXTRA   */
1772         case 0x115: /* BTN_FORWARD */
1773             xbtn = 9;
1774             break;
1775         }
1776     }
1777 
1778     if (!xbtn) {
1779         ErrorF("unknown tablet button number %d\n", button);
1780         return;
1781     }
1782 
1783     BUG_RETURN(xbtn >= 8 * sizeof(*mask));
1784 
1785     if (state)
1786         SetBit(mask, xbtn - 1);
1787     else
1788         ClearBit(mask, xbtn - 1);
1789 
1790     xwl_seat->xwl_screen->serial = serial;
1791 }
1792 
1793 static void
tablet_tool_frame(void * data,struct zwp_tablet_tool_v2 * tool,uint32_t time)1794 tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
1795 {
1796     struct xwl_tablet_tool *xwl_tablet_tool = data;
1797     ValuatorMask mask;
1798     uint32_t released, pressed, diff;
1799     int button;
1800 
1801     valuator_mask_zero(&mask);
1802     valuator_mask_set_double(&mask, 0, xwl_tablet_tool->x);
1803     valuator_mask_set_double(&mask, 1, xwl_tablet_tool->y);
1804     valuator_mask_set(&mask, 2, xwl_tablet_tool->pressure);
1805     valuator_mask_set_double(&mask, 3, xwl_tablet_tool->tilt_x);
1806     valuator_mask_set_double(&mask, 4, xwl_tablet_tool->tilt_y);
1807     valuator_mask_set_double(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider);
1808 
1809     QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0,
1810                POINTER_ABSOLUTE | POINTER_DESKTOP, &mask);
1811 
1812     valuator_mask_zero(&mask);
1813 
1814     diff = xwl_tablet_tool->buttons_prev ^ xwl_tablet_tool->buttons_now;
1815     released = diff & ~xwl_tablet_tool->buttons_now;
1816     pressed = diff & xwl_tablet_tool->buttons_now;
1817 
1818     button = 1;
1819     while (released) {
1820         if (released & 0x1)
1821             QueuePointerEvents(xwl_tablet_tool->xdevice,
1822                                ButtonRelease, button, 0, &mask);
1823         button++;
1824         released >>= 1;
1825     }
1826 
1827     button = 1;
1828     while (pressed) {
1829         if (pressed & 0x1)
1830             QueuePointerEvents(xwl_tablet_tool->xdevice,
1831                                ButtonPress, button, 0, &mask);
1832         button++;
1833         pressed >>= 1;
1834     }
1835 
1836     xwl_tablet_tool->buttons_prev = xwl_tablet_tool->buttons_now;
1837 
1838     while (xwl_tablet_tool->wheel_clicks) {
1839             if (xwl_tablet_tool->wheel_clicks < 0) {
1840                 button = 4;
1841                 xwl_tablet_tool->wheel_clicks++;
1842             }
1843             else {
1844                 button = 5;
1845                 xwl_tablet_tool->wheel_clicks--;
1846             }
1847 
1848             QueuePointerEvents(xwl_tablet_tool->xdevice,
1849                                ButtonPress, button, 0, &mask);
1850             QueuePointerEvents(xwl_tablet_tool->xdevice,
1851                                ButtonRelease, button, 0, &mask);
1852 
1853     }
1854 }
1855 
1856 static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
1857     tablet_tool_receive_type,
1858     tablet_tool_receive_hardware_serial,
1859     tablet_tool_receive_hardware_id_wacom,
1860     tablet_tool_receive_capability,
1861     tablet_tool_receive_done,
1862     tablet_tool_receive_removed,
1863     tablet_tool_proximity_in,
1864     tablet_tool_proximity_out,
1865     tablet_tool_down,
1866     tablet_tool_up,
1867     tablet_tool_motion,
1868     tablet_tool_pressure,
1869     tablet_tool_distance,
1870     tablet_tool_tilt,
1871     tablet_tool_rotation,
1872     tablet_tool_slider,
1873     tablet_tool_wheel,
1874     tablet_tool_button_state,
1875     tablet_tool_frame
1876 };
1877 
1878 static void
tablet_pad_ring_destroy(struct xwl_tablet_pad_ring * ring)1879 tablet_pad_ring_destroy(struct xwl_tablet_pad_ring *ring)
1880 {
1881     zwp_tablet_pad_ring_v2_destroy(ring->ring);
1882     xorg_list_del(&ring->link);
1883     free(ring);
1884 }
1885 
1886 static void
tablet_pad_ring_source(void * data,struct zwp_tablet_pad_ring_v2 * zwp_tablet_pad_ring_v2,uint32_t source)1887 tablet_pad_ring_source(void *data,
1888                        struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
1889                        uint32_t source)
1890 {
1891 }
1892 
1893 static void
tablet_pad_ring_angle(void * data,struct zwp_tablet_pad_ring_v2 * zwp_tablet_pad_ring_v2,wl_fixed_t degrees)1894 tablet_pad_ring_angle(void *data,
1895                       struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
1896                       wl_fixed_t degrees)
1897 {
1898     struct xwl_tablet_pad_ring *ring = data;
1899     struct xwl_tablet_pad *pad = ring->group->pad;
1900     double deg = wl_fixed_to_double(degrees);
1901     ValuatorMask mask;
1902 
1903     valuator_mask_zero(&mask);
1904     valuator_mask_set(&mask, 5 + ring->index, deg/360.0  * 71);
1905     QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask);
1906 }
1907 
1908 static void
tablet_pad_ring_stop(void * data,struct zwp_tablet_pad_ring_v2 * zwp_tablet_pad_ring_v2)1909 tablet_pad_ring_stop(void *data,
1910                      struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2)
1911 {
1912 }
1913 
1914 static void
tablet_pad_ring_frame(void * data,struct zwp_tablet_pad_ring_v2 * zwp_tablet_pad_ring_v2,uint32_t time)1915 tablet_pad_ring_frame(void *data,
1916                       struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
1917                       uint32_t time)
1918 {
1919 }
1920 
1921 static const struct zwp_tablet_pad_ring_v2_listener tablet_pad_ring_listener = {
1922     tablet_pad_ring_source,
1923     tablet_pad_ring_angle,
1924     tablet_pad_ring_stop,
1925     tablet_pad_ring_frame,
1926 };
1927 
1928 
1929 static void
tablet_pad_strip_destroy(struct xwl_tablet_pad_strip * strip)1930 tablet_pad_strip_destroy(struct xwl_tablet_pad_strip *strip)
1931 {
1932     zwp_tablet_pad_strip_v2_destroy(strip->strip);
1933     xorg_list_del(&strip->link);
1934     free(strip);
1935 }
1936 
1937 static void
tablet_pad_strip_source(void * data,struct zwp_tablet_pad_strip_v2 * zwp_tablet_pad_strip_v2,uint32_t source)1938 tablet_pad_strip_source(void *data,
1939                         struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
1940                         uint32_t source)
1941 {
1942 }
1943 
1944 static void
tablet_pad_strip_position(void * data,struct zwp_tablet_pad_strip_v2 * zwp_tablet_pad_strip_v2,uint32_t position)1945 tablet_pad_strip_position(void *data,
1946                           struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
1947                           uint32_t position)
1948 {
1949     struct xwl_tablet_pad_strip *strip = data;
1950     struct xwl_tablet_pad *pad = strip->group->pad;
1951     ValuatorMask mask;
1952 
1953     valuator_mask_zero(&mask);
1954     valuator_mask_set(&mask, 3 + strip->index, position/65535.0 * 2048);
1955     QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask);
1956 }
1957 
1958 static void
tablet_pad_strip_stop(void * data,struct zwp_tablet_pad_strip_v2 * zwp_tablet_pad_strip_v2)1959 tablet_pad_strip_stop(void *data,
1960                       struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2)
1961 {
1962 }
1963 
1964 static void
tablet_pad_strip_frame(void * data,struct zwp_tablet_pad_strip_v2 * zwp_tablet_pad_strip_v2,uint32_t time)1965 tablet_pad_strip_frame(void *data,
1966                        struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
1967                        uint32_t time)
1968 {
1969 }
1970 
1971 static const struct zwp_tablet_pad_strip_v2_listener tablet_pad_strip_listener = {
1972     tablet_pad_strip_source,
1973     tablet_pad_strip_position,
1974     tablet_pad_strip_stop,
1975     tablet_pad_strip_frame,
1976 };
1977 
1978 static void
tablet_pad_group_destroy(struct xwl_tablet_pad_group * group)1979 tablet_pad_group_destroy(struct xwl_tablet_pad_group *group)
1980 {
1981     struct xwl_tablet_pad_ring *r, *tr;
1982     struct xwl_tablet_pad_strip *s, *ts;
1983 
1984     xorg_list_for_each_entry_safe(r, tr,
1985                                   &group->pad_group_ring_list,
1986                                   link)
1987         tablet_pad_ring_destroy(r);
1988 
1989     xorg_list_for_each_entry_safe(s, ts,
1990                                   &group->pad_group_strip_list,
1991                                   link)
1992         tablet_pad_strip_destroy(s);
1993 
1994     zwp_tablet_pad_group_v2_destroy(group->group);
1995     xorg_list_del(&group->link);
1996     free(group);
1997 }
1998 
1999 static void
tablet_pad_group_buttons(void * data,struct zwp_tablet_pad_group_v2 * zwp_tablet_pad_group_v2,struct wl_array * buttons)2000 tablet_pad_group_buttons(void *data,
2001                          struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
2002                          struct wl_array *buttons)
2003 {
2004 
2005 }
2006 
2007 static void
tablet_pad_group_ring(void * data,struct zwp_tablet_pad_group_v2 * zwp_tablet_pad_group_v2,struct zwp_tablet_pad_ring_v2 * wp_ring)2008 tablet_pad_group_ring(void *data,
2009                       struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
2010                       struct zwp_tablet_pad_ring_v2 *wp_ring)
2011 {
2012     static unsigned int ring_index = 0;
2013     struct xwl_tablet_pad_group *group = data;
2014     struct xwl_tablet_pad_ring *ring;
2015 
2016     ring = calloc(1, sizeof *ring);
2017     if (ring == NULL) {
2018         ErrorF("%s ENOMEM\n", __func__);
2019         return;
2020     }
2021 
2022     ring->index = ring_index++;
2023     ring->group = group;
2024     ring->ring = wp_ring;
2025 
2026     xorg_list_add(&ring->link, &group->pad_group_ring_list);
2027 
2028     zwp_tablet_pad_ring_v2_add_listener(wp_ring, &tablet_pad_ring_listener,
2029                                         ring);
2030 }
2031 
2032 static void
tablet_pad_group_strip(void * data,struct zwp_tablet_pad_group_v2 * zwp_tablet_pad_group_v2,struct zwp_tablet_pad_strip_v2 * wp_strip)2033 tablet_pad_group_strip(void *data,
2034                        struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
2035                        struct zwp_tablet_pad_strip_v2 *wp_strip)
2036 {
2037     static unsigned int strip_index = 0;
2038     struct xwl_tablet_pad_group *group = data;
2039     struct xwl_tablet_pad_strip *strip;
2040 
2041     strip = calloc(1, sizeof *strip);
2042     if (strip == NULL) {
2043         ErrorF("%s ENOMEM\n", __func__);
2044         return;
2045     }
2046 
2047     strip->index = strip_index++;
2048     strip->group = group;
2049     strip->strip = wp_strip;
2050 
2051     xorg_list_add(&strip->link, &group->pad_group_strip_list);
2052 
2053     zwp_tablet_pad_strip_v2_add_listener(wp_strip, &tablet_pad_strip_listener,
2054                                          strip);
2055 }
2056 
2057 static void
tablet_pad_group_modes(void * data,struct zwp_tablet_pad_group_v2 * zwp_tablet_pad_group_v2,uint32_t modes)2058 tablet_pad_group_modes(void *data,
2059                        struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
2060                        uint32_t modes)
2061 {
2062 
2063 }
2064 
2065 static void
tablet_pad_group_done(void * data,struct zwp_tablet_pad_group_v2 * zwp_tablet_pad_group_v2)2066 tablet_pad_group_done(void *data,
2067                       struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2)
2068 {
2069 
2070 }
2071 
2072 static void
tablet_pad_group_mode_switch(void * data,struct zwp_tablet_pad_group_v2 * zwp_tablet_pad_group_v2,uint32_t time,uint32_t serial,uint32_t mode)2073 tablet_pad_group_mode_switch(void *data,
2074                              struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
2075                              uint32_t time,
2076                              uint32_t serial,
2077                              uint32_t mode)
2078 {
2079 
2080 }
2081 
2082 static struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = {
2083     tablet_pad_group_buttons,
2084     tablet_pad_group_ring,
2085     tablet_pad_group_strip,
2086     tablet_pad_group_modes,
2087     tablet_pad_group_done,
2088     tablet_pad_group_mode_switch,
2089 };
2090 
2091 static int
xwl_tablet_pad_proc(DeviceIntPtr device,int what)2092 xwl_tablet_pad_proc(DeviceIntPtr device, int what)
2093 {
2094     struct xwl_tablet_pad *pad = dixGetPrivate(&device->devPrivates,
2095                                                &xwl_tablet_private_key);
2096     /* Axis layout mirrors that of xf86-input-wacom to have better
2097        compatibility with existing clients */
2098 #define NAXES 7
2099     Atom axes_labels[NAXES] = { 0 };
2100     BYTE map[MAX_BUTTONS + 1];
2101     int i = 0;
2102     Atom btn_labels[MAX_BUTTONS] = { 0 }; /* btn labels are meaningless */
2103     int nbuttons;
2104 
2105     switch (what) {
2106     case DEVICE_INIT:
2107         device->public.on = FALSE;
2108 
2109         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
2110         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
2111         /* The others have no good mapping */
2112 
2113         if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
2114                                            GetMotionHistorySize(), Absolute))
2115             return BadValue;
2116 
2117         for (i = 1; i <= MAX_BUTTONS; i++)
2118             map[i] = i;
2119 
2120         /* We need at least 7 buttons to allow scrolling */
2121         nbuttons = min(max(pad->nbuttons + 4, 7), MAX_BUTTONS);
2122 
2123         if (!InitButtonClassDeviceStruct(device, nbuttons,
2124                                          btn_labels, map))
2125             return BadValue;
2126 
2127         /* Valuators */
2128         InitValuatorAxisStruct(device, 0, axes_labels[0],
2129                                0, 100, 1, 0, 1, Absolute);
2130         InitValuatorAxisStruct(device, 1, axes_labels[1],
2131                                0, 100, 1, 0, 1, Absolute);
2132         /* Pressure - unused, for backwards compat only */
2133         InitValuatorAxisStruct(device, 2, axes_labels[2],
2134                                0, 2048, 1, 0, 1, Absolute);
2135         /* strip x */
2136         InitValuatorAxisStruct(device, 3, axes_labels[3],
2137                                0, 2048, 1, 0, 1, Absolute);
2138         /* strip y */
2139         InitValuatorAxisStruct(device, 4, axes_labels[4],
2140                                0, 2048, 1, 0, 1, Absolute);
2141         /* ring */
2142         InitValuatorAxisStruct(device, 5, axes_labels[5],
2143                                0, 71, 1, 0, 1, Absolute);
2144         /* ring2 */
2145         InitValuatorAxisStruct(device, 6, axes_labels[6],
2146                                0, 71, 1, 0, 1, Absolute);
2147 
2148         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
2149             return BadValue;
2150 
2151         return Success;
2152 
2153     case DEVICE_ON:
2154         device->public.on = TRUE;
2155         return Success;
2156 
2157     case DEVICE_OFF:
2158     case DEVICE_CLOSE:
2159         device->public.on = FALSE;
2160         return Success;
2161     }
2162 
2163     return BadMatch;
2164 #undef NAXES
2165 }
2166 
2167 static void
tablet_pad_group(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2,struct zwp_tablet_pad_group_v2 * pad_group)2168 tablet_pad_group(void *data,
2169                  struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
2170                  struct zwp_tablet_pad_group_v2 *pad_group)
2171 {
2172     struct xwl_tablet_pad *pad = data;
2173     struct xwl_tablet_pad_group *group;
2174 
2175     group = calloc(1, sizeof *group);
2176     if (pad == NULL) {
2177         ErrorF("%s ENOMEM\n", __func__);
2178         return;
2179     }
2180 
2181     group->pad = pad;
2182     group->group = pad_group;
2183     xorg_list_init(&group->pad_group_ring_list);
2184     xorg_list_init(&group->pad_group_strip_list);
2185 
2186     xorg_list_add(&group->link, &pad->pad_group_list);
2187 
2188     zwp_tablet_pad_group_v2_add_listener(pad_group,
2189                                          &tablet_pad_group_listener,
2190                                          group);
2191 }
2192 
2193 static void
tablet_pad_path(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2,const char * path)2194 tablet_pad_path(void *data,
2195                 struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
2196                 const char *path)
2197 {
2198 
2199 }
2200 
2201 static void
tablet_pad_buttons(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2,uint32_t buttons)2202 tablet_pad_buttons(void *data,
2203                    struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
2204                    uint32_t buttons)
2205 {
2206     struct xwl_tablet_pad *pad = data;
2207 
2208     pad->nbuttons = buttons;
2209 }
2210 
2211 static void
tablet_pad_done(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2)2212 tablet_pad_done(void *data,
2213                 struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2)
2214 {
2215     struct xwl_tablet_pad *pad = data;
2216 
2217     pad->xdevice = add_device(pad->seat, "xwayland-pad",
2218                               xwl_tablet_pad_proc);
2219     dixSetPrivate(&pad->xdevice->devPrivates, &xwl_tablet_private_key, pad);
2220     ActivateDevice(pad->xdevice, TRUE);
2221     EnableDevice(pad->xdevice, TRUE);
2222 }
2223 
2224 static void
tablet_pad_button(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2,uint32_t time,uint32_t button,uint32_t state)2225 tablet_pad_button(void *data,
2226                   struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
2227                   uint32_t time,
2228                   uint32_t button,
2229                   uint32_t state)
2230 {
2231     struct xwl_tablet_pad *pad = data;
2232     ValuatorMask mask;
2233 
2234     button++; /* wayland index vs X's 1-offset */
2235     /* skip scroll wheel buttons 4-7 */
2236     button = button > 3 ? button + 4 : button;
2237 
2238     valuator_mask_zero(&mask);
2239     QueuePointerEvents(pad->xdevice,
2240                        state ? ButtonPress : ButtonRelease, button, 0, &mask);
2241 }
2242 
2243 static void
tablet_pad_enter(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2,uint32_t serial,struct zwp_tablet_v2 * tablet,struct wl_surface * surface)2244 tablet_pad_enter(void *data,
2245                  struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
2246                  uint32_t serial,
2247                  struct zwp_tablet_v2 *tablet,
2248                  struct wl_surface *surface)
2249 {
2250     /* pairs the pad with the tablet but also to set the focus. We
2251      * don't care about the pairing and always use X's focus */
2252 }
2253 
2254 static void
tablet_pad_leave(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2,uint32_t serial,struct wl_surface * surface)2255 tablet_pad_leave(void *data,
2256                  struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
2257                  uint32_t serial,
2258                  struct wl_surface *surface)
2259 {
2260     /* pairs the pad with the tablet but also to set the focus. We
2261      * don't care about the pairing and always use X's focus */
2262 }
2263 
2264 static void
tablet_pad_removed(void * data,struct zwp_tablet_pad_v2 * zwp_tablet_pad_v2)2265 tablet_pad_removed(void *data,
2266                    struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2)
2267 {
2268     struct xwl_tablet_pad *pad = data;
2269     struct xwl_tablet_pad_group *g, *tg;
2270 
2271     xorg_list_for_each_entry_safe(g, tg, &pad->pad_group_list, link)
2272         tablet_pad_group_destroy(g);
2273 
2274     RemoveDevice(pad->xdevice, TRUE);
2275     xorg_list_del(&pad->link);
2276     zwp_tablet_pad_v2_destroy(pad->pad);
2277     free(pad);
2278 }
2279 
2280 static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
2281     tablet_pad_group,
2282     tablet_pad_path,
2283     tablet_pad_buttons,
2284     tablet_pad_done,
2285     tablet_pad_button,
2286     tablet_pad_enter,
2287     tablet_pad_leave,
2288     tablet_pad_removed,
2289 };
2290 
2291 static void
tablet_seat_handle_add_tablet(void * data,struct zwp_tablet_seat_v2 * tablet_seat,struct zwp_tablet_v2 * tablet)2292 tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
2293                               struct zwp_tablet_v2 *tablet)
2294 {
2295     struct xwl_seat *xwl_seat = data;
2296     struct xwl_tablet *xwl_tablet;
2297 
2298     xwl_tablet = calloc(sizeof *xwl_tablet, 1);
2299     if (xwl_tablet == NULL) {
2300         ErrorF("%s ENOMEM\n", __func__);
2301         return;
2302     }
2303 
2304     xwl_tablet->tablet = tablet;
2305     xwl_tablet->seat = xwl_seat;
2306 
2307     xorg_list_add(&xwl_tablet->link, &xwl_seat->tablets);
2308 
2309     zwp_tablet_v2_add_listener(tablet, &tablet_listener, xwl_tablet);
2310 }
2311 
2312 static void
xwl_tablet_tool_update_cursor(struct xwl_cursor * xwl_cursor)2313 xwl_tablet_tool_update_cursor(struct xwl_cursor *xwl_cursor)
2314 {
2315     struct xwl_tablet_tool *xwl_tablet_tool = wl_container_of(xwl_cursor,
2316                                                               xwl_tablet_tool,
2317                                                               cursor);
2318     xwl_tablet_tool_set_cursor(xwl_tablet_tool);
2319 }
2320 
2321 static void
tablet_seat_handle_add_tool(void * data,struct zwp_tablet_seat_v2 * tablet_seat,struct zwp_tablet_tool_v2 * tool)2322 tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
2323                             struct zwp_tablet_tool_v2 *tool)
2324 {
2325     struct xwl_seat *xwl_seat = data;
2326     struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
2327     struct xwl_tablet_tool *xwl_tablet_tool;
2328 
2329     xwl_tablet_tool = calloc(sizeof *xwl_tablet_tool, 1);
2330     if (xwl_tablet_tool == NULL) {
2331         ErrorF("%s ENOMEM\n", __func__);
2332         return;
2333     }
2334 
2335     xwl_tablet_tool->tool = tool;
2336     xwl_tablet_tool->seat = xwl_seat;
2337     xwl_cursor_init(&xwl_tablet_tool->cursor, xwl_screen,
2338                     xwl_tablet_tool_update_cursor);
2339 
2340     xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools);
2341 
2342     zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, xwl_tablet_tool);
2343 }
2344 
2345 static void
tablet_seat_handle_add_pad(void * data,struct zwp_tablet_seat_v2 * tablet_seat,struct zwp_tablet_pad_v2 * pad)2346 tablet_seat_handle_add_pad(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
2347                            struct zwp_tablet_pad_v2 *pad)
2348 {
2349     struct xwl_seat *xwl_seat = data;
2350     struct xwl_tablet_pad *xwl_tablet_pad;
2351 
2352     xwl_tablet_pad = calloc(sizeof *xwl_tablet_pad, 1);
2353     if (xwl_tablet_pad == NULL) {
2354         ErrorF("%s ENOMEM\n", __func__);
2355         return;
2356     }
2357 
2358     xwl_tablet_pad->pad = pad;
2359     xwl_tablet_pad->seat = xwl_seat;
2360     xorg_list_init(&xwl_tablet_pad->pad_group_list);
2361 
2362     xorg_list_add(&xwl_tablet_pad->link, &xwl_seat->tablet_pads);
2363 
2364     zwp_tablet_pad_v2_add_listener(pad, &tablet_pad_listener,
2365                                    xwl_tablet_pad);
2366 }
2367 
2368 static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
2369     tablet_seat_handle_add_tablet,
2370     tablet_seat_handle_add_tool,
2371     tablet_seat_handle_add_pad
2372 };
2373 
2374 static void
init_tablet_manager_seat(struct xwl_screen * xwl_screen,struct xwl_seat * xwl_seat)2375 init_tablet_manager_seat(struct xwl_screen *xwl_screen,
2376                          struct xwl_seat *xwl_seat)
2377 {
2378     xorg_list_init(&xwl_seat->tablets);
2379     xorg_list_init(&xwl_seat->tablet_tools);
2380     xorg_list_init(&xwl_seat->tablet_pads);
2381 
2382     if (!xwl_screen->tablet_manager)
2383         return;
2384 
2385     xwl_seat->tablet_seat =
2386         zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager,
2387                                               xwl_seat->seat);
2388 
2389     zwp_tablet_seat_v2_add_listener(xwl_seat->tablet_seat, &tablet_seat_listener, xwl_seat);
2390 }
2391 
2392 static void
release_tablet_manager_seat(struct xwl_seat * xwl_seat)2393 release_tablet_manager_seat(struct xwl_seat *xwl_seat)
2394 {
2395     struct xwl_tablet *xwl_tablet, *next_xwl_tablet;
2396     struct xwl_tablet_tool *xwl_tablet_tool, *next_xwl_tablet_tool;
2397     struct xwl_tablet_pad *xwl_tablet_pad, *next_xwl_tablet_pad;
2398 
2399     xorg_list_for_each_entry_safe(xwl_tablet_pad, next_xwl_tablet_pad,
2400                                   &xwl_seat->tablet_pads, link) {
2401         xorg_list_del(&xwl_tablet_pad->link);
2402         zwp_tablet_pad_v2_destroy(xwl_tablet_pad->pad);
2403         free(xwl_tablet_pad);
2404     }
2405 
2406     xorg_list_for_each_entry_safe(xwl_tablet_tool, next_xwl_tablet_tool,
2407                                   &xwl_seat->tablet_tools, link) {
2408         xorg_list_del(&xwl_tablet_tool->link);
2409         zwp_tablet_tool_v2_destroy(xwl_tablet_tool->tool);
2410         free(xwl_tablet_tool);
2411     }
2412 
2413     xorg_list_for_each_entry_safe(xwl_tablet, next_xwl_tablet,
2414                                   &xwl_seat->tablets, link) {
2415         xorg_list_del(&xwl_tablet->link);
2416         zwp_tablet_v2_destroy(xwl_tablet->tablet);
2417         free(xwl_tablet);
2418     }
2419 
2420     if (xwl_seat->tablet_seat) {
2421         zwp_tablet_seat_v2_destroy(xwl_seat->tablet_seat);
2422         xwl_seat->tablet_seat = NULL;
2423     }
2424 }
2425 
2426 static void
init_tablet_manager(struct xwl_screen * xwl_screen,uint32_t id,uint32_t version)2427 init_tablet_manager(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version)
2428 {
2429     struct xwl_seat *xwl_seat;
2430 
2431     xwl_screen->tablet_manager = wl_registry_bind(xwl_screen->registry,
2432                                                   id,
2433                                                   &zwp_tablet_manager_v2_interface,
2434                                                   min(version,1));
2435 
2436     xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
2437         init_tablet_manager_seat(xwl_screen, xwl_seat);
2438     }
2439 }
2440 
2441 void
xwl_screen_release_tablet_manager(struct xwl_screen * xwl_screen)2442 xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen)
2443 {
2444     if (xwl_screen->tablet_manager) {
2445         zwp_tablet_manager_v2_destroy(xwl_screen->tablet_manager);
2446         xwl_screen->tablet_manager = NULL;
2447     }
2448 }
2449 
2450 static void
init_relative_pointer_manager(struct xwl_screen * xwl_screen,uint32_t id,uint32_t version)2451 init_relative_pointer_manager(struct xwl_screen *xwl_screen,
2452                               uint32_t id, uint32_t version)
2453 {
2454     xwl_screen->relative_pointer_manager =
2455         wl_registry_bind(xwl_screen->registry, id,
2456                          &zwp_relative_pointer_manager_v1_interface,
2457                          1);
2458 }
2459 
2460 static void
init_pointer_constraints(struct xwl_screen * xwl_screen,uint32_t id,uint32_t version)2461 init_pointer_constraints(struct xwl_screen *xwl_screen,
2462                          uint32_t id, uint32_t version)
2463 {
2464     xwl_screen->pointer_constraints =
2465         wl_registry_bind(xwl_screen->registry, id,
2466                          &zwp_pointer_constraints_v1_interface,
2467                          1);
2468 }
2469 
2470 static void
init_keyboard_grab(struct xwl_screen * xwl_screen,uint32_t id,uint32_t version)2471 init_keyboard_grab(struct xwl_screen *xwl_screen,
2472                    uint32_t id, uint32_t version)
2473 {
2474     struct xwl_seat *xwl_seat;
2475     DeviceIntPtr master;
2476 
2477     xwl_screen->wp_grab =
2478          wl_registry_bind(xwl_screen->registry, id,
2479                           &zwp_xwayland_keyboard_grab_manager_v1_interface,
2480                           1);
2481 
2482     xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
2483         if (xwl_seat->keyboard) {
2484             master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
2485             if (master)
2486                 setup_keyboard_grab_handler(master);
2487         }
2488     }
2489 }
2490 
2491 static void
input_handler(void * data,struct wl_registry * registry,uint32_t id,const char * interface,uint32_t version)2492 input_handler(void *data, struct wl_registry *registry, uint32_t id,
2493               const char *interface, uint32_t version)
2494 {
2495     struct xwl_screen *xwl_screen = data;
2496 
2497     if (strcmp(interface, "wl_seat") == 0 && version >= 3) {
2498         create_input_device(xwl_screen, id, version);
2499         xwl_screen->expecting_event++;
2500     } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
2501         init_relative_pointer_manager(xwl_screen, id, version);
2502     } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
2503         init_pointer_constraints(xwl_screen, id, version);
2504     } else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) {
2505         init_tablet_manager(xwl_screen, id, version);
2506     } else if (strcmp(interface, "zwp_xwayland_keyboard_grab_manager_v1") == 0) {
2507         init_keyboard_grab(xwl_screen, id, version);
2508     }
2509 }
2510 
2511 static void
global_remove(void * data,struct wl_registry * registry,uint32_t name)2512 global_remove(void *data, struct wl_registry *registry, uint32_t name)
2513 {
2514 }
2515 
2516 static const struct wl_registry_listener input_listener = {
2517     input_handler,
2518     global_remove,
2519 };
2520 
2521 Bool
LegalModifier(unsigned int key,DeviceIntPtr pDev)2522 LegalModifier(unsigned int key, DeviceIntPtr pDev)
2523 {
2524     return TRUE;
2525 }
2526 
2527 void
ProcessInputEvents(void)2528 ProcessInputEvents(void)
2529 {
2530     mieqProcessInputEvents();
2531 }
2532 
2533 void
DDXRingBell(int volume,int pitch,int duration)2534 DDXRingBell(int volume, int pitch, int duration)
2535 {
2536 }
2537 
2538 static Bool
sprite_check_lost_focus(SpritePtr sprite,WindowPtr window)2539 sprite_check_lost_focus(SpritePtr sprite, WindowPtr window)
2540 {
2541     DeviceIntPtr device, master;
2542     struct xwl_seat *xwl_seat;
2543 
2544     for (device = inputInfo.devices; device; device = device->next) {
2545         /* Ignore non-wayland devices */
2546         if (device->deviceProc == xwl_pointer_proc &&
2547             device->spriteInfo->sprite == sprite)
2548             break;
2549     }
2550 
2551     if (!device)
2552         return FALSE;
2553 
2554     xwl_seat = device->public.devicePrivate;
2555     if (!xwl_seat)
2556         return FALSE;
2557 
2558     master = GetMaster(device, POINTER_OR_FLOAT);
2559     if (!master || !master->lastSlave)
2560         return FALSE;
2561 
2562     /* We do want the last active slave, we only check on slave xwayland
2563      * devices so we can find out the xwl_seat, but those don't actually own
2564      * their sprite, so the match doesn't mean a lot.
2565      */
2566     if (master->lastSlave == xwl_seat->pointer &&
2567         xwl_seat->focus_window == NULL &&
2568         xwl_seat->last_xwindow != NullWindow &&
2569         IsParent(xwl_seat->last_xwindow, window))
2570         return TRUE;
2571 
2572     return FALSE;
2573 }
2574 
2575 static WindowPtr
xwl_xy_to_window(ScreenPtr screen,SpritePtr sprite,int x,int y)2576 xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y)
2577 {
2578     struct xwl_screen *xwl_screen;
2579     WindowPtr ret;
2580 
2581     xwl_screen = xwl_screen_get(screen);
2582 
2583     screen->XYToWindow = xwl_screen->XYToWindow;
2584     ret = screen->XYToWindow(screen, sprite, x, y);
2585     xwl_screen->XYToWindow = screen->XYToWindow;
2586     screen->XYToWindow = xwl_xy_to_window;
2587 
2588     /* If the device controlling the sprite has left the Wayland surface but
2589      * the DIX still finds the pointer within the X11 window, it means that
2590      * the pointer has crossed to another native Wayland window, in this
2591      * case, pretend we entered the root window so that a LeaveNotify
2592      * event is emitted.
2593      */
2594     if (sprite_check_lost_focus(sprite, ret)) {
2595         sprite->spriteTraceGood = 1;
2596         return sprite->spriteTrace[0];
2597     }
2598 
2599     return ret;
2600 }
2601 
2602 void
xwl_seat_clear_touch(struct xwl_seat * xwl_seat,WindowPtr window)2603 xwl_seat_clear_touch(struct xwl_seat *xwl_seat, WindowPtr window)
2604 {
2605     struct xwl_touch *xwl_touch, *next_xwl_touch;
2606 
2607     xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
2608                                   &xwl_seat->touches, link_touch) {
2609         if (xwl_touch->window->window == window) {
2610             xorg_list_del(&xwl_touch->link_touch);
2611             free(xwl_touch);
2612         }
2613     }
2614 }
2615 
2616 static void
xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator * warp_emulator,int x,int y)2617 xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_emulator,
2618                                        int x,
2619                                        int y)
2620 {
2621     struct zwp_locked_pointer_v1 *locked_pointer =
2622         warp_emulator->locked_pointer;
2623     WindowPtr window;
2624     int sx, sy;
2625 
2626     if (!warp_emulator->locked_pointer)
2627         return;
2628 
2629     if (!warp_emulator->xwl_seat->focus_window)
2630         return;
2631 
2632     window = warp_emulator->xwl_seat->focus_window->window;
2633     if (x >= window->drawable.x ||
2634         y >= window->drawable.y ||
2635         x < (window->drawable.x + window->drawable.width) ||
2636         y < (window->drawable.y + window->drawable.height)) {
2637         sx = x - window->drawable.x;
2638         sy = y - window->drawable.y;
2639         zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer,
2640                                                        wl_fixed_from_int(sx),
2641                                                        wl_fixed_from_int(sy));
2642         wl_surface_commit(warp_emulator->xwl_seat->focus_window->surface);
2643     }
2644 }
2645 
2646 static Bool
xwl_pointer_warp_emulator_is_locked(struct xwl_pointer_warp_emulator * warp_emulator)2647 xwl_pointer_warp_emulator_is_locked(struct xwl_pointer_warp_emulator *warp_emulator)
2648 {
2649     if (warp_emulator->locked_pointer)
2650         return TRUE;
2651     else
2652         return FALSE;
2653 }
2654 
2655 static void
xwl_pointer_warp_emulator_lock(struct xwl_pointer_warp_emulator * warp_emulator)2656 xwl_pointer_warp_emulator_lock(struct xwl_pointer_warp_emulator *warp_emulator)
2657 {
2658     struct xwl_seat *xwl_seat = warp_emulator->xwl_seat;
2659     struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
2660     struct zwp_pointer_constraints_v1 *pointer_constraints =
2661         xwl_screen->pointer_constraints;
2662     struct xwl_window *lock_window = xwl_seat->focus_window;
2663 
2664     warp_emulator->locked_window = lock_window;
2665 
2666     warp_emulator->locked_pointer =
2667         zwp_pointer_constraints_v1_lock_pointer(pointer_constraints,
2668                                                 lock_window->surface,
2669                                                 xwl_seat->wl_pointer,
2670                                                 NULL,
2671                                                 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
2672 }
2673 
2674 static void
xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator * warp_emulator,struct xwl_window * xwl_window,SpritePtr sprite,int x,int y)2675 xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator *warp_emulator,
2676                                      struct xwl_window *xwl_window,
2677                                      SpritePtr sprite,
2678                                      int x, int y)
2679 {
2680     struct xwl_seat *xwl_seat = warp_emulator->xwl_seat;
2681     GrabPtr pointer_grab = xwl_seat->pointer->deviceGrab.grab;
2682 
2683     if (warp_emulator->locked_pointer)
2684         return;
2685 
2686     /*
2687      * If there is no grab, and the window doesn't have pointer focus, ignore
2688      * the warp, as under Wayland it won't receive input anyway.
2689      */
2690     if (!pointer_grab && xwl_seat->focus_window != xwl_window)
2691         return;
2692 
2693     /*
2694      * If there is a grab, but it's not an ownerEvents grab and the destination
2695      * is not the pointer focus, ignore it, as events wouldn't be delivered
2696      * there anyway.
2697      */
2698     if (pointer_grab &&
2699         !pointer_grab->ownerEvents &&
2700         sprite &&
2701         XYToWindow(sprite, x, y) != xwl_seat->focus_window->window)
2702         return;
2703 
2704     xwl_pointer_warp_emulator_lock(warp_emulator);
2705 }
2706 
2707 static void
xwl_pointer_warp_emulator_warp(struct xwl_pointer_warp_emulator * warp_emulator,struct xwl_window * xwl_window,SpritePtr sprite,int x,int y)2708 xwl_pointer_warp_emulator_warp(struct xwl_pointer_warp_emulator *warp_emulator,
2709                                struct xwl_window *xwl_window,
2710                                SpritePtr sprite,
2711                                int x, int y)
2712 {
2713     xwl_pointer_warp_emulator_maybe_lock(warp_emulator,
2714                                          xwl_window,
2715                                          sprite,
2716                                          x, y);
2717     xwl_pointer_warp_emulator_set_fake_pos(warp_emulator, x, y);
2718 }
2719 
2720 static void
xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator * warp_emulator,double dx,double dy,double dx_unaccel,double dy_unaccel)2721 xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator *warp_emulator,
2722                                         double dx,
2723                                         double dy,
2724                                         double dx_unaccel,
2725                                         double dy_unaccel)
2726 {
2727     struct xwl_seat *xwl_seat = warp_emulator->xwl_seat;
2728     ValuatorMask mask;
2729     WindowPtr window;
2730     int x, y;
2731 
2732     valuator_mask_zero(&mask);
2733     valuator_mask_set_unaccelerated(&mask, 0, dx, dx_unaccel);
2734     valuator_mask_set_unaccelerated(&mask, 1, dy, dy_unaccel);
2735 
2736     QueuePointerEvents(xwl_seat->relative_pointer, MotionNotify, 0,
2737                        POINTER_RELATIVE, &mask);
2738 
2739     window = xwl_seat->focus_window->window;
2740     miPointerGetPosition(xwl_seat->pointer, &x, &y);
2741 
2742     if (xwl_pointer_warp_emulator_is_locked(warp_emulator) &&
2743         xwl_seat->cursor_confinement_window != warp_emulator->locked_window &&
2744         (x < window->drawable.x ||
2745          y < window->drawable.y ||
2746          x >= (window->drawable.x + window->drawable.width) ||
2747          y >= (window->drawable.y + window->drawable.height)))
2748         xwl_seat_destroy_pointer_warp_emulator(xwl_seat);
2749     else
2750         xwl_pointer_warp_emulator_set_fake_pos(warp_emulator, x, y);
2751 }
2752 
2753 static struct xwl_pointer_warp_emulator *
xwl_pointer_warp_emulator_create(struct xwl_seat * xwl_seat)2754 xwl_pointer_warp_emulator_create(struct xwl_seat *xwl_seat)
2755 {
2756     struct xwl_pointer_warp_emulator *warp_emulator;
2757 
2758     warp_emulator = calloc(1, sizeof *warp_emulator);
2759     if (!warp_emulator) {
2760         ErrorF("%s: ENOMEM\n", __func__);
2761         return NULL;
2762     }
2763 
2764     warp_emulator->xwl_seat = xwl_seat;
2765 
2766     return warp_emulator;
2767 }
2768 
2769 static void
xwl_pointer_warp_emulator_destroy(struct xwl_pointer_warp_emulator * warp_emulator)2770 xwl_pointer_warp_emulator_destroy(struct xwl_pointer_warp_emulator *warp_emulator)
2771 {
2772     if (warp_emulator->locked_pointer)
2773         zwp_locked_pointer_v1_destroy(warp_emulator->locked_pointer);
2774     free(warp_emulator);
2775 }
2776 
2777 static void
xwl_seat_create_pointer_warp_emulator(struct xwl_seat * xwl_seat)2778 xwl_seat_create_pointer_warp_emulator(struct xwl_seat *xwl_seat)
2779 {
2780     if (xwl_seat->confined_pointer)
2781         xwl_seat_destroy_confined_pointer(xwl_seat);
2782 
2783     xwl_seat->pointer_warp_emulator =
2784         xwl_pointer_warp_emulator_create(xwl_seat);
2785 }
2786 
2787 static Bool
xwl_seat_can_emulate_pointer_warp(struct xwl_seat * xwl_seat)2788 xwl_seat_can_emulate_pointer_warp(struct xwl_seat *xwl_seat)
2789 {
2790     struct xwl_screen *xwl_screen;
2791 
2792     if (!xwl_seat)
2793         return FALSE;
2794 
2795     if (!xwl_seat->pointer)
2796         return FALSE;
2797 
2798     xwl_screen = xwl_seat->xwl_screen;
2799 
2800     if (!xwl_screen->relative_pointer_manager)
2801         return FALSE;
2802 
2803     if (!xwl_screen->pointer_constraints)
2804         return FALSE;
2805 
2806     return TRUE;
2807 }
2808 
2809 void
xwl_seat_emulate_pointer_warp(struct xwl_seat * xwl_seat,struct xwl_window * xwl_window,SpritePtr sprite,int x,int y)2810 xwl_seat_emulate_pointer_warp(struct xwl_seat *xwl_seat,
2811                               struct xwl_window *xwl_window,
2812                               SpritePtr sprite,
2813                               int x, int y)
2814 {
2815     if (!xwl_seat_can_emulate_pointer_warp(xwl_seat))
2816         return;
2817 
2818     if (xwl_seat->x_cursor != NULL)
2819         return;
2820 
2821     if (!xwl_seat->pointer_warp_emulator)
2822         xwl_seat_create_pointer_warp_emulator(xwl_seat);
2823 
2824     if (!xwl_seat->pointer_warp_emulator)
2825         return;
2826 
2827     xwl_pointer_warp_emulator_warp(xwl_seat->pointer_warp_emulator,
2828                                    xwl_window,
2829                                    sprite,
2830                                    x, y);
2831 }
2832 
2833 static Bool
xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat * xwl_seat)2834 xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat *xwl_seat)
2835 {
2836     /* Some clients use hidden cursor+confineTo+relative motion
2837      * to implement infinite panning (eg. 3D views), lock the
2838      * pointer for so the relative pointer is used.
2839      */
2840     if (xwl_seat->x_cursor ||
2841         !xwl_seat->cursor_confinement_window)
2842         return FALSE;
2843 
2844     if (!xwl_seat->focus_window)
2845         return FALSE;
2846 
2847     if (xwl_seat->confined_pointer)
2848         xwl_seat_destroy_confined_pointer(xwl_seat);
2849 
2850     xwl_seat_create_pointer_warp_emulator(xwl_seat);
2851     xwl_pointer_warp_emulator_lock(xwl_seat->pointer_warp_emulator);
2852     return TRUE;
2853 }
2854 
2855 void
xwl_seat_cursor_visibility_changed(struct xwl_seat * xwl_seat)2856 xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat)
2857 {
2858     if (xwl_seat->pointer_warp_emulator && xwl_seat->x_cursor != NULL) {
2859         xwl_seat_destroy_pointer_warp_emulator(xwl_seat);
2860     } else if (!xwl_seat->x_cursor && xwl_seat->cursor_confinement_window) {
2861         /* If the cursor goes hidden as is confined, lock it for
2862          * relative motion to work. */
2863         xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat);
2864     }
2865 }
2866 
2867 void
xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat * xwl_seat)2868 xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat *xwl_seat)
2869 {
2870     if (!xwl_seat->pointer_warp_emulator)
2871         return;
2872 
2873     xwl_pointer_warp_emulator_destroy(xwl_seat->pointer_warp_emulator);
2874     xwl_seat->pointer_warp_emulator = NULL;
2875 
2876     if (xwl_seat->cursor_confinement_window) {
2877         xwl_seat_confine_pointer(xwl_seat,
2878                                  xwl_seat->cursor_confinement_window);
2879     }
2880 }
2881 
2882 void
xwl_seat_confine_pointer(struct xwl_seat * xwl_seat,struct xwl_window * xwl_window)2883 xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
2884                          struct xwl_window *xwl_window)
2885 {
2886     struct zwp_pointer_constraints_v1 *pointer_constraints =
2887         xwl_seat->xwl_screen->pointer_constraints;
2888 
2889     if (!pointer_constraints)
2890         return;
2891 
2892     if (!xwl_seat->wl_pointer)
2893         return;
2894 
2895     if (xwl_seat->cursor_confinement_window == xwl_window &&
2896         xwl_seat->confined_pointer)
2897         return;
2898 
2899     xwl_seat_unconfine_pointer(xwl_seat);
2900 
2901     xwl_seat->cursor_confinement_window = xwl_window;
2902 
2903     if (xwl_seat->pointer_warp_emulator)
2904         return;
2905 
2906     if (xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat))
2907         return;
2908 
2909     xwl_seat->confined_pointer =
2910         zwp_pointer_constraints_v1_confine_pointer(pointer_constraints,
2911                                                    xwl_window->surface,
2912                                                    xwl_seat->wl_pointer,
2913                                                    NULL,
2914                                                    ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
2915 }
2916 
2917 static void
xwl_seat_destroy_confined_pointer(struct xwl_seat * xwl_seat)2918 xwl_seat_destroy_confined_pointer(struct xwl_seat *xwl_seat)
2919 {
2920     zwp_confined_pointer_v1_destroy(xwl_seat->confined_pointer);
2921     xwl_seat->confined_pointer = NULL;
2922 }
2923 
2924 void
xwl_seat_unconfine_pointer(struct xwl_seat * xwl_seat)2925 xwl_seat_unconfine_pointer(struct xwl_seat *xwl_seat)
2926 {
2927     xwl_seat->cursor_confinement_window = NULL;
2928 
2929     if (xwl_seat->confined_pointer)
2930         xwl_seat_destroy_confined_pointer(xwl_seat);
2931 }
2932 
2933 void
InitInput(int argc,char * argv[])2934 InitInput(int argc, char *argv[])
2935 {
2936     ScreenPtr pScreen = screenInfo.screens[0];
2937     struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
2938 
2939     if (!dixRegisterPrivateKey(&xwl_tablet_private_key, PRIVATE_DEVICE, 0)) {
2940         ErrorF("Failed to register private key\n");
2941         return;
2942     }
2943 
2944     mieqInit();
2945 
2946     xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
2947     wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
2948                              xwl_screen);
2949 
2950     xwl_screen->XYToWindow = pScreen->XYToWindow;
2951     pScreen->XYToWindow = xwl_xy_to_window;
2952 
2953     xwl_screen_roundtrip(xwl_screen);
2954 }
2955 
2956 void
CloseInput(void)2957 CloseInput(void)
2958 {
2959     mieqFini();
2960 }
2961