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