debian/changelog | 29 debian/control | 2 debian/patches/CVE-2017-10971-1.patch | 41 debian/patches/CVE-2017-10971-2.patch | 43 debian/patches/CVE-2017-10971-3.patch | 66 debian/patches/CVE-2017-10972.patch | 35 debian/patches/series | 7 debian/patches/xwayland-add-grab-protocol-support.diff | 255 ++ debian/patches/xwayland-pointer-confine.diff | 143 + debian/patches/xwayland-tablet.diff | 1568 +++++++++++++++++ 10 files changed, 2188 insertions(+), 1 deletion(-)
New commits: commit 39cb1e331907a3bbe8d9efd8276d9ce9b2e773d0 Author: Timo Aaltonen <[email protected]> Date: Fri Aug 25 08:32:28 2017 +0300 release to artful diff --git a/debian/changelog b/debian/changelog index 3017f37..96db26e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -xorg-server (2:1.19.3-1ubuntu4) UNRELEASED; urgency=medium +xorg-server (2:1.19.3-1ubuntu4) artful; urgency=medium * xwayland-tablet.diff: Add support for Wacom tablets in xwayland. (LP: #1712571) @@ -7,7 +7,7 @@ xorg-server (2:1.19.3-1ubuntu4) UNRELEASED; urgency=medium * xwayland-add-grab-protocol-support.diff: Add support for keyboard grabbing to xwayland. Bump wayland-protocols build-dependency to 1.9. - -- Timo Aaltonen <[email protected]> Thu, 24 Aug 2017 14:33:30 +0300 + -- Timo Aaltonen <[email protected]> Fri, 25 Aug 2017 08:32:17 +0300 xorg-server (2:1.19.3-1ubuntu3) artful; urgency=medium commit 431ecda6854a4db7742fd66cb2815c7eb92b570d Author: Timo Aaltonen <[email protected]> Date: Thu Aug 24 21:51:48 2017 +0300 xwayland-add-grab-protocol-support.diff: Add support for keyboard grabbing to xwayland. Bump wayland-protocols build-dependency. diff --git a/debian/changelog b/debian/changelog index 0085ce2..3017f37 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,8 @@ xorg-server (2:1.19.3-1ubuntu4) UNRELEASED; urgency=medium (LP: #1712571) * xwayland-pointer-confine.diff: Add pointer locking/confinement fixes to xwayland. + * xwayland-add-grab-protocol-support.diff: Add support for keyboard + grabbing to xwayland. Bump wayland-protocols build-dependency to 1.9. -- Timo Aaltonen <[email protected]> Thu, 24 Aug 2017 14:33:30 +0300 diff --git a/debian/control b/debian/control index 972fca3..34ca069 100644 --- a/debian/control +++ b/debian/control @@ -97,7 +97,7 @@ Build-Depends: libbsd-dev, # xwayland libwayland-dev [linux-any], - wayland-protocols (>= 1.1) [linux-any], + wayland-protocols (>= 1.9) [linux-any], #logind libdbus-1-dev (>= 1.0) [linux-any], # systemd-daemon diff --git a/debian/patches/series b/debian/patches/series index 588ed0a..e2b8cb2 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -35,3 +35,4 @@ CVE-2017-10971-3.patch CVE-2017-10972.patch xwayland-tablet.diff xwayland-pointer-confine.diff +xwayland-add-grab-protocol-support.diff diff --git a/debian/patches/xwayland-add-grab-protocol-support.diff b/debian/patches/xwayland-add-grab-protocol-support.diff new file mode 100644 index 0000000..f85db7e --- /dev/null +++ b/debian/patches/xwayland-add-grab-protocol-support.diff @@ -0,0 +1,255 @@ +From 0a448d133f4f1c913b1c2cb05accff31c74a3dbf Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan <[email protected]> +Date: Wed, 12 Jul 2017 11:51:08 +0200 +Subject: [PATCH] xwayland: Add grab protocol support + +The keyboard grabbing protocol for Xwayland is included in +wayland-protocol 1.9. + +Update the wayland-protocol required version in both configure and meson +builds and add support for this new protocol in Xwayland. + +Signed-off-by: Olivier Fourdan <[email protected]> +Reviewed-by: Peter Hutterer <[email protected]> +Signed-off-by: Peter Hutterer <[email protected]> +--- + configure.ac | 2 +- + hw/xwayland/Makefile.am | 9 +++- + hw/xwayland/xwayland-input.c | 99 ++++++++++++++++++++++++++++++++++++++++++++ + hw/xwayland/xwayland.c | 2 +- + hw/xwayland/xwayland.h | 5 ++- + meson.build | 2 +- + 6 files changed, 114 insertions(+), 5 deletions(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -2526,7 +2526,7 @@ AM_CONDITIONAL(XFAKESERVER, [test "x$KDR + + dnl Xwayland DDX + +-XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.5 $LIBDRM epoxy" ++XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.9 $LIBDRM epoxy" + if test "x$XF86VIDMODE" = xyes; then + XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO" + fi +--- a/hw/xwayland/Makefile.am ++++ b/hw/xwayland/Makefile.am +@@ -58,7 +58,9 @@ Xwayland_built_sources += \ + pointer-constraints-unstable-v1-client-protocol.h \ + pointer-constraints-unstable-v1-protocol.c \ + tablet-unstable-v2-client-protocol.h \ +- tablet-unstable-v2-protocol.c ++ tablet-unstable-v2-protocol.c \ ++ xwayland-keyboard-grab-unstable-v1-protocol.c \ ++ xwayland-keyboard-grab-unstable-v1-client-protocol.h + + nodist_Xwayland_SOURCES = $(Xwayland_built_sources) + CLEANFILES = $(Xwayland_built_sources) +@@ -86,6 +88,11 @@ tablet-unstable-v2-protocol.c: $(WAYLAND + tablet-unstable-v2-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ + ++xwayland-keyboard-grab-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml ++ $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ ++xwayland-keyboard-grab-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml ++ $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ ++ + %-protocol.c : %.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ + +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1022,6 +1022,85 @@ static const struct wl_touch_listener to + touch_handle_cancel + }; + ++static struct xwl_seat * ++find_matching_seat(DeviceIntPtr device) ++{ ++ DeviceIntPtr dev; ++ ++ for (dev = inputInfo.devices; dev; dev = dev->next) ++ if (dev->deviceProc == xwl_keyboard_proc && ++ device == GetMaster(dev, MASTER_KEYBOARD)) ++ return (struct xwl_seat *) dev->public.devicePrivate; ++ ++ return NULL; ++} ++ ++static void ++release_grab(struct xwl_seat *xwl_seat) ++{ ++ if (xwl_seat->keyboard_grab) ++ zwp_xwayland_keyboard_grab_v1_destroy(xwl_seat->keyboard_grab); ++ xwl_seat->keyboard_grab = NULL; ++} ++ ++static void ++set_grab(struct xwl_seat *xwl_seat, struct xwl_window *xwl_window) ++{ ++ struct xwl_screen *xwl_screen; ++ ++ if (!xwl_window) ++ return; ++ ++ /* We already have a grab */ ++ if (xwl_seat->keyboard_grab) ++ release_grab (xwl_seat); ++ ++ xwl_screen = xwl_seat->xwl_screen; ++ if (xwl_screen->wp_grab) ++ xwl_seat->keyboard_grab = ++ zwp_xwayland_keyboard_grab_manager_v1_grab_keyboard(xwl_screen->wp_grab, ++ xwl_window->surface, ++ xwl_seat->seat); ++} ++ ++static void ++xwl_keyboard_activate_grab(DeviceIntPtr device, GrabPtr grab, TimeStamp time, Bool passive) ++{ ++ struct xwl_seat *xwl_seat = device->public.devicePrivate; ++ ++ /* We are not interested in passive grabs */ ++ if (!passive) { ++ /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */ ++ if (xwl_seat == NULL) ++ xwl_seat = find_matching_seat(device); ++ if (xwl_seat) ++ set_grab(xwl_seat, xwl_window_from_window(grab->window)); ++ } ++ ++ ActivateKeyboardGrab(device, grab, time, passive); ++} ++ ++static void ++xwl_keyboard_deactivate_grab(DeviceIntPtr device) ++{ ++ struct xwl_seat *xwl_seat = device->public.devicePrivate; ++ ++ /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */ ++ if (xwl_seat == NULL) ++ xwl_seat = find_matching_seat(device); ++ if (xwl_seat) ++ release_grab (xwl_seat); ++ ++ DeactivateKeyboardGrab(device); ++} ++ ++static void ++setup_keyboard_grab_handler (DeviceIntPtr device) ++{ ++ device->deviceGrab.ActivateGrab = xwl_keyboard_activate_grab; ++ device->deviceGrab.DeactivateGrab = xwl_keyboard_deactivate_grab; ++} ++ + static DeviceIntPtr + add_device(struct xwl_seat *xwl_seat, + const char *driver, DeviceProc device_proc) +@@ -1110,6 +1189,8 @@ release_relative_pointer(struct xwl_seat + static void + init_keyboard(struct xwl_seat *xwl_seat) + { ++ DeviceIntPtr master; ++ + xwl_seat->wl_keyboard = wl_seat_get_keyboard(xwl_seat->seat); + wl_keyboard_add_listener(xwl_seat->wl_keyboard, + &keyboard_listener, xwl_seat); +@@ -1121,6 +1202,10 @@ init_keyboard(struct xwl_seat *xwl_seat) + } + EnableDevice(xwl_seat->keyboard, TRUE); + xwl_seat->keyboard->key->xkbInfo->checkRepeat = keyboard_check_repeat; ++ ++ master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD); ++ if (master) ++ setup_keyboard_grab_handler(master); + } + + static void +@@ -1178,6 +1263,7 @@ seat_handle_capabilities(void *data, str + if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->wl_keyboard == NULL) { + init_keyboard(xwl_seat); + } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && xwl_seat->wl_keyboard) { ++ release_grab(xwl_seat); + release_keyboard(xwl_seat); + } + +@@ -1277,6 +1363,7 @@ xwl_seat_destroy(struct xwl_seat *xwl_se + + release_tablet_manager_seat(xwl_seat); + ++ release_grab(xwl_seat); + wl_seat_destroy(xwl_seat->seat); + xwl_cursor_release(&xwl_seat->cursor); + wl_array_release(&xwl_seat->keys); +@@ -2317,6 +2404,16 @@ init_pointer_constraints(struct xwl_scre + } + + static void ++init_keyboard_grab(struct xwl_screen *xwl_screen, ++ uint32_t id, uint32_t version) ++{ ++ xwl_screen->wp_grab = ++ wl_registry_bind(xwl_screen->registry, id, ++ &zwp_xwayland_keyboard_grab_manager_v1_interface, ++ 1); ++} ++ ++static void + input_handler(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) + { +@@ -2331,6 +2428,8 @@ input_handler(void *data, struct wl_regi + init_pointer_constraints(xwl_screen, id, version); + } else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) { + init_tablet_manager(xwl_screen, id, version); ++ } else if (strcmp(interface, "zwp_xwayland_keyboard_grab_manager_v1") == 0) { ++ init_keyboard_grab(xwl_screen, id, version); + } + } + +--- a/hw/xwayland/xwayland.c ++++ b/hw/xwayland/xwayland.c +@@ -142,7 +142,7 @@ xwl_close_screen(ScreenPtr screen) + return screen->CloseScreen(screen); + } + +-static struct xwl_window * ++struct xwl_window * + xwl_window_from_window(WindowPtr window) + { + struct xwl_window *xwl_window; +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -45,6 +45,7 @@ + #include "relative-pointer-unstable-v1-client-protocol.h" + #include "pointer-constraints-unstable-v1-client-protocol.h" + #include "tablet-unstable-v2-client-protocol.h" ++#include "xwayland-keyboard-grab-unstable-v1-client-protocol.h" + + struct xwl_screen { + int width; +@@ -80,7 +81,7 @@ struct xwl_screen { + struct wl_shell *shell; + struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; + struct zwp_pointer_constraints_v1 *pointer_constraints; +- ++ struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab; + uint32_t serial; + + #define XWL_FORMAT_ARGB8888 (1 << 0) +@@ -185,6 +186,7 @@ struct xwl_seat { + struct xorg_list tablets; + struct xorg_list tablet_tools; + struct xorg_list tablet_pads; ++ struct zwp_xwayland_keyboard_grab_v1 *keyboard_grab; + }; + + struct xwl_tablet { +@@ -304,6 +306,7 @@ RRModePtr xwayland_cvt(int HDisplay, int + void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap); + struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap); + ++struct xwl_window *xwl_window_from_window(WindowPtr window); + + Bool xwl_shm_create_screen_resources(ScreenPtr screen); + PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height, commit ad2d4d38a516bfe1503a4d9ee95257b9b2e8b44b Author: Timo Aaltonen <[email protected]> Date: Thu Aug 24 16:53:40 2017 +0300 xwayland-pointer-confine.diff: Add pointer locking/confinement fixes to xwayland. diff --git a/debian/changelog b/debian/changelog index 5a5ae3c..0085ce2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,8 @@ xorg-server (2:1.19.3-1ubuntu4) UNRELEASED; urgency=medium * xwayland-tablet.diff: Add support for Wacom tablets in xwayland. (LP: #1712571) + * xwayland-pointer-confine.diff: Add pointer locking/confinement fixes + to xwayland. -- Timo Aaltonen <[email protected]> Thu, 24 Aug 2017 14:33:30 +0300 diff --git a/debian/patches/series b/debian/patches/series index 9cf8f24..588ed0a 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -34,3 +34,4 @@ CVE-2017-10971-2.patch CVE-2017-10971-3.patch CVE-2017-10972.patch xwayland-tablet.diff +xwayland-pointer-confine.diff diff --git a/debian/patches/xwayland-pointer-confine.diff b/debian/patches/xwayland-pointer-confine.diff new file mode 100644 index 0000000..0fffa58 --- /dev/null +++ b/debian/patches/xwayland-pointer-confine.diff @@ -0,0 +1,143 @@ +d5e2f271ad93e50 xwayland: Remove two unused proc pointers. +ca17f3e9fd3b59f xwayland: Lock the pointer if it is confined and has no cursor +513e3bd3870fdb8 xwayland: Update root window size when desktop size changes +fafdb0cc9697eb5 xwayland: "Accept" confineTo on InputOnly windows +c217fcb4c4640ff xwayland: Allow pointer warp on root/None window + +--- a/hw/xwayland/xwayland.c ++++ b/hw/xwayland/xwayland.c +@@ -177,11 +177,31 @@ xwl_cursor_warped_to(DeviceIntPtr device + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + struct xwl_seat *xwl_seat = device->public.devicePrivate; + struct xwl_window *xwl_window; ++ WindowPtr focus; + + if (!xwl_seat) + xwl_seat = xwl_screen_get_default_seat(xwl_screen); + + xwl_window = xwl_window_from_window(window); ++ if (!xwl_window && xwl_seat->focus_window) { ++ focus = xwl_seat->focus_window->window; ++ ++ /* Warps on non wl_surface backed Windows are only allowed ++ * as long as the pointer stays within the focus window. ++ */ ++ if (x >= focus->drawable.x && ++ y >= focus->drawable.y && ++ x < focus->drawable.x + focus->drawable.width && ++ y < focus->drawable.y + focus->drawable.height) { ++ if (!window) { ++ DebugF("Warp relative to pointer, assuming pointer focus\n"); ++ xwl_window = xwl_seat->focus_window; ++ } else if (window == screen->root) { ++ DebugF("Warp on root window, assuming pointer focus\n"); ++ xwl_window = xwl_seat->focus_window; ++ } ++ } ++ } + if (!xwl_window) + return; + +@@ -206,6 +226,15 @@ xwl_cursor_confined_to(DeviceIntPtr devi + } + + xwl_window = xwl_window_from_window(window); ++ if (!xwl_window && xwl_seat->focus_window) { ++ /* Allow confining on InputOnly windows, but only if the geometry ++ * is the same than the focus window. ++ */ ++ if (window->drawable.class == InputOnly) { ++ DebugF("Confine on InputOnly window, assuming pointer focus\n"); ++ xwl_window = xwl_seat->focus_window; ++ } ++ } + if (!xwl_window) + return; + +@@ -307,9 +336,11 @@ xwl_realize_window(WindowPtr window) + screen->RealizeWindow = xwl_realize_window; + + if (xwl_screen->rootless && !window->parent) { ++ BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height }; ++ ++ RegionReset(&window->winSize, &box); + RegionNull(&window->clipList); + RegionNull(&window->borderClip); +- RegionNull(&window->winSize); + } + + if (xwl_screen->rootless) { +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -2645,11 +2645,35 @@ xwl_seat_emulate_pointer_warp(struct xwl + x, y); + } + ++static Bool ++xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat *xwl_seat) ++{ ++ /* Some clients use hidden cursor+confineTo+relative motion ++ * to implement infinite panning (eg. 3D views), lock the ++ * pointer for so the relative pointer is used. ++ */ ++ if (xwl_seat->x_cursor || ++ !xwl_seat->cursor_confinement_window) ++ return FALSE; ++ ++ if (xwl_seat->confined_pointer) ++ xwl_seat_destroy_confined_pointer(xwl_seat); ++ ++ xwl_seat_create_pointer_warp_emulator(xwl_seat); ++ xwl_pointer_warp_emulator_lock(xwl_seat->pointer_warp_emulator); ++ return TRUE; ++} ++ + void + xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat) + { +- if (xwl_seat->pointer_warp_emulator && xwl_seat->x_cursor != NULL) ++ if (xwl_seat->pointer_warp_emulator && xwl_seat->x_cursor != NULL) { + xwl_seat_destroy_pointer_warp_emulator(xwl_seat); ++ } else if (!xwl_seat->x_cursor && xwl_seat->cursor_confinement_window) { ++ /* If the cursor goes hidden as is confined, lock it for ++ * relative motion to work. */ ++ xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat); ++ } + } + + void +@@ -2688,6 +2712,9 @@ xwl_seat_confine_pointer(struct xwl_seat + if (xwl_seat->pointer_warp_emulator) + return; + ++ if (xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat)) ++ return; ++ + xwl_seat->confined_pointer = + zwp_pointer_constraints_v1_confine_pointer(pointer_constraints, + xwl_window->surface, +--- a/hw/xwayland/xwayland-output.c ++++ b/hw/xwayland/xwayland-output.c +@@ -187,8 +187,11 @@ update_screen_size(struct xwl_output *xw + SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode); + + if (xwl_screen->screen->root) { ++ BoxRec box = { 0, 0, width, height }; ++ + xwl_screen->screen->root->drawable.width = width; + xwl_screen->screen->root->drawable.height = height; ++ RegionReset(&xwl_screen->screen->root->winSize, &box); + RRScreenSizeNotify(xwl_screen->screen); + } + +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -62,8 +62,6 @@ struct xwl_screen { + + CreateScreenResourcesProcPtr CreateScreenResources; + CloseScreenProcPtr CloseScreen; +- CreateWindowProcPtr CreateWindow; +- DestroyWindowProcPtr DestroyWindow; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + XYToWindowProcPtr XYToWindow; commit 5c1f30af6024388f136ddc0204041d56dd0b64a0 Author: Timo Aaltonen <[email protected]> Date: Thu Aug 24 14:33:53 2017 +0300 xwayland-tablet.diff: Add support for Wacom tablets in xwayland. (LP: #1712571) diff --git a/debian/changelog b/debian/changelog index 4ef1932..5a5ae3c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +xorg-server (2:1.19.3-1ubuntu4) UNRELEASED; urgency=medium + + * xwayland-tablet.diff: Add support for Wacom tablets in xwayland. + (LP: #1712571) + + -- Timo Aaltonen <[email protected]> Thu, 24 Aug 2017 14:33:30 +0300 + xorg-server (2:1.19.3-1ubuntu3) artful; urgency=medium * SECURITY UPDATE: DoS and possible code execution in endianness diff --git a/debian/patches/series b/debian/patches/series index ae86e48..9cf8f24 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -33,3 +33,4 @@ CVE-2017-10971-1.patch CVE-2017-10971-2.patch CVE-2017-10971-3.patch CVE-2017-10972.patch +xwayland-tablet.diff diff --git a/debian/patches/xwayland-tablet.diff b/debian/patches/xwayland-tablet.diff new file mode 100644 index 0000000..7af7a8f --- /dev/null +++ b/debian/patches/xwayland-tablet.diff @@ -0,0 +1,1568 @@ + +7c7a540f1e1d6b5 xwayland: Implement tablet_tool_wheel for scrolling +fbc9814975fe82b xwayland: Correct off-by-one error in tablet button numbering +a06bb73053d9df5 xwayland: Unconditionally initialize lists in init_tablet_manager_seat() +8475e6360ce3155 xwayland: add tablet pad support +f471b5b8eb451b4 xwayland: update cursor on tablet tools in proximity +6d1ad39fe6c1822 xwayland: Refactor cursor management into xwl_cursor +773b04748d0c839 xwayland: handle button events after motion events +8a1defcc634dadd xwayland: Handle tablet_tool events +5812d1c28f4fb7b xwayland: Handle wp_tablet events +47c4415912b5b16 xwayland: Listen for wp_tablet_seat events +7d48b758a601ce0 xwayland: Bind to wp_tablet_manager if available and get its seats +89c841915ac4fba xwayland: Depend on wayland-protocols to build tablet protocol headers + + +--- a/configure.ac ++++ b/configure.ac +@@ -2526,7 +2526,7 @@ AM_CONDITIONAL(XFAKESERVER, [test "x$KDR + + dnl Xwayland DDX + +-XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.1 $LIBDRM epoxy" ++XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.5 $LIBDRM epoxy" + if test "x$XF86VIDMODE" = xyes; then + XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO" + fi +--- a/hw/xwayland/Makefile.am ++++ b/hw/xwayland/Makefile.am +@@ -56,7 +56,9 @@ Xwayland_built_sources += \ + relative-pointer-unstable-v1-client-protocol.h \ + relative-pointer-unstable-v1-protocol.c \ + pointer-constraints-unstable-v1-client-protocol.h \ +- pointer-constraints-unstable-v1-protocol.c ++ pointer-constraints-unstable-v1-protocol.c \ ++ tablet-unstable-v2-client-protocol.h \ ++ tablet-unstable-v2-protocol.c + + nodist_Xwayland_SOURCES = $(Xwayland_built_sources) + CLEANFILES = $(Xwayland_built_sources) +@@ -79,6 +81,11 @@ pointer-constraints-unstable-v1-protocol + pointer-constraints-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ + ++tablet-unstable-v2-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml ++ $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ ++tablet-unstable-v2-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml ++ $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ ++ + %-protocol.c : %.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ + +--- a/hw/xwayland/xwayland-cursor.c ++++ b/hw/xwayland/xwayland-cursor.c +@@ -96,11 +96,11 @@ xwl_unrealize_cursor(DeviceIntPtr device + } + + static void +-clear_cursor_frame_callback(struct xwl_seat *xwl_seat) ++clear_cursor_frame_callback(struct xwl_cursor *xwl_cursor) + { +- if (xwl_seat->cursor_frame_cb) { +- wl_callback_destroy (xwl_seat->cursor_frame_cb); +- xwl_seat->cursor_frame_cb = NULL; ++ if (xwl_cursor->frame_cb) { ++ wl_callback_destroy (xwl_cursor->frame_cb); ++ xwl_cursor->frame_cb = NULL; + } + } + +@@ -109,12 +109,12 @@ frame_callback(void *data, + struct wl_callback *callback, + uint32_t time) + { +- struct xwl_seat *xwl_seat = data; ++ struct xwl_cursor *xwl_cursor = data; + +- clear_cursor_frame_callback(xwl_seat); +- if (xwl_seat->cursor_needs_update) { +- xwl_seat->cursor_needs_update = FALSE; +- xwl_seat_set_cursor(xwl_seat); ++ clear_cursor_frame_callback(xwl_cursor); ++ if (xwl_cursor->needs_update) { ++ xwl_cursor->needs_update = FALSE; ++ xwl_cursor->update_proc(xwl_cursor); + } + } + +@@ -125,6 +125,7 @@ static const struct wl_callback_listener + void + xwl_seat_set_cursor(struct xwl_seat *xwl_seat) + { ++ struct xwl_cursor *xwl_cursor = &xwl_seat->cursor; + PixmapPtr pixmap; + CursorPtr cursor; + int stride; +@@ -135,13 +136,13 @@ xwl_seat_set_cursor(struct xwl_seat *xwl + if (!xwl_seat->x_cursor) { + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, NULL, 0, 0); +- clear_cursor_frame_callback(xwl_seat); +- xwl_seat->cursor_needs_update = FALSE; ++ clear_cursor_frame_callback(xwl_cursor); ++ xwl_cursor->needs_update = FALSE; + return; + } + +- if (xwl_seat->cursor_frame_cb) { +- xwl_seat->cursor_needs_update = TRUE; ++ if (xwl_cursor->frame_cb) { ++ xwl_cursor->needs_update = TRUE; + return; + } + +@@ -159,19 +160,69 @@ xwl_seat_set_cursor(struct xwl_seat *xwl + + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, +- xwl_seat->cursor, ++ xwl_cursor->surface, + xwl_seat->x_cursor->bits->xhot, + xwl_seat->x_cursor->bits->yhot); +- wl_surface_attach(xwl_seat->cursor, ++ wl_surface_attach(xwl_cursor->surface, + xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); +- wl_surface_damage(xwl_seat->cursor, 0, 0, ++ wl_surface_damage(xwl_cursor->surface, 0, 0, + xwl_seat->x_cursor->bits->width, + xwl_seat->x_cursor->bits->height); + +- xwl_seat->cursor_frame_cb = wl_surface_frame(xwl_seat->cursor); +- wl_callback_add_listener(xwl_seat->cursor_frame_cb, &frame_listener, xwl_seat); ++ xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface); ++ wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor); + +- wl_surface_commit(xwl_seat->cursor); ++ wl_surface_commit(xwl_cursor->surface); ++} ++ ++void ++xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool) ++{ ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor; ++ PixmapPtr pixmap; ++ CursorPtr cursor; ++ int stride; ++ ++ if (!xwl_seat->x_cursor) { ++ zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, ++ xwl_tablet_tool->proximity_in_serial, ++ NULL, 0, 0); ++ return; ++ } ++ ++ if (xwl_cursor->frame_cb) { ++ xwl_cursor->needs_update = TRUE; ++ return; ++ } ++ ++ cursor = xwl_seat->x_cursor; ++ pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); ++ if (!pixmap) ++ return; ++ ++ stride = cursor->bits->width * 4; ++ if (cursor->bits->argb) ++ memcpy(pixmap->devPrivate.ptr, ++ cursor->bits->argb, cursor->bits->height * stride); ++ else ++ expand_source_and_mask(cursor, pixmap->devPrivate.ptr); ++ ++ zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, ++ xwl_tablet_tool->proximity_in_serial, ++ xwl_cursor->surface, ++ xwl_seat->x_cursor->bits->xhot, ++ xwl_seat->x_cursor->bits->yhot); ++ wl_surface_attach(xwl_cursor->surface, ++ xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); ++ wl_surface_damage(xwl_cursor->surface, 0, 0, ++ xwl_seat->x_cursor->bits->width, ++ xwl_seat->x_cursor->bits->height); ++ ++ xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface); ++ wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor); ++ ++ wl_surface_commit(xwl_cursor->surface); + } + + static void +@@ -179,6 +230,7 @@ xwl_set_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor, int x, int y) + { + struct xwl_seat *xwl_seat; ++ struct xwl_tablet_tool *xwl_tablet_tool; + Bool cursor_visibility_changed; + + xwl_seat = device->public.devicePrivate; +@@ -193,6 +245,11 @@ xwl_set_cursor(DeviceIntPtr device, + xwl_seat_cursor_visibility_changed(xwl_seat); + + xwl_seat_set_cursor(xwl_seat); ++ ++ xorg_list_for_each_entry(xwl_tablet_tool, &xwl_seat->tablet_tools, link) { ++ if (xwl_tablet_tool->proximity_in_serial != 0) ++ xwl_tablet_tool_set_cursor(xwl_tablet_tool); ++ } + } + + static void +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -34,6 +34,8 @@ + #include <inpututils.h> + #include <mipointer.h> + #include <mipointrst.h> ++#include <misc.h> ++#include "tablet-unstable-v2-client-protocol.h" + + /* Copied from mipointer.c */ + #define MIPOINTER(dev) \ +@@ -62,6 +64,12 @@ static void + xwl_seat_destroy_confined_pointer(struct xwl_seat *xwl_seat); + + static void ++init_tablet_manager_seat(struct xwl_screen *xwl_screen, ++ struct xwl_seat *xwl_seat); ++static void ++release_tablet_manager_seat(struct xwl_seat *xwl_seat); ++ ++static void + xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl) + { + /* Nothing to do, dix handles all settings */ +@@ -287,6 +295,75 @@ xwl_touch_proc(DeviceIntPtr device, int + #undef NTOUCHPOINTS + } + ++static int ++xwl_tablet_proc(DeviceIntPtr device, int what) ++{ ++#define NBUTTONS 9 ++#define NAXES 6 ++ Atom btn_labels[NBUTTONS] = { 0 }; ++ Atom axes_labels[NAXES] = { 0 }; ++ BYTE map[NBUTTONS + 1] = { 0 }; ++ int i; ++ ++ switch (what) { ++ case DEVICE_INIT: ++ device->public.on = FALSE; ++ ++ for (i = 1; i <= NBUTTONS; i++) ++ map[i] = i; ++ ++ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); ++ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); ++ axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE); ++ axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X); ++ axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y); ++ axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL); ++ ++ if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels, ++ GetMotionHistorySize(), Absolute)) ++ return BadValue; ++ ++ /* Valuators - match the xf86-input-wacom ranges */ ++ InitValuatorAxisStruct(device, 0, axes_labels[0], ++ 0, 262143, 10000, 0, 10000, Absolute); ++ InitValuatorAxisStruct(device, 1, axes_labels[1], ++ 0, 262143, 10000, 0, 10000, Absolute); ++ /* pressure */ ++ InitValuatorAxisStruct(device, 2, axes_labels[2], ++ 0, 65535, 1, 0, 1, Absolute); ++ /* tilt x */ ++ InitValuatorAxisStruct(device, 3, axes_labels[3], ++ -64, 63, 57, 0, 57, Absolute); ++ /* tilt y */ ++ InitValuatorAxisStruct(device, 4, axes_labels[4], ++ -64, 63, 57, 0, 57, Absolute); ++ /* abs wheel (airbrush) or rotation (artpen) */ ++ InitValuatorAxisStruct(device, 5, axes_labels[5], ++ -900, 899, 1, 0, 1, Absolute); ++ ++ if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control)) ++ return BadValue; ++ ++ if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map)) ++ return BadValue; ++ ++ return Success; ++ ++ case DEVICE_ON: ++ device->public.on = TRUE; ++ return Success; ++ ++ case DEVICE_OFF: ++ case DEVICE_CLOSE: ++ device->public.on = FALSE; ++ return Success; ++ } ++ ++ return BadMatch; ++#undef NAXES ++#undef NBUTTONS ++} ++ + static void + pointer_handle_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, +@@ -347,9 +424,9 @@ pointer_handle_enter(void *data, struct + * of our surfaces might not have been shown. In that case we'll + * have a cursor surface frame callback pending which we need to + * clear so that we can continue submitting new cursor frames. */ +- if (xwl_seat->cursor_frame_cb) { +- wl_callback_destroy(xwl_seat->cursor_frame_cb); +- xwl_seat->cursor_frame_cb = NULL; ++ if (xwl_seat->cursor.frame_cb) { ++ wl_callback_destroy(xwl_seat->cursor.frame_cb); ++ xwl_seat->cursor.frame_cb = NULL; + xwl_seat_set_cursor(xwl_seat); + } + +@@ -1126,6 +1203,31 @@ static const struct wl_seat_listener sea + }; + + static void ++xwl_cursor_init(struct xwl_cursor *xwl_cursor, struct xwl_screen *xwl_screen, ++ void (* update_proc)(struct xwl_cursor *)) ++{ ++ xwl_cursor->surface = wl_compositor_create_surface(xwl_screen->compositor); ++ xwl_cursor->update_proc = update_proc; ++ xwl_cursor->frame_cb = NULL; ++ xwl_cursor->needs_update = FALSE; ++} ++ ++static void ++xwl_cursor_release(struct xwl_cursor *xwl_cursor) ++{ ++ wl_surface_destroy(xwl_cursor->surface); ++ if (xwl_cursor->frame_cb) ++ wl_callback_destroy(xwl_cursor->frame_cb); ++} ++ ++static void ++xwl_seat_update_cursor(struct xwl_cursor *xwl_cursor) ++{ ++ struct xwl_seat *xwl_seat = wl_container_of(xwl_cursor, xwl_seat, cursor); ++ xwl_seat_set_cursor(xwl_seat); ++} ++ ++static void + create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version) + { + struct xwl_seat *xwl_seat; +@@ -1144,8 +1246,12 @@ create_input_device(struct xwl_screen *x + &wl_seat_interface, min(version, 5)); + xwl_seat->id = id; + +- xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor); ++ xwl_cursor_init(&xwl_seat->cursor, xwl_seat->xwl_screen, ++ xwl_seat_update_cursor); + wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat); ++ ++ init_tablet_manager_seat(xwl_screen, xwl_seat); ++ + wl_array_init(&xwl_seat->keys); + + xorg_list_init(&xwl_seat->touches); +@@ -1169,15 +1275,1028 @@ xwl_seat_destroy(struct xwl_seat *xwl_se + free (p); + } + ++ release_tablet_manager_seat(xwl_seat); ++ + wl_seat_destroy(xwl_seat->seat); +- wl_surface_destroy(xwl_seat->cursor); +- if (xwl_seat->cursor_frame_cb) +- wl_callback_destroy(xwl_seat->cursor_frame_cb); ++ xwl_cursor_release(&xwl_seat->cursor); + wl_array_release(&xwl_seat->keys); + free(xwl_seat); + } + + static void ++tablet_handle_name(void *data, struct zwp_tablet_v2 *tablet, const char *name) ++{ ++} ++ ++static void ++tablet_handle_id(void *data, struct zwp_tablet_v2 *tablet, uint32_t vid, ++ uint32_t pid) ++{ ++} ++ ++static void ++tablet_handle_path(void *data, struct zwp_tablet_v2 *tablet, const char *path) ++{ ++} ++ ++static void ++tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet) ++{ ++ struct xwl_tablet *xwl_tablet = data; ++ struct xwl_seat *xwl_seat = xwl_tablet->seat; ++ ++ if (xwl_seat->stylus == NULL) { ++ xwl_seat->stylus = add_device(xwl_seat, "xwayland-stylus", xwl_tablet_proc); ++ ActivateDevice(xwl_seat->stylus, TRUE); ++ } ++ EnableDevice(xwl_seat->stylus, TRUE); ++ ++ if (xwl_seat->eraser == NULL) { ++ xwl_seat->eraser = add_device(xwl_seat, "xwayland-eraser", xwl_tablet_proc); ++ ActivateDevice(xwl_seat->eraser, TRUE); ++ } ++ EnableDevice(xwl_seat->eraser, TRUE); ++ ++ if (xwl_seat->puck == NULL) { ++ xwl_seat->puck = add_device(xwl_seat, "xwayland-cursor", xwl_tablet_proc); ++ ActivateDevice(xwl_seat->puck, TRUE); ++ } ++ EnableDevice(xwl_seat->puck, TRUE); ++} ++ ++static void ++tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet) ++{ ++ struct xwl_tablet *xwl_tablet = data; ++ struct xwl_seat *xwl_seat = xwl_tablet->seat; ++ ++ xorg_list_del(&xwl_tablet->link); ++ ++ /* The tablet is merely disabled, not removed. The next tablet ++ will re-use the same X devices */ ++ if (xorg_list_is_empty(&xwl_seat->tablets)) { ++ if (xwl_seat->stylus) ++ DisableDevice(xwl_seat->stylus, TRUE); ++ if (xwl_seat->eraser) ++ DisableDevice(xwl_seat->eraser, TRUE); ++ if (xwl_seat->puck) ++ DisableDevice(xwl_seat->puck, TRUE); ++ /* pads are removed separately */

