[PATCH v2 xserver 8/9] xwayland: update cursor on tablet tools in proximity

Peter Hutterer peter.hutterer at who-t.net
Thu Feb 9 23:36:40 UTC 2017


On Thu, Feb 09, 2017 at 11:31:56AM -0800, Jason Gerecke wrote:
> 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.

send me the backtrace please and maybe some more info on what you did.
Haven't been able to reproduce any crash yet.

Cheers,
   Peter

> 
> > +            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