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

2016-04-30 Thread Jonas Ådahl
On Wed, Feb 03, 2016 at 03:28:11PM +1000, Peter Hutterer wrote:
> From: Stephen Chandler Paul 
> 
> Again, a lot of this is code that has been reused from the cursor code
> for pointers.
> 
> Co-authored-by: Peter Hutterer 
> Signed-off-by: Stephen Chandler Paul 
> Signed-off-by: Peter Hutterer 

Reviewed-by: Jonas Ådahl 

> ---
>  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,
> +  &table

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

2016-02-04 Thread Bill Spitzak
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 
wrote:

> From: Stephen Chandler Paul 
>
> Again, a lot of this is code that has been reused from the cursor code
> for pointers.
>
> Co-authored-by: Peter Hutterer 
> Signed-off-by: Stephen Chandler Paul 
> Signed-off-by: Peter Hutterer 
> ---
>  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_a

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

2016-02-02 Thread Peter Hutterer
From: Stephen Chandler Paul 

Again, a lot of this is code that has been reused from the cursor code
for pointers.

Co-authored-by: Peter Hutterer 
Signed-off-by: Stephen Chandler Paul 
Signed-off-by: Peter Hutterer 
---
 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_su