Blame SOURCES/hw-cursor-on-demand-gnome-3-28.patch

41c151
diff --git a/src/Makefile.am b/src/Makefile.am
41c151
index bcb3505c7..5bbac70e8 100644
41c151
--- a/src/Makefile.am
41c151
+++ b/src/Makefile.am
41c151
@@ -114,6 +114,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES =	\
41c151
 	backends/meta-cursor-tracker-private.h	\
41c151
 	backends/meta-cursor-renderer.c		\
41c151
 	backends/meta-cursor-renderer.h		\
41c151
+	backends/meta-cursor-sprite-xcursor.c	\
41c151
+	backends/meta-cursor-sprite-xcursor.h	\
41c151
 	backends/meta-dnd-private.h		\
41c151
 	backends/meta-egl.c			\
41c151
 	backends/meta-egl.h			\
41c151
@@ -176,6 +178,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES =	\
41c151
 	backends/x11/meta-gpu-xrandr.h			\
41c151
 	backends/x11/cm/meta-backend-x11-cm.c		\
41c151
 	backends/x11/cm/meta-backend-x11-cm.h		\
41c151
+	backends/x11/cm/meta-cursor-sprite-xfixes.c	\
41c151
+	backends/x11/cm/meta-cursor-sprite-xfixes.h	\
41c151
 	backends/x11/cm/meta-renderer-x11-cm.c		\
41c151
 	backends/x11/cm/meta-renderer-x11-cm.h		\
41c151
 	backends/x11/nested/meta-backend-x11-nested.c	\
41c151
@@ -370,6 +374,8 @@ if HAVE_WAYLAND
41c151
 libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES +=	\
41c151
 	compositor/meta-surface-actor-wayland.c	\
41c151
 	compositor/meta-surface-actor-wayland.h	\
41c151
+	wayland/meta-cursor-sprite-wayland.c	\
41c151
+	wayland/meta-cursor-sprite-wayland.h	\
41c151
 	wayland/meta-wayland.c			\
41c151
 	wayland/meta-wayland.h			\
41c151
 	wayland/meta-wayland-private.h		\
41c151
@@ -431,10 +437,10 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES +=	\
41c151
 	wayland/meta-wayland-touch.h		\
41c151
 	wayland/meta-wayland-surface.c		\
41c151
 	wayland/meta-wayland-surface.h		\
41c151
-	wayland/meta-wayland-surface-role-cursor.c	\
41c151
-	wayland/meta-wayland-surface-role-cursor.h	\
41c151
-	wayland/meta-wayland-surface-role-tablet-cursor.c	\
41c151
-	wayland/meta-wayland-surface-role-tablet-cursor.h	\
41c151
+	wayland/meta-wayland-cursor-surface.c	\
41c151
+	wayland/meta-wayland-cursor-surface.h	\
41c151
+	wayland/meta-wayland-tablet-cursor-surface.c	\
41c151
+	wayland/meta-wayland-tablet-cursor-surface.h	\
41c151
 	wayland/meta-wayland-actor-surface.c	\
41c151
 	wayland/meta-wayland-actor-surface.h	\
41c151
 	wayland/meta-wayland-subsurface.c	\
41c151
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
41c151
index f6470e66a..eb79737f1 100644
41c151
--- a/src/backends/meta-cursor-renderer.c
41c151
+++ b/src/backends/meta-cursor-renderer.c
41c151
@@ -193,8 +193,8 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
41c151
 }
41c151
 
41c151
 static void
41c151
-update_cursor (MetaCursorRenderer *renderer,
41c151
-               MetaCursorSprite   *cursor_sprite)
41c151
+meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
41c151
+                                    MetaCursorSprite   *cursor_sprite)
41c151
 {
41c151
   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
41c151
   gboolean handled_by_backend;
41c151
@@ -237,7 +237,7 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
41c151
     return;
41c151
   priv->displayed_cursor = cursor_sprite;
41c151
 
41c151
-  update_cursor (renderer, cursor_sprite);
41c151
+  meta_cursor_renderer_update_cursor (renderer, cursor_sprite);
41c151
 }
41c151
 
41c151
 void
41c151
@@ -246,7 +246,7 @@ meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
41c151
   MetaCursorRendererPrivate *priv =
41c151
     meta_cursor_renderer_get_instance_private (renderer);
41c151
 
41c151
-  update_cursor (renderer, priv->displayed_cursor);
41c151
+  meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor);
41c151
 }
41c151
 
41c151
 void
41c151
@@ -261,7 +261,7 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
41c151
   priv->current_x = x;
41c151
   priv->current_y = y;
41c151
 
41c151
-  update_cursor (renderer, priv->displayed_cursor);
41c151
+  meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor);
41c151
 }
41c151
 
41c151
 ClutterPoint
41c151
@@ -283,28 +283,3 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
41c151
 
41c151
   return priv->displayed_cursor;
41c151
 }
41c151
-
41c151
-#ifdef HAVE_WAYLAND
41c151
-void
41c151
-meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
41c151
-                                                    MetaCursorSprite   *cursor_sprite,
41c151
-                                                    struct wl_resource *buffer)
41c151
-{
41c151
-
41c151
-  MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
41c151
-
41c151
-  if (renderer_class->realize_cursor_from_wl_buffer)
41c151
-    renderer_class->realize_cursor_from_wl_buffer (renderer, cursor_sprite, buffer);
41c151
-}
41c151
-#endif
41c151
-
41c151
-void
41c151
-meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
41c151
-                                                  MetaCursorSprite   *cursor_sprite,
41c151
-                                                  XcursorImage       *xc_image)
41c151
-{
41c151
-  MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
41c151
-
41c151
-  if (renderer_class->realize_cursor_from_xcursor)
41c151
-    renderer_class->realize_cursor_from_xcursor (renderer, cursor_sprite, xc_image);
41c151
-}
41c151
diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h
41c151
index 1691f4471..830d16ef6 100644
41c151
--- a/src/backends/meta-cursor-renderer.h
41c151
+++ b/src/backends/meta-cursor-renderer.h
41c151
@@ -26,10 +26,6 @@
41c151
 #define META_CURSOR_RENDERER_H
41c151
 
41c151
 #include <glib-object.h>
41c151
-#include <X11/Xcursor/Xcursor.h>
41c151
-#ifdef HAVE_WAYLAND
41c151
-#include <wayland-server.h>
41c151
-#endif
41c151
 
41c151
 #include <meta/screen.h>
41c151
 #include "meta-cursor.h"
41c151
@@ -44,14 +40,6 @@ struct _MetaCursorRendererClass
41c151
 
41c151
   gboolean (* update_cursor) (MetaCursorRenderer *renderer,
41c151
                               MetaCursorSprite   *cursor_sprite);
41c151
-#ifdef HAVE_WAYLAND
41c151
-  void (* realize_cursor_from_wl_buffer) (MetaCursorRenderer *renderer,
41c151
-                                          MetaCursorSprite *cursor_sprite,
41c151
-                                          struct wl_resource *buffer);
41c151
-#endif
41c151
-  void (* realize_cursor_from_xcursor) (MetaCursorRenderer *renderer,
41c151
-                                        MetaCursorSprite *cursor_sprite,
41c151
-                                        XcursorImage *xc_image);
41c151
 };
41c151
 
41c151
 MetaCursorRenderer * meta_cursor_renderer_new (void);
41c151
@@ -70,16 +58,6 @@ MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer
41c151
 ClutterRect meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
41c151
                                                  MetaCursorSprite   *cursor_sprite);
41c151
 
41c151
-#ifdef HAVE_WAYLAND
41c151
-void meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
41c151
-                                                         MetaCursorSprite   *cursor_sprite,
41c151
-                                                         struct wl_resource *buffer);
41c151
-#endif
41c151
-
41c151
-void meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
41c151
-                                                       MetaCursorSprite   *cursor_sprite,
41c151
-                                                       XcursorImage       *xc_image);
41c151
-
41c151
 void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
41c151
                                         MetaCursorSprite   *cursor_sprite);
41c151
 
41c151
diff --git a/src/backends/meta-cursor-sprite-xcursor.c b/src/backends/meta-cursor-sprite-xcursor.c
41c151
new file mode 100644
41c151
index 000000000..657c1dae8
41c151
--- /dev/null
41c151
+++ b/src/backends/meta-cursor-sprite-xcursor.c
41c151
@@ -0,0 +1,292 @@
41c151
+/*
41c151
+ * Copyright 2013, 2018 Red Hat, Inc.
41c151
+ *
41c151
+ * This program is free software; you can redistribute it and/or
41c151
+ * modify it under the terms of the GNU General Public License as
41c151
+ * published by the Free Software Foundation; either version 2 of the
41c151
+ * License, or (at your option) any later version.
41c151
+ *
41c151
+ * This program is distributed in the hope that it will be useful, but
41c151
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
+ * General Public License for more details.
41c151
+ *
41c151
+ * You should have received a copy of the GNU General Public License
41c151
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
41c151
+ *
41c151
+ */
41c151
+
41c151
+#include "config.h"
41c151
+
41c151
+#include "backends/meta-cursor-sprite-xcursor.h"
41c151
+
41c151
+#include "backends/meta-cursor.h"
41c151
+#include "backends/meta-cursor-renderer.h"
41c151
+#include "clutter/clutter.h"
41c151
+#include "cogl/cogl.h"
41c151
+#include "meta/prefs.h"
41c151
+
41c151
+struct _MetaCursorSpriteXcursor
41c151
+{
41c151
+  MetaCursorSprite parent;
41c151
+
41c151
+  MetaCursor cursor;
41c151
+
41c151
+  int current_frame;
41c151
+  XcursorImages *xcursor_images;
41c151
+
41c151
+  int theme_scale;
41c151
+  gboolean theme_dirty;
41c151
+};
41c151
+
41c151
+G_DEFINE_TYPE (MetaCursorSpriteXcursor, meta_cursor_sprite_xcursor,
41c151
+               META_TYPE_CURSOR_SPRITE)
41c151
+
41c151
+static const char *
41c151
+translate_meta_cursor (MetaCursor cursor)
41c151
+{
41c151
+  switch (cursor)
41c151
+    {
41c151
+    case META_CURSOR_DEFAULT:
41c151
+      return "left_ptr";
41c151
+    case META_CURSOR_NORTH_RESIZE:
41c151
+      return "top_side";
41c151
+    case META_CURSOR_SOUTH_RESIZE:
41c151
+      return "bottom_side";
41c151
+    case META_CURSOR_WEST_RESIZE:
41c151
+      return "left_side";
41c151
+    case META_CURSOR_EAST_RESIZE:
41c151
+      return "right_side";
41c151
+    case META_CURSOR_SE_RESIZE:
41c151
+      return "bottom_right_corner";
41c151
+    case META_CURSOR_SW_RESIZE:
41c151
+      return "bottom_left_corner";
41c151
+    case META_CURSOR_NE_RESIZE:
41c151
+      return "top_right_corner";
41c151
+    case META_CURSOR_NW_RESIZE:
41c151
+      return "top_left_corner";
41c151
+    case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
41c151
+      return "fleur";
41c151
+    case META_CURSOR_BUSY:
41c151
+      return "watch";
41c151
+    case META_CURSOR_DND_IN_DRAG:
41c151
+      return "dnd-none";
41c151
+    case META_CURSOR_DND_MOVE:
41c151
+      return "dnd-move";
41c151
+    case META_CURSOR_DND_COPY:
41c151
+      return "dnd-copy";
41c151
+    case META_CURSOR_DND_UNSUPPORTED_TARGET:
41c151
+      return "dnd-none";
41c151
+    case META_CURSOR_POINTING_HAND:
41c151
+      return "hand2";
41c151
+    case META_CURSOR_CROSSHAIR:
41c151
+      return "crosshair";
41c151
+    case META_CURSOR_IBEAM:
41c151
+      return "xterm";
41c151
+    default:
41c151
+      break;
41c151
+    }
41c151
+
41c151
+  g_assert_not_reached ();
41c151
+}
41c151
+
41c151
+MetaCursor
41c151
+meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcursor)
41c151
+{
41c151
+  return sprite_xcursor->cursor;
41c151
+}
41c151
+
41c151
+Cursor
41c151
+meta_create_x_cursor (Display    *xdisplay,
41c151
+                      MetaCursor  cursor)
41c151
+{
41c151
+  return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
41c151
+}
41c151
+
41c151
+static XcursorImages *
41c151
+load_cursor_on_client (MetaCursor cursor, int scale)
41c151
+{
41c151
+  return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
41c151
+                                   meta_prefs_get_cursor_theme (),
41c151
+                                   meta_prefs_get_cursor_size () * scale);
41c151
+}
41c151
+
41c151
+static void
41c151
+load_from_current_xcursor_image (MetaCursorSpriteXcursor *sprite_xcursor)
41c151
+{
41c151
+  MetaCursorSprite *sprite = META_CURSOR_SPRITE (sprite_xcursor);
41c151
+  XcursorImage *xc_image;
41c151
+  int width, height, rowstride;
41c151
+  CoglPixelFormat cogl_format;
41c151
+  ClutterBackend *clutter_backend;
41c151
+  CoglContext *cogl_context;
41c151
+  CoglTexture2D *texture;
41c151
+  CoglError *error = NULL;
41c151
+
41c151
+  g_assert (!meta_cursor_sprite_get_cogl_texture (sprite));
41c151
+
41c151
+  xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor);
41c151
+  width = (int) xc_image->width;
41c151
+  height = (int) xc_image->height;
41c151
+  rowstride = width * 4;
41c151
+
41c151
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
41c151
+  cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
41c151
+#else
41c151
+  cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
41c151
+#endif
41c151
+
41c151
+  clutter_backend = clutter_get_default_backend ();
41c151
+  cogl_context = clutter_backend_get_cogl_context (clutter_backend);
41c151
+  texture = cogl_texture_2d_new_from_data (cogl_context,
41c151
+                                           width, height,
41c151
+                                           cogl_format,
41c151
+                                           rowstride,
41c151
+                                           (uint8_t *) xc_image->pixels,
41c151
+                                           &error);
41c151
+  if (!texture)
41c151
+    {
41c151
+      g_warning ("Failed to allocate cursor texture: %s\n", error->message);
41c151
+      cogl_error_free (error);
41c151
+    }
41c151
+
41c151
+  meta_cursor_sprite_set_texture (sprite,
41c151
+                                  COGL_TEXTURE (texture),
41c151
+                                  xc_image->xhot, xc_image->yhot);
41c151
+
41c151
+  if (texture)
41c151
+    cogl_object_unref (texture);
41c151
+}
41c151
+
41c151
+void
41c151
+meta_cursor_sprite_xcursor_set_theme_scale (MetaCursorSpriteXcursor *sprite_xcursor,
41c151
+                                            int                      theme_scale)
41c151
+{
41c151
+  if (sprite_xcursor->theme_scale != theme_scale)
41c151
+    sprite_xcursor->theme_dirty = TRUE;
41c151
+  sprite_xcursor->theme_scale = theme_scale;
41c151
+}
41c151
+
41c151
+
41c151
+static gboolean
41c151
+meta_cursor_sprite_xcursor_is_animated (MetaCursorSprite *sprite)
41c151
+{
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite);
41c151
+
41c151
+  return (sprite_xcursor->xcursor_images &&
41c151
+          sprite_xcursor->xcursor_images->nimage > 1);
41c151
+}
41c151
+
41c151
+XcursorImage *
41c151
+meta_cursor_sprite_xcursor_get_current_image (MetaCursorSpriteXcursor *sprite_xcursor)
41c151
+{
41c151
+  return sprite_xcursor->xcursor_images->images[sprite_xcursor->current_frame];
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xcursor_tick_frame (MetaCursorSprite *sprite)
41c151
+{
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite);
41c151
+
41c151
+  if (!meta_cursor_sprite_is_animated (sprite))
41c151
+    return;
41c151
+
41c151
+  sprite_xcursor->current_frame++;
41c151
+
41c151
+  if (sprite_xcursor->current_frame >= sprite_xcursor->xcursor_images->nimage)
41c151
+    sprite_xcursor->current_frame = 0;
41c151
+
41c151
+  meta_cursor_sprite_clear_texture (sprite);
41c151
+  load_from_current_xcursor_image (sprite_xcursor);
41c151
+}
41c151
+
41c151
+static unsigned int
41c151
+meta_cursor_sprite_xcursor_get_current_frame_time (MetaCursorSprite *sprite)
41c151
+{
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite);
41c151
+  XcursorImages *xcursor_images;
41c151
+
41c151
+  g_return_val_if_fail (meta_cursor_sprite_is_animated (sprite), 0);
41c151
+
41c151
+  xcursor_images = sprite_xcursor->xcursor_images;
41c151
+  return xcursor_images->images[sprite_xcursor->current_frame]->delay;
41c151
+}
41c151
+
41c151
+static void
41c151
+load_cursor_from_theme (MetaCursorSprite *sprite)
41c151
+{
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite);
41c151
+
41c151
+  g_assert (sprite_xcursor->cursor != META_CURSOR_NONE);
41c151
+
41c151
+  sprite_xcursor->theme_dirty = FALSE;
41c151
+
41c151
+  /* We might be reloading with a different scale. If so clear the old data. */
41c151
+  if (sprite_xcursor->xcursor_images)
41c151
+    {
41c151
+      meta_cursor_sprite_clear_texture (sprite);
41c151
+      XcursorImagesDestroy (sprite_xcursor->xcursor_images);
41c151
+    }
41c151
+
41c151
+  sprite_xcursor->current_frame = 0;
41c151
+  sprite_xcursor->xcursor_images =
41c151
+    load_cursor_on_client (sprite_xcursor->cursor,
41c151
+                           sprite_xcursor->theme_scale);
41c151
+  if (!sprite_xcursor->xcursor_images)
41c151
+    g_error ("Could not find cursor. Perhaps set XCURSOR_PATH?");
41c151
+
41c151
+  load_from_current_xcursor_image (sprite_xcursor);
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xcursor_realize_texture (MetaCursorSprite *sprite)
41c151
+{
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite);
41c151
+
41c151
+  if (sprite_xcursor->theme_dirty)
41c151
+    load_cursor_from_theme (sprite);
41c151
+}
41c151
+
41c151
+MetaCursorSpriteXcursor *
41c151
+meta_cursor_sprite_xcursor_new (MetaCursor cursor)
41c151
+{
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor;
41c151
+
41c151
+  sprite_xcursor = g_object_new (META_TYPE_CURSOR_SPRITE_XCURSOR, NULL);
41c151
+  sprite_xcursor->cursor = cursor;
41c151
+
41c151
+  return sprite_xcursor;
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xcursor_finalize (GObject *object)
41c151
+{
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (object);
41c151
+
41c151
+  g_clear_pointer (&sprite_xcursor->xcursor_images,
41c151
+                   XcursorImagesDestroy);
41c151
+
41c151
+  G_OBJECT_CLASS (meta_cursor_sprite_xcursor_parent_class)->finalize (object);
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xcursor_init (MetaCursorSpriteXcursor *sprite_xcursor)
41c151
+{
41c151
+  sprite_xcursor->theme_dirty = TRUE;
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xcursor_class_init (MetaCursorSpriteXcursorClass *klass)
41c151
+{
41c151
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
41c151
+  MetaCursorSpriteClass *cursor_sprite_class = META_CURSOR_SPRITE_CLASS (klass);
41c151
+
41c151
+  object_class->finalize = meta_cursor_sprite_xcursor_finalize;
41c151
+
41c151
+  cursor_sprite_class->realize_texture =
41c151
+    meta_cursor_sprite_xcursor_realize_texture;
41c151
+  cursor_sprite_class->is_animated = meta_cursor_sprite_xcursor_is_animated;
41c151
+  cursor_sprite_class->tick_frame = meta_cursor_sprite_xcursor_tick_frame;
41c151
+  cursor_sprite_class->get_current_frame_time =
41c151
+    meta_cursor_sprite_xcursor_get_current_frame_time;
41c151
+}
41c151
diff --git a/src/backends/meta-cursor-sprite-xcursor.h b/src/backends/meta-cursor-sprite-xcursor.h
41c151
new file mode 100644
41c151
index 000000000..dbc927484
41c151
--- /dev/null
41c151
+++ b/src/backends/meta-cursor-sprite-xcursor.h
41c151
@@ -0,0 +1,43 @@
41c151
+/*
41c151
+ * Copyright 2013, 2018 Red Hat, Inc.
41c151
+ *
41c151
+ * This program is free software; you can redistribute it and/or
41c151
+ * modify it under the terms of the GNU General Public License as
41c151
+ * published by the Free Software Foundation; either version 2 of the
41c151
+ * License, or (at your option) any later version.
41c151
+ *
41c151
+ * This program is distributed in the hope that it will be useful, but
41c151
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
+ * General Public License for more details.
41c151
+ *
41c151
+ * You should have received a copy of the GNU General Public License
41c151
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
41c151
+ *
41c151
+ */
41c151
+
41c151
+#ifndef META_CURSOR_SPRITE_XCURSOR_H
41c151
+#define META_CURSOR_SPRITE_XCURSOR_H
41c151
+
41c151
+#include <glib-object.h>
41c151
+#include <X11/Xcursor/Xcursor.h>
41c151
+
41c151
+#include "backends/meta-cursor.h"
41c151
+
41c151
+#define META_TYPE_CURSOR_SPRITE_XCURSOR meta_cursor_sprite_xcursor_get_type ()
41c151
+G_DECLARE_FINAL_TYPE (MetaCursorSpriteXcursor, meta_cursor_sprite_xcursor,
41c151
+                      META, CURSOR_SPRITE_XCURSOR, MetaCursorSprite)
41c151
+
41c151
+MetaCursorSpriteXcursor * meta_cursor_sprite_xcursor_new (MetaCursor cursor);
41c151
+
41c151
+void meta_cursor_sprite_xcursor_set_theme_scale (MetaCursorSpriteXcursor *sprite_xcursor,
41c151
+                                                 int                      scale);
41c151
+
41c151
+MetaCursor meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcusror);
41c151
+
41c151
+XcursorImage * meta_cursor_sprite_xcursor_get_current_image (MetaCursorSpriteXcursor *sprite_xcursor);
41c151
+
41c151
+Cursor meta_create_x_cursor (Display    *xdisplay,
41c151
+                             MetaCursor  cursor);
41c151
+
41c151
+#endif /* META_CURSOR_SPRITE_XCURSOR_H */
41c151
diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h
41c151
index 2ec946847..6f4f84b83 100644
41c151
--- a/src/backends/meta-cursor-tracker-private.h
41c151
+++ b/src/backends/meta-cursor-tracker-private.h
41c151
@@ -26,6 +26,7 @@
41c151
 
41c151
 #include "meta-cursor.h"
41c151
 #include "meta-cursor-renderer.h"
41c151
+#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
41c151
 
41c151
 struct _MetaCursorTracker {
41c151
   GObject parent_instance;
41c151
@@ -46,7 +47,7 @@ struct _MetaCursorTracker {
41c151
   MetaCursorSprite *root_cursor;
41c151
 
41c151
   /* The cursor from the X11 server. */
41c151
-  MetaCursorSprite *xfixes_cursor;
41c151
+  MetaCursorSpriteXfixes *xfixes_cursor;
41c151
 };
41c151
 
41c151
 struct _MetaCursorTrackerClass {
41c151
diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c
41c151
index 74fa4351d..6244f11ee 100644
41c151
--- a/src/backends/meta-cursor-tracker.c
41c151
+++ b/src/backends/meta-cursor-tracker.c
41c151
@@ -40,9 +40,9 @@
41c151
 
41c151
 #include <gdk/gdk.h>
41c151
 #include <gdk/gdkx.h>
41c151
-#include <X11/extensions/Xfixes.h>
41c151
 
41c151
 #include "meta-backend-private.h"
41c151
+#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
41c151
 
41c151
 G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
41c151
 
41c151
@@ -218,75 +218,14 @@ static void
41c151
 ensure_xfixes_cursor (MetaCursorTracker *tracker)
41c151
 {
41c151
   MetaDisplay *display = meta_get_display ();
41c151
-  XFixesCursorImage *cursor_image;
41c151
-  CoglTexture2D *sprite;
41c151
-  guint8 *cursor_data;
41c151
-  gboolean free_cursor_data;
41c151
-  CoglContext *ctx;
41c151
-  CoglError *error = NULL;
41c151
+  g_autoptr (GError) error = NULL;
41c151
 
41c151
   if (tracker->xfixes_cursor)
41c151
     return;
41c151
 
41c151
-  cursor_image = XFixesGetCursorImage (display->xdisplay);
41c151
-  if (!cursor_image)
41c151
-    return;
41c151
-
41c151
-  /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
41c151
-   * quantities as arrays of long; we need to convert on 64 bit */
41c151
-  if (sizeof(long) == 4)
41c151
-    {
41c151
-      cursor_data = (guint8 *)cursor_image->pixels;
41c151
-      free_cursor_data = FALSE;
41c151
-    }
41c151
-  else
41c151
-    {
41c151
-      int i, j;
41c151
-      guint32 *cursor_words;
41c151
-      gulong *p;
41c151
-      guint32 *q;
41c151
-
41c151
-      cursor_words = g_new (guint32, cursor_image->width * cursor_image->height);
41c151
-      cursor_data = (guint8 *)cursor_words;
41c151
-
41c151
-      p = cursor_image->pixels;
41c151
-      q = cursor_words;
41c151
-      for (j = 0; j < cursor_image->height; j++)
41c151
-        for (i = 0; i < cursor_image->width; i++)
41c151
-          *(q++) = *(p++);
41c151
-
41c151
-      free_cursor_data = TRUE;
41c151
-    }
41c151
-
41c151
-  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
41c151
-  sprite = cogl_texture_2d_new_from_data (ctx,
41c151
-                                          cursor_image->width,
41c151
-                                          cursor_image->height,
41c151
-                                          CLUTTER_CAIRO_FORMAT_ARGB32,
41c151
-                                          cursor_image->width * 4, /* stride */
41c151
-                                          cursor_data,
41c151
-                                          &error);
41c151
-
41c151
-  if (free_cursor_data)
41c151
-    g_free (cursor_data);
41c151
-
41c151
-  if (error != NULL)
41c151
-    {
41c151
-      meta_warning ("Failed to allocate cursor sprite texture: %s\n", error->message);
41c151
-      cogl_error_free (error);
41c151
-    }
41c151
-
41c151
-  if (sprite != NULL)
41c151
-    {
41c151
-      MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
41c151
-      meta_cursor_sprite_set_texture (cursor_sprite,
41c151
-                                      COGL_TEXTURE (sprite),
41c151
-                                      cursor_image->xhot,
41c151
-                                      cursor_image->yhot);
41c151
-      cogl_object_unref (sprite);
41c151
-      tracker->xfixes_cursor = cursor_sprite;
41c151
-    }
41c151
-  XFree (cursor_image);
41c151
+  tracker->xfixes_cursor = meta_cursor_sprite_xfixes_new (display, &error);
41c151
+  if (!tracker->xfixes_cursor)
41c151
+    g_warning ("Failed to create XFIXES cursor: %s", error->message);
41c151
 }
41c151
 
41c151
 /**
41c151
@@ -308,7 +247,7 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
41c151
   else
41c151
     {
41c151
       ensure_xfixes_cursor (tracker);
41c151
-      cursor_sprite = tracker->xfixes_cursor;
41c151
+      cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
41c151
     }
41c151
 
41c151
   if (cursor_sprite)
41c151
@@ -345,7 +284,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
41c151
   else
41c151
     {
41c151
       ensure_xfixes_cursor (tracker);
41c151
-      cursor_sprite = tracker->xfixes_cursor;
41c151
+      cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
41c151
     }
41c151
 
41c151
   if (cursor_sprite)
41c151
diff --git a/src/backends/meta-cursor.c b/src/backends/meta-cursor.c
41c151
index beeee765b..9750dc00b 100644
41c151
--- a/src/backends/meta-cursor.c
41c151
+++ b/src/backends/meta-cursor.c
41c151
@@ -23,19 +23,12 @@
41c151
 
41c151
 #include "meta-cursor.h"
41c151
 
41c151
-#include <meta/errors.h>
41c151
+#include "backends/meta-backend-private.h"
41c151
+#include "cogl/cogl.h"
41c151
+#include "meta/common.h"
41c151
 
41c151
-#include "display-private.h"
41c151
-#include "screen-private.h"
41c151
-#include "meta-backend-private.h"
41c151
-
41c151
-#include <string.h>
41c151
-
41c151
-#include <X11/cursorfont.h>
41c151
-#include <X11/extensions/Xfixes.h>
41c151
-#include <X11/Xcursor/Xcursor.h>
41c151
-
41c151
-enum {
41c151
+enum
41c151
+{
41c151
   PREPARE_AT,
41c151
   TEXTURE_CHANGED,
41c151
 
41c151
@@ -44,316 +37,148 @@ enum {
41c151
 
41c151
 static guint signals[LAST_SIGNAL];
41c151
 
41c151
-struct _MetaCursorSprite
41c151
+typedef struct _MetaCursorSpritePrivate
41c151
 {
41c151
   GObject parent;
41c151
 
41c151
-  MetaCursor cursor;
41c151
-
41c151
   CoglTexture2D *texture;
41c151
   float texture_scale;
41c151
   int hot_x, hot_y;
41c151
+} MetaCursorSpritePrivate;
41c151
 
41c151
-  int current_frame;
41c151
-  XcursorImages *xcursor_images;
41c151
-
41c151
-  int theme_scale;
41c151
-  gboolean theme_dirty;
41c151
-};
41c151
-
41c151
-G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
41c151
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCursorSprite,
41c151
+                                     meta_cursor_sprite,
41c151
+                                     G_TYPE_OBJECT)
41c151
 
41c151
-static const char *
41c151
-translate_meta_cursor (MetaCursor cursor)
41c151
-{
41c151
-  switch (cursor)
41c151
-    {
41c151
-    case META_CURSOR_DEFAULT:
41c151
-      return "left_ptr";
41c151
-    case META_CURSOR_NORTH_RESIZE:
41c151
-      return "top_side";
41c151
-    case META_CURSOR_SOUTH_RESIZE:
41c151
-      return "bottom_side";
41c151
-    case META_CURSOR_WEST_RESIZE:
41c151
-      return "left_side";
41c151
-    case META_CURSOR_EAST_RESIZE:
41c151
-      return "right_side";
41c151
-    case META_CURSOR_SE_RESIZE:
41c151
-      return "bottom_right_corner";
41c151
-    case META_CURSOR_SW_RESIZE:
41c151
-      return "bottom_left_corner";
41c151
-    case META_CURSOR_NE_RESIZE:
41c151
-      return "top_right_corner";
41c151
-    case META_CURSOR_NW_RESIZE:
41c151
-      return "top_left_corner";
41c151
-    case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
41c151
-      return "fleur";
41c151
-    case META_CURSOR_BUSY:
41c151
-      return "watch";
41c151
-    case META_CURSOR_DND_IN_DRAG:
41c151
-      return "dnd-none";
41c151
-    case META_CURSOR_DND_MOVE:
41c151
-      return "dnd-move";
41c151
-    case META_CURSOR_DND_COPY:
41c151
-      return "dnd-copy";
41c151
-    case META_CURSOR_DND_UNSUPPORTED_TARGET:
41c151
-      return "dnd-none";
41c151
-    case META_CURSOR_POINTING_HAND:
41c151
-      return "hand2";
41c151
-    case META_CURSOR_CROSSHAIR:
41c151
-      return "crosshair";
41c151
-    case META_CURSOR_IBEAM:
41c151
-      return "xterm";
41c151
-    default:
41c151
-      break;
41c151
-    }
41c151
-
41c151
-  g_assert_not_reached ();
41c151
-}
41c151
-
41c151
-Cursor
41c151
-meta_cursor_create_x_cursor (Display    *xdisplay,
41c151
-                             MetaCursor  cursor)
41c151
-{
41c151
-  return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
41c151
-}
41c151
-
41c151
-static XcursorImages *
41c151
-load_cursor_on_client (MetaCursor cursor, int scale)
41c151
-{
41c151
-  return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
41c151
-                                   meta_prefs_get_cursor_theme (),
41c151
-                                   meta_prefs_get_cursor_size () * scale);
41c151
-}
41c151
-
41c151
-static void
41c151
-meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
41c151
-                                            XcursorImage     *xc_image)
41c151
+gboolean
41c151
+meta_cursor_sprite_is_animated (MetaCursorSprite *sprite)
41c151
 {
41c151
-  MetaBackend *meta_backend = meta_get_backend ();
41c151
-  MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
41c151
-  uint width, height, rowstride;
41c151
-  CoglPixelFormat cogl_format;
41c151
-  ClutterBackend *clutter_backend;
41c151
-  CoglContext *cogl_context;
41c151
-  CoglTexture2D *texture;
41c151
-  CoglError *error = NULL;
41c151
-
41c151
-  g_assert (self->texture == NULL);
41c151
-
41c151
-  width           = xc_image->width;
41c151
-  height          = xc_image->height;
41c151
-  rowstride       = width * 4;
41c151
-
41c151
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
41c151
-  cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
41c151
-#else
41c151
-  cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
41c151
-#endif
41c151
-
41c151
-  clutter_backend = clutter_get_default_backend ();
41c151
-  cogl_context = clutter_backend_get_cogl_context (clutter_backend);
41c151
-  texture = cogl_texture_2d_new_from_data (cogl_context,
41c151
-                                           width, height,
41c151
-                                           cogl_format,
41c151
-                                           rowstride,
41c151
-                                           (uint8_t *) xc_image->pixels,
41c151
-                                           &error);
41c151
-
41c151
-  if (error)
41c151
-    {
41c151
-      meta_warning ("Failed to allocate cursor texture: %s\n", error->message);
41c151
-      cogl_error_free (error);
41c151
-    }
41c151
-
41c151
-  meta_cursor_sprite_set_texture (self, COGL_TEXTURE (texture),
41c151
-                                  xc_image->xhot, xc_image->yhot);
41c151
+  MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite);
41c151
 
41c151
-  if (texture)
41c151
-    cogl_object_unref (texture);
41c151
-
41c151
-  meta_cursor_renderer_realize_cursor_from_xcursor (renderer, self, xc_image);
41c151
-}
41c151
-
41c151
-static XcursorImage *
41c151
-meta_cursor_sprite_get_current_frame_image (MetaCursorSprite *self)
41c151
-{
41c151
-  return self->xcursor_images->images[self->current_frame];
41c151
+  if (klass->is_animated)
41c151
+    return klass->is_animated (sprite);
41c151
+  else
41c151
+    return FALSE;
41c151
 }
41c151
 
41c151
 void
41c151
-meta_cursor_sprite_tick_frame (MetaCursorSprite *self)
41c151
-{
41c151
-  XcursorImage *image;
41c151
-
41c151
-  if (!meta_cursor_sprite_is_animated (self))
41c151
-    return;
41c151
-
41c151
-  self->current_frame++;
41c151
-
41c151
-  if (self->current_frame >= self->xcursor_images->nimage)
41c151
-    self->current_frame = 0;
41c151
-
41c151
-  image = meta_cursor_sprite_get_current_frame_image (self);
41c151
-
41c151
-  g_clear_pointer (&self->texture, cogl_object_unref);
41c151
-  meta_cursor_sprite_load_from_xcursor_image (self, image);
41c151
-}
41c151
-
41c151
-guint
41c151
-meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self)
41c151
-{
41c151
-  if (!meta_cursor_sprite_is_animated (self))
41c151
-    return 0;
41c151
-
41c151
-  return self->xcursor_images->images[self->current_frame]->delay;
41c151
-}
41c151
-
41c151
-gboolean
41c151
-meta_cursor_sprite_is_animated (MetaCursorSprite *self)
41c151
+meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite)
41c151
 {
41c151
-  return (self->xcursor_images &&
41c151
-          self->xcursor_images->nimage > 1);
41c151
+  return META_CURSOR_SPRITE_GET_CLASS (sprite)->tick_frame (sprite);
41c151
 }
41c151
 
41c151
-MetaCursorSprite *
41c151
-meta_cursor_sprite_new (void)
41c151
+unsigned int
41c151
+meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite)
41c151
 {
41c151
-  return g_object_new (META_TYPE_CURSOR_SPRITE, NULL);
41c151
+  return META_CURSOR_SPRITE_GET_CLASS (sprite)->get_current_frame_time (sprite);
41c151
 }
41c151
 
41c151
-static void
41c151
-meta_cursor_sprite_load_from_theme (MetaCursorSprite *self)
41c151
-{
41c151
-  XcursorImage *image;
41c151
-
41c151
-  g_assert (self->cursor != META_CURSOR_NONE);
41c151
-
41c151
-  self->theme_dirty = FALSE;
41c151
-
41c151
-  /* We might be reloading with a different scale. If so clear the old data. */
41c151
-  if (self->xcursor_images)
41c151
-    {
41c151
-      g_clear_pointer (&self->texture, cogl_object_unref);
41c151
-      XcursorImagesDestroy (self->xcursor_images);
41c151
-    }
41c151
-
41c151
-  self->current_frame = 0;
41c151
-  self->xcursor_images = load_cursor_on_client (self->cursor,
41c151
-                                                self->theme_scale);
41c151
-  if (!self->xcursor_images)
41c151
-    meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
41c151
-
41c151
-  image = meta_cursor_sprite_get_current_frame_image (self);
41c151
-  meta_cursor_sprite_load_from_xcursor_image (self, image);
41c151
-}
41c151
-
41c151
-MetaCursorSprite *
41c151
-meta_cursor_sprite_from_theme (MetaCursor cursor)
41c151
+void
41c151
+meta_cursor_sprite_clear_texture (MetaCursorSprite *sprite)
41c151
 {
41c151
-  MetaCursorSprite *self;
41c151
-
41c151
-  self = meta_cursor_sprite_new ();
41c151
-
41c151
-  self->cursor = cursor;
41c151
-  self->theme_dirty = TRUE;
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
 
41c151
-  return self;
41c151
+  g_clear_pointer (&priv->texture, cogl_object_unref);
41c151
 }
41c151
 
41c151
 void
41c151
-meta_cursor_sprite_set_texture (MetaCursorSprite *self,
41c151
+meta_cursor_sprite_set_texture (MetaCursorSprite *sprite,
41c151
                                 CoglTexture      *texture,
41c151
                                 int               hot_x,
41c151
                                 int               hot_y)
41c151
 {
41c151
-  if (self->texture == COGL_TEXTURE_2D (texture) &&
41c151
-      self->hot_x == hot_x &&
41c151
-      self->hot_y == hot_y)
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
+
41c151
+  if (priv->texture == COGL_TEXTURE_2D (texture) &&
41c151
+      priv->hot_x == hot_x &&
41c151
+      priv->hot_y == hot_y)
41c151
     return;
41c151
 
41c151
-  g_clear_pointer (&self->texture, cogl_object_unref);
41c151
+  g_clear_pointer (&priv->texture, cogl_object_unref);
41c151
   if (texture)
41c151
-    self->texture = cogl_object_ref (texture);
41c151
-  self->hot_x = hot_x;
41c151
-  self->hot_y = hot_y;
41c151
+    priv->texture = cogl_object_ref (texture);
41c151
+  priv->hot_x = hot_x;
41c151
+  priv->hot_y = hot_y;
41c151
 
41c151
-  g_signal_emit (self, signals[TEXTURE_CHANGED], 0);
41c151
+  g_signal_emit (sprite, signals[TEXTURE_CHANGED], 0);
41c151
 }
41c151
 
41c151
 void
41c151
-meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
41c151
+meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite,
41c151
                                       float             scale)
41c151
 {
41c151
-  self->texture_scale = scale;
41c151
-}
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
 
41c151
-void
41c151
-meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
41c151
-                                    int               theme_scale)
41c151
-{
41c151
-  if (self->theme_scale != theme_scale)
41c151
-    self->theme_dirty = TRUE;
41c151
-  self->theme_scale = theme_scale;
41c151
+  priv->texture_scale = scale;
41c151
 }
41c151
 
41c151
 CoglTexture *
41c151
-meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self)
41c151
+meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite)
41c151
 {
41c151
-  return COGL_TEXTURE (self->texture);
41c151
-}
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
 
41c151
-MetaCursor
41c151
-meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
41c151
-{
41c151
-  return self->cursor;
41c151
+  return COGL_TEXTURE (priv->texture);
41c151
 }
41c151
 
41c151
 void
41c151
-meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
41c151
+meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite,
41c151
                                 int              *hot_x,
41c151
                                 int              *hot_y)
41c151
 {
41c151
-  *hot_x = self->hot_x;
41c151
-  *hot_y = self->hot_y;
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
+
41c151
+  *hot_x = priv->hot_x;
41c151
+  *hot_y = priv->hot_y;
41c151
 }
41c151
 
41c151
 float
41c151
-meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self)
41c151
+meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite)
41c151
 {
41c151
-  return self->texture_scale;
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
+
41c151
+  return priv->texture_scale;
41c151
 }
41c151
 
41c151
 void
41c151
-meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
41c151
+meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
41c151
                                int               x,
41c151
                                int               y)
41c151
 {
41c151
-  g_signal_emit (self, signals[PREPARE_AT], 0, x, y);
41c151
+  g_signal_emit (sprite, signals[PREPARE_AT], 0, x, y);
41c151
 }
41c151
 
41c151
 void
41c151
-meta_cursor_sprite_realize_texture (MetaCursorSprite *self)
41c151
+meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite)
41c151
 {
41c151
-  if (self->theme_dirty)
41c151
-    meta_cursor_sprite_load_from_theme (self);
41c151
+  MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite);
41c151
+
41c151
+  if (klass->realize_texture)
41c151
+    klass->realize_texture (sprite);
41c151
 }
41c151
 
41c151
 static void
41c151
-meta_cursor_sprite_init (MetaCursorSprite *self)
41c151
+meta_cursor_sprite_init (MetaCursorSprite *sprite)
41c151
 {
41c151
-  self->texture_scale = 1.0f;
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
+
41c151
+  priv->texture_scale = 1.0f;
41c151
 }
41c151
 
41c151
 static void
41c151
 meta_cursor_sprite_finalize (GObject *object)
41c151
 {
41c151
-  MetaCursorSprite *self = META_CURSOR_SPRITE (object);
41c151
-
41c151
-  if (self->xcursor_images)
41c151
-    XcursorImagesDestroy (self->xcursor_images);
41c151
+  MetaCursorSprite *sprite = META_CURSOR_SPRITE (object);
41c151
+  MetaCursorSpritePrivate *priv =
41c151
+    meta_cursor_sprite_get_instance_private (sprite);
41c151
 
41c151
-  g_clear_pointer (&self->texture, cogl_object_unref);
41c151
+  g_clear_pointer (&priv->texture, cogl_object_unref);
41c151
 
41c151
   G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object);
41c151
 }
41c151
diff --git a/src/backends/meta-cursor.h b/src/backends/meta-cursor.h
41c151
index 6087df69c..3051fdee6 100644
41c151
--- a/src/backends/meta-cursor.h
41c151
+++ b/src/backends/meta-cursor.h
41c151
@@ -25,51 +25,50 @@
41c151
 #include <meta/common.h>
41c151
 #include <meta/boxes.h>
41c151
 
41c151
-typedef struct _MetaCursorSprite MetaCursorSprite;
41c151
-
41c151
 #define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ())
41c151
-G_DECLARE_FINAL_TYPE (MetaCursorSprite,
41c151
-                      meta_cursor_sprite,
41c151
-                      META, CURSOR_SPRITE,
41c151
-                      GObject);
41c151
-
41c151
-MetaCursorSprite * meta_cursor_sprite_new (void);
41c151
-
41c151
-MetaCursorSprite * meta_cursor_sprite_from_theme  (MetaCursor cursor);
41c151
-
41c151
-
41c151
-void meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
41c151
-                                         int               scale);
41c151
-
41c151
-MetaCursor meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self);
41c151
-
41c151
-Cursor meta_cursor_create_x_cursor (Display    *xdisplay,
41c151
-                                    MetaCursor  cursor);
41c151
-
41c151
-void meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
41c151
+G_DECLARE_DERIVABLE_TYPE (MetaCursorSprite,
41c151
+                          meta_cursor_sprite,
41c151
+                          META, CURSOR_SPRITE,
41c151
+                          GObject)
41c151
+
41c151
+struct _MetaCursorSpriteClass
41c151
+{
41c151
+  GObjectClass parent_class;
41c151
+
41c151
+  void (* realize_texture) (MetaCursorSprite *sprite);
41c151
+  gboolean (* is_animated) (MetaCursorSprite *sprite);
41c151
+  void (* tick_frame) (MetaCursorSprite *sprite);
41c151
+  unsigned int (* get_current_frame_time) (MetaCursorSprite *sprite);
41c151
+};
41c151
+
41c151
+void meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
41c151
                                     int               x,
41c151
                                     int               y);
41c151
 
41c151
-void meta_cursor_sprite_realize_texture (MetaCursorSprite *self);
41c151
+void meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite);
41c151
+
41c151
+void meta_cursor_sprite_clear_texture (MetaCursorSprite *sprite);
41c151
 
41c151
-void meta_cursor_sprite_set_texture (MetaCursorSprite *self,
41c151
+void meta_cursor_sprite_set_texture (MetaCursorSprite *sprite,
41c151
                                      CoglTexture      *texture,
41c151
                                      int               hot_x,
41c151
                                      int               hot_y);
41c151
 
41c151
-void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
41c151
+void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite,
41c151
                                            float             scale);
41c151
 
41c151
-CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self);
41c151
+CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite);
41c151
 
41c151
-void meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
41c151
+void meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite,
41c151
                                      int              *hot_x,
41c151
                                      int              *hot_y);
41c151
 
41c151
-float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self);
41c151
+float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite);
41c151
+
41c151
+gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *sprite);
41c151
+
41c151
+void meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite);
41c151
 
41c151
-gboolean meta_cursor_sprite_is_animated            (MetaCursorSprite *self);
41c151
-void     meta_cursor_sprite_tick_frame             (MetaCursorSprite *self);
41c151
-guint    meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self);
41c151
+unsigned int meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite);
41c151
 
41c151
 #endif /* META_CURSOR_H */
41c151
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
41c151
index a29f593ea..042d96ec6 100644
41c151
--- a/src/backends/native/meta-backend-native.c
41c151
+++ b/src/backends/native/meta-backend-native.c
41c151
@@ -645,8 +645,6 @@ void meta_backend_native_resume (MetaBackendNative *native)
41c151
     meta_backend_get_monitor_manager (backend);
41c151
   MetaMonitorManagerKms *monitor_manager_kms =
41c151
     META_MONITOR_MANAGER_KMS (monitor_manager);
41c151
-  MetaCursorRenderer *cursor_renderer;
41c151
-  MetaCursorRendererNative *cursor_renderer_native;
41c151
   ClutterActor *stage;
41c151
   MetaIdleMonitor *idle_monitor;
41c151
 
41c151
@@ -658,10 +656,6 @@ void meta_backend_native_resume (MetaBackendNative *native)
41c151
   stage = meta_backend_get_stage (backend);
41c151
   clutter_actor_queue_redraw (stage);
41c151
 
41c151
-  cursor_renderer = meta_backend_get_cursor_renderer (backend);
41c151
-  cursor_renderer_native = META_CURSOR_RENDERER_NATIVE (cursor_renderer);
41c151
-  meta_cursor_renderer_native_force_update (cursor_renderer_native);
41c151
-
41c151
   idle_monitor = meta_backend_get_idle_monitor (backend, 0);
41c151
   meta_idle_monitor_reset_idletime (idle_monitor);
41c151
 }
41c151
diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c
41c151
index c7326af42..29800953b 100644
41c151
--- a/src/backends/native/meta-cursor-renderer-native.c
41c151
+++ b/src/backends/native/meta-cursor-renderer-native.c
41c151
@@ -35,6 +35,7 @@
41c151
 #include <meta/meta-backend.h>
41c151
 
41c151
 #include "backends/meta-backend-private.h"
41c151
+#include "backends/meta-cursor-sprite-xcursor.h"
41c151
 #include "backends/meta-logical-monitor.h"
41c151
 #include "backends/meta-monitor.h"
41c151
 #include "backends/meta-monitor-manager-private.h"
41c151
@@ -43,6 +44,11 @@
41c151
 #include "core/boxes-private.h"
41c151
 #include "meta/boxes.h"
41c151
 
41c151
+#ifdef HAVE_WAYLAND
41c151
+#include "wayland/meta-cursor-sprite-wayland.h"
41c151
+#include "wayland/meta-wayland-buffer.h"
41c151
+#endif
41c151
+
41c151
 #ifndef DRM_CAP_CURSOR_WIDTH
41c151
 #define DRM_CAP_CURSOR_WIDTH 0x8
41c151
 #endif
41c151
@@ -113,6 +119,11 @@ static GQuark quark_cursor_renderer_native_gpu_data = 0;
41c151
 
41c151
 G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER);
41c151
 
41c151
+static void
41c151
+realize_cursor_sprite (MetaCursorRenderer *renderer,
41c151
+                       MetaCursorSprite   *cursor_sprite,
41c151
+                       GList              *gpus);
41c151
+
41c151
 static MetaCursorNativeGpuState *
41c151
 get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
41c151
                       MetaGpuKms              *gpu_kms);
41c151
@@ -152,7 +163,8 @@ static void
41c151
 meta_cursor_renderer_native_finalize (GObject *object)
41c151
 {
41c151
   MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object);
41c151
-  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (renderer);
41c151
+  MetaCursorRendererNativePrivate *priv =
41c151
+    meta_cursor_renderer_native_get_instance_private (renderer);
41c151
 
41c151
   if (priv->animation_timeout_id)
41c151
     g_source_remove (priv->animation_timeout_id);
41c151
@@ -203,7 +215,8 @@ set_crtc_cursor (MetaCursorRendererNative *native,
41c151
                  MetaCrtc                 *crtc,
41c151
                  MetaCursorSprite         *cursor_sprite)
41c151
 {
41c151
-  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
41c151
+  MetaCursorRendererNativePrivate *priv =
41c151
+    meta_cursor_renderer_native_get_instance_private (native);
41c151
   MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
41c151
   MetaGpuKms *gpu_kms;
41c151
   int kms_fd;
41c151
@@ -371,7 +384,8 @@ static void
41c151
 update_hw_cursor (MetaCursorRendererNative *native,
41c151
                   MetaCursorSprite         *cursor_sprite)
41c151
 {
41c151
-  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
41c151
+  MetaCursorRendererNativePrivate *priv =
41c151
+    meta_cursor_renderer_native_get_instance_private (native);
41c151
   MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
41c151
   MetaMonitorManager *monitor_manager = priv->monitor_manager;
41c151
   GList *logical_monitors;
41c151
@@ -564,18 +578,15 @@ can_draw_cursor_unscaled (MetaCursorRenderer *renderer,
41c151
 
41c151
 static gboolean
41c151
 should_have_hw_cursor (MetaCursorRenderer *renderer,
41c151
-                       MetaCursorSprite   *cursor_sprite)
41c151
+                       MetaCursorSprite   *cursor_sprite,
41c151
+                       GList              *gpus)
41c151
 {
41c151
-  MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
41c151
-  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
41c151
-  GList *gpus;
41c151
   GList *l;
41c151
   CoglTexture *texture;
41c151
 
41c151
   if (!cursor_sprite)
41c151
     return FALSE;
41c151
 
41c151
-  gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
41c151
   for (l = gpus; l; l = l->next)
41c151
     {
41c151
       MetaGpuKms *gpu_kms = l->data;
41c151
@@ -609,7 +620,8 @@ should_have_hw_cursor (MetaCursorRenderer *renderer,
41c151
 static gboolean
41c151
 meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
41c151
 {
41c151
-  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
41c151
+  MetaCursorRendererNativePrivate *priv =
41c151
+    meta_cursor_renderer_native_get_instance_private (native);
41c151
   MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
41c151
   MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer);
41c151
 
41c151
@@ -621,10 +633,11 @@ meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
41c151
 }
41c151
 
41c151
 static void
41c151
-meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native,
41c151
-                                           MetaCursorSprite         *cursor_sprite)
41c151
+maybe_schedule_cursor_sprite_animation_frame (MetaCursorRendererNative *native,
41c151
+                                              MetaCursorSprite         *cursor_sprite)
41c151
 {
41c151
-  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
41c151
+  MetaCursorRendererNativePrivate *priv =
41c151
+    meta_cursor_renderer_native_get_instance_private (native);
41c151
   gboolean cursor_change;
41c151
   guint delay;
41c151
 
41c151
@@ -656,21 +669,78 @@ meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native,
41c151
     }
41c151
 }
41c151
 
41c151
+static GList *
41c151
+calculate_cursor_sprite_gpus (MetaCursorRenderer *renderer,
41c151
+                              MetaCursorSprite   *cursor_sprite)
41c151
+{
41c151
+  MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
41c151
+  MetaCursorRendererNativePrivate *priv =
41c151
+    meta_cursor_renderer_native_get_instance_private (native);
41c151
+  MetaMonitorManager *monitor_manager = priv->monitor_manager;
41c151
+  GList *gpus = NULL;
41c151
+  GList *logical_monitors;
41c151
+  GList *l;
41c151
+  ClutterRect cursor_rect;
41c151
+
41c151
+  cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
41c151
+
41c151
+  logical_monitors =
41c151
+    meta_monitor_manager_get_logical_monitors (monitor_manager);
41c151
+  for (l = logical_monitors; l; l = l->next)
41c151
+    {
41c151
+      MetaLogicalMonitor *logical_monitor = l->data;
41c151
+      MetaRectangle logical_monitor_layout;
41c151
+      ClutterRect logical_monitor_rect;
41c151
+      GList *monitors, *l_mon;
41c151
+
41c151
+      logical_monitor_layout =
41c151
+        meta_logical_monitor_get_layout (logical_monitor);
41c151
+      logical_monitor_rect =
41c151
+        meta_rectangle_to_clutter_rect (&logical_monitor_layout);
41c151
+
41c151
+      if (!clutter_rect_intersection (&cursor_rect, &logical_monitor_rect,
41c151
+                                      NULL))
41c151
+        continue;
41c151
+
41c151
+      monitors = meta_logical_monitor_get_monitors (logical_monitor);
41c151
+      for (l_mon = monitors; l_mon; l_mon = l_mon->next)
41c151
+        {
41c151
+          MetaMonitor *monitor = l_mon->data;
41c151
+          MetaGpu *gpu;
41c151
+
41c151
+          gpu = meta_monitor_get_gpu (monitor);
41c151
+          if (!g_list_find (gpus, gpu))
41c151
+            gpus = g_list_prepend (gpus, gpu);
41c151
+        }
41c151
+    }
41c151
+
41c151
+  return gpus;
41c151
+}
41c151
+
41c151
 static gboolean
41c151
 meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
41c151
                                            MetaCursorSprite   *cursor_sprite)
41c151
 {
41c151
   MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
41c151
-  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
41c151
+  MetaCursorRendererNativePrivate *priv =
41c151
+    meta_cursor_renderer_native_get_instance_private (native);
41c151
+  g_autoptr (GList) gpus = NULL;
41c151
 
41c151
   if (cursor_sprite)
41c151
-    meta_cursor_sprite_realize_texture (cursor_sprite);
41c151
+    {
41c151
+      meta_cursor_sprite_realize_texture (cursor_sprite);
41c151
+      gpus = calculate_cursor_sprite_gpus (renderer, cursor_sprite);
41c151
+      realize_cursor_sprite (renderer, cursor_sprite, gpus);
41c151
+    }
41c151
 
41c151
-  meta_cursor_renderer_native_trigger_frame (native, cursor_sprite);
41c151
+  maybe_schedule_cursor_sprite_animation_frame (native, cursor_sprite);
41c151
 
41c151
-  priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite);
41c151
+  priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite, gpus);
41c151
   update_hw_cursor (native, cursor_sprite);
41c151
-  return priv->has_hw_cursor;
41c151
+
41c151
+  return (priv->has_hw_cursor ||
41c151
+          !cursor_sprite ||
41c151
+          !meta_cursor_sprite_get_cogl_texture (cursor_sprite));
41c151
 }
41c151
 
41c151
 static void
41c151
@@ -706,6 +776,24 @@ ensure_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
41c151
   return cursor_gpu_state;
41c151
 }
41c151
 
41c151
+static void
41c151
+on_cursor_sprite_texture_changed (MetaCursorSprite *cursor_sprite)
41c151
+{
41c151
+  MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
41c151
+  GHashTableIter iter;
41c151
+  MetaCursorNativeGpuState *cursor_gpu_state;
41c151
+
41c151
+  g_hash_table_iter_init (&iter, cursor_priv->gpu_states);
41c151
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &cursor_gpu_state))
41c151
+    {
41c151
+      guint pending_bo;
41c151
+      pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_gpu_state);
41c151
+      g_clear_pointer (&cursor_gpu_state->bos[pending_bo],
41c151
+                       (GDestroyNotify) gbm_bo_destroy);
41c151
+      cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED;
41c151
+    }
41c151
+}
41c151
+
41c151
 static void
41c151
 cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
41c151
 {
41c151
@@ -738,6 +826,9 @@ ensure_cursor_priv (MetaCursorSprite *cursor_sprite)
41c151
                            cursor_priv,
41c151
                            (GDestroyNotify) cursor_priv_free);
41c151
 
41c151
+  g_signal_connect (cursor_sprite, "texture-changed",
41c151
+                    G_CALLBACK (on_cursor_sprite_texture_changed), NULL);
41c151
+
41c151
   return cursor_priv;
41c151
 }
41c151
 
41c151
@@ -805,57 +896,71 @@ load_cursor_sprite_gbm_buffer_for_gpu (MetaCursorRendererNative *native,
41c151
     }
41c151
 }
41c151
 
41c151
-static void
41c151
-invalidate_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite,
41c151
-                                         MetaGpuKms       *gpu_kms)
41c151
+static gboolean
41c151
+is_cursor_hw_state_valid (MetaCursorSprite *cursor_sprite,
41c151
+                          MetaGpuKms       *gpu_kms)
41c151
 {
41c151
   MetaCursorNativePrivate *cursor_priv;
41c151
   MetaCursorNativeGpuState *cursor_gpu_state;
41c151
-  guint pending_bo;
41c151
 
41c151
   cursor_priv = get_cursor_priv (cursor_sprite);
41c151
   if (!cursor_priv)
41c151
-    return;
41c151
+    return FALSE;
41c151
 
41c151
   cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms);
41c151
   if (!cursor_gpu_state)
41c151
-    return;
41c151
+    return FALSE;
41c151
 
41c151
-  pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_gpu_state);
41c151
-  g_clear_pointer (&cursor_gpu_state->bos[pending_bo],
41c151
-                   (GDestroyNotify) gbm_bo_destroy);
41c151
-  cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED;
41c151
+  switch (cursor_gpu_state->pending_bo_state)
41c151
+    {
41c151
+    case META_CURSOR_GBM_BO_STATE_SET:
41c151
+    case META_CURSOR_GBM_BO_STATE_NONE:
41c151
+      return TRUE;
41c151
+    case META_CURSOR_GBM_BO_STATE_INVALIDATED:
41c151
+      return FALSE;
41c151
+    }
41c151
+
41c151
+  g_assert_not_reached ();
41c151
 }
41c151
 
41c151
 #ifdef HAVE_WAYLAND
41c151
 static void
41c151
-meta_cursor_renderer_native_realize_cursor_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
41c151
-                                                                   MetaGpuKms         *gpu_kms,
41c151
-                                                                   MetaCursorSprite   *cursor_sprite,
41c151
-                                                                   struct wl_resource *buffer)
41c151
+realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer      *renderer,
41c151
+                                              MetaGpuKms              *gpu_kms,
41c151
+                                              MetaCursorSpriteWayland *sprite_wayland)
41c151
 {
41c151
   MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
41c151
+  MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_wayland);
41c151
   MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
41c151
   uint32_t gbm_format;
41c151
   uint64_t cursor_width, cursor_height;
41c151
   CoglTexture *texture;
41c151
   uint width, height;
41c151
+  MetaWaylandBuffer *buffer;
41c151
+  struct wl_resource *buffer_resource;
41c151
+  struct wl_shm_buffer *shm_buffer;
41c151
 
41c151
   cursor_renderer_gpu_data =
41c151
     meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
41c151
   if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
41c151
     return;
41c151
 
41c151
-  /* Destroy any previous pending cursor buffer; we'll always either fail (which
41c151
-   * should unset, or succeed, which will set new buffer.
41c151
-   */
41c151
-  invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms);
41c151
+  if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms))
41c151
+    return;
41c151
 
41c151
   texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
41c151
   width = cogl_texture_get_width (texture);
41c151
   height = cogl_texture_get_height (texture);
41c151
 
41c151
-  struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
41c151
+  buffer = meta_cursor_sprite_wayland_get_buffer (sprite_wayland);
41c151
+  if (!buffer)
41c151
+    return;
41c151
+
41c151
+  buffer_resource = meta_wayland_buffer_get_resource (buffer);
41c151
+  if (!buffer_resource)
41c151
+    return;
41c151
+
41c151
+  shm_buffer = wl_shm_buffer_get (buffer_resource);
41c151
   if (shm_buffer)
41c151
     {
41c151
       int rowstride = wl_shm_buffer_get_stride (shm_buffer);
41c151
@@ -929,47 +1034,27 @@ meta_cursor_renderer_native_realize_cursor_from_wl_buffer_for_gpu (MetaCursorRen
41c151
       set_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms, bo);
41c151
     }
41c151
 }
41c151
-
41c151
-static void
41c151
-meta_cursor_renderer_native_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
41c151
-                                                           MetaCursorSprite *cursor_sprite,
41c151
-                                                           struct wl_resource *buffer)
41c151
-{
41c151
-  MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
41c151
-  MetaCursorRendererNativePrivate *priv =
41c151
-	  meta_cursor_renderer_native_get_instance_private (native);
41c151
-  GList *gpus;
41c151
-  GList *l;
41c151
-
41c151
-  gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
41c151
-  for (l = gpus; l; l = l->next)
41c151
-    {
41c151
-      MetaGpuKms *gpu_kms = l->data;
41c151
-
41c151
-      meta_cursor_renderer_native_realize_cursor_from_wl_buffer_for_gpu (
41c151
-        renderer,
41c151
-        gpu_kms,
41c151
-        cursor_sprite,
41c151
-        buffer);
41c151
-    }
41c151
-}
41c151
 #endif
41c151
 
41c151
 static void
41c151
-meta_cursor_renderer_native_realize_cursor_from_xcursor_for_gpu (MetaCursorRenderer *renderer,
41c151
-                                                                 MetaGpuKms         *gpu_kms,
41c151
-                                                                 MetaCursorSprite   *cursor_sprite,
41c151
-                                                                 XcursorImage       *xc_image)
41c151
+realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer      *renderer,
41c151
+                                            MetaGpuKms              *gpu_kms,
41c151
+                                            MetaCursorSpriteXcursor *sprite_xcursor)
41c151
 {
41c151
   MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
41c151
   MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
41c151
+  MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
41c151
+  XcursorImage *xc_image;
41c151
 
41c151
   cursor_renderer_gpu_data =
41c151
     meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
41c151
   if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
41c151
     return;
41c151
 
41c151
-  invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms);
41c151
+  if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms))
41c151
+    return;
41c151
+
41c151
+  xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor);
41c151
 
41c151
   load_cursor_sprite_gbm_buffer_for_gpu (native,
41c151
                                          gpu_kms,
41c151
@@ -982,26 +1067,45 @@ meta_cursor_renderer_native_realize_cursor_from_xcursor_for_gpu (MetaCursorRende
41c151
 }
41c151
 
41c151
 static void
41c151
-meta_cursor_renderer_native_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
41c151
-                                                         MetaCursorSprite   *cursor_sprite,
41c151
-                                                         XcursorImage       *xc_image)
41c151
+realize_cursor_sprite_for_gpu (MetaCursorRenderer *renderer,
41c151
+                               MetaGpuKms         *gpu_kms,
41c151
+                               MetaCursorSprite   *cursor_sprite)
41c151
+{
41c151
+#ifdef HAVE_WAYLAND
41c151
+  if (META_IS_CURSOR_SPRITE_WAYLAND (cursor_sprite))
41c151
+    {
41c151
+      MetaCursorSpriteWayland *sprite_wayland =
41c151
+        META_CURSOR_SPRITE_WAYLAND (cursor_sprite);
41c151
+
41c151
+      realize_cursor_sprite_from_wl_buffer_for_gpu (renderer,
41c151
+                                                    gpu_kms,
41c151
+                                                    sprite_wayland);
41c151
+    }
41c151
+  else
41c151
+#endif
41c151
+  if (META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite))
41c151
+    {
41c151
+      MetaCursorSpriteXcursor *sprite_xcursor =
41c151
+        META_CURSOR_SPRITE_XCURSOR (cursor_sprite);
41c151
+
41c151
+      realize_cursor_sprite_from_xcursor_for_gpu (renderer,
41c151
+                                                  gpu_kms,
41c151
+                                                  sprite_xcursor);
41c151
+    }
41c151
+}
41c151
+
41c151
+static void
41c151
+realize_cursor_sprite (MetaCursorRenderer *renderer,
41c151
+                       MetaCursorSprite   *cursor_sprite,
41c151
+                       GList              *gpus)
41c151
 {
41c151
-  MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
41c151
-  MetaCursorRendererNativePrivate *priv =
41c151
-	  meta_cursor_renderer_native_get_instance_private (native);
41c151
-  GList *gpus;
41c151
   GList *l;
41c151
 
41c151
-  gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
41c151
   for (l = gpus; l; l = l->next)
41c151
     {
41c151
       MetaGpuKms *gpu_kms = l->data;
41c151
 
41c151
-      meta_cursor_renderer_native_realize_cursor_from_xcursor_for_gpu (
41c151
-        renderer,
41c151
-        gpu_kms,
41c151
-        cursor_sprite,
41c151
-        xc_image);
41c151
+      realize_cursor_sprite_for_gpu (renderer, gpu_kms, cursor_sprite);
41c151
     }
41c151
 }
41c151
 
41c151
@@ -1013,12 +1117,6 @@ meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
41c151
 
41c151
   object_class->finalize = meta_cursor_renderer_native_finalize;
41c151
   renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor;
41c151
-#ifdef HAVE_WAYLAND
41c151
-  renderer_class->realize_cursor_from_wl_buffer =
41c151
-    meta_cursor_renderer_native_realize_cursor_from_wl_buffer;
41c151
-#endif
41c151
-  renderer_class->realize_cursor_from_xcursor =
41c151
-    meta_cursor_renderer_native_realize_cursor_from_xcursor;
41c151
 
41c151
   quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native");
41c151
   quark_cursor_renderer_native_gpu_data =
41c151
@@ -1033,14 +1131,13 @@ force_update_hw_cursor (MetaCursorRendererNative *native)
41c151
     meta_cursor_renderer_native_get_instance_private (native);
41c151
 
41c151
   priv->hw_state_invalidated = TRUE;
41c151
-  update_hw_cursor (native, meta_cursor_renderer_get_cursor (renderer));
41c151
+  meta_cursor_renderer_force_update (renderer);
41c151
 }
41c151
 
41c151
 static void
41c151
 on_monitors_changed (MetaMonitorManager       *monitors,
41c151
                      MetaCursorRendererNative *native)
41c151
 {
41c151
-  /* Our tracking is all messed up, so force an update. */
41c151
   force_update_hw_cursor (native);
41c151
 }
41c151
 
41c151
@@ -1112,9 +1209,3 @@ static void
41c151
 meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
41c151
 {
41c151
 }
41c151
-
41c151
-void
41c151
-meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
41c151
-{
41c151
-  force_update_hw_cursor (native);
41c151
-}
41c151
diff --git a/src/backends/native/meta-cursor-renderer-native.h b/src/backends/native/meta-cursor-renderer-native.h
41c151
index 09203a5f7..fb4c8edc7 100644
41c151
--- a/src/backends/native/meta-cursor-renderer-native.h
41c151
+++ b/src/backends/native/meta-cursor-renderer-native.h
41c151
@@ -32,8 +32,6 @@ G_DECLARE_FINAL_TYPE (MetaCursorRendererNative, meta_cursor_renderer_native,
41c151
                       META, CURSOR_RENDERER_NATIVE,
41c151
                       MetaCursorRenderer)
41c151
 
41c151
-void meta_cursor_renderer_native_force_update (MetaCursorRendererNative *renderer);
41c151
-
41c151
 MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend);
41c151
 
41c151
 #endif /* META_CURSOR_RENDERER_NATIVE_H */
41c151
diff --git a/src/backends/x11/cm/meta-cursor-sprite-xfixes.c b/src/backends/x11/cm/meta-cursor-sprite-xfixes.c
41c151
new file mode 100644
41c151
index 000000000..143ebb791
41c151
--- /dev/null
41c151
+++ b/src/backends/x11/cm/meta-cursor-sprite-xfixes.c
41c151
@@ -0,0 +1,226 @@
41c151
+/*
41c151
+ * Copyright 2013, 2018 Red Hat, Inc.
41c151
+ *
41c151
+ * This program is free software; you can redistribute it and/or
41c151
+ * modify it under the terms of the GNU General Public License as
41c151
+ * published by the Free Software Foundation; either version 2 of the
41c151
+ * License, or (at your option) any later version.
41c151
+ *
41c151
+ * This program is distributed in the hope that it will be useful, but
41c151
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
+ * General Public License for more details.
41c151
+ *
41c151
+ * You should have received a copy of the GNU General Public License
41c151
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
41c151
+ *
41c151
+ */
41c151
+
41c151
+#include "config.h"
41c151
+
41c151
+#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
41c151
+
41c151
+#include <X11/extensions/Xfixes.h>
41c151
+
41c151
+#include "core/display-private.h"
41c151
+
41c151
+enum
41c151
+{
41c151
+  PROP_0,
41c151
+
41c151
+  PROP_DISPLAY,
41c151
+
41c151
+  N_PROPS
41c151
+};
41c151
+
41c151
+static GParamSpec *obj_props[N_PROPS];
41c151
+
41c151
+struct _MetaCursorSpriteXfixes
41c151
+{
41c151
+  MetaCursorSprite parent;
41c151
+
41c151
+  MetaDisplay *display;
41c151
+};
41c151
+
41c151
+static void
41c151
+meta_screen_cast_xfixes_init_initable_iface (GInitableIface *iface);
41c151
+
41c151
+G_DEFINE_TYPE_WITH_CODE (MetaCursorSpriteXfixes,
41c151
+                         meta_cursor_sprite_xfixes,
41c151
+                         META_TYPE_CURSOR_SPRITE,
41c151
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
41c151
+                                                meta_screen_cast_xfixes_init_initable_iface))
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xfixes_realize_texture (MetaCursorSprite *sprite)
41c151
+{
41c151
+}
41c151
+
41c151
+static gboolean
41c151
+meta_cursor_sprite_xfixes_is_animated (MetaCursorSprite *sprite)
41c151
+{
41c151
+  return FALSE;
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xfixes_get_property (GObject    *object,
41c151
+                                        guint       prop_id,
41c151
+                                        GValue     *value,
41c151
+                                        GParamSpec *pspec)
41c151
+{
41c151
+  MetaCursorSpriteXfixes *sprite_xfixes = META_CURSOR_SPRITE_XFIXES (object);
41c151
+
41c151
+  switch (prop_id)
41c151
+    {
41c151
+    case PROP_DISPLAY:
41c151
+      g_value_set_object (value, sprite_xfixes->display);
41c151
+      break;
41c151
+    default:
41c151
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
41c151
+      break;
41c151
+    }
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xfixes_set_property (GObject      *object,
41c151
+                                        guint         prop_id,
41c151
+                                        const GValue *value,
41c151
+                                        GParamSpec   *pspec)
41c151
+{
41c151
+  MetaCursorSpriteXfixes *sprite_xfixes = META_CURSOR_SPRITE_XFIXES (object);
41c151
+
41c151
+  switch (prop_id)
41c151
+    {
41c151
+    case PROP_DISPLAY:
41c151
+      sprite_xfixes->display = g_value_get_object (value);
41c151
+      break;
41c151
+    default:
41c151
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
41c151
+      break;
41c151
+    }
41c151
+}
41c151
+
41c151
+MetaCursorSpriteXfixes *
41c151
+meta_cursor_sprite_xfixes_new (MetaDisplay  *display,
41c151
+                               GError      **error)
41c151
+{
41c151
+  return g_initable_new (META_TYPE_CURSOR_SPRITE_XFIXES,
41c151
+                         NULL, error,
41c151
+                         "display", display,
41c151
+                         NULL);
41c151
+}
41c151
+
41c151
+static gboolean
41c151
+meta_cursor_sprite_xfixes_initable_init (GInitable     *initable,
41c151
+                                         GCancellable  *cancellable,
41c151
+                                         GError       **error)
41c151
+{
41c151
+  MetaCursorSpriteXfixes *sprite_xfixes =
41c151
+    META_CURSOR_SPRITE_XFIXES (initable);
41c151
+  MetaCursorSprite *sprite = META_CURSOR_SPRITE (sprite_xfixes);
41c151
+  XFixesCursorImage *cursor_image;
41c151
+  CoglTexture2D *texture;
41c151
+  uint8_t *cursor_data;
41c151
+  gboolean free_cursor_data;
41c151
+  ClutterBackend *clutter_backend;
41c151
+  CoglContext *cogl_context;
41c151
+
41c151
+  cursor_image = XFixesGetCursorImage (sprite_xfixes->display->xdisplay);
41c151
+  if (!cursor_image)
41c151
+    {
41c151
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
41c151
+                   "Failed to get cursor image");
41c151
+      return FALSE;
41c151
+    }
41c151
+
41c151
+  /*
41c151
+   * Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
41c151
+   * quantities as arrays of long; we need to convert on 64 bit
41c151
+   */
41c151
+  if (sizeof (long) == 4)
41c151
+    {
41c151
+      cursor_data = (uint8_t *) cursor_image->pixels;
41c151
+      free_cursor_data = FALSE;
41c151
+    }
41c151
+  else
41c151
+    {
41c151
+      int i, j;
41c151
+      uint32_t *cursor_words;
41c151
+      unsigned long *p;
41c151
+      uint32_t *q;
41c151
+
41c151
+      cursor_words = g_new (uint32_t,
41c151
+                            cursor_image->width * cursor_image->height);
41c151
+      cursor_data = (uint8_t *) cursor_words;
41c151
+
41c151
+      p = cursor_image->pixels;
41c151
+      q = cursor_words;
41c151
+      for (j = 0; j < cursor_image->height; j++)
41c151
+        {
41c151
+          for (i = 0; i < cursor_image->width; i++)
41c151
+            *(q++) = *(p++);
41c151
+        }
41c151
+
41c151
+      free_cursor_data = TRUE;
41c151
+    }
41c151
+
41c151
+  clutter_backend = clutter_get_default_backend ();
41c151
+  cogl_context = clutter_backend_get_cogl_context (clutter_backend);
41c151
+  texture = cogl_texture_2d_new_from_data (cogl_context,
41c151
+                                          cursor_image->width,
41c151
+                                          cursor_image->height,
41c151
+                                          CLUTTER_CAIRO_FORMAT_ARGB32,
41c151
+                                          cursor_image->width * 4, /* stride */
41c151
+                                          cursor_data,
41c151
+                                          error);
41c151
+
41c151
+  if (free_cursor_data)
41c151
+    g_free (cursor_data);
41c151
+
41c151
+  if (!sprite)
41c151
+    return FALSE;
41c151
+
41c151
+  meta_cursor_sprite_set_texture (sprite,
41c151
+                                  COGL_TEXTURE (texture),
41c151
+                                  cursor_image->xhot,
41c151
+                                  cursor_image->yhot);
41c151
+  cogl_object_unref (texture);
41c151
+  XFree (cursor_image);
41c151
+
41c151
+  return TRUE;
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_screen_cast_xfixes_init_initable_iface (GInitableIface *iface)
41c151
+{
41c151
+  iface->init = meta_cursor_sprite_xfixes_initable_init;
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xfixes_init (MetaCursorSpriteXfixes *sprite_xfixes)
41c151
+{
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_xfixes_class_init (MetaCursorSpriteXfixesClass *klass)
41c151
+{
41c151
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
41c151
+  MetaCursorSpriteClass *cursor_sprite_class = META_CURSOR_SPRITE_CLASS (klass);
41c151
+
41c151
+  object_class->get_property = meta_cursor_sprite_xfixes_get_property;
41c151
+  object_class->set_property = meta_cursor_sprite_xfixes_set_property;
41c151
+
41c151
+  cursor_sprite_class->realize_texture =
41c151
+    meta_cursor_sprite_xfixes_realize_texture;
41c151
+  cursor_sprite_class->is_animated = meta_cursor_sprite_xfixes_is_animated;
41c151
+
41c151
+  obj_props[PROP_DISPLAY] =
41c151
+    g_param_spec_object ("display",
41c151
+                         "display",
41c151
+                         "MetaDisplay",
41c151
+                         META_TYPE_DISPLAY,
41c151
+                         G_PARAM_READWRITE |
41c151
+                         G_PARAM_CONSTRUCT_ONLY |
41c151
+                         G_PARAM_STATIC_STRINGS);
41c151
+  g_object_class_install_properties (object_class, N_PROPS, obj_props);
41c151
+}
41c151
diff --git a/src/backends/x11/cm/meta-cursor-sprite-xfixes.h b/src/backends/x11/cm/meta-cursor-sprite-xfixes.h
41c151
new file mode 100644
41c151
index 000000000..c7073fc2c
41c151
--- /dev/null
41c151
+++ b/src/backends/x11/cm/meta-cursor-sprite-xfixes.h
41c151
@@ -0,0 +1,36 @@
41c151
+/*
41c151
+ * Copyright 2013, 2018 Red Hat, Inc.
41c151
+ *
41c151
+ * This program is free software; you can redistribute it and/or
41c151
+ * modify it under the terms of the GNU General Public License as
41c151
+ * published by the Free Software Foundation; either version 2 of the
41c151
+ * License, or (at your option) any later version.
41c151
+ *
41c151
+ * This program is distributed in the hope that it will be useful, but
41c151
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
+ * General Public License for more details.
41c151
+ *
41c151
+ * You should have received a copy of the GNU General Public License
41c151
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
41c151
+ *
41c151
+ */
41c151
+
41c151
+#ifndef META_CURSOR_SPRITE_XFIXES_H
41c151
+#define META_CURSOR_SPRITE_XFIXES_H
41c151
+
41c151
+#include <glib-object.h>
41c151
+
41c151
+#include "backends/meta-cursor.h"
41c151
+#include "meta/types.h"
41c151
+
41c151
+#define META_TYPE_CURSOR_SPRITE_XFIXES (meta_cursor_sprite_xfixes_get_type ())
41c151
+G_DECLARE_FINAL_TYPE (MetaCursorSpriteXfixes,
41c151
+                      meta_cursor_sprite_xfixes,
41c151
+                      META, CURSOR_SPRITE_XFIXES,
41c151
+                      MetaCursorSprite)
41c151
+
41c151
+MetaCursorSpriteXfixes * meta_cursor_sprite_xfixes_new (MetaDisplay  *display,
41c151
+                                                        GError      **error);
41c151
+
41c151
+#endif /* META_CURSOR_SPRITE_XFIXES_H */
41c151
diff --git a/src/backends/x11/meta-cursor-renderer-x11.c b/src/backends/x11/meta-cursor-renderer-x11.c
41c151
index 82109f1f3..bb3100a91 100644
41c151
--- a/src/backends/x11/meta-cursor-renderer-x11.c
41c151
+++ b/src/backends/x11/meta-cursor-renderer-x11.c
41c151
@@ -30,6 +30,7 @@
41c151
 
41c151
 #include "meta-backend-x11.h"
41c151
 #include "meta-stage-private.h"
41c151
+#include "backends/meta-cursor-sprite-xcursor.h"
41c151
 
41c151
 struct _MetaCursorRendererX11Private
41c151
 {
41c151
@@ -59,13 +60,18 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
41c151
 
41c151
   gboolean has_server_cursor = FALSE;
41c151
 
41c151
-  if (cursor_sprite)
41c151
+  if (cursor_sprite && META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite))
41c151
     {
41c151
-      MetaCursor cursor = meta_cursor_sprite_get_meta_cursor (cursor_sprite);
41c151
+      MetaCursorSpriteXcursor *sprite_xcursor =
41c151
+        META_CURSOR_SPRITE_XCURSOR (cursor_sprite);
41c151
+      MetaCursor cursor;
41c151
 
41c151
+      cursor = meta_cursor_sprite_xcursor_get_cursor (sprite_xcursor);
41c151
       if (cursor != META_CURSOR_NONE)
41c151
         {
41c151
-          Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
41c151
+          Cursor xcursor;
41c151
+
41c151
+          xcursor = meta_create_x_cursor (xdisplay, cursor);
41c151
           XDefineCursor (xdisplay, xwindow, xcursor);
41c151
           XFlush (xdisplay);
41c151
           XFreeCursor (xdisplay, xcursor);
41c151
diff --git a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c b/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
41c151
index da1a56038..0daae683c 100644
41c151
--- a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
41c151
+++ b/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
41c151
@@ -26,6 +26,8 @@
41c151
 
41c151
 #include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
41c151
 
41c151
+#include <X11/Xcursor/Xcursor.h>
41c151
+
41c151
 #include "backends/x11/meta-backend-x11.h"
41c151
 
41c151
 struct _MetaCursorRendererX11Nested
41c151
diff --git a/src/core/display.c b/src/core/display.c
41c151
index d6da84b30..e7dd4534b 100644
41c151
--- a/src/core/display.c
41c151
+++ b/src/core/display.c
41c151
@@ -3018,7 +3018,7 @@ Cursor
41c151
 meta_display_create_x_cursor (MetaDisplay *display,
41c151
                               MetaCursor   cursor)
41c151
 {
41c151
-  return meta_cursor_create_x_cursor (display->xdisplay, cursor);
41c151
+  return meta_create_x_cursor (display->xdisplay, cursor);
41c151
 }
41c151
 
41c151
 MetaGestureTracker *
41c151
diff --git a/src/core/screen.c b/src/core/screen.c
41c151
index c14bba0cf..048104150 100644
41c151
--- a/src/core/screen.c
41c151
+++ b/src/core/screen.c
41c151
@@ -60,6 +60,7 @@
41c151
 #include "x11/xprops.h"
41c151
 
41c151
 #include "backends/x11/meta-backend-x11.h"
41c151
+#include "backends/meta-cursor-sprite-xcursor.h"
41c151
 
41c151
 static char* get_screen_name (MetaDisplay *display,
41c151
                               int          number);
41c151
@@ -1323,12 +1324,13 @@ find_highest_logical_monitor_scale (MetaBackend      *backend,
41c151
 }
41c151
 
41c151
 static void
41c151
-root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
41c151
-                        int               x,
41c151
-                        int               y,
41c151
-                        MetaScreen       *screen)
41c151
+root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
41c151
+                        int                      x,
41c151
+                        int                      y,
41c151
+                        MetaScreen              *screen)
41c151
 {
41c151
   MetaBackend *backend = meta_get_backend ();
41c151
+  MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
41c151
 
41c151
   if (meta_is_stage_views_scaled ())
41c151
     {
41c151
@@ -1337,7 +1339,7 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
41c151
       scale = find_highest_logical_monitor_scale (backend, cursor_sprite);
41c151
       if (scale != 0.0)
41c151
         {
41c151
-          meta_cursor_sprite_set_theme_scale (cursor_sprite, scale);
41c151
+          meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, scale);
41c151
           meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0 / scale);
41c151
         }
41c151
     }
41c151
@@ -1353,18 +1355,18 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
41c151
       /* Reload the cursor texture if the scale has changed. */
41c151
       if (logical_monitor)
41c151
         {
41c151
-          meta_cursor_sprite_set_theme_scale (cursor_sprite,
41c151
-                                              logical_monitor->scale);
41c151
+          meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
41c151
+                                                      logical_monitor->scale);
41c151
           meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0);
41c151
         }
41c151
     }
41c151
 }
41c151
 
41c151
 static void
41c151
-manage_root_cursor_sprite_scale (MetaScreen       *screen,
41c151
-                                 MetaCursorSprite *cursor_sprite)
41c151
+manage_root_cursor_sprite_scale (MetaScreen              *screen,
41c151
+                                 MetaCursorSpriteXcursor *sprite_xcursor)
41c151
 {
41c151
-  g_signal_connect_object (cursor_sprite,
41c151
+  g_signal_connect_object (sprite_xcursor,
41c151
                            "prepare-at",
41c151
                            G_CALLBACK (root_cursor_prepare_at),
41c151
                            screen,
41c151
@@ -1377,17 +1379,18 @@ meta_screen_update_cursor (MetaScreen *screen)
41c151
   MetaDisplay *display = screen->display;
41c151
   MetaCursor cursor = screen->current_cursor;
41c151
   Cursor xcursor;
41c151
-  MetaCursorSprite *cursor_sprite;
41c151
+  MetaCursorSpriteXcursor *sprite_xcursor;
41c151
   MetaBackend *backend = meta_get_backend ();
41c151
   MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
41c151
 
41c151
-  cursor_sprite = meta_cursor_sprite_from_theme (cursor);
41c151
+  sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor);
41c151
 
41c151
   if (meta_is_wayland_compositor ())
41c151
-    manage_root_cursor_sprite_scale (screen, cursor_sprite);
41c151
+    manage_root_cursor_sprite_scale (screen, sprite_xcursor);
41c151
 
41c151
-  meta_cursor_tracker_set_root_cursor (cursor_tracker, cursor_sprite);
41c151
-  g_object_unref (cursor_sprite);
41c151
+  meta_cursor_tracker_set_root_cursor (cursor_tracker,
41c151
+                                       META_CURSOR_SPRITE (sprite_xcursor));
41c151
+  g_object_unref (sprite_xcursor);
41c151
 
41c151
   /* Set a cursor for X11 applications that don't specify their own */
41c151
   xcursor = meta_display_create_x_cursor (display, cursor);
41c151
diff --git a/src/wayland/meta-cursor-sprite-wayland.c b/src/wayland/meta-cursor-sprite-wayland.c
41c151
new file mode 100644
41c151
index 000000000..7c14960ff
41c151
--- /dev/null
41c151
+++ b/src/wayland/meta-cursor-sprite-wayland.c
41c151
@@ -0,0 +1,75 @@
41c151
+/*
41c151
+ * Copyright 2015, 2018 Red Hat, Inc.
41c151
+ *
41c151
+ * This program is free software; you can redistribute it and/or
41c151
+ * modify it under the terms of the GNU General Public License as
41c151
+ * published by the Free Software Foundation; either version 2 of the
41c151
+ * License, or (at your option) any later version.
41c151
+ *
41c151
+ * This program is distributed in the hope that it will be useful, but
41c151
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
+ * General Public License for more details.
41c151
+ *
41c151
+ * You should have received a copy of the GNU General Public License
41c151
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
41c151
+ *
41c151
+ */
41c151
+
41c151
+#include "config.h"
41c151
+
41c151
+#include "wayland/meta-cursor-sprite-wayland.h"
41c151
+
41c151
+struct _MetaCursorSpriteWayland
41c151
+{
41c151
+  MetaCursorSprite parent;
41c151
+
41c151
+  MetaWaylandSurface *surface;
41c151
+};
41c151
+
41c151
+G_DEFINE_TYPE (MetaCursorSpriteWayland,
41c151
+               meta_cursor_sprite_wayland,
41c151
+               META_TYPE_CURSOR_SPRITE)
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_wayland_realize_texture (MetaCursorSprite *sprite)
41c151
+{
41c151
+}
41c151
+
41c151
+static gboolean
41c151
+meta_cursor_sprite_wayland_is_animated (MetaCursorSprite *sprite)
41c151
+{
41c151
+  return FALSE;
41c151
+}
41c151
+
41c151
+MetaCursorSpriteWayland *
41c151
+meta_cursor_sprite_wayland_new (MetaWaylandSurface *surface)
41c151
+{
41c151
+  MetaCursorSpriteWayland *sprite_wayland;
41c151
+
41c151
+  sprite_wayland = g_object_new (META_TYPE_CURSOR_SPRITE_WAYLAND, NULL);
41c151
+  sprite_wayland->surface = surface;
41c151
+
41c151
+  return sprite_wayland;
41c151
+}
41c151
+
41c151
+MetaWaylandBuffer *
41c151
+meta_cursor_sprite_wayland_get_buffer (MetaCursorSpriteWayland *sprite_wayland)
41c151
+{
41c151
+  return meta_wayland_surface_get_buffer (sprite_wayland->surface);
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_wayland_init (MetaCursorSpriteWayland *sprite_wayland)
41c151
+{
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_cursor_sprite_wayland_class_init (MetaCursorSpriteWaylandClass *klass)
41c151
+{
41c151
+  MetaCursorSpriteClass *cursor_sprite_class = META_CURSOR_SPRITE_CLASS (klass);
41c151
+
41c151
+  cursor_sprite_class->realize_texture =
41c151
+    meta_cursor_sprite_wayland_realize_texture;
41c151
+  cursor_sprite_class->is_animated = meta_cursor_sprite_wayland_is_animated;
41c151
+}
41c151
diff --git a/src/wayland/meta-cursor-sprite-wayland.h b/src/wayland/meta-cursor-sprite-wayland.h
41c151
new file mode 100644
41c151
index 000000000..107698f3f
41c151
--- /dev/null
41c151
+++ b/src/wayland/meta-cursor-sprite-wayland.h
41c151
@@ -0,0 +1,35 @@
41c151
+/*
41c151
+ * Copyright 2013, 2018 Red Hat, Inc.
41c151
+ *
41c151
+ * This program is free software; you can redistribute it and/or
41c151
+ * modify it under the terms of the GNU General Public License as
41c151
+ * published by the Free Software Foundation; either version 2 of the
41c151
+ * License, or (at your option) any later version.
41c151
+ *
41c151
+ * This program is distributed in the hope that it will be useful, but
41c151
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
+ * General Public License for more details.
41c151
+ *
41c151
+ * You should have received a copy of the GNU General Public License
41c151
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
41c151
+ *
41c151
+ */
41c151
+
41c151
+#ifndef META_CURSOR_SPRITE_WAYLAND_H
41c151
+#define META_CURSOR_SPRITE_WAYLAND_H
41c151
+
41c151
+#include <glib-object.h>
41c151
+
41c151
+#include "backends/meta-cursor.h"
41c151
+#include "wayland/meta-wayland-surface.h"
41c151
+
41c151
+#define META_TYPE_CURSOR_SPRITE_WAYLAND meta_cursor_sprite_wayland_get_type ()
41c151
+G_DECLARE_FINAL_TYPE (MetaCursorSpriteWayland, meta_cursor_sprite_wayland,
41c151
+                      META, CURSOR_SPRITE_WAYLAND, MetaCursorSprite)
41c151
+
41c151
+MetaCursorSpriteWayland * meta_cursor_sprite_wayland_new (MetaWaylandSurface *surface);
41c151
+
41c151
+MetaWaylandBuffer * meta_cursor_sprite_wayland_get_buffer (MetaCursorSpriteWayland *sprite_wayland);
41c151
+
41c151
+#endif /* META_CURSOR_SPRITE_WAYLAND_H */
41c151
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
41c151
index 55564492a..c759eefc1 100644
41c151
--- a/src/wayland/meta-wayland-buffer.c
41c151
+++ b/src/wayland/meta-wayland-buffer.c
41c151
@@ -88,6 +88,12 @@ meta_wayland_buffer_from_resource (struct wl_resource *resource)
41c151
   return buffer;
41c151
 }
41c151
 
41c151
+struct wl_resource *
41c151
+meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer)
41c151
+{
41c151
+  return buffer->resource;
41c151
+}
41c151
+
41c151
 static gboolean
41c151
 meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer)
41c151
 {
41c151
diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h
41c151
index 5345033c2..e00a41e09 100644
41c151
--- a/src/wayland/meta-wayland-buffer.h
41c151
+++ b/src/wayland/meta-wayland-buffer.h
41c151
@@ -68,6 +68,7 @@ G_DECLARE_FINAL_TYPE (MetaWaylandBuffer, meta_wayland_buffer,
41c151
                       META, WAYLAND_BUFFER, GObject);
41c151
 
41c151
 MetaWaylandBuffer *     meta_wayland_buffer_from_resource       (struct wl_resource    *resource);
41c151
+struct wl_resource *    meta_wayland_buffer_get_resource        (MetaWaylandBuffer     *buffer);
41c151
 gboolean                meta_wayland_buffer_attach              (MetaWaylandBuffer     *buffer,
41c151
                                                                  GError               **error);
41c151
 CoglTexture *           meta_wayland_buffer_get_texture         (MetaWaylandBuffer     *buffer);
41c151
diff --git a/src/wayland/meta-wayland-surface-role-cursor.c b/src/wayland/meta-wayland-cursor-surface.c
41c151
similarity index 52%
41c151
rename from src/wayland/meta-wayland-surface-role-cursor.c
41c151
rename to src/wayland/meta-wayland-cursor-surface.c
41c151
index d118a8917..d08af9e8c 100644
41c151
--- a/src/wayland/meta-wayland-surface-role-cursor.c
41c151
+++ b/src/wayland/meta-wayland-cursor-surface.c
41c151
@@ -23,7 +23,7 @@
41c151
 
41c151
 #include <cogl/cogl.h>
41c151
 #include <cogl/cogl-wayland-server.h>
41c151
-#include "meta-wayland-surface-role-cursor.h"
41c151
+#include "meta-wayland-cursor-surface.h"
41c151
 #include "meta-wayland-buffer.h"
41c151
 #include "meta-xwayland.h"
41c151
 #include "screen-private.h"
41c151
@@ -31,35 +31,38 @@
41c151
 #include "backends/meta-backend-private.h"
41c151
 #include "backends/meta-logical-monitor.h"
41c151
 #include "core/boxes-private.h"
41c151
+#include "wayland/meta-cursor-sprite-wayland.h"
41c151
 
41c151
-typedef struct _MetaWaylandSurfaceRoleCursorPrivate MetaWaylandSurfaceRoleCursorPrivate;
41c151
+typedef struct _MetaWaylandCursorSurfacePrivate MetaWaylandCursorSurfacePrivate;
41c151
 
41c151
-struct _MetaWaylandSurfaceRoleCursorPrivate
41c151
+struct _MetaWaylandCursorSurfacePrivate
41c151
 {
41c151
   int hot_x;
41c151
   int hot_y;
41c151
-  MetaCursorSprite *cursor_sprite;
41c151
+  MetaCursorSpriteWayland *cursor_sprite;
41c151
   MetaCursorRenderer *cursor_renderer;
41c151
   MetaWaylandBuffer *buffer;
41c151
   struct wl_list frame_callbacks;
41c151
   gulong cursor_painted_handler_id;
41c151
 };
41c151
 
41c151
-G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRoleCursor,
41c151
-                            meta_wayland_surface_role_cursor,
41c151
+G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandCursorSurface,
41c151
+                            meta_wayland_cursor_surface,
41c151
                             META_TYPE_WAYLAND_SURFACE_ROLE)
41c151
 
41c151
 static void
41c151
-update_cursor_sprite_texture (MetaWaylandSurfaceRoleCursor *cursor_role)
41c151
+update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv = meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
-  MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_role));
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
+  MetaWaylandSurface *surface =
41c151
+    meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_surface));
41c151
   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
41c151
-  MetaCursorSprite *cursor_sprite = priv->cursor_sprite;
41c151
+  MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (priv->cursor_sprite);
41c151
 
41c151
   g_return_if_fail (!buffer || buffer->texture);
41c151
 
41c151
-  if (!priv->cursor_renderer || !cursor_sprite)
41c151
+  if (!priv->cursor_renderer)
41c151
     return;
41c151
 
41c151
   if (buffer)
41c151
@@ -68,20 +71,6 @@ update_cursor_sprite_texture (MetaWaylandSurfaceRoleCursor *cursor_role)
41c151
                                       buffer->texture,
41c151
                                       priv->hot_x * surface->scale,
41c151
                                       priv->hot_y * surface->scale);
41c151
-
41c151
-      if (priv->buffer)
41c151
-        {
41c151
-          struct wl_resource *buffer_resource;
41c151
-
41c151
-          g_assert (priv->buffer == buffer);
41c151
-          buffer_resource = buffer->resource;
41c151
-          meta_cursor_renderer_realize_cursor_from_wl_buffer (priv->cursor_renderer,
41c151
-                                                              cursor_sprite,
41c151
-                                                              buffer_resource);
41c151
-
41c151
-          meta_wayland_surface_unref_buffer_use_count (surface);
41c151
-          g_clear_object (&priv->buffer);
41c151
-        }
41c151
     }
41c151
   else
41c151
     {
41c151
@@ -92,12 +81,12 @@ update_cursor_sprite_texture (MetaWaylandSurfaceRoleCursor *cursor_role)
41c151
 }
41c151
 
41c151
 static void
41c151
-cursor_sprite_prepare_at (MetaCursorSprite             *cursor_sprite,
41c151
-                          int                           x,
41c151
-                          int                           y,
41c151
-                          MetaWaylandSurfaceRoleCursor *cursor_role)
41c151
+cursor_sprite_prepare_at (MetaCursorSprite         *cursor_sprite,
41c151
+                          int                       x,
41c151
+                          int                       y,
41c151
+                          MetaWaylandCursorSurface *cursor_surface)
41c151
 {
41c151
-  MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_role);
41c151
+  MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_surface);
41c151
   MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
41c151
 
41c151
   if (!meta_xwayland_is_xwayland_surface (surface))
41c151
@@ -126,14 +115,14 @@ cursor_sprite_prepare_at (MetaCursorSprite             *cursor_sprite,
41c151
 }
41c151
 
41c151
 static void
41c151
-cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
41c151
+meta_wayland_cursor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
41c151
 {
41c151
   MetaWaylandSurface *surface =
41c151
     meta_wayland_surface_role_get_surface (surface_role);
41c151
-  MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-    META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurface *cursor_surface =
41c151
+    META_WAYLAND_CURSOR_SURFACE (surface_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
 
41c151
   wl_list_insert_list (&priv->frame_callbacks,
41c151
                        &surface->pending_frame_callback_list);
41c151
@@ -141,13 +130,13 @@ cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
41c151
 }
41c151
 
41c151
 static void
41c151
-cursor_surface_role_pre_commit (MetaWaylandSurfaceRole  *surface_role,
41c151
-                                MetaWaylandPendingState *pending)
41c151
+meta_wayland_cursor_surface_pre_commit (MetaWaylandSurfaceRole  *surface_role,
41c151
+                                        MetaWaylandPendingState *pending)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-    META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurface *cursor_surface =
41c151
+    META_WAYLAND_CURSOR_SURFACE (surface_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
   MetaWaylandSurface *surface =
41c151
     meta_wayland_surface_role_get_surface (surface_role);
41c151
 
41c151
@@ -159,13 +148,13 @@ cursor_surface_role_pre_commit (MetaWaylandSurfaceRole  *surface_role,
41c151
 }
41c151
 
41c151
 static void
41c151
-cursor_surface_role_commit (MetaWaylandSurfaceRole  *surface_role,
41c151
-                            MetaWaylandPendingState *pending)
41c151
+meta_wayland_cursor_surface_commit (MetaWaylandSurfaceRole  *surface_role,
41c151
+                                    MetaWaylandPendingState *pending)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-    META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurface *cursor_surface =
41c151
+    META_WAYLAND_CURSOR_SURFACE (surface_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
   MetaWaylandSurface *surface =
41c151
     meta_wayland_surface_role_get_surface (surface_role);
41c151
   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
41c151
@@ -182,19 +171,19 @@ cursor_surface_role_commit (MetaWaylandSurfaceRole  *surface_role,
41c151
   wl_list_init (&pending->frame_callback_list);
41c151
 
41c151
   if (pending->newly_attached)
41c151
-    update_cursor_sprite_texture (META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role));
41c151
+    update_cursor_sprite_texture (META_WAYLAND_CURSOR_SURFACE (surface_role));
41c151
 }
41c151
 
41c151
 static gboolean
41c151
-cursor_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
41c151
-                                           MetaLogicalMonitor     *logical_monitor)
41c151
+meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
41c151
+                                                   MetaLogicalMonitor     *logical_monitor)
41c151
 {
41c151
   MetaWaylandSurface *surface =
41c151
     meta_wayland_surface_role_get_surface (role);
41c151
-  MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-    META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurface *cursor_surface =
41c151
+    META_WAYLAND_CURSOR_SURFACE (surface->role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
   ClutterPoint point;
41c151
   ClutterRect logical_monitor_rect;
41c151
 
41c151
@@ -207,12 +196,12 @@ cursor_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
41c151
 }
41c151
 
41c151
 static void
41c151
-cursor_surface_role_dispose (GObject *object)
41c151
+meta_wayland_cursor_surface_dispose (GObject *object)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-    META_WAYLAND_SURFACE_ROLE_CURSOR (object);
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurface *cursor_surface =
41c151
+    META_WAYLAND_CURSOR_SURFACE (object);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
   MetaWaylandSurface *surface =
41c151
     meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
41c151
   MetaWaylandFrameCallback *cb, *next;
41c151
@@ -221,7 +210,7 @@ cursor_surface_role_dispose (GObject *object)
41c151
     wl_resource_destroy (cb->resource);
41c151
 
41c151
   g_signal_handlers_disconnect_by_func (priv->cursor_sprite,
41c151
-                                        cursor_sprite_prepare_at, cursor_role);
41c151
+                                        cursor_sprite_prepare_at, cursor_surface);
41c151
 
41c151
   g_clear_object (&priv->cursor_renderer);
41c151
   g_clear_object (&priv->cursor_sprite);
41c151
@@ -232,18 +221,18 @@ cursor_surface_role_dispose (GObject *object)
41c151
       g_clear_object (&priv->buffer);
41c151
     }
41c151
 
41c151
-  G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
41c151
+  G_OBJECT_CLASS (meta_wayland_cursor_surface_parent_class)->dispose (object);
41c151
 }
41c151
 
41c151
 static void
41c151
-cursor_surface_role_constructed (GObject *object)
41c151
+meta_wayland_cursor_surface_constructed (GObject *object)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-    META_WAYLAND_SURFACE_ROLE_CURSOR (object);
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurface *cursor_surface =
41c151
+    META_WAYLAND_CURSOR_SURFACE (object);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
   MetaWaylandSurfaceRole *surface_role =
41c151
-    META_WAYLAND_SURFACE_ROLE (cursor_role);
41c151
+    META_WAYLAND_SURFACE_ROLE (cursor_surface);
41c151
   MetaWaylandSurface *surface =
41c151
     meta_wayland_surface_role_get_surface (surface_role);
41c151
   MetaWaylandBuffer *buffer;
41c151
@@ -257,55 +246,57 @@ cursor_surface_role_constructed (GObject *object)
41c151
       g_set_object (&priv->buffer, buffer);
41c151
       meta_wayland_surface_ref_buffer_use_count (surface);
41c151
     }
41c151
-}
41c151
 
41c151
-static void
41c151
-meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
41c151
-{
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (role);
41c151
-
41c151
-  priv->cursor_sprite = meta_cursor_sprite_new ();
41c151
+  priv->cursor_sprite = meta_cursor_sprite_wayland_new (surface);
41c151
   g_signal_connect_object (priv->cursor_sprite,
41c151
                            "prepare-at",
41c151
                            G_CALLBACK (cursor_sprite_prepare_at),
41c151
-                           role,
41c151
+                           cursor_surface,
41c151
                            0);
41c151
+}
41c151
+
41c151
+static void
41c151
+meta_wayland_cursor_surface_init (MetaWaylandCursorSurface *role)
41c151
+{
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (role);
41c151
+
41c151
   wl_list_init (&priv->frame_callbacks);
41c151
 }
41c151
 
41c151
 static void
41c151
-meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
41c151
+meta_wayland_cursor_surface_class_init (MetaWaylandCursorSurfaceClass *klass)
41c151
 {
41c151
   MetaWaylandSurfaceRoleClass *surface_role_class =
41c151
     META_WAYLAND_SURFACE_ROLE_CLASS (klass);
41c151
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
41c151
 
41c151
-  surface_role_class->assigned = cursor_surface_role_assigned;
41c151
-  surface_role_class->pre_commit = cursor_surface_role_pre_commit;
41c151
-  surface_role_class->commit = cursor_surface_role_commit;
41c151
-  surface_role_class->is_on_logical_monitor = cursor_surface_role_is_on_logical_monitor;
41c151
+  surface_role_class->assigned = meta_wayland_cursor_surface_assigned;
41c151
+  surface_role_class->pre_commit = meta_wayland_cursor_surface_pre_commit;
41c151
+  surface_role_class->commit = meta_wayland_cursor_surface_commit;
41c151
+  surface_role_class->is_on_logical_monitor =
41c151
+    meta_wayland_cursor_surface_is_on_logical_monitor;
41c151
 
41c151
-  object_class->constructed = cursor_surface_role_constructed;
41c151
-  object_class->dispose = cursor_surface_role_dispose;
41c151
+  object_class->constructed = meta_wayland_cursor_surface_constructed;
41c151
+  object_class->dispose = meta_wayland_cursor_surface_dispose;
41c151
 }
41c151
 
41c151
 MetaCursorSprite *
41c151
-meta_wayland_surface_role_cursor_get_sprite (MetaWaylandSurfaceRoleCursor *cursor_role)
41c151
+meta_wayland_cursor_surface_get_sprite (MetaWaylandCursorSurface *cursor_surface)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
 
41c151
-  return priv->cursor_sprite;
41c151
+  return META_CURSOR_SPRITE (priv->cursor_sprite);
41c151
 }
41c151
 
41c151
 void
41c151
-meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
41c151
-                                              gint                          hotspot_x,
41c151
-                                              gint                          hotspot_y)
41c151
+meta_wayland_cursor_surface_set_hotspot (MetaWaylandCursorSurface *cursor_surface,
41c151
+                                         int                       hotspot_x,
41c151
+                                         int                       hotspot_y)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
 
41c151
   if (priv->hot_x == hotspot_x &&
41c151
       priv->hot_y == hotspot_y)
41c151
@@ -313,16 +304,16 @@ meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *curs
41c151
 
41c151
   priv->hot_x = hotspot_x;
41c151
   priv->hot_y = hotspot_y;
41c151
-  update_cursor_sprite_texture (cursor_role);
41c151
+  update_cursor_sprite_texture (cursor_surface);
41c151
 }
41c151
 
41c151
 void
41c151
-meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
41c151
-                                              gint                         *hotspot_x,
41c151
-                                              gint                         *hotspot_y)
41c151
+meta_wayland_cursor_surface_get_hotspot (MetaWaylandCursorSurface *cursor_surface,
41c151
+                                         int                      *hotspot_x,
41c151
+                                         int                      *hotspot_y)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
 
41c151
   if (hotspot_x)
41c151
     *hotspot_x = priv->hot_x;
41c151
@@ -331,15 +322,15 @@ meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *curs
41c151
 }
41c151
 
41c151
 static void
41c151
-on_cursor_painted (MetaCursorRenderer           *renderer,
41c151
-                   MetaCursorSprite             *displayed_sprite,
41c151
-                   MetaWaylandSurfaceRoleCursor *cursor_role)
41c151
+on_cursor_painted (MetaCursorRenderer       *renderer,
41c151
+                   MetaCursorSprite         *displayed_sprite,
41c151
+                   MetaWaylandCursorSurface *cursor_surface)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
   guint32 time = (guint32) (g_get_monotonic_time () / 1000);
41c151
 
41c151
-  if (displayed_sprite != priv->cursor_sprite)
41c151
+  if (displayed_sprite != META_CURSOR_SPRITE (priv->cursor_sprite))
41c151
     return;
41c151
 
41c151
   while (!wl_list_empty (&priv->frame_callbacks))
41c151
@@ -353,11 +344,11 @@ on_cursor_painted (MetaCursorRenderer           *renderer,
41c151
 }
41c151
 
41c151
 void
41c151
-meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
41c151
-                                               MetaCursorRenderer           *renderer)
41c151
+meta_wayland_cursor_surface_set_renderer (MetaWaylandCursorSurface *cursor_surface,
41c151
+                                          MetaCursorRenderer       *renderer)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
 
41c151
   if (priv->cursor_renderer == renderer)
41c151
     return;
41c151
@@ -373,19 +364,19 @@ meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cur
41c151
     {
41c151
       priv->cursor_painted_handler_id =
41c151
         g_signal_connect_object (renderer, "cursor-painted",
41c151
-                                 G_CALLBACK (on_cursor_painted), cursor_role, 0);
41c151
+                                 G_CALLBACK (on_cursor_painted), cursor_surface, 0);
41c151
       g_object_ref (renderer);
41c151
     }
41c151
 
41c151
   priv->cursor_renderer = renderer;
41c151
-  update_cursor_sprite_texture (cursor_role);
41c151
+  update_cursor_sprite_texture (cursor_surface);
41c151
 }
41c151
 
41c151
 MetaCursorRenderer *
41c151
-meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role)
41c151
+meta_wayland_cursor_surface_get_renderer (MetaWaylandCursorSurface *cursor_surface)
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursorPrivate *priv =
41c151
-    meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
41c151
+  MetaWaylandCursorSurfacePrivate *priv =
41c151
+    meta_wayland_cursor_surface_get_instance_private (cursor_surface);
41c151
 
41c151
   return priv->cursor_renderer;
41c151
 }
41c151
diff --git a/src/wayland/meta-wayland-cursor-surface.h b/src/wayland/meta-wayland-cursor-surface.h
41c151
new file mode 100644
41c151
index 000000000..2461a85b3
41c151
--- /dev/null
41c151
+++ b/src/wayland/meta-wayland-cursor-surface.h
41c151
@@ -0,0 +1,52 @@
41c151
+/*
41c151
+ * Wayland Support
41c151
+ *
41c151
+ * Copyright (C) 2015 Red Hat, Inc.
41c151
+ *
41c151
+ * This program is free software; you can redistribute it and/or
41c151
+ * modify it under the terms of the GNU General Public License as
41c151
+ * published by the Free Software Foundation; either version 2 of the
41c151
+ * License, or (at your option) any later version.
41c151
+ *
41c151
+ * This program is distributed in the hope that it will be useful, but
41c151
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
+ * General Public License for more details.
41c151
+ *
41c151
+ * You should have received a copy of the GNU General Public License
41c151
+ * along with this program; if not, write to the Free Software
41c151
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
41c151
+ * 02111-1307, USA.
41c151
+ */
41c151
+
41c151
+#ifndef META_WAYLAND_CURSOR_SURFACE_H
41c151
+#define META_WAYLAND_CURSOR_SURFACE_H
41c151
+
41c151
+#include "meta-wayland-surface.h"
41c151
+#include "backends/meta-cursor-renderer.h"
41c151
+
41c151
+struct _MetaWaylandCursorSurfaceClass
41c151
+{
41c151
+  MetaWaylandSurfaceRoleClass parent_class;
41c151
+};
41c151
+
41c151
+#define META_TYPE_WAYLAND_CURSOR_SURFACE (meta_wayland_cursor_surface_get_type ())
41c151
+G_DECLARE_DERIVABLE_TYPE (MetaWaylandCursorSurface,
41c151
+                          meta_wayland_cursor_surface,
41c151
+                          META, WAYLAND_CURSOR_SURFACE,
41c151
+                          MetaWaylandSurfaceRole);
41c151
+
41c151
+MetaCursorSprite *   meta_wayland_cursor_surface_get_sprite   (MetaWaylandCursorSurface *cursor_surface);
41c151
+
41c151
+void                 meta_wayland_cursor_surface_set_hotspot  (MetaWaylandCursorSurface *cursor_surface,
41c151
+                                                               int                       hotspot_x,
41c151
+                                                               int                       hotspot_y);
41c151
+void                 meta_wayland_cursor_surface_get_hotspot  (MetaWaylandCursorSurface *cursor_surface,
41c151
+                                                               int                       *hotspot_x,
41c151
+                                                               int                       *hotspot_y);
41c151
+void                 meta_wayland_cursor_surface_set_renderer (MetaWaylandCursorSurface *cursor_surface,
41c151
+                                                               MetaCursorRenderer       *renderer);
41c151
+MetaCursorRenderer * meta_wayland_cursor_surface_get_renderer (MetaWaylandCursorSurface *cursor_surface);
41c151
+
41c151
+
41c151
+#endif /* META_WAYLAND_CURSOR_SURFACE_H */
41c151
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
41c151
index d5c90c169..e8138576e 100644
41c151
--- a/src/wayland/meta-wayland-pointer.c
41c151
+++ b/src/wayland/meta-wayland-pointer.c
41c151
@@ -55,7 +55,7 @@
41c151
 #include "meta-wayland-seat.h"
41c151
 #include "meta-wayland-surface.h"
41c151
 #include "meta-wayland-buffer.h"
41c151
-#include "meta-wayland-surface-role-cursor.h"
41c151
+#include "meta-wayland-cursor-surface.h"
41c151
 #include "meta-xwayland.h"
41c151
 #include "meta-cursor.h"
41c151
 #include "meta-cursor-tracker-private.h"
41c151
@@ -1025,10 +1025,10 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
41c151
 
41c151
       if (pointer->cursor_surface)
41c151
         {
41c151
-          MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-            META_WAYLAND_SURFACE_ROLE_CURSOR (pointer->cursor_surface->role);
41c151
+          MetaWaylandCursorSurface *cursor_surface =
41c151
+            META_WAYLAND_CURSOR_SURFACE (pointer->cursor_surface->role);
41c151
 
41c151
-          cursor_sprite = meta_wayland_surface_role_cursor_get_sprite (cursor_role);
41c151
+          cursor_sprite = meta_wayland_cursor_surface_get_sprite (cursor_surface);
41c151
         }
41c151
 
41c151
       meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite);
41c151
@@ -1102,7 +1102,7 @@ pointer_set_cursor (struct wl_client *client,
41c151
 
41c151
   if (surface &&
41c151
       !meta_wayland_surface_assign_role (surface,
41c151
-                                         META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR,
41c151
+                                         META_TYPE_WAYLAND_CURSOR_SURFACE,
41c151
                                          NULL))
41c151
     {
41c151
       wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
41c151
@@ -1115,13 +1115,13 @@ pointer_set_cursor (struct wl_client *client,
41c151
     {
41c151
       MetaCursorRenderer *cursor_renderer =
41c151
         meta_backend_get_cursor_renderer (meta_get_backend ());
41c151
-      MetaWaylandSurfaceRoleCursor *cursor_role;
41c151
+      MetaWaylandCursorSurface *cursor_surface;
41c151
 
41c151
-      cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
41c151
-      meta_wayland_surface_role_cursor_set_renderer (cursor_role,
41c151
-                                                     cursor_renderer);
41c151
-      meta_wayland_surface_role_cursor_set_hotspot (cursor_role,
41c151
-                                                    hot_x, hot_y);
41c151
+      cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role);
41c151
+      meta_wayland_cursor_surface_set_renderer (cursor_surface,
41c151
+                                                cursor_renderer);
41c151
+      meta_wayland_cursor_surface_set_hotspot (cursor_surface,
41c151
+                                               hot_x, hot_y);
41c151
     }
41c151
 
41c151
   meta_wayland_pointer_set_cursor_surface (pointer, surface);
41c151
diff --git a/src/wayland/meta-wayland-surface-role-cursor.h b/src/wayland/meta-wayland-surface-role-cursor.h
41c151
deleted file mode 100644
41c151
index b6d6d4a6a..000000000
41c151
--- a/src/wayland/meta-wayland-surface-role-cursor.h
41c151
+++ /dev/null
41c151
@@ -1,52 +0,0 @@
41c151
-/*
41c151
- * Wayland Support
41c151
- *
41c151
- * Copyright (C) 2015 Red Hat, Inc.
41c151
- *
41c151
- * This program is free software; you can redistribute it and/or
41c151
- * modify it under the terms of the GNU General Public License as
41c151
- * published by the Free Software Foundation; either version 2 of the
41c151
- * License, or (at your option) any later version.
41c151
- *
41c151
- * This program is distributed in the hope that it will be useful, but
41c151
- * WITHOUT ANY WARRANTY; without even the implied warranty of
41c151
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41c151
- * General Public License for more details.
41c151
- *
41c151
- * You should have received a copy of the GNU General Public License
41c151
- * along with this program; if not, write to the Free Software
41c151
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
41c151
- * 02111-1307, USA.
41c151
- */
41c151
-
41c151
-#ifndef META_WAYLAND_SURFACE_ROLE_CURSOR_H
41c151
-#define META_WAYLAND_SURFACE_ROLE_CURSOR_H
41c151
-
41c151
-#include "meta-wayland-surface.h"
41c151
-#include "backends/meta-cursor-renderer.h"
41c151
-
41c151
-struct _MetaWaylandSurfaceRoleCursorClass
41c151
-{
41c151
-  MetaWaylandSurfaceRoleClass parent_class;
41c151
-};
41c151
-
41c151
-#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
41c151
-G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRoleCursor,
41c151
-                          meta_wayland_surface_role_cursor,
41c151
-                          META, WAYLAND_SURFACE_ROLE_CURSOR,
41c151
-                          MetaWaylandSurfaceRole);
41c151
-
41c151
-MetaCursorSprite *   meta_wayland_surface_role_cursor_get_sprite   (MetaWaylandSurfaceRoleCursor *cursor_role);
41c151
-
41c151
-void                 meta_wayland_surface_role_cursor_set_hotspot  (MetaWaylandSurfaceRoleCursor *cursor_role,
41c151
-                                                                    gint                          hotspot_x,
41c151
-                                                                    gint                          hotspot_y);
41c151
-void                 meta_wayland_surface_role_cursor_get_hotspot  (MetaWaylandSurfaceRoleCursor *cursor_role,
41c151
-                                                                    gint                         *hotspot_x,
41c151
-                                                                    gint                         *hotspot_y);
41c151
-void                 meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
41c151
-                                                                    MetaCursorRenderer           *renderer);
41c151
-MetaCursorRenderer * meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role);
41c151
-
41c151
-
41c151
-#endif /* META_WAYLAND_SURFACE_ROLE_CURSOR_H */
41c151
diff --git a/src/wayland/meta-wayland-surface-role-tablet-cursor.c b/src/wayland/meta-wayland-tablet-cursor-surface.c
41c151
similarity index 63%
41c151
rename from src/wayland/meta-wayland-surface-role-tablet-cursor.c
41c151
rename to src/wayland/meta-wayland-tablet-cursor-surface.c
41c151
index 075a5e4f6..808bf2820 100644
41c151
--- a/src/wayland/meta-wayland-surface-role-tablet-cursor.c
41c151
+++ b/src/wayland/meta-wayland-tablet-cursor-surface.c
41c151
@@ -20,23 +20,24 @@
41c151
  */
41c151
 
41c151
 #include "config.h"
41c151
-#include "meta-wayland-surface-role-tablet-cursor.h"
41c151
 
41c151
-struct _MetaWaylandSurfaceRoleTabletCursor
41c151
+#include "meta-wayland-tablet-cursor-surface.h"
41c151
+
41c151
+struct _MetaWaylandTabletCursorSurface
41c151
 {
41c151
-  MetaWaylandSurfaceRoleCursor parent;
41c151
+  MetaWaylandCursorSurface parent;
41c151
 };
41c151
 
41c151
-G_DEFINE_TYPE (MetaWaylandSurfaceRoleTabletCursor,
41c151
-               meta_wayland_surface_role_tablet_cursor,
41c151
-               META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR)
41c151
+G_DEFINE_TYPE (MetaWaylandTabletCursorSurface,
41c151
+               meta_wayland_tablet_cursor_surface,
41c151
+               META_TYPE_WAYLAND_CURSOR_SURFACE)
41c151
 
41c151
 static void
41c151
-meta_wayland_surface_role_tablet_cursor_init (MetaWaylandSurfaceRoleTabletCursor *role)
41c151
+meta_wayland_tablet_cursor_surface_init (MetaWaylandTabletCursorSurface *role)
41c151
 {
41c151
 }
41c151
 
41c151
 static void
41c151
-meta_wayland_surface_role_tablet_cursor_class_init (MetaWaylandSurfaceRoleTabletCursorClass *klass)
41c151
+meta_wayland_tablet_cursor_surface_class_init (MetaWaylandTabletCursorSurfaceClass *klass)
41c151
 {
41c151
 }
41c151
diff --git a/src/wayland/meta-wayland-surface-role-tablet-cursor.h b/src/wayland/meta-wayland-tablet-cursor-surface.h
41c151
similarity index 59%
41c151
rename from src/wayland/meta-wayland-surface-role-tablet-cursor.h
41c151
rename to src/wayland/meta-wayland-tablet-cursor-surface.h
41c151
index 69fc6cf0f..5c5c198f5 100644
41c151
--- a/src/wayland/meta-wayland-surface-role-tablet-cursor.h
41c151
+++ b/src/wayland/meta-wayland-tablet-cursor-surface.h
41c151
@@ -19,15 +19,15 @@
41c151
  * 02111-1307, USA.
41c151
  */
41c151
 
41c151
-#ifndef META_WAYLAND_SURFACE_ROLE_TABLET_CURSOR_H
41c151
-#define META_WAYLAND_SURFACE_ROLE_TABLET_CURSOR_H
41c151
+#ifndef META_WAYLAND_TABLET_CURSOR_SURFACE_H
41c151
+#define META_WAYLAND_TABLET_CURSOR_SURFACE_H
41c151
 
41c151
-#include "meta-wayland-surface-role-cursor.h"
41c151
+#include "meta-wayland-cursor-surface.h"
41c151
 
41c151
-#define META_TYPE_WAYLAND_SURFACE_ROLE_TABLET_CURSOR (meta_wayland_surface_role_tablet_cursor_get_type ())
41c151
-G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleTabletCursor,
41c151
-                      meta_wayland_surface_role_tablet_cursor,
41c151
-                      META, WAYLAND_SURFACE_ROLE_TABLET_CURSOR,
41c151
-                      MetaWaylandSurfaceRoleCursor);
41c151
+#define META_TYPE_WAYLAND_TABLET_CURSOR_SURFACE (meta_wayland_tablet_cursor_surface_get_type ())
41c151
+G_DECLARE_FINAL_TYPE (MetaWaylandTabletCursorSurface,
41c151
+                      meta_wayland_tablet_cursor_surface,
41c151
+                      META, WAYLAND_TABLET_CURSOR_SURFACE,
41c151
+                      MetaWaylandCursorSurface)
41c151
 
41c151
-#endif /* META_WAYLAND_SURFACE_ROLE_TABLET_CURSOR_H */
41c151
+#endif /* META_WAYLAND_TABLET_CURSOR_SURFACE_H */
41c151
diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
41c151
index 4b57d4156..d373f8d25 100644
41c151
--- a/src/wayland/meta-wayland-tablet-tool.c
41c151
+++ b/src/wayland/meta-wayland-tablet-tool.c
41c151
@@ -31,7 +31,7 @@
41c151
 #include <wayland-server.h>
41c151
 #include "tablet-unstable-v2-server-protocol.h"
41c151
 #include "meta-wayland-private.h"
41c151
-#include "meta-wayland-surface-role-tablet-cursor.h"
41c151
+#include "meta-wayland-tablet-cursor-surface.h"
41c151
 #include "meta-surface-actor-wayland.h"
41c151
 #include "meta-wayland-tablet.h"
41c151
 #include "meta-wayland-tablet-seat.h"
41c151
@@ -90,16 +90,16 @@ meta_wayland_tablet_tool_update_cursor_surface (MetaWaylandTabletTool *tool)
41c151
       if (tool->cursor_surface &&
41c151
           meta_wayland_surface_get_buffer (tool->cursor_surface))
41c151
         {
41c151
-          MetaWaylandSurfaceRoleCursor *cursor_role =
41c151
-            META_WAYLAND_SURFACE_ROLE_CURSOR (tool->cursor_surface->role);
41c151
+          MetaWaylandCursorSurface *cursor_surface =
41c151
+            META_WAYLAND_CURSOR_SURFACE (tool->cursor_surface->role);
41c151
 
41c151
-          cursor = meta_wayland_surface_role_cursor_get_sprite (cursor_role);
41c151
+          cursor = meta_wayland_cursor_surface_get_sprite (cursor_surface);
41c151
         }
41c151
       else
41c151
         cursor = NULL;
41c151
     }
41c151
   else if (tool->current_tablet)
41c151
-    cursor = tool->default_sprite;
41c151
+    cursor = META_CURSOR_SPRITE (tool->default_sprite);
41c151
   else
41c151
     cursor = NULL;
41c151
 
41c151
@@ -382,10 +382,10 @@ tablet_tool_handle_cursor_surface_destroy (struct wl_listener *listener,
41c151
 }
41c151
 
41c151
 static void
41c151
-tool_cursor_prepare_at (MetaCursorSprite      *cursor_sprite,
41c151
-                        int                    x,
41c151
-                        int                    y,
41c151
-                        MetaWaylandTabletTool *tool)
41c151
+tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
41c151
+                        int                      x,
41c151
+                        int                      y,
41c151
+                        MetaWaylandTabletTool   *tool)
41c151
 {
41c151
   MetaBackend *backend = meta_get_backend ();
41c151
   MetaMonitorManager *monitor_manager =
41c151
@@ -397,7 +397,8 @@ tool_cursor_prepare_at (MetaCursorSprite      *cursor_sprite,
41c151
 
41c151
   /* Reload the cursor texture if the scale has changed. */
41c151
   if (logical_monitor)
41c151
-    meta_cursor_sprite_set_theme_scale (cursor_sprite, logical_monitor->scale);
41c151
+    meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
41c151
+                                                logical_monitor->scale);
41c151
 }
41c151
 
41c151
 MetaWaylandTabletTool *
41c151
@@ -417,7 +418,7 @@ meta_wayland_tablet_tool_new (MetaWaylandTabletSeat  *seat,
41c151
   tool->focus_surface_destroy_listener.notify = tablet_tool_handle_focus_surface_destroy;
41c151
   tool->cursor_surface_destroy_listener.notify = tablet_tool_handle_cursor_surface_destroy;
41c151
 
41c151
-  tool->default_sprite = meta_cursor_sprite_from_theme (META_CURSOR_CROSSHAIR);
41c151
+  tool->default_sprite = meta_cursor_sprite_xcursor_new (META_CURSOR_CROSSHAIR);
41c151
   tool->prepare_at_signal_id =
41c151
     g_signal_connect (tool->default_sprite, "prepare-at",
41c151
                       G_CALLBACK (tool_cursor_prepare_at), tool);
41c151
@@ -471,7 +472,7 @@ tool_set_cursor (struct wl_client   *client,
41c151
 
41c151
   if (surface &&
41c151
       !meta_wayland_surface_assign_role (surface,
41c151
-                                         META_TYPE_WAYLAND_SURFACE_ROLE_TABLET_CURSOR,
41c151
+                                         META_TYPE_WAYLAND_TABLET_CURSOR_SURFACE,
41c151
                                          NULL))
41c151
     {
41c151
       wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
41c151
@@ -482,13 +483,13 @@ tool_set_cursor (struct wl_client   *client,
41c151
 
41c151
   if (surface)
41c151
     {
41c151
-      MetaWaylandSurfaceRoleCursor *cursor_role;
41c151
+      MetaWaylandCursorSurface *cursor_surface;
41c151
 
41c151
-      cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
41c151
-      meta_wayland_surface_role_cursor_set_renderer (cursor_role,
41c151
-                                                     tool->cursor_renderer);
41c151
-      meta_wayland_surface_role_cursor_set_hotspot (cursor_role,
41c151
-                                                    hotspot_x, hotspot_y);
41c151
+      cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role);
41c151
+      meta_wayland_cursor_surface_set_renderer (cursor_surface,
41c151
+                                                tool->cursor_renderer);
41c151
+      meta_wayland_cursor_surface_set_hotspot (cursor_surface,
41c151
+                                               hotspot_x, hotspot_y);
41c151
     }
41c151
 
41c151
   meta_wayland_tablet_tool_set_cursor_surface (tool, surface);
41c151
diff --git a/src/wayland/meta-wayland-tablet-tool.h b/src/wayland/meta-wayland-tablet-tool.h
41c151
index 8cd930086..011972fc2 100644
41c151
--- a/src/wayland/meta-wayland-tablet-tool.h
41c151
+++ b/src/wayland/meta-wayland-tablet-tool.h
41c151
@@ -28,6 +28,7 @@
41c151
 
41c151
 #include "meta-wayland-types.h"
41c151
 #include "meta-cursor-renderer.h"
41c151
+#include "backends/meta-cursor-sprite-xcursor.h"
41c151
 
41c151
 struct _MetaWaylandTabletTool
41c151
 {
41c151
@@ -43,7 +44,7 @@ struct _MetaWaylandTabletTool
41c151
   MetaWaylandSurface *cursor_surface;
41c151
   struct wl_listener cursor_surface_destroy_listener;
41c151
   MetaCursorRenderer *cursor_renderer;
41c151
-  MetaCursorSprite *default_sprite;
41c151
+  MetaCursorSpriteXcursor *default_sprite;
41c151
   guint prepare_at_signal_id;
41c151
 
41c151
   MetaWaylandSurface *current;