backends/cursor: Make MetaCursorSprite derivable

This makes it possible to move out backing store specific code (such as
Xcursor handling) to separate units, while also making it easier to add
more types).

https://gitlab.gnome.org/GNOME/mutter/issues/77
This commit is contained in:
Jonas Ådahl 2018-04-23 16:57:01 +02:00
parent d3441f7577
commit 2a20df0c50
2 changed files with 98 additions and 49 deletions

View File

@ -44,7 +44,7 @@ enum {
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
struct _MetaCursorSprite typedef struct _MetaCursorSpritePrivate
{ {
GObject parent; GObject parent;
@ -59,9 +59,9 @@ struct _MetaCursorSprite
int theme_scale; int theme_scale;
gboolean theme_dirty; gboolean theme_dirty;
}; } MetaCursorSpritePrivate;
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT) G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
static const char * static const char *
translate_meta_cursor (MetaCursor cursor) translate_meta_cursor (MetaCursor cursor)
@ -130,6 +130,8 @@ static void
meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *sprite, meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *sprite,
XcursorImage *xc_image) XcursorImage *xc_image)
{ {
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
MetaBackend *backend = meta_get_backend (); MetaBackend *backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend); MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend);
uint width, height, rowstride; uint width, height, rowstride;
@ -139,7 +141,7 @@ meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *sprite,
CoglTexture2D *texture; CoglTexture2D *texture;
CoglError *error = NULL; CoglError *error = NULL;
g_assert (sprite->texture == NULL); g_assert (priv->texture == NULL);
width = xc_image->width; width = xc_image->width;
height = xc_image->height; height = xc_image->height;
@ -178,42 +180,53 @@ meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *sprite,
static XcursorImage * static XcursorImage *
meta_cursor_sprite_get_current_frame_image (MetaCursorSprite *sprite) meta_cursor_sprite_get_current_frame_image (MetaCursorSprite *sprite)
{ {
return sprite->xcursor_images->images[sprite->current_frame]; MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return priv->xcursor_images->images[priv->current_frame];
} }
void void
meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite) meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite)
{ {
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
XcursorImage *image; XcursorImage *image;
if (!meta_cursor_sprite_is_animated (sprite)) if (!meta_cursor_sprite_is_animated (sprite))
return; return;
sprite->current_frame++; priv->current_frame++;
if (sprite->current_frame >= sprite->xcursor_images->nimage) if (priv->current_frame >= priv->xcursor_images->nimage)
sprite->current_frame = 0; priv->current_frame = 0;
image = meta_cursor_sprite_get_current_frame_image (sprite); image = meta_cursor_sprite_get_current_frame_image (sprite);
g_clear_pointer (&sprite->texture, cogl_object_unref); g_clear_pointer (&priv->texture, cogl_object_unref);
meta_cursor_sprite_load_from_xcursor_image (sprite, image); meta_cursor_sprite_load_from_xcursor_image (sprite, image);
} }
guint guint
meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite) meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite)
{ {
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
if (!meta_cursor_sprite_is_animated (sprite)) if (!meta_cursor_sprite_is_animated (sprite))
return 0; return 0;
return sprite->xcursor_images->images[sprite->current_frame]->delay; return priv->xcursor_images->images[priv->current_frame]->delay;
} }
gboolean gboolean
meta_cursor_sprite_is_animated (MetaCursorSprite *sprite) meta_cursor_sprite_is_animated (MetaCursorSprite *sprite)
{ {
return (sprite->xcursor_images && MetaCursorSpritePrivate *priv =
sprite->xcursor_images->nimage > 1); meta_cursor_sprite_get_instance_private (sprite);
return (priv->xcursor_images &&
priv->xcursor_images->nimage > 1);
} }
MetaCursorSprite * MetaCursorSprite *
@ -225,23 +238,25 @@ meta_cursor_sprite_new (void)
static void static void
meta_cursor_sprite_load_from_theme (MetaCursorSprite *sprite) meta_cursor_sprite_load_from_theme (MetaCursorSprite *sprite)
{ {
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
XcursorImage *image; XcursorImage *image;
g_assert (sprite->cursor != META_CURSOR_NONE); g_assert (priv->cursor != META_CURSOR_NONE);
sprite->theme_dirty = FALSE; priv->theme_dirty = FALSE;
/* We might be reloading with a different scale. If so clear the old data. */ /* We might be reloading with a different scale. If so clear the old data. */
if (sprite->xcursor_images) if (priv->xcursor_images)
{ {
g_clear_pointer (&sprite->texture, cogl_object_unref); g_clear_pointer (&priv->texture, cogl_object_unref);
XcursorImagesDestroy (sprite->xcursor_images); XcursorImagesDestroy (priv->xcursor_images);
} }
sprite->current_frame = 0; priv->current_frame = 0;
sprite->xcursor_images = load_cursor_on_client (sprite->cursor, priv->xcursor_images = load_cursor_on_client (priv->cursor,
sprite->theme_scale); priv->theme_scale);
if (!sprite->xcursor_images) if (!priv->xcursor_images)
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?"); meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
image = meta_cursor_sprite_get_current_frame_image (sprite); image = meta_cursor_sprite_get_current_frame_image (sprite);
@ -252,11 +267,13 @@ MetaCursorSprite *
meta_cursor_sprite_from_theme (MetaCursor cursor) meta_cursor_sprite_from_theme (MetaCursor cursor)
{ {
MetaCursorSprite *sprite; MetaCursorSprite *sprite;
MetaCursorSpritePrivate *priv;
sprite = meta_cursor_sprite_new (); sprite = meta_cursor_sprite_new ();
priv = meta_cursor_sprite_get_instance_private (sprite);
sprite->cursor = cursor; priv->cursor = cursor;
sprite->theme_dirty = TRUE; priv->theme_dirty = TRUE;
return sprite; return sprite;
} }
@ -267,16 +284,19 @@ meta_cursor_sprite_set_texture (MetaCursorSprite *sprite,
int hot_x, int hot_x,
int hot_y) int hot_y)
{ {
if (sprite->texture == COGL_TEXTURE_2D (texture) && MetaCursorSpritePrivate *priv =
sprite->hot_x == hot_x && meta_cursor_sprite_get_instance_private (sprite);
sprite->hot_y == hot_y)
if (priv->texture == COGL_TEXTURE_2D (texture) &&
priv->hot_x == hot_x &&
priv->hot_y == hot_y)
return; return;
g_clear_pointer (&sprite->texture, cogl_object_unref); g_clear_pointer (&priv->texture, cogl_object_unref);
if (texture) if (texture)
sprite->texture = cogl_object_ref (texture); priv->texture = cogl_object_ref (texture);
sprite->hot_x = hot_x; priv->hot_x = hot_x;
sprite->hot_y = hot_y; priv->hot_y = hot_y;
g_signal_emit (sprite, signals[TEXTURE_CHANGED], 0); g_signal_emit (sprite, signals[TEXTURE_CHANGED], 0);
} }
@ -285,28 +305,40 @@ void
meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite, meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite,
float scale) float scale)
{ {
sprite->texture_scale = scale; MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
priv->texture_scale = scale;
} }
void void
meta_cursor_sprite_set_theme_scale (MetaCursorSprite *sprite, meta_cursor_sprite_set_theme_scale (MetaCursorSprite *sprite,
int theme_scale) int theme_scale)
{ {
if (sprite->theme_scale != theme_scale) MetaCursorSpritePrivate *priv =
sprite->theme_dirty = TRUE; meta_cursor_sprite_get_instance_private (sprite);
sprite->theme_scale = theme_scale;
if (priv->theme_scale != theme_scale)
priv->theme_dirty = TRUE;
priv->theme_scale = theme_scale;
} }
CoglTexture * CoglTexture *
meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite) meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite)
{ {
return COGL_TEXTURE (sprite->texture); MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return COGL_TEXTURE (priv->texture);
} }
MetaCursor MetaCursor
meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *sprite) meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *sprite)
{ {
return sprite->cursor; MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return priv->cursor;
} }
void void
@ -314,14 +346,20 @@ meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite,
int *hot_x, int *hot_x,
int *hot_y) int *hot_y)
{ {
*hot_x = sprite->hot_x; MetaCursorSpritePrivate *priv =
*hot_y = sprite->hot_y; meta_cursor_sprite_get_instance_private (sprite);
*hot_x = priv->hot_x;
*hot_y = priv->hot_y;
} }
float float
meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite) meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite)
{ {
return sprite->texture_scale; MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return priv->texture_scale;
} }
void void
@ -335,25 +373,33 @@ meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
void void
meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite) meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite)
{ {
if (sprite->theme_dirty) MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
if (priv->theme_dirty)
meta_cursor_sprite_load_from_theme (sprite); meta_cursor_sprite_load_from_theme (sprite);
} }
static void static void
meta_cursor_sprite_init (MetaCursorSprite *sprite) meta_cursor_sprite_init (MetaCursorSprite *sprite)
{ {
sprite->texture_scale = 1.0f; MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
priv->texture_scale = 1.0f;
} }
static void static void
meta_cursor_sprite_finalize (GObject *object) meta_cursor_sprite_finalize (GObject *object)
{ {
MetaCursorSprite *sprite = META_CURSOR_SPRITE (object); MetaCursorSprite *sprite = META_CURSOR_SPRITE (object);
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
if (sprite->xcursor_images) if (priv->xcursor_images)
XcursorImagesDestroy (sprite->xcursor_images); XcursorImagesDestroy (priv->xcursor_images);
g_clear_pointer (&sprite->texture, cogl_object_unref); g_clear_pointer (&priv->texture, cogl_object_unref);
G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object); G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object);
} }

View File

@ -25,13 +25,16 @@
#include <meta/common.h> #include <meta/common.h>
#include <meta/boxes.h> #include <meta/boxes.h>
typedef struct _MetaCursorSprite MetaCursorSprite; struct _MetaCursorSpriteClass
{
GObjectClass parent_class;
};
#define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ()) #define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ())
G_DECLARE_FINAL_TYPE (MetaCursorSprite, G_DECLARE_DERIVABLE_TYPE (MetaCursorSprite,
meta_cursor_sprite, meta_cursor_sprite,
META, CURSOR_SPRITE, META, CURSOR_SPRITE,
GObject); GObject)
MetaCursorSprite * meta_cursor_sprite_new (void); MetaCursorSprite * meta_cursor_sprite_new (void);