xorg-server: Changes to 'ubuntu'
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 <tjaalton@debian.org>
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 <tjaalton@debian.org> Thu, 24 Aug 2017 14:33:30 +0300
+ -- Timo Aaltonen <tjaalton@debian.org> Fri, 25 Aug 2017 08:32:17 +0300
xorg-server (2:1.19.3-1ubuntu3) artful; urgency=medium
commit 431ecda6854a4db7742fd66cb2815c7eb92b570d
Author: Timo Aaltonen <tjaalton@debian.org>
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 <tjaalton@debian.org> 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 <ofourdan@redhat.com>
+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 <ofourdan@redhat.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ 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 <tjaalton@debian.org>
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 <tjaalton@debian.org> 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 <tjaalton@debian.org>
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 <tjaalton@debian.org> 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 */
Reply to: