mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 20:12:06 +00:00
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
This commit is contained in:
parent
3c538d4a92
commit
b8336633a7
@ -178,6 +178,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
|||||||
backends/x11/meta-gpu-xrandr.h \
|
backends/x11/meta-gpu-xrandr.h \
|
||||||
backends/x11/cm/meta-backend-x11-cm.c \
|
backends/x11/cm/meta-backend-x11-cm.c \
|
||||||
backends/x11/cm/meta-backend-x11-cm.h \
|
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.c \
|
||||||
backends/x11/cm/meta-renderer-x11-cm.h \
|
backends/x11/cm/meta-renderer-x11-cm.h \
|
||||||
backends/x11/nested/meta-backend-x11-nested.c \
|
backends/x11/nested/meta-backend-x11-nested.c \
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "meta-cursor.h"
|
#include "meta-cursor.h"
|
||||||
#include "meta-cursor-renderer.h"
|
#include "meta-cursor-renderer.h"
|
||||||
|
#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
|
||||||
|
|
||||||
struct _MetaCursorTracker {
|
struct _MetaCursorTracker {
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
@ -46,7 +47,7 @@ struct _MetaCursorTracker {
|
|||||||
MetaCursorSprite *root_cursor;
|
MetaCursorSprite *root_cursor;
|
||||||
|
|
||||||
/* The cursor from the X11 server. */
|
/* The cursor from the X11 server. */
|
||||||
MetaCursorSprite *xfixes_cursor;
|
MetaCursorSpriteXfixes *xfixes_cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaCursorTrackerClass {
|
struct _MetaCursorTrackerClass {
|
||||||
|
@ -40,9 +40,9 @@
|
|||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
#include <X11/extensions/Xfixes.h>
|
|
||||||
|
|
||||||
#include "meta-backend-private.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);
|
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||||
|
|
||||||
@ -218,75 +218,14 @@ static void
|
|||||||
ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||||
{
|
{
|
||||||
MetaDisplay *display = meta_get_display ();
|
MetaDisplay *display = meta_get_display ();
|
||||||
XFixesCursorImage *cursor_image;
|
g_autoptr (GError) error = NULL;
|
||||||
CoglTexture2D *sprite;
|
|
||||||
guint8 *cursor_data;
|
|
||||||
gboolean free_cursor_data;
|
|
||||||
CoglContext *ctx;
|
|
||||||
CoglError *error = NULL;
|
|
||||||
|
|
||||||
if (tracker->xfixes_cursor)
|
if (tracker->xfixes_cursor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cursor_image = XFixesGetCursorImage (display->xdisplay);
|
tracker->xfixes_cursor = meta_cursor_sprite_xfixes_new (display, &error);
|
||||||
if (!cursor_image)
|
if (!tracker->xfixes_cursor)
|
||||||
return;
|
g_warning ("Failed to create XFIXES cursor: %s", error->message);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -308,7 +247,7 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ensure_xfixes_cursor (tracker);
|
ensure_xfixes_cursor (tracker);
|
||||||
cursor_sprite = tracker->xfixes_cursor;
|
cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor_sprite)
|
if (cursor_sprite)
|
||||||
@ -345,7 +284,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ensure_xfixes_cursor (tracker);
|
ensure_xfixes_cursor (tracker);
|
||||||
cursor_sprite = tracker->xfixes_cursor;
|
cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor_sprite)
|
if (cursor_sprite)
|
||||||
|
226
src/backends/x11/cm/meta-cursor-sprite-xfixes.c
Normal file
226
src/backends/x11/cm/meta-cursor-sprite-xfixes.c
Normal file
@ -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);
|
||||||
|
}
|
36
src/backends/x11/cm/meta-cursor-sprite-xfixes.h
Normal file
36
src/backends/x11/cm/meta-cursor-sprite-xfixes.h
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user