[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