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
This commit is contained in:
parent
e648f2c244
commit
141760057b
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "meta-cursor.h"
|
#include "meta-cursor.h"
|
||||||
|
|
||||||
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
@ -42,6 +43,8 @@ typedef struct {
|
|||||||
struct _MetaCursorReference {
|
struct _MetaCursorReference {
|
||||||
int ref_count;
|
int ref_count;
|
||||||
|
|
||||||
|
int current_frame;
|
||||||
|
XcursorImages *xcursor_images;
|
||||||
MetaCursor cursor;
|
MetaCursor cursor;
|
||||||
MetaCursorImage image;
|
MetaCursorImage image;
|
||||||
};
|
};
|
||||||
@ -56,4 +59,8 @@ struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
|||||||
int *hot_y);
|
int *hot_y);
|
||||||
#endif
|
#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 */
|
#endif /* META_CURSOR_PRIVATE_H */
|
||||||
|
@ -67,6 +67,8 @@ meta_cursor_image_free (MetaCursorImage *image)
|
|||||||
static void
|
static void
|
||||||
meta_cursor_reference_free (MetaCursorReference *self)
|
meta_cursor_reference_free (MetaCursorReference *self)
|
||||||
{
|
{
|
||||||
|
if (self->xcursor_images)
|
||||||
|
XcursorImagesDestroy (self->xcursor_images);
|
||||||
meta_cursor_image_free (&self->image);
|
meta_cursor_image_free (&self->image);
|
||||||
g_slice_free (MetaCursorReference, self);
|
g_slice_free (MetaCursorReference, self);
|
||||||
}
|
}
|
||||||
@ -135,10 +137,10 @@ meta_cursor_create_x_cursor (Display *xdisplay,
|
|||||||
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
|
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
static XcursorImage *
|
static XcursorImages *
|
||||||
load_cursor_on_client (MetaCursor cursor)
|
load_cursor_on_client (MetaCursor cursor)
|
||||||
{
|
{
|
||||||
return XcursorLibraryLoadImage (translate_meta_cursor (cursor),
|
return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
|
||||||
meta_prefs_get_cursor_theme (),
|
meta_prefs_get_cursor_theme (),
|
||||||
meta_prefs_get_cursor_size ());
|
meta_prefs_get_cursor_size ());
|
||||||
}
|
}
|
||||||
@ -256,6 +258,46 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
|||||||
#endif
|
#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
|
static void
|
||||||
load_cursor_image (MetaCursorReference *cursor)
|
load_cursor_image (MetaCursorReference *cursor)
|
||||||
{
|
{
|
||||||
@ -266,12 +308,16 @@ load_cursor_image (MetaCursorReference *cursor)
|
|||||||
* load this directly. */
|
* load this directly. */
|
||||||
g_assert (cursor->cursor != META_CURSOR_NONE);
|
g_assert (cursor->cursor != META_CURSOR_NONE);
|
||||||
|
|
||||||
image = load_cursor_on_client (cursor->cursor);
|
if (!cursor->xcursor_images)
|
||||||
if (!image)
|
{
|
||||||
|
cursor->current_frame = 0;
|
||||||
|
cursor->xcursor_images = load_cursor_on_client (cursor->cursor);
|
||||||
|
if (!cursor->xcursor_images)
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
image = meta_cursor_reference_get_current_frame_image (cursor);
|
||||||
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
|
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
|
||||||
XcursorImageDestroy (image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaCursorReference *
|
MetaCursorReference *
|
||||||
|
Loading…
Reference in New Issue
Block a user