Blame SOURCES/0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch

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