[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