[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: