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