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.
209 lines
7.2 KiB
209 lines
7.2 KiB
6 years ago
|
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
|
||
|
|