[PATCH v2 weston 07/13] client: Add tablet cursor support into libtoytoolkit

Bill Spitzak spitzak at gmail.com
Wed Feb 3 19:21:07 UTC 2016


Does toytoolkit really need to support animated cursors?

If so it would be nice to animate the normal cursor, too, and perhaps
demonstrate code reuse for this.


On Tue, Feb 2, 2016 at 9:28 PM, Peter Hutterer <peter.hutterer at who-t.net>
wrote:

> From: Stephen Chandler Paul <thatslyude at gmail.com>
>
> Again, a lot of this is code that has been reused from the cursor code
> for pointers.
>
> Co-authored-by: Peter Hutterer <peter.hutterer at who-t.net>
> Signed-off-by: Stephen Chandler Paul <thatslyude at gmail.com>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>  clients/window.c | 138
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  clients/window.h |  13 ++++--
>  2 files changed, 145 insertions(+), 6 deletions(-)
>
> diff --git a/clients/window.c b/clients/window.c
> index 37c703b..26c2593 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -159,6 +159,12 @@ struct tablet_tool {
>         struct tablet *current_tablet;
>         struct window *focus;
>         struct widget *focus_widget;
> +       uint32_t enter_serial;
> +       uint32_t cursor_serial;
> +       int current_cursor;
> +       struct wl_surface *cursor_surface;
> +       uint32_t cursor_anim_start;
> +       struct wl_callback *cursor_frame_cb;
>
>         enum zwp_tablet_tool_v1_type type;
>         uint64_t serial;
> @@ -332,6 +338,7 @@ struct widget {
>         int opaque;
>         int tooltip_count;
>         int default_cursor;
> +       int default_tablet_cursor;
>         /* If this is set to false then no cairo surface will be
>          * created before redrawing the surface. This is useful if the
>          * redraw handler is going to do completely custom rendering
> @@ -1676,6 +1683,7 @@ widget_create(struct window *window, struct surface
> *surface, void *data)
>         widget->tooltip = NULL;
>         widget->tooltip_count = 0;
>         widget->default_cursor = CURSOR_LEFT_PTR;
> +       widget->default_tablet_cursor = CURSOR_LEFT_PTR;
>         widget->use_cairo = 1;
>
>         return widget;
> @@ -1734,6 +1742,12 @@ widget_set_default_cursor(struct widget *widget,
> int cursor)
>  }
>
>  void
> +widget_set_default_tablet_cursor(struct widget *widget, int cursor)
> +{
> +       widget->default_tablet_cursor = cursor;
> +}
> +
> +void
>  widget_get_allocation(struct widget *widget, struct rectangle *allocation)
>  {
>         *allocation = widget->allocation;
> @@ -5667,6 +5681,117 @@ tablet_tool_handle_removed(void *data, struct
> zwp_tablet_tool_v1 *zwp_tablet_too
>         zwp_tablet_tool_v1_destroy(zwp_tablet_tool_v1);
>  }
>
> +static const struct wl_callback_listener
> tablet_tool_cursor_surface_listener;
> +
> +static void
> +tablet_tool_set_cursor_image_index(struct tablet_tool *tool, int index)
> +{
> +       struct wl_buffer *buffer;
> +       struct wl_cursor *cursor;
> +       struct wl_cursor_image *image;
> +
> +       cursor = tool->input->display->cursors[tool->current_cursor];
> +       if (index >= (int)cursor->image_count) {
> +               fprintf(stderr, "cursor index out of range\n");
> +               return;
> +       }
> +
> +       image = cursor->images[index];
> +       buffer = wl_cursor_image_get_buffer(image);
> +       if (!buffer)
> +               return;
> +
> +       wl_surface_attach(tool->cursor_surface, buffer, 0, 0);
> +       wl_surface_damage(tool->cursor_surface, 0, 0,
> +                         image->width, image->height);
> +       wl_surface_commit(tool->cursor_surface);
> +       zwp_tablet_tool_v1_set_cursor(tool->tool, tool->enter_serial,
> +                                     tool->cursor_surface,
> +                                     image->hotspot_x, image->hotspot_y);
> +}
> +
> +static void
> +tablet_tool_surface_frame_callback(void *data, struct wl_callback
> *callback,
> +                                  uint32_t time)
> +{
> +       struct tablet_tool *tool = data;
> +       struct wl_cursor *cursor;
> +       int i;
> +
> +       if (callback) {
> +               assert(callback == tool->cursor_frame_cb);
> +               wl_callback_destroy(callback);
> +               tool->cursor_frame_cb = NULL;
> +       }
> +
> +       if (tool->current_cursor == CURSOR_BLANK) {
> +               zwp_tablet_tool_v1_set_cursor(tool->tool,
> tool->enter_serial,
> +                                             NULL, 0, 0);
> +               return;
> +       }
> +
> +       if (tool->current_cursor == CURSOR_UNSET)
> +               return;
> +
> +       cursor = tool->input->display->cursors[tool->current_cursor];
> +       if (!cursor)
> +               return;
> +
> +       /* FIXME We don't have the current time on the first call so we set
> +        * the animation start to the time of the first frame callback. */
> +       if (time == 0)
> +               tool->cursor_anim_start = 0;
> +       else if (tool->cursor_anim_start == 0)
> +               tool->cursor_anim_start = time;
> +
> +       if (time == 0 || tool->cursor_anim_start == 0)
> +               i = 0;
> +       else
> +               i = wl_cursor_frame(cursor, time -
> tool->cursor_anim_start);
> +
> +       if (cursor->image_count > 1) {
> +               tool->cursor_frame_cb =
> +                       wl_surface_frame(tool->cursor_surface);
> +               wl_callback_add_listener(tool->cursor_frame_cb,
> +
> &tablet_tool_cursor_surface_listener,
> +                                        tool);
> +       }
> +
> +       tablet_tool_set_cursor_image_index(tool, i);
> +}
> +
> +static const struct wl_callback_listener
> tablet_tool_cursor_surface_listener =  {
> +       tablet_tool_surface_frame_callback,
> +};
> +
> +void
> +tablet_tool_set_cursor_image(struct tablet_tool *tool, int cursor)
> +{
> +       bool force = false;
> +
> +       if (tool->enter_serial > tool->cursor_serial)
> +               force = true;
> +
> +       if (!force && cursor == tool->current_cursor)
> +               return;
> +
> +       tool->current_cursor = cursor;
> +       tool->cursor_serial = tool->enter_serial;
> +
> +       if (!tool->cursor_frame_cb) {
> +               tablet_tool_surface_frame_callback(tool, NULL, 0);
> +       } else if (force) {
> +               /* The current frame callback may be stuck if, for
> instance,
> +                * the set cursor request was processed by the server after
> +                * this client lost the focus. In this case the cursor
> surface
> +                * might not be mapped and the frame callback wouldn't ever
> +                * complete. Send a set_cursor and attach to try to map the
> +                * cursor surface again so that the callback will finish
> +                */
> +               tablet_tool_set_cursor_image_index(tool, 0);
> +       }
> +}
> +
>  static void
>  tablet_tool_set_focus_widget(struct tablet_tool *tool, struct window
> *window,
>                              wl_fixed_t sx, wl_fixed_t sy)
> @@ -5707,6 +5832,7 @@ tablet_tool_handle_proximity_in(void *data,
>
>         tool->focus = window;
>         tool->current_tablet = tablet;
> +       tool->enter_serial = serial;
>  }
>
>  static void
> @@ -5751,6 +5877,7 @@ tablet_tool_handle_motion(void *data, struct
> zwp_tablet_tool_v1 *zwp_tablet_tool
>         double sy = wl_fixed_to_double(y);
>         struct window *window = tool->focus;
>         struct widget *widget;
> +       int cursor;
>
>         if (!window)
>                 return;
> @@ -5765,9 +5892,14 @@ tablet_tool_handle_motion(void *data, struct
> zwp_tablet_tool_v1 *zwp_tablet_tool
>         tablet_tool_set_focus_widget(tool, window, sx, sy);
>         widget = tool->focus_widget;
>         if (widget && widget->tablet_tool_motion_handler) {
> -               widget->tablet_tool_motion_handler(widget, tool, sx, sy,
> -                                                  widget->user_data);
> +               cursor = widget->tablet_tool_motion_handler(widget, tool,
> +                                                           sx, sy,
> +
>  widget->user_data);
> +       } else {
> +               cursor = widget->default_tablet_cursor;
>         }
> +
> +       tablet_tool_set_cursor_image(tool, cursor);
>  }
>
>  static void
> @@ -5908,6 +6040,8 @@ tablet_tool_added(void *data, struct
> zwp_tablet_seat_v1 *zwp_tablet_seat1,
>
>         tool->tool = id;
>         tool->input = input;
> +       tool->cursor_surface =
> +               wl_compositor_create_surface(input->display->compositor);
>  }
>
>  static const struct zwp_tablet_seat_v1_listener tablet_seat_listener = {
> diff --git a/clients/window.h b/clients/window.h
> index 86f0366..903abf0 100644
> --- a/clients/window.h
> +++ b/clients/window.h
> @@ -275,10 +275,10 @@ typedef void (*widget_axis_handler_t)(struct widget
> *widget,
>                                       uint32_t axis,
>                                       wl_fixed_t value,
>                                       void *data);
> -typedef void (*widget_tablet_tool_motion_handler_t)(struct widget *widget,
> -                                                   struct tablet_tool
> *tool,
> -                                                   float x, float y,
> -                                                   void *data);
> +typedef int (*widget_tablet_tool_motion_handler_t)(struct widget *widget,
> +                                                  struct tablet_tool
> *tool,
> +                                                  float x, float y,
> +                                                  void *data);
>  typedef void (*widget_tablet_tool_down_handler_t)(struct widget *widget,
>                                                   struct tablet_tool *tool,
>                                                   void *data);
> @@ -533,6 +533,8 @@ widget_destroy(struct widget *widget);
>  void
>  widget_set_default_cursor(struct widget *widget, int cursor);
>  void
> +widget_set_default_tablet_cursor(struct widget *widget, int cursor);
> +void
>  widget_get_allocation(struct widget *widget, struct rectangle
> *allocation);
>
>  void
> @@ -750,4 +752,7 @@ tablet_tool_get_serial(struct tablet_tool *tool);
>  uint64_t
>  tablet_tool_get_hwid(struct tablet_tool *tool);
>
> +void
> +tablet_tool_set_cursor_image(struct tablet_tool *tool, int cursor);
> +
>  #endif
> --
> 2.5.0
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20160203/ef5fd28c/attachment-0001.html>


More information about the wayland-devel mailing list