Changeset View
Changeset View
Standalone View
Standalone View
files/0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch
- This file was added.
| 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 | |||||
Copyright © 2015-2021 Solus Project. The Solus logo is Copyright © 2016-2021 Solus Project. All Rights Reserved.