You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
7.2 KiB
208 lines
7.2 KiB
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 |
|
|
|
|