[mutter] cursor-tracker: Split out XFIXES cursor code into cursor sprite type



commit b8336633a7c91ac28491dace0fe9155c19599197
Author: Jonas Ådahl <jadahl gmail com>
Date:   Mon Apr 30 10:21:51 2018 +0200

    cursor-tracker: Split out XFIXES cursor code into cursor sprite type
    
    Remove some X11 compositing manager specific code from the general
    purpose cursor tracker into a new MetaCursorSprite based special
    purpose XFIXES cursor sprite.
    
    https://gitlab.gnome.org/GNOME/mutter/issues/77

 src/Makefile.am                                 |   2 +
 src/backends/meta-cursor-tracker-private.h      |   3 +-
 src/backends/meta-cursor-tracker.c              |  75 +-------
 src/backends/x11/cm/meta-cursor-sprite-xfixes.c | 226 ++++++++++++++++++++++++
 src/backends/x11/cm/meta-cursor-sprite-xfixes.h |  36 ++++
 5 files changed, 273 insertions(+), 69 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 96dd01ebe..8094abc98 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -178,6 +178,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES =      \
        backends/x11/meta-gpu-xrandr.h                  \
        backends/x11/cm/meta-backend-x11-cm.c           \
        backends/x11/cm/meta-backend-x11-cm.h           \
+       backends/x11/cm/meta-cursor-sprite-xfixes.c     \
+       backends/x11/cm/meta-cursor-sprite-xfixes.h     \
        backends/x11/cm/meta-renderer-x11-cm.c          \
        backends/x11/cm/meta-renderer-x11-cm.h          \
        backends/x11/nested/meta-backend-x11-nested.c   \
diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h
index 2ec946847..6f4f84b83 100644
--- a/src/backends/meta-cursor-tracker-private.h
+++ b/src/backends/meta-cursor-tracker-private.h
@@ -26,6 +26,7 @@
 
 #include "meta-cursor.h"
 #include "meta-cursor-renderer.h"
+#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
 
 struct _MetaCursorTracker {
   GObject parent_instance;
@@ -46,7 +47,7 @@ struct _MetaCursorTracker {
   MetaCursorSprite *root_cursor;
 
   /* The cursor from the X11 server. */
-  MetaCursorSprite *xfixes_cursor;
+  MetaCursorSpriteXfixes *xfixes_cursor;
 };
 
 struct _MetaCursorTrackerClass {
diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c
index 74fa4351d..6244f11ee 100644
--- a/src/backends/meta-cursor-tracker.c
+++ b/src/backends/meta-cursor-tracker.c
@@ -40,9 +40,9 @@
 
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
-#include <X11/extensions/Xfixes.h>
 
 #include "meta-backend-private.h"
+#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
 
 G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
 
@@ -218,75 +218,14 @@ static void
 ensure_xfixes_cursor (MetaCursorTracker *tracker)
 {
   MetaDisplay *display = meta_get_display ();
-  XFixesCursorImage *cursor_image;
-  CoglTexture2D *sprite;
-  guint8 *cursor_data;
-  gboolean free_cursor_data;
-  CoglContext *ctx;
-  CoglError *error = NULL;
+  g_autoptr (GError) error = NULL;
 
   if (tracker->xfixes_cursor)
     return;
 
-  cursor_image = XFixesGetCursorImage (display->xdisplay);
-  if (!cursor_image)
-    return;
-
-  /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
-   * quantities as arrays of long; we need to convert on 64 bit */
-  if (sizeof(long) == 4)
-    {
-      cursor_data = (guint8 *)cursor_image->pixels;
-      free_cursor_data = FALSE;
-    }
-  else
-    {
-      int i, j;
-      guint32 *cursor_words;
-      gulong *p;
-      guint32 *q;
-
-      cursor_words = g_new (guint32, cursor_image->width * cursor_image->height);
-      cursor_data = (guint8 *)cursor_words;
-
-      p = cursor_image->pixels;
-      q = cursor_words;
-      for (j = 0; j < cursor_image->height; j++)
-        for (i = 0; i < cursor_image->width; i++)
-          *(q++) = *(p++);
-
-      free_cursor_data = TRUE;
-    }
-
-  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
-  sprite = cogl_texture_2d_new_from_data (ctx,
-                                          cursor_image->width,
-                                          cursor_image->height,
-                                          CLUTTER_CAIRO_FORMAT_ARGB32,
-                                          cursor_image->width * 4, /* stride */
-                                          cursor_data,
-                                          &error);
-
-  if (free_cursor_data)
-    g_free (cursor_data);
-
-  if (error != NULL)
-    {
-      meta_warning ("Failed to allocate cursor sprite texture: %s\n", error->message);
-      cogl_error_free (error);
-    }
-
-  if (sprite != NULL)
-    {
-      MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
-      meta_cursor_sprite_set_texture (cursor_sprite,
-                                      COGL_TEXTURE (sprite),
-                                      cursor_image->xhot,
-                                      cursor_image->yhot);
-      cogl_object_unref (sprite);
-      tracker->xfixes_cursor = cursor_sprite;
-    }
-  XFree (cursor_image);
+  tracker->xfixes_cursor = meta_cursor_sprite_xfixes_new (display, &error);
+  if (!tracker->xfixes_cursor)
+    g_warning ("Failed to create XFIXES cursor: %s", error->message);
 }
 
 /**
@@ -308,7 +247,7 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
   else
     {
       ensure_xfixes_cursor (tracker);
-      cursor_sprite = tracker->xfixes_cursor;
+      cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
     }
 
   if (cursor_sprite)
@@ -345,7 +284,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
   else
     {
       ensure_xfixes_cursor (tracker);
-      cursor_sprite = tracker->xfixes_cursor;
+      cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
     }
 
   if (cursor_sprite)
diff --git a/src/backends/x11/cm/meta-cursor-sprite-xfixes.c b/src/backends/x11/cm/meta-cursor-sprite-xfixes.c
new file mode 100644
index 000000000..143ebb791
--- /dev/null
+++ b/src/backends/x11/cm/meta-cursor-sprite-xfixes.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2013, 2018 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "config.h"
+
+#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
+
+#include <X11/extensions/Xfixes.h>
+
+#include "core/display-private.h"
+
+enum
+{
+  PROP_0,
+
+  PROP_DISPLAY,
+
+  N_PROPS
+};
+
+static GParamSpec *obj_props[N_PROPS];
+
+struct _MetaCursorSpriteXfixes
+{
+  MetaCursorSprite parent;
+
+  MetaDisplay *display;
+};
+
+static void
+meta_screen_cast_xfixes_init_initable_iface (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (MetaCursorSpriteXfixes,
+                         meta_cursor_sprite_xfixes,
+                         META_TYPE_CURSOR_SPRITE,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                meta_screen_cast_xfixes_init_initable_iface))
+
+static void
+meta_cursor_sprite_xfixes_realize_texture (MetaCursorSprite *sprite)
+{
+}
+
+static gboolean
+meta_cursor_sprite_xfixes_is_animated (MetaCursorSprite *sprite)
+{
+  return FALSE;
+}
+
+static void
+meta_cursor_sprite_xfixes_get_property (GObject    *object,
+                                        guint       prop_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+  MetaCursorSpriteXfixes *sprite_xfixes = META_CURSOR_SPRITE_XFIXES (object);
+
+  switch (prop_id)
+    {
+    case PROP_DISPLAY:
+      g_value_set_object (value, sprite_xfixes->display);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+meta_cursor_sprite_xfixes_set_property (GObject      *object,
+                                        guint         prop_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+  MetaCursorSpriteXfixes *sprite_xfixes = META_CURSOR_SPRITE_XFIXES (object);
+
+  switch (prop_id)
+    {
+    case PROP_DISPLAY:
+      sprite_xfixes->display = g_value_get_object (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+MetaCursorSpriteXfixes *
+meta_cursor_sprite_xfixes_new (MetaDisplay  *display,
+                               GError      **error)
+{
+  return g_initable_new (META_TYPE_CURSOR_SPRITE_XFIXES,
+                         NULL, error,
+                         "display", display,
+                         NULL);
+}
+
+static gboolean
+meta_cursor_sprite_xfixes_initable_init (GInitable     *initable,
+                                         GCancellable  *cancellable,
+                                         GError       **error)
+{
+  MetaCursorSpriteXfixes *sprite_xfixes =
+    META_CURSOR_SPRITE_XFIXES (initable);
+  MetaCursorSprite *sprite = META_CURSOR_SPRITE (sprite_xfixes);
+  XFixesCursorImage *cursor_image;
+  CoglTexture2D *texture;
+  uint8_t *cursor_data;
+  gboolean free_cursor_data;
+  ClutterBackend *clutter_backend;
+  CoglContext *cogl_context;
+
+  cursor_image = XFixesGetCursorImage (sprite_xfixes->display->xdisplay);
+  if (!cursor_image)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Failed to get cursor image");
+      return FALSE;
+    }
+
+  /*
+   * Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
+   * quantities as arrays of long; we need to convert on 64 bit
+   */
+  if (sizeof (long) == 4)
+    {
+      cursor_data = (uint8_t *) cursor_image->pixels;
+      free_cursor_data = FALSE;
+    }
+  else
+    {
+      int i, j;
+      uint32_t *cursor_words;
+      unsigned long *p;
+      uint32_t *q;
+
+      cursor_words = g_new (uint32_t,
+                            cursor_image->width * cursor_image->height);
+      cursor_data = (uint8_t *) cursor_words;
+
+      p = cursor_image->pixels;
+      q = cursor_words;
+      for (j = 0; j < cursor_image->height; j++)
+        {
+          for (i = 0; i < cursor_image->width; i++)
+            *(q++) = *(p++);
+        }
+
+      free_cursor_data = TRUE;
+    }
+
+  clutter_backend = clutter_get_default_backend ();
+  cogl_context = clutter_backend_get_cogl_context (clutter_backend);
+  texture = cogl_texture_2d_new_from_data (cogl_context,
+                                          cursor_image->width,
+                                          cursor_image->height,
+                                          CLUTTER_CAIRO_FORMAT_ARGB32,
+                                          cursor_image->width * 4, /* stride */
+                                          cursor_data,
+                                          error);
+
+  if (free_cursor_data)
+    g_free (cursor_data);
+
+  if (!sprite)
+    return FALSE;
+
+  meta_cursor_sprite_set_texture (sprite,
+                                  COGL_TEXTURE (texture),
+                                  cursor_image->xhot,
+                                  cursor_image->yhot);
+  cogl_object_unref (texture);
+  XFree (cursor_image);
+
+  return TRUE;
+}
+
+static void
+meta_screen_cast_xfixes_init_initable_iface (GInitableIface *iface)
+{
+  iface->init = meta_cursor_sprite_xfixes_initable_init;
+}
+
+static void
+meta_cursor_sprite_xfixes_init (MetaCursorSpriteXfixes *sprite_xfixes)
+{
+}
+
+static void
+meta_cursor_sprite_xfixes_class_init (MetaCursorSpriteXfixesClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  MetaCursorSpriteClass *cursor_sprite_class = META_CURSOR_SPRITE_CLASS (klass);
+
+  object_class->get_property = meta_cursor_sprite_xfixes_get_property;
+  object_class->set_property = meta_cursor_sprite_xfixes_set_property;
+
+  cursor_sprite_class->realize_texture =
+    meta_cursor_sprite_xfixes_realize_texture;
+  cursor_sprite_class->is_animated = meta_cursor_sprite_xfixes_is_animated;
+
+  obj_props[PROP_DISPLAY] =
+    g_param_spec_object ("display",
+                         "display",
+                         "MetaDisplay",
+                         META_TYPE_DISPLAY,
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
+  g_object_class_install_properties (object_class, N_PROPS, obj_props);
+}
diff --git a/src/backends/x11/cm/meta-cursor-sprite-xfixes.h b/src/backends/x11/cm/meta-cursor-sprite-xfixes.h
new file mode 100644
index 000000000..c7073fc2c
--- /dev/null
+++ b/src/backends/x11/cm/meta-cursor-sprite-xfixes.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2013, 2018 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef META_CURSOR_SPRITE_XFIXES_H
+#define META_CURSOR_SPRITE_XFIXES_H
+
+#include <glib-object.h>
+
+#include "backends/meta-cursor.h"
+#include "meta/types.h"
+
+#define META_TYPE_CURSOR_SPRITE_XFIXES (meta_cursor_sprite_xfixes_get_type ())
+G_DECLARE_FINAL_TYPE (MetaCursorSpriteXfixes,
+                      meta_cursor_sprite_xfixes,
+                      META, CURSOR_SPRITE_XFIXES,
+                      MetaCursorSprite)
+
+MetaCursorSpriteXfixes * meta_cursor_sprite_xfixes_new (MetaDisplay  *display,
+                                                        GError      **error);
+
+#endif /* META_CURSOR_SPRITE_XFIXES_H */


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