2 * Copyright © 2014 Intel Corporation
3 * Copyright © 2008 Kristian Høgsberg
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
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
27 #include <xwayland-config.h>
29 #include <linux/input.h>
32 #include "dix/dix_priv.h"
33 #include "dix/exevents_priv.h"
34 #include "dix/input_priv.h"
35 #include "mi/mi_priv.h"
36 #include "mi/mipointer_priv.h"
40 #include <xserver-properties.h>
41 #include <inpututils.h>
42 #include <mipointer.h>
43 #include <mipointrst.h>
46 #include "xwayland-cursor.h"
47 #include "xwayland-input.h"
48 #include "xwayland-window.h"
49 #include "xwayland-screen.h"
52 #include "xwayland-xtest.h"
55 #include "pointer-constraints-unstable-v1-client-protocol.h"
56 #include "relative-pointer-unstable-v1-client-protocol.h"
57 #include "tablet-unstable-v2-client-protocol.h"
58 #include "pointer-gestures-unstable-v1-client-protocol.h"
59 #include "xwayland-keyboard-grab-unstable-v1-client-protocol.h"
60 #include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
61 #include "xdg-system-bell-v1-client-protocol.h"
63 #define SCROLL_AXIS_HORIZ 2
64 #define SCROLL_AXIS_VERT 3
68 DeviceIntPtr pending_dev
;
71 static DevPrivateKeyRec xwl_tablet_private_key
;
74 xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator
*warp_emulator
,
80 xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator
*warp_emulator
,
81 struct xwl_window
*xwl_window
,
86 xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat
*xwl_seat
);
89 xwl_seat_destroy_confined_pointer(struct xwl_seat
*xwl_seat
);
92 init_tablet_manager_seat(struct xwl_screen
*xwl_screen
,
93 struct xwl_seat
*xwl_seat
);
95 release_tablet_manager_seat(struct xwl_seat
*xwl_seat
);
98 xwl_pointer_control(DeviceIntPtr device
, PtrCtrl
*ctrl
)
100 /* Nothing to do, dix handles all settings */
104 get_pointer_device(struct xwl_seat
*xwl_seat
)
106 if (xwl_seat
->relative_pointer
)
107 return xwl_seat
->relative_pointer
;
109 return xwl_seat
->pointer
;
113 init_pointer_buttons(DeviceIntPtr device
)
116 BYTE map
[NBUTTONS
+ 1];
118 Atom btn_labels
[NBUTTONS
] = { 0 };
120 for (i
= 1; i
<= NBUTTONS
; i
++)
123 btn_labels
[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT
);
124 btn_labels
[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE
);
125 btn_labels
[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT
);
126 btn_labels
[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP
);
127 btn_labels
[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN
);
128 btn_labels
[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT
);
129 btn_labels
[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT
);
130 /* don't know about the rest */
132 if (!InitButtonClassDeviceStruct(device
, NBUTTONS
, btn_labels
, map
))
139 maybe_fake_grab_devices(struct xwl_seat
*xwl_seat
)
141 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
142 struct xwl_window
*xwl_window
;
144 if (xwl_screen
->rootless
)
147 if (!xwl_screen
->host_grab
)
150 if (!xwl_screen
->has_grab
)
153 if (!xwl_screen
->screen
->root
)
156 xwl_window
= xwl_window_get(xwl_screen
->screen
->root
);
160 xwl_seat_confine_pointer(xwl_seat
, xwl_window
);
162 if (!xwl_screen
->shortcuts_inhibit_manager
)
165 if (xwl_screen
->shortcuts_inhibit
)
168 xwl_screen
->shortcuts_inhibit
=
169 zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts (
170 xwl_screen
->shortcuts_inhibit_manager
,
176 maybe_fake_ungrab_devices(struct xwl_seat
*xwl_seat
)
178 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
180 xwl_seat_unconfine_pointer(xwl_seat
);
182 if (!xwl_screen
->shortcuts_inhibit
)
185 zwp_keyboard_shortcuts_inhibitor_v1_destroy (xwl_screen
->shortcuts_inhibit
);
186 xwl_screen
->shortcuts_inhibit
= NULL
;
190 xwl_pointer_proc(DeviceIntPtr device
, int what
)
193 Atom axes_labels
[NAXES
] = { 0 };
197 device
->public.on
= FALSE
;
199 if (!init_pointer_buttons(device
))
202 axes_labels
[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X
);
203 axes_labels
[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y
);
204 axes_labels
[SCROLL_AXIS_HORIZ
] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL
);
205 axes_labels
[SCROLL_AXIS_VERT
] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL
);
207 if (!InitValuatorClassDeviceStruct(device
, NAXES
, axes_labels
,
208 GetMotionHistorySize(), Absolute
))
212 InitValuatorAxisStruct(device
, 0, axes_labels
[0],
213 0, 0xFFFF, 10000, 0, 10000, Absolute
);
214 InitValuatorAxisStruct(device
, 1, axes_labels
[1],
215 0, 0xFFFF, 10000, 0, 10000, Absolute
);
216 InitValuatorAxisStruct(device
, SCROLL_AXIS_HORIZ
, axes_labels
[2],
217 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
218 InitValuatorAxisStruct(device
, SCROLL_AXIS_VERT
, axes_labels
[3],
219 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
221 SetScrollValuator(device
, SCROLL_AXIS_HORIZ
, SCROLL_TYPE_HORIZONTAL
, 1.0, SCROLL_FLAG_NONE
);
222 SetScrollValuator(device
, SCROLL_AXIS_VERT
, SCROLL_TYPE_VERTICAL
, 1.0, SCROLL_FLAG_PREFERRED
);
224 if (!InitPtrFeedbackClassDeviceStruct(device
, xwl_pointer_control
))
230 device
->public.on
= TRUE
;
235 device
->public.on
= FALSE
;
246 xwl_pointer_proc_relative(DeviceIntPtr device
, int what
)
249 Atom axes_labels
[NAXES
] = { 0 };
253 device
->public.on
= FALSE
;
255 axes_labels
[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X
);
256 axes_labels
[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y
);
257 axes_labels
[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL
);
258 axes_labels
[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL
);
261 * We'll never send buttons, but XGetPointerMapping might in certain
262 * situations make the client think we have no buttons.
264 if (!init_pointer_buttons(device
))
267 if (!InitValuatorClassDeviceStruct(device
, NAXES
, axes_labels
,
268 GetMotionHistorySize(), Relative
))
272 InitValuatorAxisStruct(device
, 0, axes_labels
[0],
273 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
274 InitValuatorAxisStruct(device
, 1, axes_labels
[1],
275 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
276 InitValuatorAxisStruct(device
, 2, axes_labels
[2],
277 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
278 InitValuatorAxisStruct(device
, 3, axes_labels
[3],
279 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
281 SetScrollValuator(device
, 2, SCROLL_TYPE_HORIZONTAL
, 1.0, SCROLL_FLAG_NONE
);
282 SetScrollValuator(device
, 3, SCROLL_TYPE_VERTICAL
, 1.0, SCROLL_FLAG_PREFERRED
);
284 if (!InitPtrFeedbackClassDeviceStruct(device
, xwl_pointer_control
))
290 device
->public.on
= TRUE
;
295 device
->public.on
= FALSE
;
305 xwl_pointer_proc_pointer_gestures(DeviceIntPtr device
, int what
)
307 #define NTOUCHPOINTS 20
309 Atom axes_labels
[NAXES
] = { 0 };
313 device
->public.on
= FALSE
;
315 /* We need to setup a pointer device so that the device is attached to
316 master pointer device.
318 axes_labels
[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X
);
319 axes_labels
[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y
);
322 * We'll never send buttons, but XGetPointerMapping might in certain
323 * situations make the client think we have no buttons.
325 if (!init_pointer_buttons(device
))
328 if (!InitValuatorClassDeviceStruct(device
, NAXES
, axes_labels
,
329 GetMotionHistorySize(), Relative
))
332 InitValuatorAxisStruct(device
, 0, axes_labels
[0],
333 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
334 InitValuatorAxisStruct(device
, 1, axes_labels
[1],
335 NO_AXIS_LIMITS
, NO_AXIS_LIMITS
, 0, 0, 0, Relative
);
337 InitGestureClassDeviceStruct(device
, NTOUCHPOINTS
);
341 device
->public.on
= TRUE
;
346 device
->public.on
= FALSE
;
357 xwl_keyboard_control(DeviceIntPtr device
, KeybdCtrl
*ctrl
)
362 xwl_keyboard_proc(DeviceIntPtr device
, int what
)
364 struct xwl_seat
*xwl_seat
= device
->public.devicePrivate
;
369 device
->public.on
= FALSE
;
370 if (xwl_seat
->keymap
)
371 len
= strnlen(xwl_seat
->keymap
, xwl_seat
->keymap_size
);
374 if (!InitKeyboardDeviceStructFromString(device
, xwl_seat
->keymap
,
376 NULL
, xwl_keyboard_control
))
381 device
->public.on
= TRUE
;
386 device
->public.on
= FALSE
;
394 xwl_touch_proc(DeviceIntPtr device
, int what
)
396 #define NTOUCHPOINTS 20
399 Atom btn_labels
[NBUTTONS
] = { 0 };
400 Atom axes_labels
[NAXES
] = { 0 };
401 BYTE map
[NBUTTONS
+ 1] = { 0 };
405 device
->public.on
= FALSE
;
407 axes_labels
[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X
);
408 axes_labels
[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y
);
410 if (!InitValuatorClassDeviceStruct(device
, NAXES
, axes_labels
,
411 GetMotionHistorySize(), Absolute
))
414 if (!InitButtonClassDeviceStruct(device
, NBUTTONS
, btn_labels
, map
))
417 if (!InitTouchClassDeviceStruct(device
, NTOUCHPOINTS
,
418 XIDirectTouch
, NAXES
))
422 InitValuatorAxisStruct(device
, 0, axes_labels
[0],
423 0, 0xFFFF, 10000, 0, 10000, Absolute
);
424 InitValuatorAxisStruct(device
, 1, axes_labels
[1],
425 0, 0xFFFF, 10000, 0, 10000, Absolute
);
427 if (!InitPtrFeedbackClassDeviceStruct(device
, xwl_pointer_control
))
433 device
->public.on
= TRUE
;
438 device
->public.on
= FALSE
;
449 xwl_tablet_proc(DeviceIntPtr device
, int what
)
453 Atom btn_labels
[NBUTTONS
] = { 0 };
454 Atom axes_labels
[NAXES
] = { 0 };
455 BYTE map
[NBUTTONS
+ 1] = { 0 };
460 device
->public.on
= FALSE
;
462 for (i
= 1; i
<= NBUTTONS
; i
++)
465 axes_labels
[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X
);
466 axes_labels
[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y
);
467 axes_labels
[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE
);
468 axes_labels
[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X
);
469 axes_labels
[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y
);
470 axes_labels
[5] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL
);
472 if (!InitValuatorClassDeviceStruct(device
, NAXES
, axes_labels
,
473 GetMotionHistorySize(), Absolute
))
476 /* Valuators - match the xf86-input-wacom ranges */
477 InitValuatorAxisStruct(device
, 0, axes_labels
[0],
478 0, 262143, 10000, 0, 10000, Absolute
);
479 InitValuatorAxisStruct(device
, 1, axes_labels
[1],
480 0, 262143, 10000, 0, 10000, Absolute
);
482 InitValuatorAxisStruct(device
, 2, axes_labels
[2],
483 0, 65535, 1, 0, 1, Absolute
);
485 InitValuatorAxisStruct(device
, 3, axes_labels
[3],
486 -64, 63, 57, 0, 57, Absolute
);
488 InitValuatorAxisStruct(device
, 4, axes_labels
[4],
489 -64, 63, 57, 0, 57, Absolute
);
490 /* abs wheel (airbrush) or rotation (artpen) */
491 InitValuatorAxisStruct(device
, 5, axes_labels
[5],
492 -900, 899, 1, 0, 1, Absolute
);
494 if (!InitPtrFeedbackClassDeviceStruct(device
, xwl_pointer_control
))
497 if (!InitButtonClassDeviceStruct(device
, NBUTTONS
, btn_labels
, map
))
503 device
->public.on
= TRUE
;
508 device
->public.on
= FALSE
;
518 pointer_handle_enter(void *data
, struct wl_pointer
*pointer
,
519 uint32_t serial
, struct wl_surface
*surface
,
520 wl_fixed_t sx_w
, wl_fixed_t sy_w
)
522 struct xwl_seat
*xwl_seat
= data
;
523 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
524 DeviceIntPtr dev
= get_pointer_device(xwl_seat
);
529 ScreenPtr pScreen
= xwl_screen
->screen
;
532 /* There's a race here where if we create and then immediately
533 * destroy a surface, we might end up in a state where the Wayland
534 * compositor sends us an event for a surface that doesn't exist.
536 * Don't process enter events in this case.
541 if (!is_surface_from_xwl_window(surface
))
544 sx
= wl_fixed_to_int(sx_w
) * xwl_screen
->global_surface_scale
;
545 sy
= wl_fixed_to_int(sy_w
) * xwl_screen
->global_surface_scale
;
547 xwl_seat
->xwl_screen
->serial
= serial
;
548 xwl_seat
->pointer_enter_serial
= serial
;
550 xwl_seat
->focus_window
= wl_surface_get_user_data(surface
);
551 dx
= xwl_seat
->focus_window
->toplevel
->drawable
.x
;
552 dy
= xwl_seat
->focus_window
->toplevel
->drawable
.y
;
554 /* We just entered a new xwindow, forget about the old last xwindow */
555 xwl_seat
->last_focus_window
= NULL
;
557 master
= GetMaster(dev
, POINTER_OR_FLOAT
);
558 (*pScreen
->SetCursorPosition
) (dev
, pScreen
, dx
+ sx
, dy
+ sy
, TRUE
);
560 miPointerInvalidateSprite(master
);
562 CheckMotion(NULL
, master
);
564 /* Ideally, X clients shouldn't see these button releases. When
565 * the pointer leaves a window with buttons down, it means that
566 * the wayland compositor has grabbed the pointer. The button
567 * release event is consumed by whatever grab in the compositor
568 * and won't be sent to clients (the X server is a client).
569 * However, we need to reset X's idea of which buttons are up and
570 * down, and they're all up (by definition) when the pointer
571 * enters a window. We should figure out a way to swallow these
572 * events, perhaps using an X grab whenever the pointer is not in
573 * any X window, but for now just send the events. */
574 valuator_mask_zero(&mask
);
575 for (i
= 0; i
< dev
->button
->numButtons
; i
++)
576 if (BitIsOn(dev
->button
->down
, i
))
577 QueuePointerEvents(dev
, ButtonRelease
, i
, 0, &mask
);
579 /* The last cursor frame we committed before the pointer left one
580 * of our surfaces might not have been shown. In that case we'll
581 * have a cursor surface frame callback pending which we need to
582 * clear so that we can continue submitting new cursor frames. */
583 if (xwl_cursor_clear_frame_cb(&xwl_seat
->cursor
))
584 xwl_seat_set_cursor(xwl_seat
);
586 if (xwl_seat
->pointer_warp_emulator
) {
587 xwl_pointer_warp_emulator_maybe_lock(xwl_seat
->pointer_warp_emulator
,
588 xwl_seat
->focus_window
,
592 xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat
);
595 maybe_fake_grab_devices(xwl_seat
);
599 xwl_seat_leave_ptr(struct xwl_seat
*xwl_seat
, Bool focus_lost
)
601 DeviceIntPtr dev
= get_pointer_device(xwl_seat
);
607 CheckMotion(NULL
, GetMaster(dev
, POINTER_OR_FLOAT
));
609 maybe_fake_ungrab_devices(xwl_seat
);
613 pointer_handle_leave(void *data
, struct wl_pointer
*pointer
,
614 uint32_t serial
, struct wl_surface
*surface
)
616 struct xwl_seat
*xwl_seat
= data
;
617 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
618 Bool focus_lost
= FALSE
;
620 xwl_screen
->serial
= serial
;
622 /* The pointer has left a known xwindow, save it for a possible match
623 * in sprite_check_lost_focus()
625 if (xwl_seat
->focus_window
) {
626 xwl_seat
->last_focus_window
= xwl_seat
->focus_window
;
627 xwl_seat
->focus_window
= NULL
;
631 if (xwl_screen
->rootless
)
632 xwl_seat_leave_ptr(xwl_seat
, focus_lost
);
636 dispatch_relative_motion_with_warp(struct xwl_seat
*xwl_seat
)
638 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
639 double dx
, dx_unaccel
;
640 double dy
, dy_unaccel
;
642 dx
= xwl_seat
->pending_pointer_event
.dx
;
643 dy
= xwl_seat
->pending_pointer_event
.dy
;
644 dx_unaccel
= xwl_seat
->pending_pointer_event
.dx_unaccel
;
645 dy_unaccel
= xwl_seat
->pending_pointer_event
.dy_unaccel
;
647 dx
*= xwl_screen
->global_surface_scale
;
648 dy
*= xwl_screen
->global_surface_scale
;
649 dx_unaccel
*= xwl_screen
->global_surface_scale
;
650 dy_unaccel
*= xwl_screen
->global_surface_scale
;
652 dx
*= xwl_seat
->focus_window
->viewport_scale_x
;
653 dy
*= xwl_seat
->focus_window
->viewport_scale_y
;
654 dx_unaccel
*= xwl_seat
->focus_window
->viewport_scale_x
;
655 dy_unaccel
*= xwl_seat
->focus_window
->viewport_scale_y
;
657 xwl_pointer_warp_emulator_handle_motion(xwl_seat
->pointer_warp_emulator
,
659 dx_unaccel
, dy_unaccel
);
663 dispatch_absolute_motion(struct xwl_seat
*xwl_seat
)
665 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
669 int event_x
= wl_fixed_to_int(xwl_seat
->pending_pointer_event
.x
);
670 int event_y
= wl_fixed_to_int(xwl_seat
->pending_pointer_event
.y
);
671 int drawable_x
= xwl_seat
->focus_window
->toplevel
->drawable
.x
;
672 int drawable_y
= xwl_seat
->focus_window
->toplevel
->drawable
.y
;
676 event_x
*= xwl_screen
->global_surface_scale
;
677 event_y
*= xwl_screen
->global_surface_scale
;
679 event_x
*= xwl_seat
->focus_window
->viewport_scale_x
;
680 event_y
*= xwl_seat
->focus_window
->viewport_scale_y
;
682 x
= drawable_x
+ event_x
;
683 y
= drawable_y
+ event_y
;
685 valuator_mask_zero(&mask
);
686 valuator_mask_set(&mask
, 0, x
);
687 valuator_mask_set(&mask
, 1, y
);
689 if (xwl_seat
->pending_pointer_event
.has_relative
) {
690 flags
= POINTER_ABSOLUTE
| POINTER_SCREEN
| POINTER_NORAW
;
691 device
= xwl_seat
->relative_pointer
;
693 flags
= POINTER_ABSOLUTE
| POINTER_SCREEN
;
694 device
= xwl_seat
->pointer
;
697 QueuePointerEvents(device
, MotionNotify
, 0, flags
, &mask
);
701 dispatch_relative_motion(struct xwl_seat
*xwl_seat
)
703 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
705 double event_dx
= xwl_seat
->pending_pointer_event
.dx
;
706 double event_dy
= xwl_seat
->pending_pointer_event
.dy
;
707 double event_dx_unaccel
= xwl_seat
->pending_pointer_event
.dx_unaccel
;
708 double event_dy_unaccel
= xwl_seat
->pending_pointer_event
.dy_unaccel
;
710 event_dx
*= xwl_screen
->global_surface_scale
;
711 event_dy
*= xwl_screen
->global_surface_scale
;
712 event_dx_unaccel
*= xwl_screen
->global_surface_scale
;
713 event_dy_unaccel
*= xwl_screen
->global_surface_scale
;
715 event_dx
*= xwl_seat
->focus_window
->viewport_scale_x
;
716 event_dy
*= xwl_seat
->focus_window
->viewport_scale_y
;
717 event_dx_unaccel
*= xwl_seat
->focus_window
->viewport_scale_x
;
718 event_dy_unaccel
*= xwl_seat
->focus_window
->viewport_scale_y
;
720 valuator_mask_zero(&mask
);
721 valuator_mask_set_unaccelerated(&mask
, 0, event_dx
, event_dx_unaccel
);
722 valuator_mask_set_unaccelerated(&mask
, 1, event_dy
, event_dy_unaccel
);
724 QueuePointerEvents(xwl_seat
->relative_pointer
, MotionNotify
, 0,
725 POINTER_RAWONLY
, &mask
);
729 dispatch_scroll_motion(struct xwl_seat
*xwl_seat
)
732 const int divisor
= 10;
733 wl_fixed_t dy
= xwl_seat
->pending_pointer_event
.scroll_dy
;
734 wl_fixed_t dx
= xwl_seat
->pending_pointer_event
.scroll_dx
;
735 int32_t dy_v120
= xwl_seat
->pending_pointer_event
.scroll_dy_v120
;
736 int32_t dx_v120
= xwl_seat
->pending_pointer_event
.scroll_dx_v120
;
738 valuator_mask_zero(&mask
);
739 if (xwl_seat
->pending_pointer_event
.has_vertical_scroll_v120
)
740 valuator_mask_set_double(&mask
, SCROLL_AXIS_VERT
, dy_v120
/ 120.0);
741 else if (xwl_seat
->pending_pointer_event
.has_vertical_scroll
)
742 valuator_mask_set_double(&mask
,
744 wl_fixed_to_double(dy
) / divisor
);
746 if (xwl_seat
->pending_pointer_event
.has_horizontal_scroll_v120
)
747 valuator_mask_set_double(&mask
, SCROLL_AXIS_HORIZ
, dx_v120
/ 120.0);
748 else if (xwl_seat
->pending_pointer_event
.has_horizontal_scroll
)
749 valuator_mask_set_double(&mask
,
751 wl_fixed_to_double(dx
) / divisor
);
753 QueuePointerEvents(get_pointer_device(xwl_seat
),
754 MotionNotify
, 0, POINTER_RELATIVE
, &mask
);
759 dispatch_pointer_motion_event(struct xwl_seat
*xwl_seat
)
761 Bool has_relative
= xwl_seat
->pending_pointer_event
.has_relative
;
762 Bool has_absolute
= xwl_seat
->pending_pointer_event
.has_absolute
;
764 if (xwl_seat
->pointer_warp_emulator
&& has_relative
) {
765 dispatch_relative_motion_with_warp(xwl_seat
);
768 dispatch_relative_motion(xwl_seat
);
771 dispatch_absolute_motion(xwl_seat
);
774 if (xwl_seat
->pending_pointer_event
.has_vertical_scroll
||
775 xwl_seat
->pending_pointer_event
.has_horizontal_scroll
||
776 xwl_seat
->pending_pointer_event
.has_vertical_scroll_v120
||
777 xwl_seat
->pending_pointer_event
.has_horizontal_scroll_v120
)
778 dispatch_scroll_motion(xwl_seat
);
780 xwl_seat
->pending_pointer_event
.has_absolute
= FALSE
;
781 xwl_seat
->pending_pointer_event
.has_relative
= FALSE
;
782 xwl_seat
->pending_pointer_event
.has_vertical_scroll
= FALSE
;
783 xwl_seat
->pending_pointer_event
.has_horizontal_scroll
= FALSE
;
784 xwl_seat
->pending_pointer_event
.has_vertical_scroll_v120
= FALSE
;
785 xwl_seat
->pending_pointer_event
.has_horizontal_scroll_v120
= FALSE
;
789 pointer_handle_motion(void *data
, struct wl_pointer
*pointer
,
790 uint32_t time
, wl_fixed_t sx_w
, wl_fixed_t sy_w
)
792 struct xwl_seat
*xwl_seat
= data
;
794 if (!xwl_seat
->focus_window
)
797 xwl_seat
->pending_pointer_event
.has_absolute
= TRUE
;
798 xwl_seat
->pending_pointer_event
.x
= sx_w
;
799 xwl_seat
->pending_pointer_event
.y
= sy_w
;
801 if (wl_proxy_get_version((struct wl_proxy
*) xwl_seat
->wl_pointer
) < 5)
802 dispatch_pointer_motion_event(xwl_seat
);
806 pointer_handle_button(void *data
, struct wl_pointer
*pointer
, uint32_t serial
,
807 uint32_t time
, uint32_t button
, uint32_t state
)
809 struct xwl_seat
*xwl_seat
= data
;
813 xwl_seat
->xwl_screen
->serial
= serial
;
826 /* Skip indexes 4-7: they are used for vertical and horizontal scroll.
827 The rest of the buttons go in order: BTN_SIDE becomes 8, etc. */
828 index
= 8 + button
- BTN_SIDE
;
832 valuator_mask_zero(&mask
);
833 QueuePointerEvents(get_pointer_device(xwl_seat
),
834 state
? ButtonPress
: ButtonRelease
, index
, 0, &mask
);
838 pointer_handle_axis(void *data
, struct wl_pointer
*pointer
,
839 uint32_t time
, uint32_t axis
, wl_fixed_t value
)
841 struct xwl_seat
*xwl_seat
= data
;
844 case WL_POINTER_AXIS_VERTICAL_SCROLL
:
845 xwl_seat
->pending_pointer_event
.has_vertical_scroll
= TRUE
;
846 xwl_seat
->pending_pointer_event
.scroll_dy
= value
;
848 case WL_POINTER_AXIS_HORIZONTAL_SCROLL
:
849 xwl_seat
->pending_pointer_event
.has_horizontal_scroll
= TRUE
;
850 xwl_seat
->pending_pointer_event
.scroll_dx
= value
;
856 pointer_handle_frame(void *data
, struct wl_pointer
*wl_pointer
)
858 struct xwl_seat
*xwl_seat
= data
;
860 if (!xwl_seat
->focus_window
)
863 dispatch_pointer_motion_event(xwl_seat
);
867 pointer_handle_axis_source(void *data
, struct wl_pointer
*wl_pointer
, uint32_t axis_source
)
872 pointer_handle_axis_stop(void *data
, struct wl_pointer
*wl_pointer
,
873 uint32_t time
, uint32_t axis
)
875 struct xwl_seat
*xwl_seat
= data
;
878 case WL_POINTER_AXIS_VERTICAL_SCROLL
:
879 xwl_seat
->pending_pointer_event
.has_vertical_scroll
= TRUE
;
880 xwl_seat
->pending_pointer_event
.scroll_dy
= 0;
882 case WL_POINTER_AXIS_HORIZONTAL_SCROLL
:
883 xwl_seat
->pending_pointer_event
.has_horizontal_scroll
= TRUE
;
884 xwl_seat
->pending_pointer_event
.scroll_dx
= 0;
890 pointer_handle_axis_discrete(void *data
, struct wl_pointer
*wl_pointer
,
891 uint32_t axis
, int32_t discrete
)
893 struct xwl_seat
*xwl_seat
= data
;
896 case WL_POINTER_AXIS_VERTICAL_SCROLL
:
897 xwl_seat
->pending_pointer_event
.has_vertical_scroll_v120
= TRUE
;
898 xwl_seat
->pending_pointer_event
.scroll_dy_v120
= 120 * discrete
;
900 case WL_POINTER_AXIS_HORIZONTAL_SCROLL
:
901 xwl_seat
->pending_pointer_event
.has_horizontal_scroll_v120
= TRUE
;
902 xwl_seat
->pending_pointer_event
.scroll_dx_v120
= 120 * discrete
;
908 pointer_handle_axis_v120(void *data
, struct wl_pointer
*pointer
,
909 uint32_t axis
, int32_t v120
)
911 struct xwl_seat
*xwl_seat
= data
;
914 case WL_POINTER_AXIS_VERTICAL_SCROLL
:
915 xwl_seat
->pending_pointer_event
.has_vertical_scroll_v120
= TRUE
;
916 xwl_seat
->pending_pointer_event
.scroll_dy_v120
= v120
;
918 case WL_POINTER_AXIS_HORIZONTAL_SCROLL
:
919 xwl_seat
->pending_pointer_event
.has_horizontal_scroll_v120
= TRUE
;
920 xwl_seat
->pending_pointer_event
.scroll_dx_v120
= v120
;
925 static const struct wl_pointer_listener pointer_listener
= {
926 pointer_handle_enter
,
927 pointer_handle_leave
,
928 pointer_handle_motion
,
929 pointer_handle_button
,
931 pointer_handle_frame
,
932 pointer_handle_axis_source
,
933 pointer_handle_axis_stop
,
934 pointer_handle_axis_discrete
,
935 pointer_handle_axis_v120
,
939 relative_pointer_handle_relative_motion(void *data
,
940 struct zwp_relative_pointer_v1
*zwp_relative_pointer_v1
,
945 wl_fixed_t dx_unaccelf
,
946 wl_fixed_t dy_unaccelf
)
948 struct xwl_seat
*xwl_seat
= data
;
950 xwl_seat
->pending_pointer_event
.has_relative
= TRUE
;
951 xwl_seat
->pending_pointer_event
.dx
= wl_fixed_to_double(dxf
);
952 xwl_seat
->pending_pointer_event
.dy
= wl_fixed_to_double(dyf
);
953 xwl_seat
->pending_pointer_event
.dx_unaccel
= wl_fixed_to_double(dx_unaccelf
);
954 xwl_seat
->pending_pointer_event
.dy_unaccel
= wl_fixed_to_double(dy_unaccelf
);
956 if (!xwl_seat
->focus_window
)
959 if (wl_proxy_get_version((struct wl_proxy
*) xwl_seat
->wl_pointer
) < 5)
960 dispatch_pointer_motion_event(xwl_seat
);
963 static const struct zwp_relative_pointer_v1_listener relative_pointer_listener
= {
964 relative_pointer_handle_relative_motion
,
968 pointer_gesture_swipe_handle_begin(void *data
,
969 struct zwp_pointer_gesture_swipe_v1
*swipe
,
972 struct wl_surface
*surface
,
975 struct xwl_seat
*xwl_seat
= data
;
977 if (surface
!= NULL
&& !is_surface_from_xwl_window(surface
))
980 xwl_seat
->pointer_gesture_swipe_fingers
= fingers
;
981 QueueGestureSwipeEvents(xwl_seat
->pointer_gestures
,
982 XI_GestureSwipeBegin
, fingers
, 0, 0.0, 0.0, 0.0, 0.0);
986 pointer_gesture_swipe_handle_update(void *data
,
987 struct zwp_pointer_gesture_swipe_v1
*swipe
,
992 struct xwl_seat
*xwl_seat
= data
;
993 double dx
= wl_fixed_to_double(dxf
);
994 double dy
= wl_fixed_to_double(dyf
);
996 QueueGestureSwipeEvents(xwl_seat
->pointer_gestures
,
997 XI_GestureSwipeUpdate
,
998 xwl_seat
->pointer_gesture_swipe_fingers
,
1005 pointer_gesture_swipe_handle_end(void *data
,
1006 struct zwp_pointer_gesture_swipe_v1
*swipe
,
1011 struct xwl_seat
*xwl_seat
= data
;
1015 flags
|= XIGestureSwipeEventCancelled
;
1017 QueueGestureSwipeEvents(xwl_seat
->pointer_gestures
,
1019 xwl_seat
->pointer_gesture_swipe_fingers
,
1020 flags
, 0.0, 0.0, 0.0, 0.0);
1023 static const struct zwp_pointer_gesture_swipe_v1_listener pointer_gesture_swipe_listener
= {
1024 pointer_gesture_swipe_handle_begin
,
1025 pointer_gesture_swipe_handle_update
,
1026 pointer_gesture_swipe_handle_end
1030 pointer_gesture_pinch_handle_begin(void *data
,
1031 struct zwp_pointer_gesture_pinch_v1
*pinch
,
1034 struct wl_surface
*surface
,
1037 struct xwl_seat
*xwl_seat
= data
;
1039 if (surface
!= NULL
&& !is_surface_from_xwl_window(surface
))
1042 xwl_seat
->pointer_gesture_pinch_fingers
= fingers
;
1043 xwl_seat
->pointer_gesture_pinch_last_scale
= 1.0;
1044 QueueGesturePinchEvents(xwl_seat
->pointer_gestures
,
1045 XI_GesturePinchBegin
, fingers
, 0, 0.0, 0.0, 0.0, 0.0,
1050 pointer_gesture_pinch_handle_update(void *data
,
1051 struct zwp_pointer_gesture_pinch_v1
*pinch
,
1056 wl_fixed_t rotation
)
1058 struct xwl_seat
*xwl_seat
= data
;
1059 double dx
= wl_fixed_to_double(dxf
);
1060 double dy
= wl_fixed_to_double(dyf
);
1061 double scale
= wl_fixed_to_double(scalef
);
1063 xwl_seat
->pointer_gesture_pinch_last_scale
= scale
;
1064 QueueGesturePinchEvents(xwl_seat
->pointer_gestures
,
1065 XI_GesturePinchUpdate
,
1066 xwl_seat
->pointer_gesture_pinch_fingers
,
1070 scale
, wl_fixed_to_double(rotation
));
1074 pointer_gesture_pinch_handle_end(void *data
,
1075 struct zwp_pointer_gesture_pinch_v1
*pinch
,
1080 struct xwl_seat
*xwl_seat
= data
;
1084 flags
|= XIGesturePinchEventCancelled
;
1086 QueueGesturePinchEvents(xwl_seat
->pointer_gestures
,
1088 xwl_seat
->pointer_gesture_pinch_fingers
,
1089 flags
, 0.0, 0.0, 0.0, 0.0,
1090 xwl_seat
->pointer_gesture_pinch_last_scale
, 0.0);
1093 static const struct zwp_pointer_gesture_pinch_v1_listener pointer_gesture_pinch_listener
= {
1094 pointer_gesture_pinch_handle_begin
,
1095 pointer_gesture_pinch_handle_update
,
1096 pointer_gesture_pinch_handle_end
1100 maybe_toggle_fake_grab(struct xwl_seat
*xwl_seat
, uint32_t key
)
1102 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
1103 struct xwl_window
*xwl_window
;
1104 XkbStateRec state_rec
;
1107 if (xwl_screen
->rootless
)
1110 if (!xwl_screen
->host_grab
)
1113 state_rec
= xwl_seat
->keyboard
->key
->xkbInfo
->state
;
1114 xkb_state
= (XkbStateFieldFromRec(&state_rec
) & 0xff);
1116 if (((key
== KEY_LEFTSHIFT
|| key
== KEY_RIGHTSHIFT
) && (xkb_state
& ControlMask
)) ||
1117 ((key
== KEY_LEFTCTRL
|| key
== KEY_RIGHTCTRL
) && (xkb_state
& ShiftMask
))) {
1119 xwl_screen
->has_grab
= !xwl_screen
->has_grab
;
1121 if (xwl_screen
->has_grab
)
1122 maybe_fake_grab_devices(xwl_seat
);
1124 maybe_fake_ungrab_devices(xwl_seat
);
1126 xwl_window
= xwl_window_get(xwl_screen
->screen
->root
);
1128 xwl_window_rootful_update_title(xwl_window
);
1133 keyboard_handle_key(void *data
, struct wl_keyboard
*keyboard
, uint32_t serial
,
1134 uint32_t time
, uint32_t key
, uint32_t state
)
1136 struct xwl_seat
*xwl_seat
= data
;
1139 xwl_seat
->xwl_screen
->serial
= serial
;
1141 end
= (uint32_t *) ((char *) xwl_seat
->keys
.data
+ xwl_seat
->keys
.size
);
1142 for (k
= xwl_seat
->keys
.data
; k
< end
; k
++) {
1146 xwl_seat
->keys
.size
= (char *) end
- (char *) xwl_seat
->keys
.data
;
1148 k
= wl_array_add(&xwl_seat
->keys
, sizeof *k
);
1152 QueueKeyboardEvents(xwl_seat
->keyboard
,
1153 state
? KeyPress
: KeyRelease
, key
+ 8);
1156 maybe_toggle_fake_grab(xwl_seat
, key
);
1160 keyboard_handle_keymap(void *data
, struct wl_keyboard
*keyboard
,
1161 uint32_t format
, int fd
, uint32_t size
)
1163 struct xwl_seat
*xwl_seat
= data
;
1164 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
1165 DeviceIntPtr master
;
1167 XkbChangesRec changes
= { 0 };
1169 if (xwl_screen
->nokeymap
)
1172 if (xwl_seat
->keymap
)
1173 munmap(xwl_seat
->keymap
, xwl_seat
->keymap_size
);
1175 xwl_seat
->keymap_size
= size
;
1176 xwl_seat
->keymap
= mmap(NULL
, size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
1177 if (xwl_seat
->keymap
== MAP_FAILED
) {
1178 xwl_seat
->keymap_size
= 0;
1179 xwl_seat
->keymap
= NULL
;
1183 xkb
= XkbCompileKeymapFromString(xwl_seat
->keyboard
, xwl_seat
->keymap
,
1184 strnlen(xwl_seat
->keymap
,
1185 xwl_seat
->keymap_size
));
1189 XkbUpdateDescActions(xkb
, xkb
->min_key_code
, XkbNumKeys(xkb
), &changes
);
1192 xwl_seat
->keyboard
->kbdfeed
->ctrl
.autoRepeats
,
1193 xkb
->ctrls
->per_key_repeat
,
1194 XkbPerKeyBitArraySize
1196 if (xwl_seat
->keyboard
->key
) {
1197 /* Keep the current controls */
1198 XkbCopyControls(xkb
, xwl_seat
->keyboard
->key
->xkbInfo
->desc
);
1200 xkb
->ctrls
->per_key_repeat
,
1201 xwl_seat
->keyboard
->kbdfeed
->ctrl
.autoRepeats
,
1202 XkbPerKeyBitArraySize
1206 XkbDeviceApplyKeymap(xwl_seat
->keyboard
, xkb
);
1208 master
= GetMaster(xwl_seat
->keyboard
, MASTER_KEYBOARD
);
1210 XkbDeviceApplyKeymap(master
, xkb
);
1212 XkbFreeKeyboard(xkb
, XkbAllComponentsMask
, TRUE
);
1219 keyboard_handle_enter(void *data
, struct wl_keyboard
*keyboard
,
1221 struct wl_surface
*surface
, struct wl_array
*keys
)
1223 struct xwl_seat
*xwl_seat
= data
;
1226 if (surface
!= NULL
&& !is_surface_from_xwl_window(surface
))
1229 xwl_seat
->xwl_screen
->serial
= serial
;
1230 xwl_seat
->keyboard_focus
= surface
;
1232 /* If `leave` wasn't sent (for a destroyed surface), release keys here. */
1233 wl_array_for_each(k
, &xwl_seat
->keys
)
1234 QueueKeyboardEvents(xwl_seat
->keyboard
, LeaveNotify
, *k
+ 8);
1236 wl_array_copy(&xwl_seat
->keys
, keys
);
1237 wl_array_for_each(k
, &xwl_seat
->keys
)
1238 QueueKeyboardEvents(xwl_seat
->keyboard
, EnterNotify
, *k
+ 8);
1240 maybe_fake_grab_devices(xwl_seat
);
1244 xwl_seat_leave_kbd(struct xwl_seat
*xwl_seat
)
1248 wl_array_for_each(k
, &xwl_seat
->keys
)
1249 QueueKeyboardEvents(xwl_seat
->keyboard
, LeaveNotify
, *k
+ 8);
1250 xwl_seat
->keys
.size
= 0;
1252 xwl_seat
->keyboard_focus
= NULL
;
1254 maybe_fake_ungrab_devices(xwl_seat
);
1258 keyboard_handle_leave(void *data
, struct wl_keyboard
*keyboard
,
1259 uint32_t serial
, struct wl_surface
*surface
)
1261 struct xwl_seat
*xwl_seat
= data
;
1262 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
1264 xwl_screen
->serial
= serial
;
1266 if (xwl_screen
->rootless
)
1267 xwl_seat_leave_kbd(xwl_seat
);
1271 keyboard_handle_modifiers(void *data
, struct wl_keyboard
*keyboard
,
1272 uint32_t serial
, uint32_t mods_depressed
,
1273 uint32_t mods_latched
, uint32_t mods_locked
,
1276 struct xwl_seat
*xwl_seat
= data
;
1278 XkbStateRec old_state
, *new_state
;
1282 mieqProcessInputEvents();
1284 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
1285 if (dev
!= xwl_seat
->keyboard
&&
1286 dev
!= GetMaster(xwl_seat
->keyboard
, MASTER_KEYBOARD
))
1289 old_state
= dev
->key
->xkbInfo
->state
;
1290 new_state
= &dev
->key
->xkbInfo
->state
;
1292 new_state
->base_group
= 0;
1293 new_state
->latched_group
= 0;
1294 new_state
->locked_group
= group
& XkbAllGroupsMask
;
1295 new_state
->base_mods
= mods_depressed
& XkbAllModifiersMask
;
1296 new_state
->latched_mods
= mods_latched
& XkbAllModifiersMask
;
1297 new_state
->locked_mods
= mods_locked
& XkbAllModifiersMask
;
1299 XkbComputeDerivedState(dev
->key
->xkbInfo
);
1301 changed
= XkbStateChangedFlags(&old_state
, new_state
);
1307 sn
.requestMajor
= XkbReqCode
;
1308 sn
.requestMinor
= X_kbLatchLockState
; /* close enough */
1309 sn
.changed
= changed
;
1310 XkbSendStateNotify(dev
, &sn
);
1315 remove_sync_pending(DeviceIntPtr dev
)
1317 struct xwl_seat
*xwl_seat
= dev
->public.devicePrivate
;
1318 struct sync_pending
*p
, *npd
;
1323 xorg_list_for_each_entry_safe(p
, npd
, &xwl_seat
->sync_pending
, l
) {
1324 if (p
->pending_dev
== dev
) {
1325 xorg_list_del(&xwl_seat
->sync_pending
);
1333 sync_callback(void *data
, struct wl_callback
*callback
, uint32_t serial
)
1335 DeviceIntPtr dev
= (DeviceIntPtr
) data
;
1337 remove_sync_pending(dev
);
1338 wl_callback_destroy(callback
);
1341 static const struct wl_callback_listener sync_listener
= {
1346 keyboard_check_repeat (DeviceIntPtr dev
, XkbSrvInfoPtr xkbi
, unsigned key
)
1348 struct xwl_seat
*xwl_seat
= dev
->public.devicePrivate
;
1349 struct xwl_screen
*xwl_screen
;
1350 struct wl_callback
*callback
;
1351 struct sync_pending
*p
;
1356 /* Make sure we didn't miss a possible reply from the compositor */
1357 xwl_screen
= xwl_seat
->xwl_screen
;
1358 xwl_sync_events (xwl_screen
);
1360 xorg_list_for_each_entry(p
, &xwl_seat
->sync_pending
, l
) {
1361 if (p
->pending_dev
== dev
) {
1362 ErrorF("Key repeat discarded, Wayland compositor doesn't "
1363 "seem to be processing events fast enough!\n");
1369 p
= XNFalloc(sizeof(struct sync_pending
));
1370 p
->pending_dev
= dev
;
1371 callback
= wl_display_sync (xwl_screen
->display
);
1372 xorg_list_add(&p
->l
, &xwl_seat
->sync_pending
);
1374 wl_callback_add_listener(callback
, &sync_listener
, dev
);
1380 keyboard_handle_repeat_info (void *data
, struct wl_keyboard
*keyboard
,
1381 int32_t rate
, int32_t delay
)
1383 struct xwl_seat
*xwl_seat
= data
;
1385 XkbControlsPtr ctrl
;
1387 if (rate
< 0 || delay
< 0) {
1388 ErrorF("Wrong rate/delay: %d, %d\n", rate
, delay
);
1392 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
1393 if (dev
!= xwl_seat
->keyboard
&&
1394 dev
!= GetMaster(xwl_seat
->keyboard
, MASTER_KEYBOARD
))
1398 ctrl
= dev
->key
->xkbInfo
->desc
->ctrls
;
1399 ctrl
->repeat_delay
= delay
;
1400 /* rate is number of keys per second */
1401 ctrl
->repeat_interval
= 1000 / rate
;
1403 XkbSetRepeatKeys(dev
, -1, AutoRepeatModeOn
);
1405 XkbSetRepeatKeys(dev
, -1, AutoRepeatModeOff
);
1409 static const struct wl_keyboard_listener keyboard_listener
= {
1410 keyboard_handle_keymap
,
1411 keyboard_handle_enter
,
1412 keyboard_handle_leave
,
1413 keyboard_handle_key
,
1414 keyboard_handle_modifiers
,
1415 keyboard_handle_repeat_info
,
1418 static struct xwl_touch
*
1419 xwl_seat_lookup_touch(struct xwl_seat
*xwl_seat
, int32_t id
)
1421 struct xwl_touch
*xwl_touch
, *next_xwl_touch
;
1423 xorg_list_for_each_entry_safe(xwl_touch
, next_xwl_touch
,
1424 &xwl_seat
->touches
, link_touch
) {
1425 if (xwl_touch
->id
== id
)
1433 xwl_touch_send_event(struct xwl_touch
*xwl_touch
,
1434 struct xwl_seat
*xwl_seat
, int type
)
1436 double dx
, dy
, x
, y
;
1439 dx
= xwl_touch
->window
->toplevel
->drawable
.x
;
1440 dy
= xwl_touch
->window
->toplevel
->drawable
.y
;
1442 x
= (dx
+ xwl_touch
->x
) * 0xFFFF / xwl_screen_get_width(xwl_seat
->xwl_screen
);
1443 y
= (dy
+ xwl_touch
->y
) * 0xFFFF / xwl_screen_get_height(xwl_seat
->xwl_screen
);
1445 valuator_mask_zero(&mask
);
1446 valuator_mask_set_double(&mask
, 0, x
);
1447 valuator_mask_set_double(&mask
, 1, y
);
1448 QueueTouchEvents(xwl_seat
->touch
, type
, xwl_touch
->id
, 0, &mask
);
1452 touch_handle_down(void *data
, struct wl_touch
*wl_touch
,
1453 uint32_t serial
, uint32_t time
,
1454 struct wl_surface
*surface
,
1455 int32_t id
, wl_fixed_t sx_w
, wl_fixed_t sy_w
)
1457 struct xwl_seat
*xwl_seat
= data
;
1458 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
1459 struct xwl_touch
*xwl_touch
;
1461 if (surface
== NULL
)
1464 if (!is_surface_from_xwl_window(surface
))
1467 xwl_touch
= calloc(1, sizeof *xwl_touch
);
1468 if (xwl_touch
== NULL
) {
1469 ErrorF("%s: ENOMEM\n", __func__
);
1473 xwl_touch
->window
= wl_surface_get_user_data(surface
);
1475 xwl_touch
->x
= wl_fixed_to_int(sx_w
);
1476 xwl_touch
->y
= wl_fixed_to_int(sy_w
);
1477 xorg_list_add(&xwl_touch
->link_touch
, &xwl_seat
->touches
);
1479 xwl_touch
->x
*= xwl_screen
->global_surface_scale
;
1480 xwl_touch
->y
*= xwl_screen
->global_surface_scale
;
1482 xwl_touch
->x
*= xwl_touch
->window
->viewport_scale_x
;
1483 xwl_touch
->y
*= xwl_touch
->window
->viewport_scale_y
;
1485 xwl_touch_send_event(xwl_touch
, xwl_seat
, XI_TouchBegin
);
1489 touch_handle_up(void *data
, struct wl_touch
*wl_touch
,
1490 uint32_t serial
, uint32_t time
, int32_t id
)
1492 struct xwl_touch
*xwl_touch
;
1493 struct xwl_seat
*xwl_seat
= data
;
1495 xwl_touch
= xwl_seat_lookup_touch(xwl_seat
, id
);
1500 xwl_touch_send_event(xwl_touch
, xwl_seat
, XI_TouchEnd
);
1501 xorg_list_del(&xwl_touch
->link_touch
);
1506 touch_handle_motion(void *data
, struct wl_touch
*wl_touch
,
1507 uint32_t time
, int32_t id
,
1508 wl_fixed_t sx_w
, wl_fixed_t sy_w
)
1510 struct xwl_seat
*xwl_seat
= data
;
1511 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
1512 struct xwl_touch
*xwl_touch
;
1514 xwl_touch
= xwl_seat_lookup_touch(xwl_seat
, id
);
1519 xwl_touch
->x
= wl_fixed_to_int(sx_w
);
1520 xwl_touch
->y
= wl_fixed_to_int(sy_w
);
1522 xwl_touch
->x
*= xwl_screen
->global_surface_scale
;
1523 xwl_touch
->y
*= xwl_screen
->global_surface_scale
;
1525 xwl_touch
->x
*= xwl_touch
->window
->viewport_scale_x
;
1526 xwl_touch
->y
*= xwl_touch
->window
->viewport_scale_y
;
1528 xwl_touch_send_event(xwl_touch
, xwl_seat
, XI_TouchUpdate
);
1532 touch_handle_frame(void *data
, struct wl_touch
*wl_touch
)
1537 touch_handle_cancel(void *data
, struct wl_touch
*wl_touch
)
1539 struct xwl_seat
*xwl_seat
= data
;
1540 struct xwl_touch
*xwl_touch
, *next_xwl_touch
;
1542 xorg_list_for_each_entry_safe(xwl_touch
, next_xwl_touch
,
1543 &xwl_seat
->touches
, link_touch
) {
1544 /* We can't properly notify of cancellation to the X client
1545 * once it thinks it has the ownership, send at least a
1548 xwl_touch_send_event(xwl_touch
, xwl_seat
, XI_TouchEnd
);
1549 xorg_list_del(&xwl_touch
->link_touch
);
1554 static const struct wl_touch_listener touch_listener
= {
1557 touch_handle_motion
,
1562 static struct xwl_seat
*
1563 find_matching_seat(DeviceIntPtr device
)
1567 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
)
1568 if (dev
->deviceProc
== xwl_keyboard_proc
&&
1569 device
== GetMaster(dev
, MASTER_KEYBOARD
))
1570 return (struct xwl_seat
*) dev
->public.devicePrivate
;
1576 release_grab(struct xwl_seat
*xwl_seat
)
1578 if (xwl_seat
->keyboard_grab
)
1579 zwp_xwayland_keyboard_grab_v1_destroy(xwl_seat
->keyboard_grab
);
1580 xwl_seat
->keyboard_grab
= NULL
;
1584 set_grab(struct xwl_seat
*xwl_seat
, struct xwl_window
*xwl_window
)
1586 struct xwl_screen
*xwl_screen
;
1591 /* We already have a grab */
1592 if (xwl_seat
->keyboard_grab
)
1593 release_grab (xwl_seat
);
1595 xwl_screen
= xwl_seat
->xwl_screen
;
1596 xwl_seat
->keyboard_grab
=
1597 zwp_xwayland_keyboard_grab_manager_v1_grab_keyboard(xwl_screen
->wp_grab
,
1598 xwl_window
->surface
,
1603 find_toplevel_callback(void *resource
, XID id
, void *user_data
)
1605 WindowPtr window
= resource
;
1606 WindowPtr
*toplevel
= user_data
;
1608 /* Pick the first realized toplevel we find */
1609 if (*toplevel
== NullWindow
&& window
->realized
&& xwl_window_is_toplevel(window
))
1614 xwl_keyboard_search_window(ClientPtr client
)
1616 WindowPtr window
= NullWindow
;
1618 FindClientResourcesByType(client
, X11_RESTYPE_WINDOW
, find_toplevel_callback
, &window
);
1624 xwl_keyboard_activate_grab(DeviceIntPtr device
, GrabPtr grab
, TimeStamp time
, Bool passive
)
1626 struct xwl_seat
*xwl_seat
= device
->public.devicePrivate
;
1627 WindowPtr grab_window
= grab
->window
;
1629 /* We are not interested in passive grabs */
1631 /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
1632 if (xwl_seat
== NULL
)
1633 xwl_seat
= find_matching_seat(device
);
1635 if (grab_window
== xwl_seat
->xwl_screen
->screen
->root
)
1636 grab_window
= xwl_keyboard_search_window(GetCurrentClient());
1638 set_grab(xwl_seat
, xwl_window_from_window(grab_window
));
1642 ActivateKeyboardGrab(device
, grab
, time
, passive
);
1646 xwl_keyboard_deactivate_grab(DeviceIntPtr device
)
1648 struct xwl_seat
*xwl_seat
= device
->public.devicePrivate
;
1650 /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
1651 if (xwl_seat
== NULL
)
1652 xwl_seat
= find_matching_seat(device
);
1654 release_grab (xwl_seat
);
1656 DeactivateKeyboardGrab(device
);
1660 setup_keyboard_grab_handler (DeviceIntPtr device
)
1662 device
->deviceGrab
.ActivateGrab
= xwl_keyboard_activate_grab
;
1663 device
->deviceGrab
.DeactivateGrab
= xwl_keyboard_deactivate_grab
;
1667 add_device(struct xwl_seat
*xwl_seat
,
1668 const char *driver
, DeviceProc device_proc
)
1670 DeviceIntPtr dev
= NULL
;
1671 static Atom type_atom
;
1674 dev
= AddInputDevice(serverClient
, device_proc
, TRUE
);
1678 if (type_atom
== None
)
1679 type_atom
= MakeAtom(driver
, strlen(driver
), TRUE
);
1680 snprintf(name
, sizeof name
, "%s:%d", driver
, xwl_seat
->id
);
1681 AssignTypeAndName(dev
, type_atom
, name
);
1682 dev
->public.devicePrivate
= xwl_seat
;
1684 dev
->spriteInfo
->spriteOwner
= FALSE
;
1685 dev
->ignoreXkbActionsBehaviors
= TRUE
;
1691 disable_device(DeviceIntPtr dev
)
1693 DisableDevice(dev
, TRUE
);
1694 dev
->public.devicePrivate
= NULL
;
1698 enable_device(struct xwl_seat
*xwl_seat
, DeviceIntPtr dev
)
1700 dev
->public.devicePrivate
= xwl_seat
;
1701 EnableDevice(dev
, TRUE
);
1706 init_pointer(struct xwl_seat
*xwl_seat
)
1708 xwl_seat
->wl_pointer
= wl_seat_get_pointer(xwl_seat
->seat
);
1709 wl_pointer_add_listener(xwl_seat
->wl_pointer
,
1710 &pointer_listener
, xwl_seat
);
1712 if (xwl_seat
->pointer
== NULL
) {
1713 xwl_seat_set_cursor(xwl_seat
);
1715 add_device(xwl_seat
, "xwayland-pointer", xwl_pointer_proc
);
1716 ActivateDevice(xwl_seat
->pointer
, TRUE
);
1718 enable_device(xwl_seat
, xwl_seat
->pointer
);
1722 release_pointer(struct xwl_seat
*xwl_seat
)
1724 wl_pointer_release(xwl_seat
->wl_pointer
);
1725 xwl_seat
->wl_pointer
= NULL
;
1727 if (xwl_seat
->pointer
)
1728 disable_device(xwl_seat
->pointer
);
1732 init_relative_pointer(struct xwl_seat
*xwl_seat
)
1734 if (xwl_seat
->relative_pointer
== NULL
) {
1735 xwl_seat
->relative_pointer
=
1736 add_device(xwl_seat
, "xwayland-relative-pointer",
1737 xwl_pointer_proc_relative
);
1738 ActivateDevice(xwl_seat
->relative_pointer
, TRUE
);
1740 enable_device(xwl_seat
, xwl_seat
->relative_pointer
);
1744 init_relative_pointer_listener(struct xwl_seat
*xwl_seat
)
1746 struct zwp_relative_pointer_manager_v1
*relative_pointer_manager
=
1747 xwl_seat
->xwl_screen
->relative_pointer_manager
;
1749 if (relative_pointer_manager
) {
1750 xwl_seat
->wp_relative_pointer
=
1751 zwp_relative_pointer_manager_v1_get_relative_pointer(
1752 relative_pointer_manager
, xwl_seat
->wl_pointer
);
1753 zwp_relative_pointer_v1_add_listener(xwl_seat
->wp_relative_pointer
,
1754 &relative_pointer_listener
,
1760 release_relative_pointer(struct xwl_seat
*xwl_seat
)
1762 if (xwl_seat
->wp_relative_pointer
) {
1763 zwp_relative_pointer_v1_destroy(xwl_seat
->wp_relative_pointer
);
1764 xwl_seat
->wp_relative_pointer
= NULL
;
1767 if (xwl_seat
->relative_pointer
)
1768 disable_device(xwl_seat
->relative_pointer
);
1772 init_pointer_gestures_device(struct xwl_seat
*xwl_seat
)
1774 if (xwl_seat
->pointer_gestures
== NULL
) {
1775 xwl_seat
->pointer_gestures
=
1776 add_device(xwl_seat
, "xwayland-pointer-gestures",
1777 xwl_pointer_proc_pointer_gestures
);
1778 ActivateDevice(xwl_seat
->pointer_gestures
, TRUE
);
1780 enable_device(xwl_seat
, xwl_seat
->pointer_gestures
);
1784 init_pointer_gestures_listener(struct xwl_seat
*xwl_seat
)
1786 struct zwp_pointer_gestures_v1
*pointer_gestures
=
1787 xwl_seat
->xwl_screen
->pointer_gestures
;
1789 if (pointer_gestures
&& !xwl_seat
->wp_pointer_gesture_swipe
) {
1790 xwl_seat
->wp_pointer_gesture_swipe
=
1791 zwp_pointer_gestures_v1_get_swipe_gesture(pointer_gestures
,
1792 xwl_seat
->wl_pointer
);
1793 zwp_pointer_gesture_swipe_v1_set_user_data(xwl_seat
->wp_pointer_gesture_swipe
,
1795 zwp_pointer_gesture_swipe_v1_add_listener(xwl_seat
->wp_pointer_gesture_swipe
,
1796 &pointer_gesture_swipe_listener
,
1800 if (pointer_gestures
&& !xwl_seat
->wp_pointer_gesture_pinch
) {
1801 xwl_seat
->wp_pointer_gesture_pinch
=
1802 zwp_pointer_gestures_v1_get_pinch_gesture(pointer_gestures
,
1803 xwl_seat
->wl_pointer
);
1804 zwp_pointer_gesture_pinch_v1_set_user_data(xwl_seat
->wp_pointer_gesture_pinch
,
1806 zwp_pointer_gesture_pinch_v1_add_listener(xwl_seat
->wp_pointer_gesture_pinch
,
1807 &pointer_gesture_pinch_listener
,
1813 release_pointer_gestures_device(struct xwl_seat
*xwl_seat
)
1815 if (xwl_seat
->wp_pointer_gesture_swipe
) {
1816 zwp_pointer_gesture_swipe_v1_destroy(xwl_seat
->wp_pointer_gesture_swipe
);
1817 xwl_seat
->wp_pointer_gesture_swipe
= NULL
;
1820 if (xwl_seat
->wp_pointer_gesture_pinch
) {
1821 zwp_pointer_gesture_pinch_v1_destroy(xwl_seat
->wp_pointer_gesture_pinch
);
1822 xwl_seat
->wp_pointer_gesture_pinch
= NULL
;
1825 if (xwl_seat
->pointer_gestures
)
1826 disable_device(xwl_seat
->pointer_gestures
);
1830 init_keyboard(struct xwl_seat
*xwl_seat
)
1832 DeviceIntPtr master
;
1834 xwl_seat
->wl_keyboard
= wl_seat_get_keyboard(xwl_seat
->seat
);
1835 wl_keyboard_add_listener(xwl_seat
->wl_keyboard
,
1836 &keyboard_listener
, xwl_seat
);
1838 if (xwl_seat
->keyboard
== NULL
) {
1839 xwl_seat
->keyboard
=
1840 add_device(xwl_seat
, "xwayland-keyboard", xwl_keyboard_proc
);
1841 ActivateDevice(xwl_seat
->keyboard
, TRUE
);
1843 enable_device(xwl_seat
, xwl_seat
->keyboard
);
1844 xwl_seat
->keyboard
->key
->xkbInfo
->checkRepeat
= keyboard_check_repeat
;
1846 if (xwl_seat
->xwl_screen
->wp_grab
) {
1847 /* We have Xwayland grab protocol supported by the compositor */
1848 master
= GetMaster(xwl_seat
->keyboard
, MASTER_KEYBOARD
);
1850 setup_keyboard_grab_handler(master
);
1855 release_keyboard(struct xwl_seat
*xwl_seat
)
1857 release_grab(xwl_seat
);
1858 wl_keyboard_release(xwl_seat
->wl_keyboard
);
1859 xwl_seat
->wl_keyboard
= NULL
;
1861 if (xwl_seat
->keyboard
) {
1862 remove_sync_pending(xwl_seat
->keyboard
);
1863 disable_device(xwl_seat
->keyboard
);
1868 init_touch(struct xwl_seat
*xwl_seat
)
1870 xwl_seat
->wl_touch
= wl_seat_get_touch(xwl_seat
->seat
);
1871 wl_touch_add_listener(xwl_seat
->wl_touch
,
1872 &touch_listener
, xwl_seat
);
1874 if (xwl_seat
->touch
== NULL
) {
1876 add_device(xwl_seat
, "xwayland-touch", xwl_touch_proc
);
1877 ActivateDevice(xwl_seat
->touch
, TRUE
);
1879 enable_device(xwl_seat
, xwl_seat
->touch
);
1883 release_touch(struct xwl_seat
*xwl_seat
)
1885 wl_touch_release(xwl_seat
->wl_touch
);
1886 xwl_seat
->wl_touch
= NULL
;
1888 if (xwl_seat
->touch
)
1889 disable_device(xwl_seat
->touch
);
1893 seat_handle_capabilities(void *data
, struct wl_seat
*seat
,
1894 enum wl_seat_capability caps
)
1896 struct xwl_seat
*xwl_seat
= data
;
1898 if (caps
& WL_SEAT_CAPABILITY_POINTER
&& xwl_seat
->wl_pointer
== NULL
) {
1899 init_pointer(xwl_seat
);
1900 init_relative_pointer(xwl_seat
);
1901 init_relative_pointer_listener(xwl_seat
);
1902 init_pointer_gestures_device(xwl_seat
);
1903 init_pointer_gestures_listener(xwl_seat
);
1904 } else if (!(caps
& WL_SEAT_CAPABILITY_POINTER
) && xwl_seat
->wl_pointer
) {
1905 release_pointer(xwl_seat
);
1906 release_relative_pointer(xwl_seat
);
1907 release_pointer_gestures_device(xwl_seat
);
1910 if (caps
& WL_SEAT_CAPABILITY_KEYBOARD
&& xwl_seat
->wl_keyboard
== NULL
) {
1911 init_keyboard(xwl_seat
);
1912 } else if (!(caps
& WL_SEAT_CAPABILITY_KEYBOARD
) && xwl_seat
->wl_keyboard
) {
1913 release_keyboard(xwl_seat
);
1916 if (caps
& WL_SEAT_CAPABILITY_TOUCH
&& xwl_seat
->wl_touch
== NULL
) {
1917 init_touch(xwl_seat
);
1918 } else if (!(caps
& WL_SEAT_CAPABILITY_TOUCH
) && xwl_seat
->wl_touch
) {
1919 release_touch(xwl_seat
);
1922 xwl_seat
->xwl_screen
->expecting_event
--;
1926 seat_handle_name(void *data
, struct wl_seat
*seat
,
1932 static const struct wl_seat_listener seat_listener
= {
1933 seat_handle_capabilities
,
1938 xwl_cursor_init(struct xwl_cursor
*xwl_cursor
, struct xwl_screen
*xwl_screen
,
1939 void (* update_proc
)(struct xwl_cursor
*))
1941 xwl_cursor
->surface
= wl_compositor_create_surface(xwl_screen
->compositor
);
1942 xwl_cursor
->update_proc
= update_proc
;
1943 xwl_cursor
->frame_cb
= NULL
;
1944 xwl_cursor
->needs_update
= FALSE
;
1948 xwl_seat_update_cursor(struct xwl_cursor
*xwl_cursor
)
1950 struct xwl_seat
*xwl_seat
= wl_container_of(xwl_cursor
, xwl_seat
, cursor
);
1951 xwl_seat_set_cursor(xwl_seat
);
1955 create_input_device(struct xwl_screen
*xwl_screen
, uint32_t id
, uint32_t version
)
1957 struct xwl_seat
*xwl_seat
;
1958 int seat_version
= 8;
1960 xwl_seat
= calloc(1, sizeof *xwl_seat
);
1961 if (xwl_seat
== NULL
) {
1962 ErrorF("%s: ENOMEM\n", __func__
);
1966 xwl_seat
->xwl_screen
= xwl_screen
;
1967 xorg_list_add(&xwl_seat
->link
, &xwl_screen
->seat_list
);
1970 wl_registry_bind(xwl_screen
->registry
, id
,
1971 &wl_seat_interface
, min(version
, seat_version
));
1974 xwl_cursor_init(&xwl_seat
->cursor
, xwl_seat
->xwl_screen
,
1975 xwl_seat_update_cursor
);
1976 wl_seat_add_listener(xwl_seat
->seat
, &seat_listener
, xwl_seat
);
1978 init_tablet_manager_seat(xwl_screen
, xwl_seat
);
1980 wl_array_init(&xwl_seat
->keys
);
1982 xorg_list_init(&xwl_seat
->touches
);
1983 xorg_list_init(&xwl_seat
->sync_pending
);
1987 xwl_seat_destroy(struct xwl_seat
*xwl_seat
)
1989 struct xwl_touch
*xwl_touch
, *next_xwl_touch
;
1990 struct sync_pending
*p
, *npd
;
1992 xorg_list_for_each_entry_safe(xwl_touch
, next_xwl_touch
,
1993 &xwl_seat
->touches
, link_touch
) {
1994 xorg_list_del(&xwl_touch
->link_touch
);
1998 xorg_list_for_each_entry_safe(p
, npd
, &xwl_seat
->sync_pending
, l
) {
1999 xorg_list_del(&xwl_seat
->sync_pending
);
2003 release_tablet_manager_seat(xwl_seat
);
2005 release_grab(xwl_seat
);
2006 wl_seat_destroy(xwl_seat
->seat
);
2007 xwl_cursor_release(&xwl_seat
->cursor
);
2008 wl_array_release(&xwl_seat
->keys
);
2013 tablet_handle_name(void *data
, struct zwp_tablet_v2
*tablet
, const char *name
)
2018 tablet_handle_id(void *data
, struct zwp_tablet_v2
*tablet
, uint32_t vid
,
2024 tablet_handle_path(void *data
, struct zwp_tablet_v2
*tablet
, const char *path
)
2029 tablet_handle_done(void *data
, struct zwp_tablet_v2
*tablet
)
2031 struct xwl_tablet
*xwl_tablet
= data
;
2032 struct xwl_seat
*xwl_seat
= xwl_tablet
->seat
;
2034 if (xwl_seat
->stylus
== NULL
) {
2035 xwl_seat
->stylus
= add_device(xwl_seat
, "xwayland-tablet stylus", xwl_tablet_proc
);
2036 ActivateDevice(xwl_seat
->stylus
, TRUE
);
2038 enable_device(xwl_seat
, xwl_seat
->stylus
);
2040 if (xwl_seat
->eraser
== NULL
) {
2041 xwl_seat
->eraser
= add_device(xwl_seat
, "xwayland-tablet eraser", xwl_tablet_proc
);
2042 ActivateDevice(xwl_seat
->eraser
, TRUE
);
2044 enable_device(xwl_seat
, xwl_seat
->eraser
);
2046 if (xwl_seat
->puck
== NULL
) {
2047 xwl_seat
->puck
= add_device(xwl_seat
, "xwayland-tablet cursor", xwl_tablet_proc
);
2048 ActivateDevice(xwl_seat
->puck
, TRUE
);
2050 enable_device(xwl_seat
, xwl_seat
->puck
);
2054 tablet_handle_removed(void *data
, struct zwp_tablet_v2
*tablet
)
2056 struct xwl_tablet
*xwl_tablet
= data
;
2057 struct xwl_seat
*xwl_seat
= xwl_tablet
->seat
;
2059 xorg_list_del(&xwl_tablet
->link
);
2061 /* The tablet is merely disabled, not removed. The next tablet
2062 will re-use the same X devices */
2063 if (xorg_list_is_empty(&xwl_seat
->tablets
)) {
2064 if (xwl_seat
->stylus
)
2065 disable_device(xwl_seat
->stylus
);
2066 if (xwl_seat
->eraser
)
2067 disable_device(xwl_seat
->eraser
);
2069 disable_device(xwl_seat
->puck
);
2070 /* pads are removed separately */
2073 zwp_tablet_v2_destroy(tablet
);
2077 static const struct zwp_tablet_v2_listener tablet_listener
= {
2082 tablet_handle_removed
2086 tablet_tool_receive_type(void *data
, struct zwp_tablet_tool_v2
*tool
,
2089 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2090 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2093 case ZWP_TABLET_TOOL_V2_TYPE_ERASER
:
2094 xwl_tablet_tool
->xdevice
= xwl_seat
->eraser
;
2096 case ZWP_TABLET_TOOL_V2_TYPE_MOUSE
:
2097 case ZWP_TABLET_TOOL_V2_TYPE_LENS
:
2098 xwl_tablet_tool
->xdevice
= xwl_seat
->puck
;
2101 xwl_tablet_tool
->xdevice
= xwl_seat
->stylus
;
2107 tablet_tool_receive_hardware_serial(void *data
, struct zwp_tablet_tool_v2
*tool
,
2108 uint32_t hi
, uint32_t low
)
2113 tablet_tool_receive_hardware_id_wacom(void *data
, struct zwp_tablet_tool_v2
*tool
,
2114 uint32_t hi
, uint32_t low
)
2119 tablet_tool_receive_capability(void *data
, struct zwp_tablet_tool_v2
*tool
,
2120 uint32_t capability
)
2125 tablet_tool_receive_done(void *data
, struct zwp_tablet_tool_v2
*tool
)
2130 tablet_tool_receive_removed(void *data
, struct zwp_tablet_tool_v2
*tool
)
2132 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2134 xorg_list_del(&xwl_tablet_tool
->link
);
2135 xwl_cursor_release(&xwl_tablet_tool
->cursor
);
2136 zwp_tablet_tool_v2_destroy(tool
);
2137 free(xwl_tablet_tool
);
2141 tablet_tool_proximity_in(void *data
, struct zwp_tablet_tool_v2
*tool
,
2142 uint32_t serial
, struct zwp_tablet_v2
*tablet
,
2143 struct wl_surface
*wl_surface
)
2145 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2146 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2148 /* There's a race here where if we create and then immediately
2149 * destroy a surface, we might end up in a state where the Wayland
2150 * compositor sends us an event for a surface that doesn't exist.
2152 * Don't process enter events in this case.
2154 * see pointer_handle_enter()
2156 if (wl_surface
== NULL
)
2159 if (!is_surface_from_xwl_window(wl_surface
))
2162 xwl_tablet_tool
->proximity_in_serial
= serial
;
2163 xwl_seat
->tablet_focus_window
= wl_surface_get_user_data(wl_surface
);
2165 /* If there is a cursor surface frame callback pending, we need to clear it
2166 * so that we can continue submitting new cursor frames.
2168 xwl_cursor_clear_frame_cb(&xwl_tablet_tool
->cursor
);
2169 xwl_tablet_tool_set_cursor(xwl_tablet_tool
);
2173 tablet_tool_proximity_out(void *data
, struct zwp_tablet_tool_v2
*tool
)
2175 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2176 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2178 xwl_tablet_tool
->proximity_in_serial
= 0;
2179 xwl_seat
->tablet_focus_window
= NULL
;
2181 xwl_tablet_tool
->pressure
= 0;
2182 xwl_tablet_tool
->tilt_x
= 0;
2183 xwl_tablet_tool
->tilt_y
= 0;
2184 xwl_tablet_tool
->rotation
= 0;
2185 xwl_tablet_tool
->slider
= 0;
2189 tablet_tool_down(void *data
, struct zwp_tablet_tool_v2
*tool
, uint32_t serial
)
2191 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2192 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2195 xwl_seat
->xwl_screen
->serial
= serial
;
2197 valuator_mask_zero(&mask
);
2198 QueuePointerEvents(xwl_tablet_tool
->xdevice
, ButtonPress
, 1, 0, &mask
);
2202 tablet_tool_up(void *data
, struct zwp_tablet_tool_v2
*tool
)
2204 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2207 valuator_mask_zero(&mask
);
2208 QueuePointerEvents(xwl_tablet_tool
->xdevice
, ButtonRelease
, 1, 0, &mask
);
2212 tablet_tool_motion(void *data
, struct zwp_tablet_tool_v2
*tool
,
2213 wl_fixed_t x
, wl_fixed_t y
)
2215 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2216 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2217 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
2219 double sx
= wl_fixed_to_double(x
);
2220 double sy
= wl_fixed_to_double(y
);
2222 if (!xwl_seat
->tablet_focus_window
)
2225 sx
*= xwl_screen
->global_surface_scale
;
2226 sy
*= xwl_screen
->global_surface_scale
;
2228 sx
*= xwl_seat
->tablet_focus_window
->viewport_scale_x
;
2229 sy
*= xwl_seat
->tablet_focus_window
->viewport_scale_y
;
2231 dx
= xwl_seat
->tablet_focus_window
->toplevel
->drawable
.x
;
2232 dy
= xwl_seat
->tablet_focus_window
->toplevel
->drawable
.y
;
2234 xwl_tablet_tool
->x
= (double) dx
+ sx
;
2235 xwl_tablet_tool
->y
= (double) dy
+ sy
;
2239 tablet_tool_pressure(void *data
, struct zwp_tablet_tool_v2
*tool
,
2242 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2243 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2245 if (!xwl_seat
->tablet_focus_window
)
2248 /* normalized to 65535 already */
2249 xwl_tablet_tool
->pressure
= pressure
;
2253 tablet_tool_distance(void *data
, struct zwp_tablet_tool_v2
*tool
,
2254 uint32_t distance_raw
)
2259 tablet_tool_tilt(void *data
, struct zwp_tablet_tool_v2
*tool
,
2260 wl_fixed_t tilt_x
, wl_fixed_t tilt_y
)
2262 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2263 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2264 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
2266 if (!xwl_seat
->tablet_focus_window
)
2269 xwl_tablet_tool
->tilt_x
= wl_fixed_to_double(tilt_x
);
2270 xwl_tablet_tool
->tilt_y
= wl_fixed_to_double(tilt_y
);
2272 xwl_tablet_tool
->tilt_x
*= xwl_screen
->global_surface_scale
;
2273 xwl_tablet_tool
->tilt_y
*= xwl_screen
->global_surface_scale
;
2275 xwl_tablet_tool
->tilt_x
*= xwl_seat
->tablet_focus_window
->viewport_scale_x
;
2276 xwl_tablet_tool
->tilt_y
*= xwl_seat
->tablet_focus_window
->viewport_scale_y
;
2280 tablet_tool_rotation(void *data
, struct zwp_tablet_tool_v2
*tool
,
2283 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2284 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2285 double rotation
= wl_fixed_to_double(angle
);
2287 if (!xwl_seat
->tablet_focus_window
)
2290 /* change origin (buttons facing right [libinput +90 degrees]) and
2291 * scaling (5 points per degree) to match wacom driver behavior
2293 rotation
= remainderf(rotation
+ 90.0f
, 360.0f
);
2295 xwl_tablet_tool
->rotation
= rotation
;
2299 tablet_tool_slider(void *data
, struct zwp_tablet_tool_v2
*tool
,
2300 int32_t position_raw
)
2302 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2303 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2304 float position
= position_raw
/ 65535.0;
2306 if (!xwl_seat
->tablet_focus_window
)
2309 xwl_tablet_tool
->slider
= (position
* 1799.0f
) - 900.0f
;
2313 tablet_tool_wheel(void *data
, struct zwp_tablet_tool_v2
*tool
,
2314 wl_fixed_t degrees
, int32_t clicks
)
2316 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2317 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2319 if (!xwl_seat
->tablet_focus_window
)
2322 xwl_tablet_tool
->wheel_clicks
= clicks
;
2326 tablet_tool_button_state(void *data
, struct zwp_tablet_tool_v2
*tool
,
2327 uint32_t serial
, uint32_t button
, uint32_t state
)
2329 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2330 struct xwl_seat
*xwl_seat
= xwl_tablet_tool
->seat
;
2331 uint32_t *mask
= &xwl_tablet_tool
->buttons_now
;
2334 /* BTN_0 .. BTN_9 */
2335 if (button
>= 0x100 && button
<= 0x109) {
2336 xbtn
= button
- 0x100 + 1;
2338 /* BTN_A .. BTN_Z */
2339 else if (button
>= 0x130 && button
<= 0x135) {
2340 xbtn
= button
- 0x130 + 10;
2342 /* BTN_BASE .. BTN_BASE6 */
2343 else if (button
>= 0x126 && button
<= 0x12b) {
2344 xbtn
= button
- 0x126 + 16;
2348 case 0x110: /* BTN_LEFT */
2349 case 0x14a: /* BTN_TOUCH */
2353 case 0x112: /* BTN_MIDDLE */
2354 case 0x14b: /* BTN_STYLUS */
2358 case 0x111: /* BTN_RIGHT */
2359 case 0x14c: /* BTN_STYLUS2 */
2363 case 0x113: /* BTN_SIDE */
2364 case 0x116: /* BTN_BACK */
2365 case 0x149: /* BTN_STYLUS3 */
2369 case 0x114: /* BTN_EXTRA */
2370 case 0x115: /* BTN_FORWARD */
2377 ErrorF("unknown tablet button number %d\n", button
);
2381 BUG_RETURN(xbtn
>= 8 * sizeof(*mask
));
2384 SetBit(mask
, xbtn
- 1);
2386 ClearBit(mask
, xbtn
- 1);
2388 xwl_seat
->xwl_screen
->serial
= serial
;
2392 tablet_tool_frame(void *data
, struct zwp_tablet_tool_v2
*tool
, uint32_t time
)
2394 struct xwl_tablet_tool
*xwl_tablet_tool
= data
;
2396 uint32_t released
, pressed
, diff
;
2399 valuator_mask_zero(&mask
);
2400 valuator_mask_set_double(&mask
, 0, xwl_tablet_tool
->x
);
2401 valuator_mask_set_double(&mask
, 1, xwl_tablet_tool
->y
);
2402 valuator_mask_set(&mask
, 2, xwl_tablet_tool
->pressure
);
2403 valuator_mask_set_double(&mask
, 3, xwl_tablet_tool
->tilt_x
);
2404 valuator_mask_set_double(&mask
, 4, xwl_tablet_tool
->tilt_y
);
2405 valuator_mask_set_double(&mask
, 5, xwl_tablet_tool
->rotation
+ xwl_tablet_tool
->slider
);
2407 QueuePointerEvents(xwl_tablet_tool
->xdevice
, MotionNotify
, 0,
2408 POINTER_ABSOLUTE
| POINTER_DESKTOP
, &mask
);
2410 valuator_mask_zero(&mask
);
2412 diff
= xwl_tablet_tool
->buttons_prev
^ xwl_tablet_tool
->buttons_now
;
2413 released
= diff
& ~xwl_tablet_tool
->buttons_now
;
2414 pressed
= diff
& xwl_tablet_tool
->buttons_now
;
2419 QueuePointerEvents(xwl_tablet_tool
->xdevice
,
2420 ButtonRelease
, button
, 0, &mask
);
2428 QueuePointerEvents(xwl_tablet_tool
->xdevice
,
2429 ButtonPress
, button
, 0, &mask
);
2434 xwl_tablet_tool
->buttons_prev
= xwl_tablet_tool
->buttons_now
;
2436 while (xwl_tablet_tool
->wheel_clicks
) {
2437 if (xwl_tablet_tool
->wheel_clicks
< 0) {
2439 xwl_tablet_tool
->wheel_clicks
++;
2443 xwl_tablet_tool
->wheel_clicks
--;
2446 QueuePointerEvents(xwl_tablet_tool
->xdevice
,
2447 ButtonPress
, button
, 0, &mask
);
2448 QueuePointerEvents(xwl_tablet_tool
->xdevice
,
2449 ButtonRelease
, button
, 0, &mask
);
2454 static const struct zwp_tablet_tool_v2_listener tablet_tool_listener
= {
2455 tablet_tool_receive_type
,
2456 tablet_tool_receive_hardware_serial
,
2457 tablet_tool_receive_hardware_id_wacom
,
2458 tablet_tool_receive_capability
,
2459 tablet_tool_receive_done
,
2460 tablet_tool_receive_removed
,
2461 tablet_tool_proximity_in
,
2462 tablet_tool_proximity_out
,
2466 tablet_tool_pressure
,
2467 tablet_tool_distance
,
2469 tablet_tool_rotation
,
2472 tablet_tool_button_state
,
2477 tablet_pad_ring_destroy(struct xwl_tablet_pad_ring
*ring
)
2479 zwp_tablet_pad_ring_v2_destroy(ring
->ring
);
2480 xorg_list_del(&ring
->link
);
2485 tablet_pad_ring_source(void *data
,
2486 struct zwp_tablet_pad_ring_v2
*zwp_tablet_pad_ring_v2
,
2492 tablet_pad_ring_angle(void *data
,
2493 struct zwp_tablet_pad_ring_v2
*zwp_tablet_pad_ring_v2
,
2496 struct xwl_tablet_pad_ring
*ring
= data
;
2497 struct xwl_tablet_pad
*pad
= ring
->group
->pad
;
2498 double deg
= wl_fixed_to_double(degrees
);
2501 valuator_mask_zero(&mask
);
2502 valuator_mask_set(&mask
, 5 + ring
->index
, deg
/360.0 * 71);
2503 QueuePointerEvents(pad
->xdevice
, MotionNotify
, 0, 0, &mask
);
2507 tablet_pad_ring_stop(void *data
,
2508 struct zwp_tablet_pad_ring_v2
*zwp_tablet_pad_ring_v2
)
2513 tablet_pad_ring_frame(void *data
,
2514 struct zwp_tablet_pad_ring_v2
*zwp_tablet_pad_ring_v2
,
2519 static const struct zwp_tablet_pad_ring_v2_listener tablet_pad_ring_listener
= {
2520 tablet_pad_ring_source
,
2521 tablet_pad_ring_angle
,
2522 tablet_pad_ring_stop
,
2523 tablet_pad_ring_frame
,
2528 tablet_pad_strip_destroy(struct xwl_tablet_pad_strip
*strip
)
2530 zwp_tablet_pad_strip_v2_destroy(strip
->strip
);
2531 xorg_list_del(&strip
->link
);
2536 tablet_pad_strip_source(void *data
,
2537 struct zwp_tablet_pad_strip_v2
*zwp_tablet_pad_strip_v2
,
2543 tablet_pad_strip_position(void *data
,
2544 struct zwp_tablet_pad_strip_v2
*zwp_tablet_pad_strip_v2
,
2547 struct xwl_tablet_pad_strip
*strip
= data
;
2548 struct xwl_tablet_pad
*pad
= strip
->group
->pad
;
2551 valuator_mask_zero(&mask
);
2552 valuator_mask_set(&mask
, 3 + strip
->index
, position
/65535.0 * 2048);
2553 QueuePointerEvents(pad
->xdevice
, MotionNotify
, 0, 0, &mask
);
2557 tablet_pad_strip_stop(void *data
,
2558 struct zwp_tablet_pad_strip_v2
*zwp_tablet_pad_strip_v2
)
2563 tablet_pad_strip_frame(void *data
,
2564 struct zwp_tablet_pad_strip_v2
*zwp_tablet_pad_strip_v2
,
2569 static const struct zwp_tablet_pad_strip_v2_listener tablet_pad_strip_listener
= {
2570 tablet_pad_strip_source
,
2571 tablet_pad_strip_position
,
2572 tablet_pad_strip_stop
,
2573 tablet_pad_strip_frame
,
2577 tablet_pad_group_destroy(struct xwl_tablet_pad_group
*group
)
2579 struct xwl_tablet_pad_ring
*r
, *tr
;
2580 struct xwl_tablet_pad_strip
*s
, *ts
;
2582 xorg_list_for_each_entry_safe(r
, tr
,
2583 &group
->pad_group_ring_list
,
2585 tablet_pad_ring_destroy(r
);
2587 xorg_list_for_each_entry_safe(s
, ts
,
2588 &group
->pad_group_strip_list
,
2590 tablet_pad_strip_destroy(s
);
2592 zwp_tablet_pad_group_v2_destroy(group
->group
);
2593 xorg_list_del(&group
->link
);
2598 tablet_pad_group_buttons(void *data
,
2599 struct zwp_tablet_pad_group_v2
*zwp_tablet_pad_group_v2
,
2600 struct wl_array
*buttons
)
2606 tablet_pad_group_ring(void *data
,
2607 struct zwp_tablet_pad_group_v2
*zwp_tablet_pad_group_v2
,
2608 struct zwp_tablet_pad_ring_v2
*wp_ring
)
2610 static unsigned int ring_index
= 0;
2611 struct xwl_tablet_pad_group
*group
= data
;
2612 struct xwl_tablet_pad_ring
*ring
;
2614 ring
= calloc(1, sizeof *ring
);
2616 ErrorF("%s ENOMEM\n", __func__
);
2620 ring
->index
= ring_index
++;
2621 ring
->group
= group
;
2622 ring
->ring
= wp_ring
;
2624 xorg_list_add(&ring
->link
, &group
->pad_group_ring_list
);
2626 zwp_tablet_pad_ring_v2_add_listener(wp_ring
, &tablet_pad_ring_listener
,
2631 tablet_pad_group_strip(void *data
,
2632 struct zwp_tablet_pad_group_v2
*zwp_tablet_pad_group_v2
,
2633 struct zwp_tablet_pad_strip_v2
*wp_strip
)
2635 static unsigned int strip_index
= 0;
2636 struct xwl_tablet_pad_group
*group
= data
;
2637 struct xwl_tablet_pad_strip
*strip
;
2639 strip
= calloc(1, sizeof *strip
);
2640 if (strip
== NULL
) {
2641 ErrorF("%s ENOMEM\n", __func__
);
2645 strip
->index
= strip_index
++;
2646 strip
->group
= group
;
2647 strip
->strip
= wp_strip
;
2649 xorg_list_add(&strip
->link
, &group
->pad_group_strip_list
);
2651 zwp_tablet_pad_strip_v2_add_listener(wp_strip
, &tablet_pad_strip_listener
,
2656 tablet_pad_group_modes(void *data
,
2657 struct zwp_tablet_pad_group_v2
*zwp_tablet_pad_group_v2
,
2664 tablet_pad_group_done(void *data
,
2665 struct zwp_tablet_pad_group_v2
*zwp_tablet_pad_group_v2
)
2671 tablet_pad_group_mode_switch(void *data
,
2672 struct zwp_tablet_pad_group_v2
*zwp_tablet_pad_group_v2
,
2680 static struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener
= {
2681 tablet_pad_group_buttons
,
2682 tablet_pad_group_ring
,
2683 tablet_pad_group_strip
,
2684 tablet_pad_group_modes
,
2685 tablet_pad_group_done
,
2686 tablet_pad_group_mode_switch
,
2690 xwl_tablet_pad_proc(DeviceIntPtr device
, int what
)
2692 struct xwl_tablet_pad
*pad
= dixGetPrivate(&device
->devPrivates
,
2693 &xwl_tablet_private_key
);
2694 /* Axis layout mirrors that of xf86-input-wacom to have better
2695 compatibility with existing clients */
2697 Atom axes_labels
[NAXES
] = { 0 };
2698 BYTE map
[MAX_BUTTONS
+ 1];
2700 Atom btn_labels
[MAX_BUTTONS
] = { 0 }; /* btn labels are meaningless */
2705 device
->public.on
= FALSE
;
2707 axes_labels
[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X
);
2708 axes_labels
[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y
);
2709 /* The others have no good mapping */
2711 if (!InitValuatorClassDeviceStruct(device
, NAXES
, axes_labels
,
2712 GetMotionHistorySize(), Absolute
))
2715 for (i
= 1; i
<= MAX_BUTTONS
; i
++)
2718 /* We need at least 7 buttons to allow scrolling */
2719 nbuttons
= min(max(pad
->nbuttons
+ 4, 7), MAX_BUTTONS
);
2721 if (!InitButtonClassDeviceStruct(device
, nbuttons
,
2726 InitValuatorAxisStruct(device
, 0, axes_labels
[0],
2727 0, 100, 1, 0, 1, Absolute
);
2728 InitValuatorAxisStruct(device
, 1, axes_labels
[1],
2729 0, 100, 1, 0, 1, Absolute
);
2730 /* Pressure - unused, for backwards compat only */
2731 InitValuatorAxisStruct(device
, 2, axes_labels
[2],
2732 0, 2048, 1, 0, 1, Absolute
);
2734 InitValuatorAxisStruct(device
, 3, axes_labels
[3],
2735 0, 2048, 1, 0, 1, Absolute
);
2737 InitValuatorAxisStruct(device
, 4, axes_labels
[4],
2738 0, 2048, 1, 0, 1, Absolute
);
2740 InitValuatorAxisStruct(device
, 5, axes_labels
[5],
2741 0, 71, 1, 0, 1, Absolute
);
2743 InitValuatorAxisStruct(device
, 6, axes_labels
[6],
2744 0, 71, 1, 0, 1, Absolute
);
2746 if (!InitPtrFeedbackClassDeviceStruct(device
, xwl_pointer_control
))
2752 device
->public.on
= TRUE
;
2757 device
->public.on
= FALSE
;
2766 tablet_pad_group(void *data
,
2767 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
,
2768 struct zwp_tablet_pad_group_v2
*pad_group
)
2770 struct xwl_tablet_pad
*pad
= data
;
2771 struct xwl_tablet_pad_group
*group
;
2773 group
= calloc(1, sizeof *group
);
2774 if (group
== NULL
) {
2775 ErrorF("%s ENOMEM\n", __func__
);
2780 group
->group
= pad_group
;
2781 xorg_list_init(&group
->pad_group_ring_list
);
2782 xorg_list_init(&group
->pad_group_strip_list
);
2784 xorg_list_add(&group
->link
, &pad
->pad_group_list
);
2786 zwp_tablet_pad_group_v2_add_listener(pad_group
,
2787 &tablet_pad_group_listener
,
2792 tablet_pad_path(void *data
,
2793 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
,
2800 tablet_pad_buttons(void *data
,
2801 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
,
2804 struct xwl_tablet_pad
*pad
= data
;
2806 pad
->nbuttons
= buttons
;
2810 tablet_pad_done(void *data
,
2811 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
)
2813 struct xwl_tablet_pad
*pad
= data
;
2815 pad
->xdevice
= add_device(pad
->seat
, "xwayland-tablet-pad",
2816 xwl_tablet_pad_proc
);
2817 dixSetPrivate(&pad
->xdevice
->devPrivates
, &xwl_tablet_private_key
, pad
);
2818 ActivateDevice(pad
->xdevice
, TRUE
);
2819 EnableDevice(pad
->xdevice
, TRUE
);
2823 tablet_pad_button(void *data
,
2824 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
,
2829 struct xwl_tablet_pad
*pad
= data
;
2832 button
++; /* wayland index vs X's 1-offset */
2833 /* skip scroll wheel buttons 4-7 */
2834 button
= button
> 3 ? button
+ 4 : button
;
2836 valuator_mask_zero(&mask
);
2837 QueuePointerEvents(pad
->xdevice
,
2838 state
? ButtonPress
: ButtonRelease
, button
, 0, &mask
);
2842 tablet_pad_enter(void *data
,
2843 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
,
2845 struct zwp_tablet_v2
*tablet
,
2846 struct wl_surface
*surface
)
2848 /* pairs the pad with the tablet but also to set the focus. We
2849 * don't care about the pairing and always use X's focus */
2853 tablet_pad_leave(void *data
,
2854 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
,
2856 struct wl_surface
*surface
)
2858 /* pairs the pad with the tablet but also to set the focus. We
2859 * don't care about the pairing and always use X's focus */
2863 tablet_pad_removed(void *data
,
2864 struct zwp_tablet_pad_v2
*zwp_tablet_pad_v2
)
2866 struct xwl_tablet_pad
*pad
= data
;
2867 struct xwl_tablet_pad_group
*g
, *tg
;
2869 xorg_list_for_each_entry_safe(g
, tg
, &pad
->pad_group_list
, link
)
2870 tablet_pad_group_destroy(g
);
2872 RemoveDevice(pad
->xdevice
, TRUE
);
2873 xorg_list_del(&pad
->link
);
2874 zwp_tablet_pad_v2_destroy(pad
->pad
);
2878 static const struct zwp_tablet_pad_v2_listener tablet_pad_listener
= {
2890 tablet_seat_handle_add_tablet(void *data
, struct zwp_tablet_seat_v2
*tablet_seat
,
2891 struct zwp_tablet_v2
*tablet
)
2893 struct xwl_seat
*xwl_seat
= data
;
2894 struct xwl_tablet
*xwl_tablet
;
2896 xwl_tablet
= calloc(1, sizeof *xwl_tablet
);
2897 if (xwl_tablet
== NULL
) {
2898 ErrorF("%s ENOMEM\n", __func__
);
2902 xwl_tablet
->tablet
= tablet
;
2903 xwl_tablet
->seat
= xwl_seat
;
2905 xorg_list_add(&xwl_tablet
->link
, &xwl_seat
->tablets
);
2907 zwp_tablet_v2_add_listener(tablet
, &tablet_listener
, xwl_tablet
);
2911 xwl_tablet_tool_update_cursor(struct xwl_cursor
*xwl_cursor
)
2913 struct xwl_tablet_tool
*xwl_tablet_tool
= wl_container_of(xwl_cursor
,
2916 xwl_tablet_tool_set_cursor(xwl_tablet_tool
);
2920 tablet_seat_handle_add_tool(void *data
, struct zwp_tablet_seat_v2
*tablet_seat
,
2921 struct zwp_tablet_tool_v2
*tool
)
2923 struct xwl_seat
*xwl_seat
= data
;
2924 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
2925 struct xwl_tablet_tool
*xwl_tablet_tool
;
2927 xwl_tablet_tool
= calloc(1, sizeof *xwl_tablet_tool
);
2928 if (xwl_tablet_tool
== NULL
) {
2929 ErrorF("%s ENOMEM\n", __func__
);
2933 xwl_tablet_tool
->tool
= tool
;
2934 xwl_tablet_tool
->seat
= xwl_seat
;
2935 xwl_cursor_init(&xwl_tablet_tool
->cursor
, xwl_screen
,
2936 xwl_tablet_tool_update_cursor
);
2938 xorg_list_add(&xwl_tablet_tool
->link
, &xwl_seat
->tablet_tools
);
2940 zwp_tablet_tool_v2_add_listener(tool
, &tablet_tool_listener
, xwl_tablet_tool
);
2944 tablet_seat_handle_add_pad(void *data
, struct zwp_tablet_seat_v2
*tablet_seat
,
2945 struct zwp_tablet_pad_v2
*pad
)
2947 struct xwl_seat
*xwl_seat
= data
;
2948 struct xwl_tablet_pad
*xwl_tablet_pad
;
2950 xwl_tablet_pad
= calloc(1, sizeof *xwl_tablet_pad
);
2951 if (xwl_tablet_pad
== NULL
) {
2952 ErrorF("%s ENOMEM\n", __func__
);
2956 xwl_tablet_pad
->pad
= pad
;
2957 xwl_tablet_pad
->seat
= xwl_seat
;
2958 xorg_list_init(&xwl_tablet_pad
->pad_group_list
);
2960 xorg_list_add(&xwl_tablet_pad
->link
, &xwl_seat
->tablet_pads
);
2962 zwp_tablet_pad_v2_add_listener(pad
, &tablet_pad_listener
,
2966 static const struct zwp_tablet_seat_v2_listener tablet_seat_listener
= {
2967 tablet_seat_handle_add_tablet
,
2968 tablet_seat_handle_add_tool
,
2969 tablet_seat_handle_add_pad
2973 init_tablet_manager_seat(struct xwl_screen
*xwl_screen
,
2974 struct xwl_seat
*xwl_seat
)
2976 xorg_list_init(&xwl_seat
->tablets
);
2977 xorg_list_init(&xwl_seat
->tablet_tools
);
2978 xorg_list_init(&xwl_seat
->tablet_pads
);
2980 if (!xwl_screen
->tablet_manager
)
2983 xwl_seat
->tablet_seat
=
2984 zwp_tablet_manager_v2_get_tablet_seat(xwl_screen
->tablet_manager
,
2987 zwp_tablet_seat_v2_add_listener(xwl_seat
->tablet_seat
, &tablet_seat_listener
, xwl_seat
);
2991 release_tablet_manager_seat(struct xwl_seat
*xwl_seat
)
2993 struct xwl_tablet
*xwl_tablet
, *next_xwl_tablet
;
2994 struct xwl_tablet_tool
*xwl_tablet_tool
, *next_xwl_tablet_tool
;
2995 struct xwl_tablet_pad
*xwl_tablet_pad
, *next_xwl_tablet_pad
;
2997 xorg_list_for_each_entry_safe(xwl_tablet_pad
, next_xwl_tablet_pad
,
2998 &xwl_seat
->tablet_pads
, link
) {
2999 xorg_list_del(&xwl_tablet_pad
->link
);
3000 zwp_tablet_pad_v2_destroy(xwl_tablet_pad
->pad
);
3001 free(xwl_tablet_pad
);
3004 xorg_list_for_each_entry_safe(xwl_tablet_tool
, next_xwl_tablet_tool
,
3005 &xwl_seat
->tablet_tools
, link
) {
3006 xorg_list_del(&xwl_tablet_tool
->link
);
3007 zwp_tablet_tool_v2_destroy(xwl_tablet_tool
->tool
);
3008 free(xwl_tablet_tool
);
3011 xorg_list_for_each_entry_safe(xwl_tablet
, next_xwl_tablet
,
3012 &xwl_seat
->tablets
, link
) {
3013 xorg_list_del(&xwl_tablet
->link
);
3014 zwp_tablet_v2_destroy(xwl_tablet
->tablet
);
3018 if (xwl_seat
->tablet_seat
) {
3019 zwp_tablet_seat_v2_destroy(xwl_seat
->tablet_seat
);
3020 xwl_seat
->tablet_seat
= NULL
;
3025 init_tablet_manager(struct xwl_screen
*xwl_screen
, uint32_t id
, uint32_t version
)
3027 struct xwl_seat
*xwl_seat
;
3029 xwl_screen
->tablet_manager
= wl_registry_bind(xwl_screen
->registry
,
3031 &zwp_tablet_manager_v2_interface
,
3034 xorg_list_for_each_entry(xwl_seat
, &xwl_screen
->seat_list
, link
) {
3035 init_tablet_manager_seat(xwl_screen
, xwl_seat
);
3040 xwl_screen_release_tablet_manager(struct xwl_screen
*xwl_screen
)
3042 if (xwl_screen
->tablet_manager
) {
3043 zwp_tablet_manager_v2_destroy(xwl_screen
->tablet_manager
);
3044 xwl_screen
->tablet_manager
= NULL
;
3049 init_relative_pointer_manager(struct xwl_screen
*xwl_screen
,
3050 uint32_t id
, uint32_t version
)
3052 xwl_screen
->relative_pointer_manager
=
3053 wl_registry_bind(xwl_screen
->registry
, id
,
3054 &zwp_relative_pointer_manager_v1_interface
,
3059 init_pointer_constraints(struct xwl_screen
*xwl_screen
,
3060 uint32_t id
, uint32_t version
)
3062 xwl_screen
->pointer_constraints
=
3063 wl_registry_bind(xwl_screen
->registry
, id
,
3064 &zwp_pointer_constraints_v1_interface
,
3069 init_pointer_gestures(struct xwl_screen
*xwl_screen
,
3070 uint32_t id
, uint32_t version
)
3072 xwl_screen
->pointer_gestures
=
3073 wl_registry_bind(xwl_screen
->registry
, id
,
3074 &zwp_pointer_gestures_v1_interface
,
3079 init_keyboard_grab(struct xwl_screen
*xwl_screen
,
3080 uint32_t id
, uint32_t version
)
3082 struct xwl_seat
*xwl_seat
;
3083 DeviceIntPtr master
;
3085 xwl_screen
->wp_grab
=
3086 wl_registry_bind(xwl_screen
->registry
, id
,
3087 &zwp_xwayland_keyboard_grab_manager_v1_interface
,
3090 xorg_list_for_each_entry(xwl_seat
, &xwl_screen
->seat_list
, link
) {
3091 if (xwl_seat
->keyboard
) {
3092 master
= GetMaster(xwl_seat
->keyboard
, MASTER_KEYBOARD
);
3094 setup_keyboard_grab_handler(master
);
3100 init_keyboard_shortcuts_inhibit(struct xwl_screen
*xwl_screen
,
3101 uint32_t id
, uint32_t version
)
3103 xwl_screen
->shortcuts_inhibit_manager
=
3104 wl_registry_bind(xwl_screen
->registry
, id
,
3105 &zwp_keyboard_shortcuts_inhibit_manager_v1_interface
,
3110 init_system_bell(struct xwl_screen
*xwl_screen
, uint32_t id
, uint32_t version
)
3112 xwl_screen
->system_bell
=
3113 wl_registry_bind(xwl_screen
->registry
, id
,
3114 &xdg_system_bell_v1_interface
,
3118 /* The compositor may send us wl_seat and its capabilities before sending e.g.
3119 relative_pointer_manager or pointer_gesture interfaces. This would result in
3120 devices being created in capabilities handler, but listeners not, because
3121 the interfaces weren't available at the time. So we manually attempt to setup
3125 maybe_init_relative_pointer_listeners_after_capabilities(struct xwl_screen
* xwl_screen
)
3127 struct xwl_seat
*xwl_seat
;
3128 xorg_list_for_each_entry(xwl_seat
, &xwl_screen
->seat_list
, link
) {
3129 if (xwl_seat
->wl_pointer
) {
3130 init_relative_pointer_listener(xwl_seat
);
3136 maybe_init_pointer_gesture_listeners_after_capabilities(struct xwl_screen
* xwl_screen
)
3138 struct xwl_seat
*xwl_seat
;
3139 xorg_list_for_each_entry(xwl_seat
, &xwl_screen
->seat_list
, link
) {
3140 if (xwl_seat
->wl_pointer
) {
3141 init_pointer_gestures_listener(xwl_seat
);
3147 input_handler(void *data
, struct wl_registry
*registry
, uint32_t id
,
3148 const char *interface
, uint32_t version
)
3150 struct xwl_screen
*xwl_screen
= data
;
3152 if (strcmp(interface
, wl_seat_interface
.name
) == 0 && version
>= 3) {
3153 create_input_device(xwl_screen
, id
, version
);
3154 xwl_screen
->expecting_event
++;
3155 } else if (strcmp(interface
, zwp_relative_pointer_manager_v1_interface
.name
) == 0) {
3156 init_relative_pointer_manager(xwl_screen
, id
, version
);
3157 maybe_init_relative_pointer_listeners_after_capabilities(xwl_screen
);
3158 } else if (strcmp(interface
, zwp_pointer_constraints_v1_interface
.name
) == 0) {
3159 init_pointer_constraints(xwl_screen
, id
, version
);
3160 } else if (strcmp(interface
, zwp_pointer_gestures_v1_interface
.name
) == 0) {
3161 init_pointer_gestures(xwl_screen
, id
, version
);
3162 maybe_init_pointer_gesture_listeners_after_capabilities(xwl_screen
);
3163 } else if (strcmp(interface
, zwp_tablet_manager_v2_interface
.name
) == 0) {
3164 init_tablet_manager(xwl_screen
, id
, version
);
3165 } else if (strcmp(interface
, zwp_xwayland_keyboard_grab_manager_v1_interface
.name
) == 0) {
3166 init_keyboard_grab(xwl_screen
, id
, version
);
3167 } else if (strcmp(interface
, zwp_keyboard_shortcuts_inhibit_manager_v1_interface
.name
) == 0) {
3168 init_keyboard_shortcuts_inhibit(xwl_screen
, id
, version
);
3169 } else if (strcmp(interface
, xdg_system_bell_v1_interface
.name
) == 0) {
3170 init_system_bell(xwl_screen
, id
, version
);
3175 global_remove(void *data
, struct wl_registry
*registry
, uint32_t name
)
3179 static const struct wl_registry_listener input_listener
= {
3185 ProcessInputEvents(void)
3187 mieqProcessInputEvents();
3191 DDXRingBell(int volume
, int pitch
, int duration
)
3193 ScreenPtr screen
= screenInfo
.screens
[0];
3194 struct xwl_screen
*xwl_screen
;
3195 struct xwl_seat
*xwl_seat
;
3197 xwl_screen
= xwl_screen_get(screen
);
3198 if (!xwl_screen
->system_bell
)
3201 xorg_list_for_each_entry(xwl_seat
, &xwl_screen
->seat_list
, link
) {
3202 if (!xwl_seat
->keyboard
)
3205 if (!xwl_seat
->keyboard
->coreEvents
)
3208 if (!xwl_seat
->keyboard_focus
)
3211 DebugF("XWAYLAND: Ringing the bell\n");
3212 xdg_system_bell_v1_ring (xwl_screen
->system_bell
, xwl_seat
->keyboard_focus
);
3218 sprite_check_lost_focus(SpritePtr sprite
, WindowPtr window
)
3220 DeviceIntPtr device
, master
;
3221 struct xwl_seat
*xwl_seat
;
3223 for (device
= inputInfo
.devices
; device
; device
= device
->next
) {
3224 /* Ignore non-wayland devices */
3225 if (device
->deviceProc
== xwl_pointer_proc
&&
3226 device
->spriteInfo
->sprite
== sprite
)
3233 xwl_seat
= device
->public.devicePrivate
;
3237 master
= GetMaster(device
, POINTER_OR_FLOAT
);
3238 if (!master
|| !master
->lastSlave
)
3241 /* We do want the last active slave, we only check on slave xwayland
3242 * devices so we can find out the xwl_seat, but those don't actually own
3243 * their sprite, so the match doesn't mean a lot.
3245 if (master
->lastSlave
!= get_pointer_device(xwl_seat
))
3248 if (xwl_seat
->focus_window
!= NULL
&&
3249 xwl_seat
->cursor_confinement_window
!= NULL
&&
3250 xwl_seat
->focus_window
!= xwl_seat
->cursor_confinement_window
)
3253 if (xwl_seat
->focus_window
== NULL
&&
3254 xwl_seat
->last_focus_window
!= NULL
&&
3255 (xwl_seat
->last_focus_window
->toplevel
== window
||
3256 IsParent(xwl_seat
->last_focus_window
->toplevel
, window
)))
3263 xwl_xy_to_window(ScreenPtr screen
, SpritePtr sprite
, int x
, int y
)
3265 struct xwl_screen
*xwl_screen
;
3268 xwl_screen
= xwl_screen_get(screen
);
3270 screen
->XYToWindow
= xwl_screen
->XYToWindow
;
3271 ret
= screen
->XYToWindow(screen
, sprite
, x
, y
);
3272 xwl_screen
->XYToWindow
= screen
->XYToWindow
;
3273 screen
->XYToWindow
= xwl_xy_to_window
;
3275 /* If the device controlling the sprite has left the Wayland surface but
3276 * the DIX still finds the pointer within the X11 window, it means that
3277 * the pointer has crossed to another native Wayland window, in this
3278 * case, pretend we entered the root window so that a LeaveNotify
3281 if (sprite_check_lost_focus(sprite
, ret
)) {
3282 sprite
->spriteTraceGood
= 1;
3283 return sprite
->spriteTrace
[0];
3290 xwl_seat_clear_touch(struct xwl_seat
*xwl_seat
, struct xwl_window
*xwl_window
)
3292 struct xwl_touch
*xwl_touch
, *next_xwl_touch
;
3294 xorg_list_for_each_entry_safe(xwl_touch
, next_xwl_touch
,
3295 &xwl_seat
->touches
, link_touch
) {
3296 if (xwl_touch
->window
== xwl_window
) {
3297 xorg_list_del(&xwl_touch
->link_touch
);
3304 xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator
*warp_emulator
,
3308 struct zwp_locked_pointer_v1
*locked_pointer
=
3309 warp_emulator
->locked_pointer
;
3313 if (!warp_emulator
->locked_pointer
)
3316 if (!warp_emulator
->xwl_seat
->focus_window
)
3319 window
= warp_emulator
->xwl_seat
->focus_window
->toplevel
;
3320 if (x
>= window
->drawable
.x
||
3321 y
>= window
->drawable
.y
||
3322 x
< (window
->drawable
.x
+ window
->drawable
.width
) ||
3323 y
< (window
->drawable
.y
+ window
->drawable
.height
)) {
3324 sx
= x
- window
->drawable
.x
;
3325 sy
= y
- window
->drawable
.y
;
3326 zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer
,
3327 wl_fixed_from_int(sx
),
3328 wl_fixed_from_int(sy
));
3329 wl_surface_commit(warp_emulator
->xwl_seat
->focus_window
->surface
);
3334 xwl_pointer_warp_emulator_is_locked(struct xwl_pointer_warp_emulator
*warp_emulator
)
3336 if (warp_emulator
->locked_pointer
)
3343 xwl_pointer_warp_emulator_lock(struct xwl_pointer_warp_emulator
*warp_emulator
)
3345 struct xwl_seat
*xwl_seat
= warp_emulator
->xwl_seat
;
3346 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
3347 struct zwp_pointer_constraints_v1
*pointer_constraints
=
3348 xwl_screen
->pointer_constraints
;
3349 struct xwl_window
*lock_window
= xwl_seat
->focus_window
;
3351 warp_emulator
->locked_window
= lock_window
;
3353 warp_emulator
->locked_pointer
=
3354 zwp_pointer_constraints_v1_lock_pointer(pointer_constraints
,
3355 lock_window
->surface
,
3356 xwl_seat
->wl_pointer
,
3358 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT
);
3362 xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator
*warp_emulator
,
3363 struct xwl_window
*xwl_window
,
3367 struct xwl_seat
*xwl_seat
= warp_emulator
->xwl_seat
;
3368 GrabPtr pointer_grab
= xwl_seat
->pointer
->deviceGrab
.grab
;
3370 if (warp_emulator
->locked_pointer
)
3374 * If there is no grab, and the window doesn't have pointer focus, ignore
3375 * the warp, as under Wayland it won't receive input anyway.
3377 if (!pointer_grab
&& xwl_seat
->focus_window
!= xwl_window
)
3381 * If there is a grab, but it's not an ownerEvents grab and the destination
3382 * is not the pointer focus, ignore it, as events wouldn't be delivered
3386 !pointer_grab
->ownerEvents
&&
3388 XYToWindow(sprite
, x
, y
) != xwl_seat
->focus_window
->toplevel
)
3391 xwl_pointer_warp_emulator_lock(warp_emulator
);
3395 xwl_pointer_warp_emulator_warp(struct xwl_pointer_warp_emulator
*warp_emulator
,
3396 struct xwl_window
*xwl_window
,
3400 xwl_pointer_warp_emulator_maybe_lock(warp_emulator
,
3404 xwl_pointer_warp_emulator_set_fake_pos(warp_emulator
, x
, y
);
3408 xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator
*warp_emulator
,
3414 struct xwl_seat
*xwl_seat
= warp_emulator
->xwl_seat
;
3419 valuator_mask_zero(&mask
);
3420 valuator_mask_set_unaccelerated(&mask
, 0, dx
, dx_unaccel
);
3421 valuator_mask_set_unaccelerated(&mask
, 1, dy
, dy_unaccel
);
3423 QueuePointerEvents(xwl_seat
->relative_pointer
, MotionNotify
, 0,
3424 POINTER_RELATIVE
, &mask
);
3426 window
= xwl_seat
->focus_window
->toplevel
;
3427 miPointerGetPosition(xwl_seat
->pointer
, &x
, &y
);
3429 if (xwl_pointer_warp_emulator_is_locked(warp_emulator
) &&
3430 xwl_seat
->cursor_confinement_window
!= warp_emulator
->locked_window
&&
3431 (x
< window
->drawable
.x
||
3432 y
< window
->drawable
.y
||
3433 x
>= (window
->drawable
.x
+ window
->drawable
.width
) ||
3434 y
>= (window
->drawable
.y
+ window
->drawable
.height
)))
3435 xwl_seat_destroy_pointer_warp_emulator(xwl_seat
);
3437 xwl_pointer_warp_emulator_set_fake_pos(warp_emulator
, x
, y
);
3440 static struct xwl_pointer_warp_emulator
*
3441 xwl_pointer_warp_emulator_create(struct xwl_seat
*xwl_seat
)
3443 struct xwl_pointer_warp_emulator
*warp_emulator
;
3445 warp_emulator
= calloc(1, sizeof *warp_emulator
);
3446 if (!warp_emulator
) {
3447 ErrorF("%s: ENOMEM\n", __func__
);
3451 warp_emulator
->xwl_seat
= xwl_seat
;
3453 return warp_emulator
;
3457 xwl_pointer_warp_emulator_destroy(struct xwl_pointer_warp_emulator
*warp_emulator
)
3459 if (warp_emulator
->locked_pointer
)
3460 zwp_locked_pointer_v1_destroy(warp_emulator
->locked_pointer
);
3461 free(warp_emulator
);
3465 xwl_seat_create_pointer_warp_emulator(struct xwl_seat
*xwl_seat
)
3467 if (xwl_seat
->confined_pointer
)
3468 xwl_seat_destroy_confined_pointer(xwl_seat
);
3470 xwl_seat
->pointer_warp_emulator
=
3471 xwl_pointer_warp_emulator_create(xwl_seat
);
3475 xwl_seat_can_emulate_pointer_warp(struct xwl_seat
*xwl_seat
)
3477 struct xwl_screen
*xwl_screen
;
3482 if (!xwl_seat
->pointer
)
3485 xwl_screen
= xwl_seat
->xwl_screen
;
3487 if (!xwl_screen
->relative_pointer_manager
)
3490 if (!xwl_screen
->pointer_constraints
)
3497 xwl_seat_emulate_pointer_warp(struct xwl_seat
*xwl_seat
,
3498 struct xwl_window
*xwl_window
,
3502 if (!xwl_seat_can_emulate_pointer_warp(xwl_seat
))
3505 if (xwl_seat
->x_cursor
!= NULL
)
3508 if (!xwl_seat
->pointer_warp_emulator
)
3509 xwl_seat_create_pointer_warp_emulator(xwl_seat
);
3511 if (!xwl_seat
->pointer_warp_emulator
)
3514 xwl_pointer_warp_emulator_warp(xwl_seat
->pointer_warp_emulator
,
3521 xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat
*xwl_seat
)
3523 struct xwl_screen
*xwl_screen
= xwl_seat
->xwl_screen
;
3525 /* Some clients use hidden cursor+confineTo+relative motion
3526 * to implement infinite panning (eg. 3D views), lock the
3527 * pointer for so the relative pointer is used.
3529 if (xwl_seat
->x_cursor
)
3532 if (!xwl_seat
->focus_window
)
3535 if (!xwl_screen
->rootless
)
3538 if (xwl_seat
->cursor_confinement_window
!= xwl_seat
->focus_window
)
3541 if (xwl_seat
->confined_pointer
)
3542 xwl_seat_destroy_confined_pointer(xwl_seat
);
3544 xwl_seat_create_pointer_warp_emulator(xwl_seat
);
3545 xwl_pointer_warp_emulator_lock(xwl_seat
->pointer_warp_emulator
);
3550 xwl_seat_cursor_visibility_changed(struct xwl_seat
*xwl_seat
)
3552 if (xwl_seat
->pointer_warp_emulator
&& xwl_seat
->x_cursor
!= NULL
) {
3553 xwl_seat_destroy_pointer_warp_emulator(xwl_seat
);
3554 } else if (!xwl_seat
->x_cursor
&& xwl_seat
->cursor_confinement_window
) {
3555 /* If the cursor goes hidden as is confined, lock it for
3556 * relative motion to work. */
3557 xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat
);
3562 xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat
*xwl_seat
)
3564 if (!xwl_seat
->pointer_warp_emulator
)
3567 xwl_pointer_warp_emulator_destroy(xwl_seat
->pointer_warp_emulator
);
3568 xwl_seat
->pointer_warp_emulator
= NULL
;
3570 if (xwl_seat
->cursor_confinement_window
) {
3571 xwl_seat_confine_pointer(xwl_seat
,
3572 xwl_seat
->cursor_confinement_window
);
3577 xwl_seat_confine_pointer(struct xwl_seat
*xwl_seat
,
3578 struct xwl_window
*xwl_window
)
3580 struct zwp_pointer_constraints_v1
*pointer_constraints
=
3581 xwl_seat
->xwl_screen
->pointer_constraints
;
3583 if (!pointer_constraints
)
3586 if (!xwl_seat
->wl_pointer
)
3589 if (xwl_seat
->cursor_confinement_window
== xwl_window
&&
3590 xwl_seat
->confined_pointer
)
3593 xwl_seat_unconfine_pointer(xwl_seat
);
3595 xwl_seat
->cursor_confinement_window
= xwl_window
;
3597 if (xwl_seat
->pointer_warp_emulator
)
3600 if (xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat
))
3603 xwl_seat
->confined_pointer
=
3604 zwp_pointer_constraints_v1_confine_pointer(pointer_constraints
,
3605 xwl_window
->surface
,
3606 xwl_seat
->wl_pointer
,
3608 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT
);
3612 xwl_seat_destroy_confined_pointer(struct xwl_seat
*xwl_seat
)
3614 zwp_confined_pointer_v1_destroy(xwl_seat
->confined_pointer
);
3615 xwl_seat
->confined_pointer
= NULL
;
3619 xwl_seat_unconfine_pointer(struct xwl_seat
*xwl_seat
)
3621 xwl_seat
->cursor_confinement_window
= NULL
;
3623 if (xwl_seat
->confined_pointer
)
3624 xwl_seat_destroy_confined_pointer(xwl_seat
);
3628 InitInput(int argc
, char *argv
[])
3630 ScreenPtr pScreen
= screenInfo
.screens
[0];
3631 struct xwl_screen
*xwl_screen
= xwl_screen_get(pScreen
);
3633 if (!dixRegisterPrivateKey(&xwl_tablet_private_key
, PRIVATE_DEVICE
, 0)) {
3634 ErrorF("Failed to register private key\n");
3640 inputInfo
.keyboard
->ignoreXkbActionsBehaviors
= TRUE
;
3641 xwl_screen
->input_registry
= wl_display_get_registry(xwl_screen
->display
);
3642 wl_registry_add_listener(xwl_screen
->input_registry
, &input_listener
,
3645 xwl_screen
->XYToWindow
= pScreen
->XYToWindow
;
3646 pScreen
->XYToWindow
= xwl_xy_to_window
;
3648 xwl_screen_roundtrip(xwl_screen
);
3650 if (xwl_screen
->rootless
)
3651 xwayland_override_xtest();
3659 xwayland_restore_xtest();