diff --git a/src/Makefile.am b/src/Makefile.am
index f3b15f34f..fca87308a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -296,6 +296,8 @@ libmutter_la_SOURCES += \
wayland/meta-wayland-touch.h \
wayland/meta-wayland-surface.c \
wayland/meta-wayland-surface.h \
+ wayland/meta-wayland-surface-role-cursor.c \
+ wayland/meta-wayland-surface-role-cursor.h \
wayland/meta-wayland-types.h \
wayland/meta-wayland-versions.h \
wayland/meta-wayland-outputs.c \
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index 798583bfd..d16a0bc73 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -54,6 +54,7 @@
#include "meta-wayland-private.h"
#include "meta-wayland-surface.h"
#include "meta-wayland-buffer.h"
+#include "meta-wayland-surface-role-cursor.h"
#include "meta-xwayland.h"
#include "meta-cursor.h"
#include "meta-cursor-tracker-private.h"
@@ -73,24 +74,6 @@
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
-struct _MetaWaylandSurfaceRoleCursor
-{
- MetaWaylandSurfaceRole parent;
-
- int hot_x;
- int hot_y;
- MetaCursorSprite *cursor_sprite;
-
- MetaWaylandBuffer *buffer;
-};
-
-G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
- meta_wayland_surface_role_cursor,
- META_TYPE_WAYLAND_SURFACE_ROLE);
-
-static void
-meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer);
-
static MetaWaylandPointerClient *
meta_wayland_pointer_client_new (void)
{
@@ -501,6 +484,12 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer)
(gpointer) meta_wayland_pointer_on_cursor_changed,
pointer);
+ if (pointer->cursor_surface && pointer->cursor_surface_destroy_id)
+ {
+ g_signal_handler_disconnect (pointer->cursor_surface,
+ pointer->cursor_surface_destroy_id);
+ }
+
meta_wayland_pointer_set_focus (pointer, NULL);
g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
@@ -928,7 +917,7 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
*sy = wl_fixed_from_double (yf);
}
-static void
+void
meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
{
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
@@ -942,7 +931,7 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
MetaWaylandSurfaceRoleCursor *cursor_role =
META_WAYLAND_SURFACE_ROLE_CURSOR (pointer->cursor_surface->role);
- cursor_sprite = cursor_role->cursor_sprite;
+ cursor_sprite = meta_wayland_surface_role_cursor_get_sprite (cursor_role);
}
meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite);
@@ -954,68 +943,14 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
}
static void
-update_cursor_sprite_texture (MetaWaylandSurface *surface)
+ensure_update_cursor_surface (MetaWaylandPointer *pointer,
+ MetaWaylandSurface *surface)
{
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (meta_get_backend ());
- MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
- MetaWaylandSurfaceRoleCursor *cursor_role =
- META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
- MetaCursorSprite *cursor_sprite = cursor_role->cursor_sprite;
- MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
+ if (pointer->cursor_surface != surface)
+ return;
- g_return_if_fail (!buffer || buffer->texture);
-
- if (buffer)
- {
- meta_cursor_sprite_set_texture (cursor_sprite,
- buffer->texture,
- cursor_role->hot_x * surface->scale,
- cursor_role->hot_y * surface->scale);
-
- if (cursor_role->buffer)
- {
- struct wl_resource *buffer_resource;
-
- g_assert (cursor_role->buffer == buffer);
- buffer_resource = buffer->resource;
- meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_renderer,
- cursor_sprite,
- buffer_resource);
-
- meta_wayland_surface_unref_buffer_use_count (surface);
- g_clear_object (&cursor_role->buffer);
- }
- }
- else
- {
- meta_cursor_sprite_set_texture (cursor_sprite, NULL, 0, 0);
- }
-
- if (cursor_sprite == meta_cursor_tracker_get_displayed_cursor (cursor_tracker))
- meta_cursor_renderer_force_update (cursor_renderer);
-}
-
-static void
-cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
- int x,
- int y,
- MetaWaylandSurfaceRoleCursor *cursor_role)
-{
- MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_role);
- MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
- MetaDisplay *display = meta_get_display ();
- MetaScreen *screen = display->screen;
- const MetaMonitorInfo *monitor;
-
- if (!meta_xwayland_is_xwayland_surface (surface))
- {
- monitor = meta_screen_get_monitor_for_point (screen, x, y);
- if (monitor)
- meta_cursor_sprite_set_texture_scale (cursor_sprite,
- (float)monitor->scale / surface->scale);
- }
- meta_wayland_surface_update_outputs (surface);
+ pointer->cursor_surface = NULL;
+ meta_wayland_pointer_update_cursor_surface (pointer);
}
static void
@@ -1025,14 +960,28 @@ meta_wayland_pointer_set_cursor_surface (MetaWaylandPointer *pointer,
MetaWaylandSurface *prev_cursor_surface;
prev_cursor_surface = pointer->cursor_surface;
+
+ if (prev_cursor_surface == cursor_surface)
+ return;
+
pointer->cursor_surface = cursor_surface;
- if (prev_cursor_surface != cursor_surface)
+ if (prev_cursor_surface)
{
- if (prev_cursor_surface)
- meta_wayland_surface_update_outputs (prev_cursor_surface);
- meta_wayland_pointer_update_cursor_surface (pointer);
+ meta_wayland_surface_update_outputs (prev_cursor_surface);
+ g_signal_handler_disconnect (prev_cursor_surface,
+ pointer->cursor_surface_destroy_id);
}
+
+ if (cursor_surface)
+ {
+ pointer->cursor_surface_destroy_id =
+ g_signal_connect_swapped (cursor_surface, "destroy",
+ G_CALLBACK (ensure_update_cursor_surface),
+ pointer);
+ }
+
+ meta_wayland_pointer_update_cursor_surface (pointer);
}
static void
@@ -1066,23 +1015,15 @@ pointer_set_cursor (struct wl_client *client,
if (surface)
{
+ MetaCursorRenderer *cursor_renderer =
+ meta_backend_get_cursor_renderer (meta_get_backend ());
MetaWaylandSurfaceRoleCursor *cursor_role;
cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
- if (!cursor_role->cursor_sprite)
- {
- cursor_role->cursor_sprite = meta_cursor_sprite_new ();
- g_signal_connect_object (cursor_role->cursor_sprite,
- "prepare-at",
- G_CALLBACK (cursor_sprite_prepare_at),
- cursor_role,
- 0);
- }
-
- cursor_role->hot_x = hot_x;
- cursor_role->hot_y = hot_y;
-
- update_cursor_sprite_texture (surface);
+ meta_wayland_surface_role_cursor_set_renderer (cursor_role,
+ cursor_renderer);
+ meta_wayland_surface_role_cursor_set_hotspot (cursor_role,
+ hot_x, hot_y);
}
meta_wayland_pointer_set_cursor_surface (pointer, surface);
@@ -1255,136 +1196,3 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer)
MetaWaylandSeat *seat = wl_container_of (pointer, seat, pointer);
return seat;
}
-
-static void
-cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
-{
- MetaWaylandSurfaceRoleCursor *cursor_role =
- META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
-
- if (buffer)
- {
- g_set_object (&cursor_role->buffer, buffer);
- meta_wayland_surface_ref_buffer_use_count (surface);
- }
-
- meta_wayland_surface_queue_pending_frame_callbacks (surface);
-}
-
-static void
-cursor_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
- MetaWaylandPendingState *pending)
-{
- MetaWaylandSurfaceRoleCursor *cursor_role =
- META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
-
- if (pending->newly_attached && cursor_role->buffer)
- {
- meta_wayland_surface_unref_buffer_use_count (surface);
- g_clear_object (&cursor_role->buffer);
- }
-}
-
-static void
-cursor_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
- MetaWaylandPendingState *pending)
-{
- MetaWaylandSurfaceRoleCursor *cursor_role =
- META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
-
- if (pending->newly_attached)
- {
- g_set_object (&cursor_role->buffer, buffer);
- if (cursor_role->buffer)
- meta_wayland_surface_ref_buffer_use_count (surface);
- }
-
- meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
-
- if (pending->newly_attached)
- update_cursor_sprite_texture (surface);
-}
-
-static gboolean
-cursor_surface_role_is_on_output (MetaWaylandSurfaceRole *role,
- MetaMonitorInfo *monitor)
-{
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (role);
- MetaWaylandPointer *pointer = &surface->compositor->seat->pointer;
- MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (meta_get_backend ());
- MetaWaylandSurfaceRoleCursor *cursor_role =
- META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
- MetaCursorSprite *displayed_cursor_sprite;
- MetaRectangle rect;
-
- if (surface != pointer->cursor_surface)
- return FALSE;
-
- displayed_cursor_sprite =
- meta_cursor_tracker_get_displayed_cursor (cursor_tracker);
- if (!displayed_cursor_sprite)
- return FALSE;
-
- if (cursor_role->cursor_sprite != displayed_cursor_sprite)
- return FALSE;
-
- rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
- cursor_role->cursor_sprite);
- return meta_rectangle_overlap (&rect, &monitor->rect);
-}
-
-static void
-cursor_surface_role_dispose (GObject *object)
-{
- MetaWaylandSurfaceRoleCursor *cursor_role =
- META_WAYLAND_SURFACE_ROLE_CURSOR (object);
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
- MetaWaylandPointer *pointer = &compositor->seat->pointer;
-
- if (pointer->cursor_surface == surface)
- pointer->cursor_surface = NULL;
- meta_wayland_pointer_update_cursor_surface (pointer);
-
- g_clear_object (&cursor_role->cursor_sprite);
-
- if (cursor_role->buffer)
- {
- meta_wayland_surface_unref_buffer_use_count (surface);
- g_clear_object (&cursor_role->buffer);
- }
-
- G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
-}
-
-static void
-meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
-{
-}
-
-static void
-meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
-{
- MetaWaylandSurfaceRoleClass *surface_role_class =
- META_WAYLAND_SURFACE_ROLE_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- surface_role_class->assigned = cursor_surface_role_assigned;
- surface_role_class->pre_commit = cursor_surface_role_pre_commit;
- surface_role_class->commit = cursor_surface_role_commit;
- surface_role_class->is_on_output = cursor_surface_role_is_on_output;
-
- object_class->dispose = cursor_surface_role_dispose;
-}
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 4e97ec962..a7b25aeac 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -32,12 +32,6 @@
#include
-#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
-G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleCursor,
- meta_wayland_surface_role_cursor,
- META, WAYLAND_SURFACE_ROLE_CURSOR,
- MetaWaylandSurfaceRole);
-
struct _MetaWaylandPointerGrabInterface
{
void (*focus) (MetaWaylandPointerGrab *grab,
@@ -75,6 +69,7 @@ struct _MetaWaylandPointer
guint32 click_serial;
MetaWaylandSurface *cursor_surface;
+ guint cursor_surface_destroy_id;
MetaWaylandPointerGrab *grab;
MetaWaylandPointerGrab default_grab;
@@ -151,4 +146,8 @@ void meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor);
MetaWaylandSeat *meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer);
+void meta_wayland_surface_cursor_update (MetaWaylandSurface *cursor_surface);
+
+void meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer);
+
#endif /* META_WAYLAND_POINTER_H */
diff --git a/src/wayland/meta-wayland-surface-role-cursor.c b/src/wayland/meta-wayland-surface-role-cursor.c
new file mode 100644
index 000000000..51bd2db6e
--- /dev/null
+++ b/src/wayland/meta-wayland-surface-role-cursor.c
@@ -0,0 +1,281 @@
+/*
+ * Wayland Support
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include
+#include
+#include "meta-wayland-surface-role-cursor.h"
+#include "meta-wayland-buffer.h"
+#include "meta-xwayland.h"
+#include "screen-private.h"
+
+struct _MetaWaylandSurfaceRoleCursor
+{
+ MetaWaylandSurfaceRole parent;
+
+ int hot_x;
+ int hot_y;
+ MetaCursorSprite *cursor_sprite;
+ MetaCursorRenderer *cursor_renderer;
+ MetaWaylandBuffer *buffer;
+};
+
+G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
+ meta_wayland_surface_role_cursor,
+ META_TYPE_WAYLAND_SURFACE_ROLE)
+
+static void
+update_cursor_sprite_texture (MetaWaylandSurfaceRoleCursor *cursor_role)
+{
+ MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_role));
+ MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
+ MetaCursorSprite *cursor_sprite = cursor_role->cursor_sprite;
+
+ g_return_if_fail (!buffer || buffer->texture);
+
+ if (!cursor_role->cursor_renderer || !cursor_sprite)
+ return;
+
+ if (buffer)
+ {
+ meta_cursor_sprite_set_texture (cursor_sprite,
+ buffer->texture,
+ cursor_role->hot_x * surface->scale,
+ cursor_role->hot_y * surface->scale);
+
+ if (cursor_role->buffer)
+ {
+ struct wl_resource *buffer_resource;
+
+ g_assert (cursor_role->buffer == buffer);
+ buffer_resource = buffer->resource;
+ meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_role->cursor_renderer,
+ cursor_sprite,
+ buffer_resource);
+
+ meta_wayland_surface_unref_buffer_use_count (surface);
+ g_clear_object (&cursor_role->buffer);
+ }
+ }
+ else
+ {
+ meta_cursor_sprite_set_texture (cursor_sprite, NULL, 0, 0);
+ }
+
+ meta_cursor_renderer_force_update (cursor_role->cursor_renderer);
+}
+
+static void
+cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
+ int x,
+ int y,
+ MetaWaylandSurfaceRoleCursor *cursor_role)
+{
+ MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_role);
+ MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
+ MetaDisplay *display = meta_get_display ();
+ MetaScreen *screen = display->screen;
+ const MetaMonitorInfo *monitor;
+
+ if (!meta_xwayland_is_xwayland_surface (surface))
+ {
+ monitor = meta_screen_get_monitor_for_point (screen, x, y);
+ if (monitor)
+ meta_cursor_sprite_set_texture_scale (cursor_sprite,
+ (float) monitor->scale / surface->scale);
+ }
+ meta_wayland_surface_update_outputs (surface);
+}
+
+static void
+cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
+{
+ MetaWaylandSurfaceRoleCursor *cursor_role =
+ META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
+
+ if (buffer)
+ {
+ g_set_object (&cursor_role->buffer, buffer);
+ meta_wayland_surface_ref_buffer_use_count (surface);
+ }
+
+ meta_wayland_surface_queue_pending_frame_callbacks (surface);
+}
+
+static void
+cursor_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
+ MetaWaylandPendingState *pending)
+{
+ MetaWaylandSurfaceRoleCursor *cursor_role =
+ META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+
+ if (pending->newly_attached && cursor_role->buffer)
+ {
+ meta_wayland_surface_unref_buffer_use_count (surface);
+ g_clear_object (&cursor_role->buffer);
+ }
+}
+
+static void
+cursor_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
+ MetaWaylandPendingState *pending)
+{
+ MetaWaylandSurfaceRoleCursor *cursor_role =
+ META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
+
+ if (pending->newly_attached)
+ {
+ g_set_object (&cursor_role->buffer, buffer);
+ if (cursor_role->buffer)
+ meta_wayland_surface_ref_buffer_use_count (surface);
+ }
+
+ meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
+
+ if (pending->newly_attached)
+ update_cursor_sprite_texture (META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role));
+}
+
+static gboolean
+cursor_surface_role_is_on_output (MetaWaylandSurfaceRole *role,
+ MetaMonitorInfo *monitor)
+{
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (role);
+ MetaWaylandSurfaceRoleCursor *cursor_role =
+ META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
+ MetaRectangle rect;
+
+ rect = meta_cursor_renderer_calculate_rect (cursor_role->cursor_renderer,
+ cursor_role->cursor_sprite);
+ return meta_rectangle_overlap (&rect, &monitor->rect);
+}
+
+static void
+cursor_surface_role_dispose (GObject *object)
+{
+ MetaWaylandSurfaceRoleCursor *cursor_role =
+ META_WAYLAND_SURFACE_ROLE_CURSOR (object);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
+
+ g_signal_handlers_disconnect_by_func (cursor_role->cursor_sprite,
+ cursor_sprite_prepare_at, cursor_role);
+
+ g_clear_object (&cursor_role->cursor_renderer);
+ g_clear_object (&cursor_role->cursor_sprite);
+
+ if (cursor_role->buffer)
+ {
+ meta_wayland_surface_unref_buffer_use_count (surface);
+ g_clear_object (&cursor_role->buffer);
+ }
+
+ G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
+}
+
+static void
+meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
+{
+ role->cursor_sprite = meta_cursor_sprite_new ();
+ g_signal_connect_object (role->cursor_sprite,
+ "prepare-at",
+ G_CALLBACK (cursor_sprite_prepare_at),
+ role,
+ 0);
+}
+
+static void
+meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
+{
+ MetaWaylandSurfaceRoleClass *surface_role_class =
+ META_WAYLAND_SURFACE_ROLE_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ surface_role_class->assigned = cursor_surface_role_assigned;
+ surface_role_class->pre_commit = cursor_surface_role_pre_commit;
+ surface_role_class->commit = cursor_surface_role_commit;
+ surface_role_class->is_on_output = cursor_surface_role_is_on_output;
+
+ object_class->dispose = cursor_surface_role_dispose;
+}
+
+MetaCursorSprite *
+meta_wayland_surface_role_cursor_get_sprite (MetaWaylandSurfaceRoleCursor *cursor_role)
+{
+ return cursor_role->cursor_sprite;
+}
+
+void
+meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
+ gint hotspot_x,
+ gint hotspot_y)
+{
+ if (cursor_role->hot_x == hotspot_x &&
+ cursor_role->hot_y == hotspot_y)
+ return;
+
+ cursor_role->hot_x = hotspot_x;
+ cursor_role->hot_y = hotspot_y;
+ update_cursor_sprite_texture (cursor_role);
+}
+
+void
+meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
+ gint *hotspot_x,
+ gint *hotspot_y)
+{
+ if (hotspot_x)
+ *hotspot_x = cursor_role->hot_x;
+ if (hotspot_y)
+ *hotspot_y = cursor_role->hot_y;
+}
+
+void
+meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
+ MetaCursorRenderer *renderer)
+{
+ if (cursor_role->cursor_renderer == renderer)
+ return;
+
+ if (renderer)
+ g_object_ref (renderer);
+ if (cursor_role->cursor_renderer)
+ g_object_unref (cursor_role->cursor_renderer);
+
+ cursor_role->cursor_renderer = renderer;
+ update_cursor_sprite_texture (cursor_role);
+}
+
+MetaCursorRenderer *
+meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role)
+{
+ return cursor_role->cursor_renderer;
+}
diff --git a/src/wayland/meta-wayland-surface-role-cursor.h b/src/wayland/meta-wayland-surface-role-cursor.h
new file mode 100644
index 000000000..16ab8eb3b
--- /dev/null
+++ b/src/wayland/meta-wayland-surface-role-cursor.h
@@ -0,0 +1,47 @@
+/*
+ * Wayland Support
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_WAYLAND_SURFACE_ROLE_CURSOR_H
+#define META_WAYLAND_SURFACE_ROLE_CURSOR_H
+
+#include "meta-wayland-surface.h"
+#include "backends/meta-cursor-renderer.h"
+
+#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
+G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleCursor,
+ meta_wayland_surface_role_cursor,
+ META, WAYLAND_SURFACE_ROLE_CURSOR,
+ MetaWaylandSurfaceRole);
+
+MetaCursorSprite * meta_wayland_surface_role_cursor_get_sprite (MetaWaylandSurfaceRoleCursor *cursor_role);
+
+void meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
+ gint hotspot_x,
+ gint hotspot_y);
+void meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
+ gint *hotspot_x,
+ gint *hotspot_y);
+void meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
+ MetaCursorRenderer *renderer);
+MetaCursorRenderer * meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role);
+
+
+#endif /* META_WAYLAND_SURFACE_ROLE_CURSOR_H */