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