[mutter/wip/wayland] wayland: Support the attach method on the input device interface



commit 87c1d7c047ea6f4bea84d7677a8d3114d428f55f
Author: Neil Roberts <neil linux intel com>
Date:   Wed Jan 18 23:55:46 2012 +0000

    wayland: Support the attach method on the input device interface
    
    The attach method sets a buffer and a hotspot position to use for the
    cursor image. Mutter now just converts the buffer to a Cogl texture
    and sets it on the ClutterTexture for the cursor. The cursor reverts
    back to the default image whenever to the pointer focus is moved off
    of any surface.

 src/wayland/meta-wayland-input-device.c |   20 +++++++++
 src/wayland/meta-wayland-stage.c        |   69 ++++++++++++++++++++++++++++--
 src/wayland/meta-wayland-stage.h        |   20 ++++++---
 src/wayland/meta-wayland.c              |    3 +
 4 files changed, 101 insertions(+), 11 deletions(-)
---
diff --git a/src/wayland/meta-wayland-input-device.c b/src/wayland/meta-wayland-input-device.c
index adba30c..48beb03 100644
--- a/src/wayland/meta-wayland-input-device.c
+++ b/src/wayland/meta-wayland-input-device.c
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <linux/input.h>
 #include "meta-wayland-input-device.h"
+#include "meta-wayland-stage.h"
 #include "meta-wayland-private.h"
 
 struct _MetaWaylandInputDevice
@@ -45,6 +46,25 @@ input_device_attach (struct wl_client *client,
                      int32_t hotspot_x,
                      int32_t hotspot_y)
 {
+  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+  MetaWaylandStage *stage = META_WAYLAND_STAGE (compositor->stage);
+  MetaWaylandInputDevice *device = resource->data;
+  struct wl_input_device *input_device = (struct wl_input_device *) device;
+
+  if (time < input_device->pointer_focus_time)
+    return;
+  if (input_device->pointer_focus == NULL)
+    return;
+  if (input_device->pointer_focus->resource.client != client)
+    return;
+
+  if (buffer_resource)
+    meta_wayland_stage_set_cursor_from_buffer (stage,
+                                               buffer_resource->data,
+                                               hotspot_x,
+                                               hotspot_y);
+  else
+    meta_wayland_stage_set_invisible_cursor (stage);
 }
 
 const static struct wl_input_device_interface
diff --git a/src/wayland/meta-wayland-stage.c b/src/wayland/meta-wayland-stage.c
index 4956f09..3f32199 100644
--- a/src/wayland/meta-wayland-stage.c
+++ b/src/wayland/meta-wayland-stage.c
@@ -22,6 +22,7 @@
 #include <config.h>
 
 #define COGL_ENABLE_EXPERIMENTAL_2_0_API
+#define CLUTTER_ENABLE_EXPERIMENTAL_API
 #include <clutter/clutter.h>
 
 #include "meta-wayland-stage.h"
@@ -163,17 +164,75 @@ meta_wayland_stage_set_cursor_position (MetaWaylandStage *self,
   update_cursor_position (self);
 }
 
-void
-meta_wayland_stage_set_default_cursor (MetaWaylandStage *self)
+static void
+meta_wayland_stage_set_cursor_from_texture (MetaWaylandStage *self,
+                                            CoglTexture      *texture,
+                                            int               hotspot_x,
+                                            int               hotspot_y)
 {
   ClutterTexture *cursor_texture =
     CLUTTER_TEXTURE (self->cursor_texture);
 
-  self->cursor_hotspot_x = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X;
-  self->cursor_hotspot_y = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y;
+  self->cursor_hotspot_x = hotspot_x;
+  self->cursor_hotspot_y = hotspot_y;
+
+  clutter_texture_set_cogl_texture (cursor_texture, texture);
+
+  clutter_actor_show (self->cursor_texture);
+
+  update_cursor_position (self);
+}
+
+void
+meta_wayland_stage_set_invisible_cursor (MetaWaylandStage *self)
+{
+  ClutterTexture *cursor_texture =
+    CLUTTER_TEXTURE (self->cursor_texture);
 
   clutter_texture_set_cogl_texture (cursor_texture,
                                     self->default_cursor_image);
+  clutter_actor_hide (self->cursor_texture);
+}
 
-  update_cursor_position (self);
+void
+meta_wayland_stage_set_default_cursor (MetaWaylandStage *self)
+{
+  int hotspot_x = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X;
+  int hotspot_y = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y;
+
+  meta_wayland_stage_set_cursor_from_texture (self,
+                                              self->default_cursor_image,
+                                              hotspot_x,
+                                              hotspot_y);
+}
+
+void
+meta_wayland_stage_set_cursor_from_buffer (MetaWaylandStage *self,
+                                           struct wl_buffer *buffer,
+                                           int               hotspot_x,
+                                           int               hotspot_y)
+{
+  ClutterBackend *backend = clutter_get_default_backend ();
+  CoglContext *context = clutter_backend_get_cogl_context (backend);
+  CoglTexture *texture;
+  GError *error = NULL;
+
+  texture = COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (context,
+                                                                   buffer,
+                                                                   &error));
+
+  if (texture == NULL)
+    {
+      g_warning ("%s", error->message);
+      meta_wayland_stage_set_invisible_cursor (self);
+    }
+  else
+    {
+      meta_wayland_stage_set_cursor_from_texture (self,
+                                                  texture,
+                                                  hotspot_x,
+                                                  hotspot_y);
+
+      cogl_object_unref (texture);
+    }
 }
diff --git a/src/wayland/meta-wayland-stage.h b/src/wayland/meta-wayland-stage.h
index 05412b9..46539ca 100644
--- a/src/wayland/meta-wayland-stage.h
+++ b/src/wayland/meta-wayland-stage.h
@@ -21,6 +21,7 @@
 #define META_WAYLAND_STAGE_H
 
 #include <clutter/clutter.h>
+#include <wayland-server.h>
 
 G_BEGIN_DECLS
 
@@ -69,15 +70,22 @@ struct _MetaWaylandStage
   int cursor_hotspot_y;
 };
 
-GType             meta_wayland_stage_get_type            (void) G_GNUC_CONST;
+GType             meta_wayland_stage_get_type               (void) G_GNUC_CONST;
 
-ClutterActor     *meta_wayland_stage_new                 (void);
+ClutterActor     *meta_wayland_stage_new                    (void);
 
-void              meta_wayland_stage_set_cursor_position (MetaWaylandStage *stage,
-                                                          int               x,
-                                                          int               y);
+void              meta_wayland_stage_set_cursor_position    (MetaWaylandStage *stage,
+                                                             int               x,
+                                                             int               y);
 
-void              meta_wayland_stage_set_default_cursor (MetaWaylandStage  *self);
+void              meta_wayland_stage_set_default_cursor     (MetaWaylandStage *self);
+
+void              meta_wayland_stage_set_cursor_from_buffer (MetaWaylandStage *self,
+                                                             struct wl_buffer *buffer,
+                                                             int               hotspot_x,
+                                                             int               hotspot_y);
+
+void              meta_wayland_stage_set_invisible_cursor   (MetaWaylandStage *self);
 
 
 G_END_DECLS
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 0cc1399..7ea3362 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -1077,6 +1077,9 @@ event_cb (ClutterActor *stage,
                                           device->x,
                                           device->y);
 
+  if (device->pointer_focus == NULL)
+    meta_wayland_stage_set_default_cursor (META_WAYLAND_STAGE (stage));
+
   display = meta_get_display ();
   if (!display)
     return FALSE;



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