- xserver-1.19.4

- Backport tablet support for Xwayland
This commit is contained in:
Olivier Fourdan 2017-10-05 16:19:23 +02:00
parent 78f536200b
commit 314a7cadab
16 changed files with 2266 additions and 47 deletions

View File

@ -1,4 +1,4 @@
From fc306295751178802405e0faa3f2e4e40cd913f0 Mon Sep 17 00:00:00 2001
From e96a83d9b1b5a52a41213c7a4840dc96b4f5b06f Mon Sep 17 00:00:00 2001
From: Adam Jackson <ajax@redhat.com>
Date: Wed, 15 Aug 2012 12:35:21 -0400
Subject: [PATCH] Always install vbe and int10 sdk headers
@ -9,7 +9,7 @@ Signed-off-by: Adam Jackson <ajax@redhat.com>
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 27f2cc6..f9a078f 100644
index b876b79..a170b58 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -26,17 +26,9 @@ if VGAHW
@ -27,11 +27,11 @@ index 27f2cc6..f9a078f 100644
-SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \
+SUBDIRS = common ddc x86emu int10 os-support parser \
ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \
- $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
- $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods xkb \
+ $(DRI2_SUBDIR) . vbe i2c dixmods \
fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man \
$(GLAMOR_EGL_SUBDIR) drivers
--
2.1.0
2.13.6

View File

@ -1,38 +0,0 @@
From 0c8e6ed85810e96d84173a52d628863802a78d82 Mon Sep 17 00:00:00 2001
From: Daniel Stone <daniels@collabora.com>
Date: Fri, 7 Apr 2017 14:27:58 +0100
Subject: [PATCH xserver] modesetting: Set correct DRM event context version
DRM_EVENT_CONTEXT_VERSION is the latest context version supported by
whatever version of libdrm is present. modesetting was blindly asserting
it supported whatever version that may be, even if it actually didn't.
With libdrm 2.4.78, setting a higher context version than 2 will attempt
to call the page_flip_handler2 vfunc if it was non-NULL, which being a
random chunk of stack memory, it might well have been.
Set the version as 2, which should be bumped only with the appropriate
version checks.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Daniel Stone <daniels@collabora.com>
---
hw/xfree86/drivers/modesetting/vblank.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 04a8952..8682f4d 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -402,7 +402,7 @@ ms_vblank_screen_init(ScreenPtr screen)
modesettingEntPtr ms_ent = ms_ent_priv(scrn);
xorg_list_init(&ms_drm_queue);
- ms->event_context.version = DRM_EVENT_CONTEXT_VERSION;
+ ms->event_context.version = 2;
ms->event_context.vblank_handler = ms_drm_handler;
ms->event_context.page_flip_handler = ms_drm_handler;
--
2.9.3

View File

@ -0,0 +1,73 @@
From 7f22271ca7ace43f6fa1168a2acea9af6f2d5896 Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Thu, 13 Oct 2016 10:39:46 -0700
Subject: [PATCH xserver 01/12] xwayland: Depend on wayland-protocols to build
tablet protocol headers
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 89c841915ac4fba6d2a5ad0051c778f1a76ffbf3)
---
configure.ac | 2 +-
hw/xwayland/Makefile.am | 9 ++++++++-
hw/xwayland/xwayland-input.c | 1 +
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index e6c5b35de..d34e10538 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2503,7 +2503,7 @@ AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes])
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
diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
index a3c9fce48..e376f09dd 100644
--- 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.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstab
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 < $< > $@
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index f2564d5d3..8fdc875ea 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -34,6 +34,7 @@
#include <inpututils.h>
#include <mipointer.h>
#include <mipointrst.h>
+#include "tablet-unstable-v2-client-protocol.h"
/* Copied from mipointer.c */
#define MIPOINTER(dev) \
--
2.13.5

View File

@ -0,0 +1,166 @@
From 8dcc03fb4a5db18fb52377ee578a2a673d691a1e Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Fri, 15 Jan 2016 17:29:37 -0800
Subject: [PATCH xserver 02/12] xwayland: Bind to wp_tablet_manager if
available and get its seats
If we're notified about the existence of the wp_tablet_manager interface,
we bind to it so that we can make use of any tablets that are (or later
become) available. For each seat that exists or comes into existance at
a later point, obtain the associated tablet_seat.
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 7d48b758a601ce0252ebd21297a7c42263adfaaf)
---
hw/xwayland/xwayland-input.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.c | 2 ++
hw/xwayland/xwayland.h | 4 +++
3 files changed, 65 insertions(+)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 8fdc875ea..1d2be978e 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -63,6 +63,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 */
@@ -1147,6 +1153,9 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version
xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
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);
@@ -1170,6 +1179,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
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)
@@ -1178,6 +1189,52 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
free(xwl_seat);
}
+
+static void
+init_tablet_manager_seat(struct xwl_screen *xwl_screen,
+ struct xwl_seat *xwl_seat)
+{
+ if (!xwl_screen->tablet_manager)
+ return;
+
+ xwl_seat->tablet_seat =
+ zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager,
+ xwl_seat->seat);
+}
+
+static void
+release_tablet_manager_seat(struct xwl_seat *xwl_seat)
+{
+ if (xwl_seat->tablet_seat) {
+ zwp_tablet_seat_v2_destroy(xwl_seat->tablet_seat);
+ xwl_seat->tablet_seat = NULL;
+ }
+}
+
+static void
+init_tablet_manager(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version)
+{
+ struct xwl_seat *xwl_seat;
+
+ xwl_screen->tablet_manager = wl_registry_bind(xwl_screen->registry,
+ id,
+ &zwp_tablet_manager_v2_interface,
+ min(version,1));
+
+ xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
+ init_tablet_manager_seat(xwl_screen, xwl_seat);
+ }
+}
+
+void
+xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen)
+{
+ if (xwl_screen->tablet_manager) {
+ zwp_tablet_manager_v2_destroy(xwl_screen->tablet_manager);
+ xwl_screen->tablet_manager = NULL;
+ }
+}
+
static void
init_relative_pointer_manager(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version)
@@ -1211,6 +1268,8 @@ input_handler(void *data, struct wl_registry *registry, uint32_t id,
init_relative_pointer_manager(xwl_screen, id, version);
} else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
init_pointer_constraints(xwl_screen, id, version);
+ } else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) {
+ init_tablet_manager(xwl_screen, id, version);
}
}
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 939f3392c..fa7b81c7a 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -130,6 +130,8 @@ xwl_close_screen(ScreenPtr screen)
&xwl_screen->seat_list, link)
xwl_seat_destroy(xwl_seat);
+ xwl_screen_release_tablet_manager(xwl_screen);
+
RemoveNotifyFd(xwl_screen->wayland_fd);
wl_display_disconnect(xwl_screen->display);
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 5e5624be0..2752d731c 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -76,6 +76,7 @@ struct xwl_screen {
struct wl_registry *registry;
struct wl_registry *input_registry;
struct wl_compositor *compositor;
+ struct zwp_tablet_manager_v2 *tablet_manager;
struct wl_shm *shm;
struct wl_shell *shell;
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
@@ -137,6 +138,7 @@ struct xwl_seat {
struct zwp_relative_pointer_v1 *wp_relative_pointer;
struct wl_keyboard *wl_keyboard;
struct wl_touch *wl_touch;
+ struct zwp_tablet_seat_v2 *tablet_seat;
struct wl_array keys;
struct xwl_window *focus_window;
uint32_t id;
@@ -241,6 +243,8 @@ Bool xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version);
struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap);
+void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
+
#ifdef XV
/* glamor Xv Adaptor */
Bool xwl_glamor_xv_init(ScreenPtr pScreen);
--
2.13.5

View File

@ -0,0 +1,173 @@
From 243eadc7979e35756a4f0e349ee97bbbd3a268c3 Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Fri, 14 Oct 2016 14:50:18 -0700
Subject: [PATCH xserver 03/12] xwayland: Listen for wp_tablet_seat events
The wp_tablet_seat interface provides us with notifications as tablets,
tools, and pads are connected to the system. Add listener functions and
store references to the obtained devices.
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 47c4415912b5b16b115135be365beb370858df76)
---
hw/xwayland/xwayland-input.c | 94 ++++++++++++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.h | 22 +++++++++++
2 files changed, 116 insertions(+)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 1d2be978e..d5d12933c 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1191,6 +1191,69 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
static void
+tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
+ struct zwp_tablet_v2 *tablet)
+{
+ struct xwl_seat *xwl_seat = data;
+ struct xwl_tablet *xwl_tablet;
+
+ xwl_tablet = calloc(sizeof *xwl_tablet, 1);
+ if (xwl_tablet == NULL) {
+ ErrorF("%s ENOMEM\n", __func__);
+ return;
+ }
+
+ xwl_tablet->tablet = tablet;
+ xwl_tablet->seat = xwl_seat;
+
+ xorg_list_add(&xwl_tablet->link, &xwl_seat->tablets);
+}
+
+static void
+tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
+ struct zwp_tablet_tool_v2 *tool)
+{
+ struct xwl_seat *xwl_seat = data;
+ struct xwl_tablet_tool *xwl_tablet_tool;
+
+ xwl_tablet_tool = calloc(sizeof *xwl_tablet_tool, 1);
+ if (xwl_tablet_tool == NULL) {
+ ErrorF("%s ENOMEM\n", __func__);
+ return;
+ }
+
+ xwl_tablet_tool->tool = tool;
+ xwl_tablet_tool->seat = xwl_seat;
+
+ xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools);
+}
+
+static void
+tablet_seat_handle_add_pad(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
+ struct zwp_tablet_pad_v2 *pad)
+{
+ struct xwl_seat *xwl_seat = data;
+ struct xwl_tablet_pad *xwl_tablet_pad;
+
+ xwl_tablet_pad = calloc(sizeof *xwl_tablet_pad, 1);
+ if (xwl_tablet_pad == NULL) {
+ ErrorF("%s ENOMEM\n", __func__);
+ return;
+ }
+
+ xwl_tablet_pad->pad = pad;
+ xwl_tablet_pad->seat = xwl_seat;
+
+ xorg_list_add(&xwl_tablet_pad->link, &xwl_seat->tablet_pads);
+}
+
+static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
+ tablet_seat_handle_add_tablet,
+ tablet_seat_handle_add_tool,
+ tablet_seat_handle_add_pad
+};
+
+static void
init_tablet_manager_seat(struct xwl_screen *xwl_screen,
struct xwl_seat *xwl_seat)
{
@@ -1200,11 +1263,42 @@ init_tablet_manager_seat(struct xwl_screen *xwl_screen,
xwl_seat->tablet_seat =
zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager,
xwl_seat->seat);
+
+ xorg_list_init(&xwl_seat->tablets);
+ xorg_list_init(&xwl_seat->tablet_tools);
+ xorg_list_init(&xwl_seat->tablet_pads);
+
+ zwp_tablet_seat_v2_add_listener(xwl_seat->tablet_seat, &tablet_seat_listener, xwl_seat);
}
static void
release_tablet_manager_seat(struct xwl_seat *xwl_seat)
{
+ struct xwl_tablet *xwl_tablet, *next_xwl_tablet;
+ struct xwl_tablet_tool *xwl_tablet_tool, *next_xwl_tablet_tool;
+ struct xwl_tablet_pad *xwl_tablet_pad, *next_xwl_tablet_pad;
+
+ xorg_list_for_each_entry_safe(xwl_tablet_pad, next_xwl_tablet_pad,
+ &xwl_seat->tablet_pads, link) {
+ xorg_list_del(&xwl_tablet_pad->link);
+ zwp_tablet_pad_v2_destroy(xwl_tablet_pad->pad);
+ free(xwl_tablet_pad);
+ }
+
+ xorg_list_for_each_entry_safe(xwl_tablet_tool, next_xwl_tablet_tool,
+ &xwl_seat->tablet_tools, link) {
+ xorg_list_del(&xwl_tablet_tool->link);
+ zwp_tablet_tool_v2_destroy(xwl_tablet_tool->tool);
+ free(xwl_tablet_tool);
+ }
+
+ xorg_list_for_each_entry_safe(xwl_tablet, next_xwl_tablet,
+ &xwl_seat->tablets, link) {
+ xorg_list_del(&xwl_tablet->link);
+ zwp_tablet_v2_destroy(xwl_tablet->tablet);
+ free(xwl_tablet);
+ }
+
if (xwl_seat->tablet_seat) {
zwp_tablet_seat_v2_destroy(xwl_seat->tablet_seat);
xwl_seat->tablet_seat = NULL;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 2752d731c..a7f30b3c8 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -174,6 +174,28 @@ struct xwl_seat {
double dx_unaccel;
double dy_unaccel;
} pending_pointer_event;
+
+ struct xorg_list tablets;
+ struct xorg_list tablet_tools;
+ struct xorg_list tablet_pads;
+};
+
+struct xwl_tablet {
+ struct xorg_list link;
+ struct zwp_tablet_v2 *tablet;
+ struct xwl_seat *seat;
+};
+
+struct xwl_tablet_tool {
+ struct xorg_list link;
+ struct zwp_tablet_tool_v2 *tool;
+ struct xwl_seat *seat;
+};
+
+struct xwl_tablet_pad {
+ struct xorg_list link;
+ struct zwp_tablet_pad_v2 *pad;
+ struct xwl_seat *seat;
};
struct xwl_output {
--
2.13.5

View File

@ -0,0 +1,211 @@
From 591b08b3311c5217969a8ceb3ed58b58fabc4891 Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Fri, 15 Jan 2016 17:01:38 -0800
Subject: [PATCH xserver 04/12] xwayland: Handle wp_tablet events
Creates and maintains the canonical trio of X devices (stylus, eraser,
and cursor) to be shared by all connected tablets. A per-tablet trio
could be created instead, but there are very few benefits to such a
configuration since all tablets still ultimately share control of a
single master pointer.
The three X devices are modeled after those created by xf86-input-wacom
but use a generic maximum X and Y that should be large enough to
accurately represent values from even the largest currently-available
tablets.
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 5812d1c28f4fb7b7de8b96a81415a21425561fd4)
---
hw/xwayland/xwayland-input.c | 142 +++++++++++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.h | 3 +
2 files changed, 145 insertions(+)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index d5d12933c..64655de5f 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -294,6 +294,75 @@ xwl_touch_proc(DeviceIntPtr device, int what)
#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,
@@ -1189,6 +1258,77 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
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);
+ }
+
+ zwp_tablet_v2_destroy(tablet);
+ free(xwl_tablet);
+}
+
+static const struct zwp_tablet_v2_listener tablet_listener = {
+ tablet_handle_name,
+ tablet_handle_id,
+ tablet_handle_path,
+ tablet_handle_done,
+ tablet_handle_removed
+};
static void
tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
@@ -1207,6 +1347,8 @@ tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat
xwl_tablet->seat = xwl_seat;
xorg_list_add(&xwl_tablet->link, &xwl_seat->tablets);
+
+ zwp_tablet_v2_add_listener(tablet, &tablet_listener, xwl_tablet);
}
static void
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index a7f30b3c8..e7e62882b 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -132,6 +132,9 @@ struct xwl_seat {
DeviceIntPtr relative_pointer;
DeviceIntPtr keyboard;
DeviceIntPtr touch;
+ DeviceIntPtr stylus;
+ DeviceIntPtr eraser;
+ DeviceIntPtr puck;
struct xwl_screen *xwl_screen;
struct wl_seat *seat;
struct wl_pointer *wl_pointer;
--
2.13.5

View File

@ -0,0 +1,374 @@
From 4354336014ca0c29270a6cdf83e9f9e5fe16080e Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Fri, 14 Oct 2016 14:31:46 -0700
Subject: [PATCH xserver 05/12] xwayland: Handle tablet_tool events
Translates Wayland tablet events into corresponding X11 tablet events. As
with the prior commit, these events are modeled after those created by the
xf86-input-wacom driver to maximize compatibility with existing applications.
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 8a1defcc634daddbb3570519d69ec5c9e39a8b56)
---
hw/xwayland/xwayland-input.c | 313 +++++++++++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.h | 9 ++
2 files changed, 322 insertions(+)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 64655de5f..142862f7e 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1331,6 +1331,317 @@ static const struct zwp_tablet_v2_listener tablet_listener = {
};
static void
+tablet_tool_receive_type(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t type)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+
+ switch (type) {
+ case ZWP_TABLET_TOOL_V2_TYPE_ERASER:
+ xwl_tablet_tool->xdevice = xwl_seat->eraser;
+ break;
+ case ZWP_TABLET_TOOL_V2_TYPE_MOUSE:
+ case ZWP_TABLET_TOOL_V2_TYPE_LENS:
+ xwl_tablet_tool->xdevice = xwl_seat->puck;
+ break;
+ default:
+ xwl_tablet_tool->xdevice = xwl_seat->stylus;
+ break;
+ }
+}
+
+static void
+tablet_tool_receive_hardware_serial(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t hi, uint32_t low)
+{
+}
+
+static void
+tablet_tool_receive_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t hi, uint32_t low)
+{
+}
+
+static void
+tablet_tool_receive_capability(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t capability)
+{
+}
+
+static void
+tablet_tool_receive_done(void *data, struct zwp_tablet_tool_v2 *tool)
+{
+}
+
+static void
+tablet_tool_receive_removed(void *data, struct zwp_tablet_tool_v2 *tool)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+
+ xorg_list_del(&xwl_tablet_tool->link);
+ zwp_tablet_tool_v2_destroy(tool);
+ free(xwl_tablet_tool);
+}
+
+static void
+tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t serial, struct zwp_tablet_v2 *tablet,
+ struct wl_surface *wl_surface)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+
+ /* There's a race here where if we create and then immediately
+ * destroy a surface, we might end up in a state where the Wayland
+ * compositor sends us an event for a surface that doesn't exist.
+ *
+ * Don't process enter events in this case.
+ *
+ * see pointer_handle_enter()
+ */
+ if (wl_surface == NULL)
+ return;
+
+ xwl_seat->focus_window = wl_surface_get_user_data(wl_surface);
+}
+
+static void
+tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+
+ xwl_seat->focus_window = NULL;
+
+ xwl_tablet_tool->pressure = 0;
+ xwl_tablet_tool->tilt_x = 0;
+ xwl_tablet_tool->tilt_y = 0;
+ xwl_tablet_tool->rotation = 0;
+ xwl_tablet_tool->slider = 0;
+}
+
+static void
+tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+ ValuatorMask mask;
+
+ xwl_seat->xwl_screen->serial = serial;
+
+ valuator_mask_zero(&mask);
+ QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonPress, 1, 0, &mask);
+}
+
+static void
+tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ ValuatorMask mask;
+
+ valuator_mask_zero(&mask);
+ QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonRelease, 1, 0, &mask);
+}
+
+static void
+tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
+ wl_fixed_t x, wl_fixed_t y)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+ int32_t dx, dy;
+ int sx = wl_fixed_to_int(x);
+ int sy = wl_fixed_to_int(y);
+
+ if (!xwl_seat->focus_window)
+ return;
+
+ dx = xwl_seat->focus_window->window->drawable.x;
+ dy = xwl_seat->focus_window->window->drawable.y;
+
+ xwl_tablet_tool->x = dx + sx;
+ xwl_tablet_tool->y = dy + sy;
+}
+
+static void
+tablet_tool_pressure(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t pressure)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+
+ if (!xwl_seat->focus_window)
+ return;
+
+ /* normalized to 65535 already */
+ xwl_tablet_tool->pressure = pressure;
+}
+
+static void
+tablet_tool_distance(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t distance_raw)
+{
+}
+
+static void
+tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *tool,
+ wl_fixed_t tilt_x, wl_fixed_t tilt_y)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+
+ if (!xwl_seat->focus_window)
+ return;
+
+ xwl_tablet_tool->tilt_x = wl_fixed_to_double(tilt_x);
+ xwl_tablet_tool->tilt_y = wl_fixed_to_double(tilt_y);
+}
+
+static void
+tablet_tool_rotation(void *data, struct zwp_tablet_tool_v2 *tool,
+ wl_fixed_t angle)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+ double rotation = wl_fixed_to_double(angle);
+
+ if (!xwl_seat->focus_window)
+ return;
+
+ /* change origin (buttons facing right [libinput +90 degrees]) and
+ * scaling (5 points per degree) to match wacom driver behavior
+ */
+ rotation = remainderf(rotation + 90.0f, 360.0f);
+ rotation *= 5.0f;
+ xwl_tablet_tool->rotation = rotation;
+}
+
+static void
+tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *tool,
+ int32_t position_raw)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+ float position = position_raw / 65535.0;
+
+ if (!xwl_seat->focus_window)
+ return;
+
+ xwl_tablet_tool->slider = (position * 1799.0f) - 900.0f;
+}
+
+static void
+tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool,
+ wl_fixed_t degrees, int32_t clicks)
+{
+}
+
+static void
+tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool,
+ uint32_t serial, uint32_t button, uint32_t state)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+ int xbtn = 0;
+ ValuatorMask mask;
+
+ /* BTN_0 .. BTN_9 */
+ if (button >= 0x100 && button <= 0x109) {
+ xbtn = button - 0x100 + 1;
+ }
+ /* BTN_A .. BTN_Z */
+ else if (button >= 0x130 && button <= 0x135) {
+ xbtn = button - 0x130 + 10;
+ }
+ /* BTN_BASE .. BTN_BASE6 */
+ else if (button >= 0x126 && button <= 0x12b) {
+ xbtn = button - 0x126 + 16;
+ }
+ else {
+ switch (button) {
+ case 0x110: /* BTN_LEFT */
+ case 0x14a: /* BTN_TOUCH */
+ xbtn = 1;
+ break;
+
+ case 0x112: /* BTN_MIDDLE */
+ case 0x14b: /* BTN_STYLUS */
+ xbtn = 2;
+ break;
+
+ case 0x111: /* BTN_RIGHT */
+ case 0x14c: /* BTN_STYLUS2 */
+ xbtn = 3;
+ break;
+
+ case 0x113: /* BTN_SIDE */
+ case 0x116: /* BTN_BACK */
+ xbtn = 8;
+ break;
+
+ case 0x114: /* BTN_EXTRA */
+ case 0x115: /* BTN_FORWARD */
+ xbtn = 9;
+ break;
+ }
+ }
+
+ if (!xbtn) {
+ ErrorF("unknown tablet button number %d\n", button);
+ return;
+ }
+
+ xwl_seat->xwl_screen->serial = serial;
+
+ valuator_mask_zero(&mask);
+ QueuePointerEvents(xwl_tablet_tool->xdevice,
+ state ? ButtonPress : ButtonRelease, xbtn, 0, &mask);
+}
+
+static void
+tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ ValuatorMask mask;
+
+ valuator_mask_zero(&mask);
+ valuator_mask_set(&mask, 0, xwl_tablet_tool->x);
+ valuator_mask_set(&mask, 1, xwl_tablet_tool->y);
+ valuator_mask_set(&mask, 2, xwl_tablet_tool->pressure);
+ valuator_mask_set(&mask, 3, xwl_tablet_tool->tilt_x);
+ valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y);
+ valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider);
+
+ /* FIXME: Store button mask in xwl_tablet_tool and send events *HERE* if
+ changed */
+ QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0,
+ POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
+}
+
+static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
+ tablet_tool_receive_type,
+ tablet_tool_receive_hardware_serial,
+ tablet_tool_receive_hardware_id_wacom,
+ tablet_tool_receive_capability,
+ tablet_tool_receive_done,
+ tablet_tool_receive_removed,
+ tablet_tool_proximity_in,
+ tablet_tool_proximity_out,
+ tablet_tool_down,
+ tablet_tool_up,
+ tablet_tool_motion,
+ tablet_tool_pressure,
+ tablet_tool_distance,
+ tablet_tool_tilt,
+ tablet_tool_rotation,
+ tablet_tool_slider,
+ tablet_tool_wheel,
+ tablet_tool_button_state,
+ tablet_tool_frame
+};
+
+static void
tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
struct zwp_tablet_v2 *tablet)
{
@@ -1368,6 +1679,8 @@ tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
xwl_tablet_tool->seat = xwl_seat;
xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools);
+
+ zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, xwl_tablet_tool);
}
static void
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index e7e62882b..fb9ac4804 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -193,6 +193,15 @@ struct xwl_tablet_tool {
struct xorg_list link;
struct zwp_tablet_tool_v2 *tool;
struct xwl_seat *seat;
+
+ DeviceIntPtr xdevice;
+ uint32_t x;
+ uint32_t y;
+ uint32_t pressure;
+ float tilt_x;
+ float tilt_y;
+ float rotation;
+ float slider;
};
struct xwl_tablet_pad {
--
2.13.5

View File

@ -0,0 +1,121 @@
From 317ce1201a2ec848f9066294ea544b756f735385 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 7 Feb 2017 12:23:46 +1000
Subject: [PATCH xserver 06/12] xwayland: handle button events after motion
events
Make sure the button events are sent after the motion events into the new
position.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 773b04748d0c839bc8b12e33f74bb8d11c447f5b)
---
hw/xwayland/xwayland-input.c | 44 +++++++++++++++++++++++++++++++++++++-------
hw/xwayland/xwayland.h | 3 +++
2 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 142862f7e..50da10839 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -34,6 +34,7 @@
#include <inpututils.h>
#include <mipointer.h>
#include <mipointrst.h>
+#include <misc.h>
#include "tablet-unstable-v2-client-protocol.h"
/* Copied from mipointer.c */
@@ -1543,8 +1544,8 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool,
{
struct xwl_tablet_tool *xwl_tablet_tool = data;
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+ uint32_t *mask = &xwl_tablet_tool->buttons_now;
int xbtn = 0;
- ValuatorMask mask;
/* BTN_0 .. BTN_9 */
if (button >= 0x100 && button <= 0x109) {
@@ -1592,11 +1593,14 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool,
return;
}
- xwl_seat->xwl_screen->serial = serial;
+ BUG_RETURN(xbtn >= 8 * sizeof(*mask));
- valuator_mask_zero(&mask);
- QueuePointerEvents(xwl_tablet_tool->xdevice,
- state ? ButtonPress : ButtonRelease, xbtn, 0, &mask);
+ if (state)
+ SetBit(mask, xbtn);
+ else
+ ClearBit(mask, xbtn);
+
+ xwl_seat->xwl_screen->serial = serial;
}
static void
@@ -1604,6 +1608,8 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
{
struct xwl_tablet_tool *xwl_tablet_tool = data;
ValuatorMask mask;
+ uint32_t released, pressed, diff;
+ int button;
valuator_mask_zero(&mask);
valuator_mask_set(&mask, 0, xwl_tablet_tool->x);
@@ -1613,10 +1619,34 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y);
valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider);
- /* FIXME: Store button mask in xwl_tablet_tool and send events *HERE* if
- changed */
QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
+
+ valuator_mask_zero(&mask);
+
+ diff = xwl_tablet_tool->buttons_prev ^ xwl_tablet_tool->buttons_now;
+ released = diff & ~xwl_tablet_tool->buttons_now;
+ pressed = diff & xwl_tablet_tool->buttons_now;
+
+ button = 1;
+ while (released) {
+ if (released & 0x1)
+ QueuePointerEvents(xwl_tablet_tool->xdevice,
+ ButtonRelease, button, 0, &mask);
+ button++;
+ released >>= 1;
+ }
+
+ button = 1;
+ while (pressed) {
+ if (pressed & 0x1)
+ QueuePointerEvents(xwl_tablet_tool->xdevice,
+ ButtonPress, button, 0, &mask);
+ button++;
+ pressed >>= 1;
+ }
+
+ xwl_tablet_tool->buttons_prev = xwl_tablet_tool->buttons_now;
}
static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index fb9ac4804..bb119dad7 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -202,6 +202,9 @@ struct xwl_tablet_tool {
float tilt_y;
float rotation;
float slider;
+
+ uint32_t buttons_now,
+ buttons_prev;
};
struct xwl_tablet_pad {
--
2.13.5

View File

@ -0,0 +1,213 @@
From 94a88b752a9373656bb0f62897513c8f5e552127 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 4 Nov 2016 19:36:10 +0100
Subject: [PATCH xserver 07/12] xwayland: Refactor cursor management into
xwl_cursor
This struct takes away the cursor info in xwl_seat, and has
an update function so we can share the frame handling code
across several xwl_cursors.
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 6d1ad39fe6c18220dd39b0653fd1e4145140e2dc)
---
hw/xwayland/xwayland-cursor.c | 39 ++++++++++++++++++++-------------------
hw/xwayland/xwayland-input.c | 38 +++++++++++++++++++++++++++++++-------
hw/xwayland/xwayland.h | 11 ++++++++---
3 files changed, 59 insertions(+), 29 deletions(-)
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index f334f1ca5..fdae3ce85 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -96,11 +96,11 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
}
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 frame_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_seat)
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,19 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
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);
}
static void
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 50da10839..bb520e891 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -424,9 +424,9 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
* 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);
}
@@ -1203,6 +1203,31 @@ static const struct wl_seat_listener seat_listener = {
};
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;
@@ -1221,7 +1246,8 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version
&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);
@@ -1252,9 +1278,7 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
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);
}
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index bb119dad7..bfa5f47c7 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -127,6 +127,13 @@ struct xwl_pointer_warp_emulator {
struct zwp_locked_pointer_v1 *locked_pointer;
};
+struct xwl_cursor {
+ void (* update_proc) (struct xwl_cursor *);
+ struct wl_surface *surface;
+ struct wl_callback *frame_cb;
+ Bool needs_update;
+};
+
struct xwl_seat {
DeviceIntPtr pointer;
DeviceIntPtr relative_pointer;
@@ -148,9 +155,7 @@ struct xwl_seat {
uint32_t pointer_enter_serial;
struct xorg_list link;
CursorPtr x_cursor;
- struct wl_surface *cursor;
- struct wl_callback *cursor_frame_cb;
- Bool cursor_needs_update;
+ struct xwl_cursor cursor;
WindowPtr last_xwindow;
struct xorg_list touches;
--
2.13.5

View File

@ -0,0 +1,208 @@
From 78a4493bc8e60da7b97342660dd1ff6de844e951 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 4 Nov 2016 19:58:04 +0100
Subject: [PATCH xserver 08/12] xwayland: update cursor on tablet tools in
proximity
Each xwl_tablet_tool gets a xwl_cursor, as on wayland each of those
will get an independent cursor that can be set through
zwp_tablet_tool.set_cursor.
However, all tools (and the pointer) share conceptually the same VCP
on Xwayland, so have cursor changes trigger a xwl_cursor update on
every tool (and the pointer, again). Maybe Xwayland could keep track
of the most recent device and only update that cursor to get better
visual results, but this is simpler, and it's going to be odd
anyway...
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit f471b5b8eb451b442554517c7cb6f0aa90d218c4)
---
hw/xwayland/xwayland-cursor.c | 56 +++++++++++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland-input.c | 17 +++++++++++++
hw/xwayland/xwayland.h | 5 ++++
3 files changed, 78 insertions(+)
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index fdae3ce85..c95f4e830 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -175,11 +175,62 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
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
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;
@@ -194,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
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index bb520e891..77cd42789 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1405,6 +1405,7 @@ tablet_tool_receive_removed(void *data, struct zwp_tablet_tool_v2 *tool)
struct xwl_tablet_tool *xwl_tablet_tool = data;
xorg_list_del(&xwl_tablet_tool->link);
+ xwl_cursor_release(&xwl_tablet_tool->cursor);
zwp_tablet_tool_v2_destroy(tool);
free(xwl_tablet_tool);
}
@@ -1428,7 +1429,10 @@ tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool,
if (wl_surface == NULL)
return;
+ xwl_tablet_tool->proximity_in_serial = serial;
xwl_seat->focus_window = wl_surface_get_user_data(wl_surface);
+
+ xwl_tablet_tool_set_cursor(xwl_tablet_tool);
}
static void
@@ -1437,6 +1441,7 @@ tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool)
struct xwl_tablet_tool *xwl_tablet_tool = data;
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+ xwl_tablet_tool->proximity_in_serial = 0;
xwl_seat->focus_window = NULL;
xwl_tablet_tool->pressure = 0;
@@ -1717,10 +1722,20 @@ tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat
}
static void
+xwl_tablet_tool_update_cursor(struct xwl_cursor *xwl_cursor)
+{
+ struct xwl_tablet_tool *xwl_tablet_tool = wl_container_of(xwl_cursor,
+ xwl_tablet_tool,
+ cursor);
+ xwl_tablet_tool_set_cursor(xwl_tablet_tool);
+}
+
+static void
tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
struct zwp_tablet_tool_v2 *tool)
{
struct xwl_seat *xwl_seat = data;
+ struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
struct xwl_tablet_tool *xwl_tablet_tool;
xwl_tablet_tool = calloc(sizeof *xwl_tablet_tool, 1);
@@ -1731,6 +1746,8 @@ tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
xwl_tablet_tool->tool = tool;
xwl_tablet_tool->seat = xwl_seat;
+ xwl_cursor_init(&xwl_tablet_tool->cursor, xwl_screen,
+ xwl_tablet_tool_update_cursor);
xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools);
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index bfa5f47c7..02a218c43 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -44,6 +44,7 @@
#include "relative-pointer-unstable-v1-client-protocol.h"
#include "pointer-constraints-unstable-v1-client-protocol.h"
+#include "tablet-unstable-v2-client-protocol.h"
struct xwl_screen {
int width;
@@ -200,6 +201,7 @@ struct xwl_tablet_tool {
struct xwl_seat *seat;
DeviceIntPtr xdevice;
+ uint32_t proximity_in_serial;
uint32_t x;
uint32_t y;
uint32_t pressure;
@@ -210,6 +212,8 @@ struct xwl_tablet_tool {
uint32_t buttons_now,
buttons_prev;
+
+ struct xwl_cursor cursor;
};
struct xwl_tablet_pad {
@@ -237,6 +241,7 @@ Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
struct xwl_screen *xwl_screen_get(ScreenPtr screen);
+void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
void xwl_seat_destroy(struct xwl_seat *xwl_seat);
--
2.13.5

View File

@ -0,0 +1,511 @@
From 6f79f4993d351a891a715e994ab9574542e64b35 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 7 Feb 2017 15:04:46 +1000
Subject: [PATCH xserver 09/12] xwayland: add tablet pad support
Hooked up a bit differently to the other tools. Those tools can be static for
all and be re-used. The wacom driver initializes the pad with the correct
number of buttons though and we can't do this until we have the pad done event.
If the tablet is removed and we plug a different one in, we should initialize
that correctly, so unlike the other tools the pad is properly removed and
re-initialized on plug.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Ping Cheng <ping.cheng@wacom.com>
(cherry picked from commit 8475e6360ce31551d50fd63a26f7a44d1e8928f2)
---
hw/xwayland/xwayland-input.c | 417 +++++++++++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.h | 28 +++
2 files changed, 445 insertions(+)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 77cd42789..8011b965c 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1341,6 +1341,7 @@ tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet)
DisableDevice(xwl_seat->eraser, TRUE);
if (xwl_seat->puck)
DisableDevice(xwl_seat->puck, TRUE);
+ /* pads are removed separately */
}
zwp_tablet_v2_destroy(tablet);
@@ -1701,6 +1702,418 @@ static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
};
static void
+tablet_pad_ring_destroy(struct xwl_tablet_pad_ring *ring)
+{
+ zwp_tablet_pad_ring_v2_destroy(ring->ring);
+ xorg_list_del(&ring->link);
+ free(ring);
+}
+
+static void
+tablet_pad_ring_source(void *data,
+ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
+ uint32_t source)
+{
+}
+
+static void
+tablet_pad_ring_angle(void *data,
+ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
+ wl_fixed_t degrees)
+{
+ struct xwl_tablet_pad_ring *ring = data;
+ struct xwl_tablet_pad *pad = ring->group->pad;
+ double deg = wl_fixed_to_double(degrees);
+ ValuatorMask mask;
+
+ valuator_mask_zero(&mask);
+ valuator_mask_set(&mask, 5 + ring->index, deg/360.0 * 71);
+ QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask);
+}
+
+static void
+tablet_pad_ring_stop(void *data,
+ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2)
+{
+}
+
+static void
+tablet_pad_ring_frame(void *data,
+ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
+ uint32_t time)
+{
+}
+
+static const struct zwp_tablet_pad_ring_v2_listener tablet_pad_ring_listener = {
+ tablet_pad_ring_source,
+ tablet_pad_ring_angle,
+ tablet_pad_ring_stop,
+ tablet_pad_ring_frame,
+};
+
+
+static void
+tablet_pad_strip_destroy(struct xwl_tablet_pad_strip *strip)
+{
+ zwp_tablet_pad_strip_v2_destroy(strip->strip);
+ xorg_list_del(&strip->link);
+ free(strip);
+}
+
+static void
+tablet_pad_strip_source(void *data,
+ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
+ uint32_t source)
+{
+}
+
+static void
+tablet_pad_strip_position(void *data,
+ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
+ uint32_t position)
+{
+ struct xwl_tablet_pad_strip *strip = data;
+ struct xwl_tablet_pad *pad = strip->group->pad;
+ ValuatorMask mask;
+
+ valuator_mask_zero(&mask);
+ valuator_mask_set(&mask, 3 + strip->index, position/65535.0 * 2048);
+ QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask);
+}
+
+static void
+tablet_pad_strip_stop(void *data,
+ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2)
+{
+}
+
+static void
+tablet_pad_strip_frame(void *data,
+ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
+ uint32_t time)
+{
+}
+
+static const struct zwp_tablet_pad_strip_v2_listener tablet_pad_strip_listener = {
+ tablet_pad_strip_source,
+ tablet_pad_strip_position,
+ tablet_pad_strip_stop,
+ tablet_pad_strip_frame,
+};
+
+static void
+tablet_pad_group_destroy(struct xwl_tablet_pad_group *group)
+{
+ struct xwl_tablet_pad_ring *r, *tr;
+ struct xwl_tablet_pad_strip *s, *ts;
+
+ xorg_list_for_each_entry_safe(r, tr,
+ &group->pad_group_ring_list,
+ link)
+ tablet_pad_ring_destroy(r);
+
+ xorg_list_for_each_entry_safe(s, ts,
+ &group->pad_group_strip_list,
+ link)
+ tablet_pad_strip_destroy(s);
+
+ zwp_tablet_pad_group_v2_destroy(group->group);
+ xorg_list_del(&group->link);
+ free(group);
+}
+
+static void
+tablet_pad_group_buttons(void *data,
+ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
+ struct wl_array *buttons)
+{
+
+}
+
+static void
+tablet_pad_group_ring(void *data,
+ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
+ struct zwp_tablet_pad_ring_v2 *wp_ring)
+{
+ static unsigned int ring_index = 0;
+ struct xwl_tablet_pad_group *group = data;
+ struct xwl_tablet_pad_ring *ring;
+
+ ring = calloc(1, sizeof *ring);
+ if (ring == NULL) {
+ ErrorF("%s ENOMEM\n", __func__);
+ return;
+ }
+
+ ring->index = ring_index++;
+ ring->group = group;
+ ring->ring = wp_ring;
+
+ xorg_list_add(&ring->link, &group->pad_group_ring_list);
+
+ zwp_tablet_pad_ring_v2_add_listener(wp_ring, &tablet_pad_ring_listener,
+ ring);
+}
+
+static void
+tablet_pad_group_strip(void *data,
+ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
+ struct zwp_tablet_pad_strip_v2 *wp_strip)
+{
+ static unsigned int strip_index = 0;
+ struct xwl_tablet_pad_group *group = data;
+ struct xwl_tablet_pad_strip *strip;
+
+ strip = calloc(1, sizeof *strip);
+ if (strip == NULL) {
+ ErrorF("%s ENOMEM\n", __func__);
+ return;
+ }
+
+ strip->index = strip_index++;
+ strip->group = group;
+ strip->strip = wp_strip;
+
+ xorg_list_add(&strip->link, &group->pad_group_strip_list);
+
+ zwp_tablet_pad_strip_v2_add_listener(wp_strip, &tablet_pad_strip_listener,
+ strip);
+}
+
+static void
+tablet_pad_group_modes(void *data,
+ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
+ uint32_t modes)
+{
+
+}
+
+static void
+tablet_pad_group_done(void *data,
+ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2)
+{
+
+}
+
+static void
+tablet_pad_group_mode_switch(void *data,
+ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
+ uint32_t time,
+ uint32_t serial,
+ uint32_t mode)
+{
+
+}
+
+static struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = {
+ tablet_pad_group_buttons,
+ tablet_pad_group_ring,
+ tablet_pad_group_strip,
+ tablet_pad_group_modes,
+ tablet_pad_group_done,
+ tablet_pad_group_mode_switch,
+};
+
+static int
+xwl_tablet_pad_proc(DeviceIntPtr device, int what)
+{
+ struct xwl_tablet_pad *pad = device->public.devicePrivate;
+ /* Axis layout mirrors that of xf86-input-wacom to have better
+ compatibility with existing clients */
+#define NAXES 7
+ Atom axes_labels[NAXES] = { 0 };
+ BYTE map[MAX_BUTTONS + 1];
+ int i = 0;
+ Atom btn_labels[MAX_BUTTONS] = { 0 }; /* btn labels are meaningless */
+ int nbuttons;
+
+ switch (what) {
+ case DEVICE_INIT:
+ device->public.on = FALSE;
+
+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+ /* The others have no good mapping */
+
+ if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
+ GetMotionHistorySize(), Absolute))
+ return BadValue;
+
+ for (i = 1; i <= MAX_BUTTONS; i++)
+ map[i] = i;
+
+ /* We need at least 7 buttons to allow scrolling */
+ nbuttons = min(max(pad->nbuttons + 4, 7), MAX_BUTTONS);
+
+ if (!InitButtonClassDeviceStruct(device, nbuttons,
+ btn_labels, map))
+ return BadValue;
+
+ /* Valuators */
+ InitValuatorAxisStruct(device, 0, axes_labels[0],
+ 0, 100, 1, 0, 1, Absolute);
+ InitValuatorAxisStruct(device, 1, axes_labels[1],
+ 0, 100, 1, 0, 1, Absolute);
+ /* Pressure - unused, for backwards compat only */
+ InitValuatorAxisStruct(device, 2, axes_labels[2],
+ 0, 2048, 1, 0, 1, Absolute);
+ /* strip x */
+ InitValuatorAxisStruct(device, 3, axes_labels[3],
+ 0, 2048, 1, 0, 1, Absolute);
+ /* strip y */
+ InitValuatorAxisStruct(device, 4, axes_labels[4],
+ 0, 2048, 1, 0, 1, Absolute);
+ /* ring */
+ InitValuatorAxisStruct(device, 5, axes_labels[5],
+ 0, 71, 1, 0, 1, Absolute);
+ /* ring2 */
+ InitValuatorAxisStruct(device, 6, axes_labels[6],
+ 0, 71, 1, 0, 1, Absolute);
+
+ if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
+ 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
+}
+
+static void
+tablet_pad_group(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
+ struct zwp_tablet_pad_group_v2 *pad_group)
+{
+ struct xwl_tablet_pad *pad = data;
+ struct xwl_tablet_pad_group *group;
+
+ group = calloc(1, sizeof *group);
+ if (pad == NULL) {
+ ErrorF("%s ENOMEM\n", __func__);
+ return;
+ }
+
+ group->pad = pad;
+ group->group = pad_group;
+ xorg_list_init(&group->pad_group_ring_list);
+ xorg_list_init(&group->pad_group_strip_list);
+
+ xorg_list_add(&group->link, &pad->pad_group_list);
+
+ zwp_tablet_pad_group_v2_add_listener(pad_group,
+ &tablet_pad_group_listener,
+ group);
+}
+
+static void
+tablet_pad_path(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
+ const char *path)
+{
+
+}
+
+static void
+tablet_pad_buttons(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
+ uint32_t buttons)
+{
+ struct xwl_tablet_pad *pad = data;
+
+ pad->nbuttons = buttons;
+}
+
+static void
+tablet_pad_done(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2)
+{
+ struct xwl_tablet_pad *pad = data;
+
+ pad->xdevice = add_device(pad->seat, "xwayland-pad",
+ xwl_tablet_pad_proc);
+ pad->xdevice->public.devicePrivate = pad;
+ ActivateDevice(pad->xdevice, TRUE);
+ EnableDevice(pad->xdevice, TRUE);
+}
+
+static void
+tablet_pad_button(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
+ uint32_t time,
+ uint32_t button,
+ uint32_t state)
+{
+ struct xwl_tablet_pad *pad = data;
+ ValuatorMask mask;
+
+ button++; /* wayland index vs X's 1-offset */
+ /* skip scroll wheel buttons 4-7 */
+ button = button > 3 ? button + 4 : button;
+
+ valuator_mask_zero(&mask);
+ QueuePointerEvents(pad->xdevice,
+ state ? ButtonPress : ButtonRelease, button, 0, &mask);
+}
+
+static void
+tablet_pad_enter(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
+ uint32_t serial,
+ struct zwp_tablet_v2 *tablet,
+ struct wl_surface *surface)
+{
+ /* pairs the pad with the tablet but also to set the focus. We
+ * don't care about the pairing and always use X's focus */
+}
+
+static void
+tablet_pad_leave(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
+ uint32_t serial,
+ struct wl_surface *surface)
+{
+ /* pairs the pad with the tablet but also to set the focus. We
+ * don't care about the pairing and always use X's focus */
+}
+
+static void
+tablet_pad_removed(void *data,
+ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2)
+{
+ struct xwl_tablet_pad *pad = data;
+ struct xwl_tablet_pad_group *g, *tg;
+
+ xorg_list_for_each_entry_safe(g, tg, &pad->pad_group_list, link)
+ tablet_pad_group_destroy(g);
+
+ RemoveDevice(pad->xdevice, TRUE);
+ xorg_list_del(&pad->link);
+ zwp_tablet_pad_v2_destroy(pad->pad);
+ free(pad);
+}
+
+static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
+ tablet_pad_group,
+ tablet_pad_path,
+ tablet_pad_buttons,
+ tablet_pad_done,
+ tablet_pad_button,
+ tablet_pad_enter,
+ tablet_pad_leave,
+ tablet_pad_removed,
+};
+
+static void
tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
struct zwp_tablet_v2 *tablet)
{
@@ -1769,8 +2182,12 @@ tablet_seat_handle_add_pad(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
xwl_tablet_pad->pad = pad;
xwl_tablet_pad->seat = xwl_seat;
+ xorg_list_init(&xwl_tablet_pad->pad_group_list);
xorg_list_add(&xwl_tablet_pad->link, &xwl_seat->tablet_pads);
+
+ zwp_tablet_pad_v2_add_listener(pad, &tablet_pad_listener,
+ xwl_tablet_pad);
}
static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 02a218c43..250564f73 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -216,10 +216,38 @@ struct xwl_tablet_tool {
struct xwl_cursor cursor;
};
+struct xwl_tablet_pad_ring {
+ unsigned int index;
+ struct xorg_list link;
+ struct xwl_tablet_pad_group *group;
+ struct zwp_tablet_pad_ring_v2 *ring;
+};
+
+struct xwl_tablet_pad_strip {
+ unsigned int index;
+ struct xorg_list link;
+ struct xwl_tablet_pad_group *group;
+ struct zwp_tablet_pad_strip_v2 *strip;
+};
+
+struct xwl_tablet_pad_group {
+ struct xorg_list link;
+ struct xwl_tablet_pad *pad;
+ struct zwp_tablet_pad_group_v2 *group;
+
+ struct xorg_list pad_group_ring_list;
+ struct xorg_list pad_group_strip_list;
+};
+
struct xwl_tablet_pad {
struct xorg_list link;
struct zwp_tablet_pad_v2 *pad;
struct xwl_seat *seat;
+
+ DeviceIntPtr xdevice;
+
+ unsigned int nbuttons;
+ struct xorg_list pad_group_list;
};
struct xwl_output {
--
2.13.5

View File

@ -0,0 +1,74 @@
From 81d85fb95d71c0d781328506f1417e7b92c68b97 Mon Sep 17 00:00:00 2001
From: Lyude <lyude@redhat.com>
Date: Thu, 4 May 2017 18:04:31 -0400
Subject: [PATCH xserver 10/12] xwayland: Unconditionally initialize lists in
init_tablet_manager_seat()
In the event that xwayland gets launched on a wayland compositor that
doesn't yet have support for wp_tablet_manager, we end up skipping the
initialization of the lists. This is wrong, because regardless of
whether or not a tablet is present we still attempt to traverse these
lists later in xwl_set_cursor(), expecting that if the lists are empty
from no tablet manager that we simply won't execute any loop iterations.
(EE)
(EE) Backtrace:
(EE) 0: Xwayland (OsSigHandler+0x3b) [0x4982f9]
(EE) 1: /lib64/libpthread.so.0 (__restore_rt+0x0) [0x7f73722545bf]
(EE) 2: Xwayland (xwl_set_cursor+0x9f) [0x429974]
(EE) 3: Xwayland (miPointerUpdateSprite+0x261) [0x4fe1ca]
(EE) 4: Xwayland (mieqProcessInputEvents+0x239) [0x4f8d33]
(EE) 5: Xwayland (ProcessInputEvents+0x9) [0x4282f0]
(EE) 6: Xwayland (Dispatch+0x42) [0x43e2d4]
(EE) 7: Xwayland (dix_main+0x5c9) [0x44c6dc]
(EE) 8: Xwayland (main+0x28) [0x61c523]
(EE) 9: /lib64/libc.so.6 (__libc_start_main+0xf1) [0x7f7371e9d401]
(EE) 10: Xwayland (_start+0x2a) [0x4208fa]
(EE) 11: ? (?+0x2a) [0x2a]
(EE)
(EE) Segmentation fault at address 0x28
(EE)
Fatal server error:
(EE) Caught signal 11 (Segmentation fault). Server aborting
(EE)
Reproduced when trying to run upstream xwayland under fedora 25's weston
package.
Signed-off-by: Lyude <lyude@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit a06bb73053d9df56d9070ce325a43af3a3c7a6a2)
---
hw/xwayland/xwayland-input.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 8011b965c..ee932be60 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -2200,6 +2200,10 @@ static void
init_tablet_manager_seat(struct xwl_screen *xwl_screen,
struct xwl_seat *xwl_seat)
{
+ xorg_list_init(&xwl_seat->tablets);
+ xorg_list_init(&xwl_seat->tablet_tools);
+ xorg_list_init(&xwl_seat->tablet_pads);
+
if (!xwl_screen->tablet_manager)
return;
@@ -2207,10 +2211,6 @@ init_tablet_manager_seat(struct xwl_screen *xwl_screen,
zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager,
xwl_seat->seat);
- xorg_list_init(&xwl_seat->tablets);
- xorg_list_init(&xwl_seat->tablet_tools);
- xorg_list_init(&xwl_seat->tablet_pads);
-
zwp_tablet_seat_v2_add_listener(xwl_seat->tablet_seat, &tablet_seat_listener, xwl_seat);
}
--
2.13.5

View File

@ -0,0 +1,39 @@
From edcc95e914079485b7d693cecbfc436d084ad47d Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Fri, 9 Jun 2017 16:02:06 -0700
Subject: [PATCH xserver 11/12] xwayland: Correct off-by-one error in tablet
button numbering
The 'tablet_tool_frame' function treats the button masks as though they
are zero-indexed, but 'tablet_tool_button_state' treats them as one-
indexed. The result is that an e.g. middle click event recieved from
Wayland will be sent from the X server as a right-click instead.
Fixes: 773b04748d0 ("xwayland: handle button events after motion events")
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit fbc9814975fe82be25becf1a55d4f8d34298a956)
---
hw/xwayland/xwayland-input.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index ee932be60..a6d7d9356 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1626,9 +1626,9 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool,
BUG_RETURN(xbtn >= 8 * sizeof(*mask));
if (state)
- SetBit(mask, xbtn);
+ SetBit(mask, xbtn - 1);
else
- ClearBit(mask, xbtn);
+ ClearBit(mask, xbtn - 1);
xwl_seat->xwl_screen->serial = serial;
}
--
2.13.5

View File

@ -0,0 +1,78 @@
From d03bf0d1759d7d113216a0311e794b5adb0845de Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Fri, 9 Jun 2017 16:02:07 -0700
Subject: [PATCH xserver 12/12] xwayland: Implement tablet_tool_wheel for
scrolling
The 'tablet_tool_wheel' function for tablet scrolling was added back in
8a1defcc634 but left unimplemented. This commit fills in the necessary
details, using the "clicks" count as the number of discrete scroll up/down
events to send.
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 7c7a540f1e1d6b5466e1c9aa28476a2d7273d5ed)
---
hw/xwayland/xwayland-input.c | 24 ++++++++++++++++++++++++
hw/xwayland/xwayland.h | 2 ++
2 files changed, 26 insertions(+)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index a6d7d9356..0cf318623 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1566,6 +1566,13 @@ static void
tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool,
wl_fixed_t degrees, int32_t clicks)
{
+ struct xwl_tablet_tool *xwl_tablet_tool = data;
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
+
+ if (!xwl_seat->focus_window)
+ return;
+
+ xwl_tablet_tool->wheel_clicks = clicks;
}
static void
@@ -1677,6 +1684,23 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
}
xwl_tablet_tool->buttons_prev = xwl_tablet_tool->buttons_now;
+
+ while (xwl_tablet_tool->wheel_clicks) {
+ if (xwl_tablet_tool->wheel_clicks < 0) {
+ button = 4;
+ xwl_tablet_tool->wheel_clicks++;
+ }
+ else {
+ button = 5;
+ xwl_tablet_tool->wheel_clicks--;
+ }
+
+ QueuePointerEvents(xwl_tablet_tool->xdevice,
+ ButtonPress, button, 0, &mask);
+ QueuePointerEvents(xwl_tablet_tool->xdevice,
+ ButtonRelease, button, 0, &mask);
+
+ }
}
static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 250564f73..135aa8761 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -213,6 +213,8 @@ struct xwl_tablet_tool {
uint32_t buttons_now,
buttons_prev;
+ int32_t wheel_clicks;
+
struct xwl_cursor cursor;
};
--
2.13.5

View File

@ -1 +1 @@
SHA512 (xorg-server-1.19.3.tar.bz2) = b988897418399e1361fdcca9465a781f55f8f6fbfdc5a59edfaee9046a0c6ad7a76f348d88b6004ce3d3fb3966b4c5af0b854f6549c32b2b8d7a43758809f669
SHA512 (xorg-server-1.19.4.tar.bz2) = ff80934e42a7dd2d437e947fe02c74c3b25bdbb3002b7005191d52272d5eae8cb3a83377fa32f40000011be88405830e796f6bd3b914bd7fc163ea8ece76226b

View File

@ -44,8 +44,8 @@
Summary: X.Org X11 X server
Name: xorg-x11-server
Version: 1.19.3
Release: 9%{?gitdate:.%{gitdate}}%{dist}
Version: 1.19.4
Release: 1%{?gitdate:.%{gitdate}}%{dist}
URL: http://www.x.org
License: MIT
Group: User Interface/X
@ -90,6 +90,20 @@ Patch14: 0004-xfree86-xf86platformProbe-split-finding-pci-info-and.patch
Patch15: 0005-xfree86-Allow-overriding-primary-GPU-detection-from-.patch
Patch16: 0006-xfree86-Add-ModulePath-support-for-OutputClass-confi.patch
# Backport tablet support for Xwayland - *NOT* in server-1.19-branch
Patch9901: 0001-xwayland-Depend-on-wayland-protocols-to-build-tablet.patch
Patch9902: 0002-xwayland-Bind-to-wp_tablet_manager-if-available-and-.patch
Patch9903: 0003-xwayland-Listen-for-wp_tablet_seat-events.patch
Patch9904: 0004-xwayland-Handle-wp_tablet-events.patch
Patch9905: 0005-xwayland-Handle-tablet_tool-events.patch
Patch9906: 0006-xwayland-handle-button-events-after-motion-events.patch
Patch9907: 0007-xwayland-Refactor-cursor-management-into-xwl_cursor.patch
Patch9908: 0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch
Patch9909: 0009-xwayland-add-tablet-pad-support.patch
Patch9910: 0010-xwayland-Unconditionally-initialize-lists-in-init_ta.patch
Patch9911: 0011-xwayland-Correct-off-by-one-error-in-tablet-button-n.patch
Patch9912: 0012-xwayland-Implement-tablet_tool_wheel-for-scrolling.patch
# From Debian use intel ddx driver only for gen4 and older chipsets
%if 0%{?fedora} > 25 || 0%{?rhel} > 7
Patch20: 06_use-intel-only-on-pre-gen4.diff
@ -98,8 +112,6 @@ Patch20: 06_use-intel-only-on-pre-gen4.diff
# Submitted upstream
Patch21: 0001-xf86-dri2-Use-va_gl-as-vdpau_driver-for-Intel-i965-G.patch
Patch22: 0001-modesetting-Set-correct-DRM-event-context-version.patch
#Patch6044: xserver-1.6.99-hush-prerelease-warning.patch
Patch7025: 0001-Always-install-vbe-and-int10-sdk-headers.patch
@ -605,6 +617,10 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete
%changelog
* Thu Oct 05 2017 Olivier Fourdan <ofourdan@redhat.com> - 1.19.4-1
- xserver-1.19.4
- Backport tablet support for Xwayland
* Fri Sep 08 2017 Troy Dawson <tdawson@redhat.com> - 1.19.3-9
- Cleanup spec file conditionals