summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2015-07-13 20:32:42 +0200
committerCarlos Garnacho <carlosg@gnome.org>2015-07-20 22:06:44 +0200
commit141760057b409cdf31067cf9e4ec2efdc5c79fe7 (patch)
tree934430d43f21d9d813d734b451e996b2230a3832
parente648f2c244dbdf2b65122ce0754ab7be71de7e42 (diff)
downloadmutter-141760057b409cdf31067cf9e4ec2efdc5c79fe7.tar.gz
backend: Store XcursorImages for theme cursors
There's a chance the icon will be animated, so store the XcursorImages instead of the individual XcursorImage, and handle that as a nimages=1 special case. API to "tick" a cursor animation, and retrieve current frame timing information has been added. https://bugzilla.gnome.org/show_bug.cgi?id=752342
-rw-r--r--src/backends/meta-cursor-private.h7
-rw-r--r--src/backends/meta-cursor.c62
2 files changed, 61 insertions, 8 deletions
diff --git a/src/backends/meta-cursor-private.h b/src/backends/meta-cursor-private.h
index c8440e87e..9f1845115 100644
--- a/src/backends/meta-cursor-private.h
+++ b/src/backends/meta-cursor-private.h
@@ -24,6 +24,7 @@
#include "meta-cursor.h"
+#include <X11/Xcursor/Xcursor.h>
#include <cogl/cogl.h>
#ifdef HAVE_NATIVE_BACKEND
@@ -42,6 +43,8 @@ typedef struct {
struct _MetaCursorReference {
int ref_count;
+ int current_frame;
+ XcursorImages *xcursor_images;
MetaCursor cursor;
MetaCursorImage image;
};
@@ -56,4 +59,8 @@ struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_y);
#endif
+gboolean meta_cursor_reference_is_animated (MetaCursorReference *self);
+void meta_cursor_reference_tick_frame (MetaCursorReference *self);
+guint meta_cursor_reference_get_current_frame_time (MetaCursorReference *self);
+
#endif /* META_CURSOR_PRIVATE_H */
diff --git a/src/backends/meta-cursor.c b/src/backends/meta-cursor.c
index 7c51ef08e..d888c3ee3 100644
--- a/src/backends/meta-cursor.c
+++ b/src/backends/meta-cursor.c
@@ -67,6 +67,8 @@ meta_cursor_image_free (MetaCursorImage *image)
static void
meta_cursor_reference_free (MetaCursorReference *self)
{
+ if (self->xcursor_images)
+ XcursorImagesDestroy (self->xcursor_images);
meta_cursor_image_free (&self->image);
g_slice_free (MetaCursorReference, self);
}
@@ -135,12 +137,12 @@ meta_cursor_create_x_cursor (Display *xdisplay,
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
}
-static XcursorImage *
+static XcursorImages *
load_cursor_on_client (MetaCursor cursor)
{
- return XcursorLibraryLoadImage (translate_meta_cursor (cursor),
- meta_prefs_get_cursor_theme (),
- meta_prefs_get_cursor_size ());
+ return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
+ meta_prefs_get_cursor_theme (),
+ meta_prefs_get_cursor_size ());
}
#ifdef HAVE_NATIVE_BACKEND
@@ -256,6 +258,46 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
#endif
}
+static XcursorImage *
+meta_cursor_reference_get_current_frame_image (MetaCursorReference *self)
+{
+ return self->xcursor_images->images[self->current_frame];
+}
+
+void
+meta_cursor_reference_tick_frame (MetaCursorReference *self)
+{
+ XcursorImage *image;
+
+ if (!meta_cursor_reference_is_animated (self))
+ return;
+
+ self->current_frame++;
+
+ if (self->current_frame >= self->xcursor_images->nimage)
+ self->current_frame = 0;
+
+ meta_cursor_image_free (&self->image);
+ image = meta_cursor_reference_get_current_frame_image (self);
+ meta_cursor_image_load_from_xcursor_image (&self->image, image);
+}
+
+guint
+meta_cursor_reference_get_current_frame_time (MetaCursorReference *self)
+{
+ if (!meta_cursor_reference_is_animated (self))
+ return 0;
+
+ return self->xcursor_images->images[self->current_frame]->delay;
+}
+
+gboolean
+meta_cursor_reference_is_animated (MetaCursorReference *self)
+{
+ return (self->xcursor_images &&
+ self->xcursor_images->nimage > 1);
+}
+
static void
load_cursor_image (MetaCursorReference *cursor)
{
@@ -266,12 +308,16 @@ load_cursor_image (MetaCursorReference *cursor)
* load this directly. */
g_assert (cursor->cursor != META_CURSOR_NONE);
- image = load_cursor_on_client (cursor->cursor);
- if (!image)
- return;
+ if (!cursor->xcursor_images)
+ {
+ cursor->current_frame = 0;
+ cursor->xcursor_images = load_cursor_on_client (cursor->cursor);
+ if (!cursor->xcursor_images)
+ return;
+ }
+ image = meta_cursor_reference_get_current_frame_image (cursor);
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
- XcursorImageDestroy (image);
}
MetaCursorReference *