[mutter/wip/tablet-protocol: 48/50] wayland: Handle wl_tablet cursor updates



commit 072408e01dc3117717ba1c40268cb6f5652e9dc9
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Feb 5 12:10:03 2015 +0100

    wayland: Handle wl_tablet cursor updates
    
    The cursor is now properly changed on wl_tablet.set_cursor, unset if the
    surface is destroyed, and shown/hidden on tool proximity.

 src/wayland/meta-wayland-tablet.c |   91 +++++++++++++++++++++++++++++++++++++
 src/wayland/meta-wayland-tablet.h |    4 ++
 2 files changed, 95 insertions(+), 0 deletions(-)
---
diff --git a/src/wayland/meta-wayland-tablet.c b/src/wayland/meta-wayland-tablet.c
index 81dcbaf..92f1a70 100644
--- a/src/wayland/meta-wayland-tablet.c
+++ b/src/wayland/meta-wayland-tablet.c
@@ -30,11 +30,14 @@
 #include <wayland-server.h>
 #include "wayland-tablet-server-protocol.h"
 
+#include "meta-wayland-buffer.h"
 #include "meta-surface-actor-wayland.h"
 #include "meta-wayland-private.h"
 #include "meta-wayland-tablet.h"
 #include "meta-wayland-tablet-tool.h"
 
+static void meta_wayland_tablet_set_cursor_surface (MetaWaylandTablet  *tablet,
+                                                    MetaWaylandSurface *surface);
 static void meta_wayland_tablet_set_focus          (MetaWaylandTablet  *tablet,
                                                     MetaWaylandSurface *surface);
 
@@ -77,6 +80,16 @@ tablet_handle_focus_surface_destroy (struct wl_listener *listener,
   meta_wayland_tablet_set_focus (tablet, NULL);
 }
 
+static void
+tablet_handle_cursor_surface_destroy (struct wl_listener *listener,
+                                      void               *data)
+{
+  MetaWaylandTablet *tablet;
+
+  tablet = wl_container_of (listener, tablet, cursor_surface_destroy_listener);
+  meta_wayland_tablet_set_cursor_surface (tablet, NULL);
+}
+
 MetaWaylandTablet *
 meta_wayland_tablet_new (ClutterInputDevice       *device,
                          MetaWaylandTabletManager *manager)
@@ -90,9 +103,12 @@ meta_wayland_tablet_new (ClutterInputDevice       *device,
   tablet->manager = manager;
 
   tablet->focus_surface_destroy_listener.notify = tablet_handle_focus_surface_destroy;
+  tablet->cursor_surface_destroy_listener.notify = tablet_handle_cursor_surface_destroy;
 
   tablet->cursor_renderer = meta_cursor_renderer_new ();
   meta_cursor_renderer_set_cursor (tablet->cursor_renderer, NULL);
+  tablet->tools = g_hash_table_new_full (NULL, NULL, NULL,
+                                         (GDestroyNotify) meta_wayland_tablet_tool_free);
 
   return tablet;
 }
@@ -103,6 +119,7 @@ meta_wayland_tablet_free (MetaWaylandTablet *tablet)
   struct wl_resource *resource, *next;
 
   meta_wayland_tablet_set_focus (tablet, NULL);
+  meta_wayland_tablet_set_cursor_surface (tablet, NULL);
   g_hash_table_destroy (tablet->tools);
 
   wl_resource_for_each_safe (resource, next, &tablet->resource_list)
@@ -115,6 +132,61 @@ meta_wayland_tablet_free (MetaWaylandTablet *tablet)
   g_slice_free (MetaWaylandTablet, tablet);
 }
 
+static void
+meta_wayland_tablet_update_cursor_surface (MetaWaylandTablet *tablet)
+{
+  MetaCursorReference *cursor = NULL;
+
+  if (tablet->cursor_renderer == NULL)
+    return;
+
+  if (tablet->current && tablet->current_tool)
+    {
+      if (tablet->cursor_surface && tablet->cursor_surface->buffer)
+        {
+          struct wl_resource *buffer = tablet->cursor_surface->buffer->resource;
+          cursor = meta_cursor_reference_from_buffer (buffer,
+                                                      tablet->hotspot_x,
+                                                      tablet->hotspot_y);
+        }
+      else
+        cursor = NULL;
+    }
+  else if (tablet->current_tool)
+    cursor = meta_cursor_reference_from_theme (META_CURSOR_CROSSHAIR);
+  else
+    cursor = NULL;
+
+  if (!tablet->cursor && !cursor)
+    return;
+
+  meta_cursor_renderer_set_cursor (tablet->cursor_renderer, cursor);
+
+  if (tablet->cursor)
+    meta_cursor_reference_unref (tablet->cursor);
+
+  tablet->cursor = cursor;
+}
+
+static void
+meta_wayland_tablet_set_cursor_surface (MetaWaylandTablet  *tablet,
+                                        MetaWaylandSurface *surface)
+{
+  if (tablet->cursor_surface == surface)
+    return;
+
+  if (tablet->cursor_surface)
+    wl_list_remove (&tablet->cursor_surface_destroy_listener.link);
+
+  tablet->cursor_surface = surface;
+
+  if (tablet->cursor_surface)
+    wl_resource_add_destroy_listener (tablet->cursor_surface->resource,
+                                      &tablet->cursor_surface_destroy_listener);
+
+  meta_wayland_tablet_update_cursor_surface (tablet);
+}
+
 static struct wl_resource *
 meta_wayland_tablet_ensure_tool_resource_for_client (MetaWaylandTablet *tablet,
                                                      struct wl_client  *client)
@@ -199,6 +271,8 @@ meta_wayland_tablet_set_focus (MetaWaylandTablet  *tablet,
             }
         }
     }
+
+  meta_wayland_tablet_update_cursor_surface (tablet);
 }
 
 static void
@@ -258,6 +332,7 @@ repick_for_event (MetaWaylandTablet  *tablet,
     tablet->current = NULL;
 
   sync_focus_surface (tablet);
+  meta_wayland_tablet_update_cursor_surface (tablet);
 }
 
 static MetaWaylandTabletTool *
@@ -313,6 +388,7 @@ meta_wayland_tablet_update (MetaWaylandTablet  *tablet,
       }
     case CLUTTER_PROXIMITY_OUT:
       tablet->current_tool = NULL;
+      meta_wayland_tablet_update_cursor_surface (tablet);
       break;
     default:
       break;
@@ -374,6 +450,21 @@ tablet_set_cursor (struct wl_client   *client,
                    int32_t             hotspot_x,
                    int32_t             hotspot_y)
 {
+  MetaWaylandTablet *tablet = wl_resource_get_user_data (resource);
+  MetaWaylandSurface *surface;
+
+  surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL);
+
+  if (tablet->focus_surface == NULL)
+    return;
+  if (wl_resource_get_client (tablet->focus_surface->resource) != client)
+    return;
+  if (tablet->proximity_serial - serial > G_MAXUINT32 / 2)
+    return;
+
+  tablet->hotspot_x = hotspot_x;
+  tablet->hotspot_y = hotspot_y;
+  meta_wayland_tablet_set_cursor_surface (tablet, surface);
 }
 
 static const struct wl_tablet_interface tablet_interface = {
diff --git a/src/wayland/meta-wayland-tablet.h b/src/wayland/meta-wayland-tablet.h
index 6e6230f..b3d4106 100644
--- a/src/wayland/meta-wayland-tablet.h
+++ b/src/wayland/meta-wayland-tablet.h
@@ -45,6 +45,10 @@ struct _MetaWaylandTablet
   struct wl_listener focus_surface_destroy_listener;
 
   MetaCursorRenderer *cursor_renderer;
+  MetaCursorReference *cursor;
+  MetaWaylandSurface *cursor_surface;
+  struct wl_listener cursor_surface_destroy_listener;
+  int hotspot_x, hotspot_y;
 
   MetaWaylandSurface *current;
   GSList *buttons;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]