[PATCH v2 xserver 8/9] xwayland: update cursor on tablet tools in proximity
Jason Gerecke
killertofu at gmail.com
Thu Feb 9 19:31:56 UTC 2017
On Tue, Feb 7, 2017 at 6:42 PM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> From: Carlos Garnacho <carlosg at gnome.org>
>
> 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 at gnome.org>
> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> No changes to v1
>
> 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 1b854bf..5316b56 100644
> --- a/hw/xwayland/xwayland-cursor.c
> +++ b/hw/xwayland/xwayland-cursor.c
> @@ -165,11 +165,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;
> @@ -184,6 +235,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)
I got a segfault here once while "abusing" things with simultaneous
stylus/pointer input in GNOME. I haven't been able to replicate it a
second time yet and don't have the coredump anymore, though I still
have the backtrace.
Jason
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one /
(That is to say, eight) to the two, /
But you can’t take seven from three, /
So you look at the sixty-fours....
> + 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 3cf2082..31e2473 100644
> --- a/hw/xwayland/xwayland-input.c
> +++ b/hw/xwayland/xwayland-input.c
> @@ -1398,6 +1398,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);
> }
> @@ -1421,7 +1422,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
> @@ -1430,6 +1434,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;
> @@ -1710,10 +1715,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);
> @@ -1724,6 +1739,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 a1e97f2..eceac32 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;
> float 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.9.3
>
More information about the xorg-devel
mailing list