[gtk/wayland-cursors: 2/2] Make wayland load cursors on demand
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wayland-cursors: 2/2] Make wayland load cursors on demand
- Date: Fri, 24 Jan 2020 19:41:18 +0000 (UTC)
commit fa28101b55a81b9944c9b4e223698d62390d2629
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Jan 24 14:36:21 2020 -0500
Make wayland load cursors on demand
This changes the startup cost for cursor theme loading
from 25ms to 0.1ms.
Only problem: the cursor is blank the first time I use it.
gdk/wayland/cursor/wayland-cursor.c | 127 ++++++++----------------------------
gdk/wayland/cursor/xcursor.c | 13 ++++
gdk/wayland/cursor/xcursor.h | 4 ++
gdk/wayland/gdkdisplay-wayland.c | 5 +-
4 files changed, 49 insertions(+), 100 deletions(-)
---
diff --git a/gdk/wayland/cursor/wayland-cursor.c b/gdk/wayland/cursor/wayland-cursor.c
index 0a208bc8ef..594239aaf7 100644
--- a/gdk/wayland/cursor/wayland-cursor.c
+++ b/gdk/wayland/cursor/wayland-cursor.c
@@ -36,6 +36,7 @@
#include <fcntl.h>
#include <errno.h>
#include <os-compatibility.h>
+#include <glib.h>
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
@@ -134,8 +135,8 @@ struct wl_cursor_theme {
struct wl_cursor **cursors;
struct wl_shm *shm;
struct shm_pool *pool;
- char *name;
int size;
+ char *path;
};
struct cursor_image {
@@ -200,7 +201,8 @@ wl_cursor_destroy(struct wl_cursor *cursor)
static struct wl_cursor *
wl_cursor_create_from_xcursor_images(XcursorImages *images,
- struct wl_cursor_theme *theme)
+ struct wl_cursor_theme *theme,
+ const char *name)
{
struct cursor *cursor;
struct cursor_image *image;
@@ -217,7 +219,7 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
return NULL;
}
- cursor->cursor.name = strdup(images->name);
+ cursor->cursor.name = strdup(name);
cursor->total_delay = 0;
for (i = 0; i < images->nimage; i++) {
@@ -260,17 +262,15 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
}
static void
-load_callback(XcursorImages *images, void *data)
+load_cursor(struct wl_cursor_theme *theme, const char *name)
{
- struct wl_cursor_theme *theme = data;
+ XcursorImages *images;
struct wl_cursor *cursor;
+ char *path;
- if (wl_cursor_theme_get_cursor(theme, images->name)) {
- XcursorImagesDestroy(images);
- return;
- }
-
- cursor = wl_cursor_create_from_xcursor_images(images, theme);
+ path = g_strconcat (theme->path, "/", name, NULL);
+ images = xcursor_load_images (path, theme->size);
+ cursor = wl_cursor_create_from_xcursor_images(images, theme, name);
if (cursor) {
theme->cursor_count++;
@@ -287,6 +287,7 @@ load_callback(XcursorImages *images, void *data)
}
XcursorImagesDestroy(images);
+ g_free (path);
}
/** Load a cursor theme to memory shared with the compositor
@@ -301,7 +302,7 @@ load_callback(XcursorImages *images, void *data)
* name exists, a default theme will be loaded.
*/
WL_EXPORT struct wl_cursor_theme *
-wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
+wl_cursor_theme_load(const char *path, int size, struct wl_shm *shm)
{
struct wl_cursor_theme *theme;
@@ -309,29 +310,19 @@ wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
if (!theme)
return NULL;
- if (!name)
- name = "default";
-
- theme->name = strdup(name);
- if (!theme->name)
- goto out_error_name;
+ theme->path = strdup (path);
theme->size = size;
theme->cursor_count = 0;
theme->cursors = NULL;
theme->pool = shm_pool_create(shm, size * size * 4);
- if (!theme->pool)
- goto out_error_pool;
-
- xcursor_load_theme(name, size, load_callback, theme);
+ if (!theme->pool) {
+ free (theme->path);
+ free (theme);
+ return NULL;
+ }
return theme;
-
-out_error_pool:
- free(theme->name);
-out_error_name:
- free(theme);
- return NULL;
}
/** Destroys a cursor theme object
@@ -348,8 +339,8 @@ wl_cursor_theme_destroy(struct wl_cursor_theme *theme)
shm_pool_destroy(theme->pool);
- free(theme->name);
free(theme->cursors);
+ free(theme->path);
free(theme);
}
@@ -364,78 +355,16 @@ WL_EXPORT struct wl_cursor *
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
const char *name)
{
+ int t;
unsigned int i;
- for (i = 0; i < theme->cursor_count; i++) {
- if (strcmp(name, theme->cursors[i]->name) == 0)
- return theme->cursors[i];
- }
+ for (t = 0; t < 1; t++) {
+ for (i = 0; i < theme->cursor_count; i++) {
+ if (strcmp(name, theme->cursors[i]->name) == 0)
+ return theme->cursors[i];
+ }
+ load_cursor (theme, name);
+ }
return NULL;
}
-
-/** Find the frame for a given elapsed time in a cursor animation
- * as well as the time left until next cursor change.
- *
- * \param cursor The cursor
- * \param time Elapsed time in ms since the beginning of the animation
- * \param duration pointer to uint32_t to store time left for this image or
- * zero if the cursor won't change.
- *
- * \return The index of the image that should be displayed for the
- * given time in the cursor animation.
- */
-WL_EXPORT int
-wl_cursor_frame_and_duration(struct wl_cursor *_cursor, uint32_t time,
- uint32_t *duration)
-{
- struct cursor *cursor = (struct cursor *) _cursor;
- uint32_t t;
- int i;
-
- if (cursor->cursor.image_count == 1) {
- if (duration)
- *duration = 0;
- return 0;
- }
-
- i = 0;
- t = time % cursor->total_delay;
-
- /* If there is a 0 delay in the image set then this
- * loop breaks on it and we display that cursor until
- * time % cursor->total_delay wraps again.
- * Since a 0 delay is silly, and we've never actually
- * seen one in a cursor file, we haven't bothered to
- * "fix" this.
- */
- while (t - cursor->cursor.images[i]->delay < t)
- t -= cursor->cursor.images[i++]->delay;
-
- if (!duration)
- return i;
-
- /* Make sure we don't accidentally tell the caller this is
- * a static cursor image.
- */
- if (t >= cursor->cursor.images[i]->delay)
- *duration = 1;
- else
- *duration = cursor->cursor.images[i]->delay - t;
-
- return i;
-}
-
-/** Find the frame for a given elapsed time in a cursor animation
- *
- * \param cursor The cursor
- * \param time Elapsed time in ms since the beginning of the animation
- *
- * \return The index of the image that should be displayed for the
- * given time in the cursor animation.
- */
-WL_EXPORT int
-wl_cursor_frame(struct wl_cursor *_cursor, uint32_t time)
-{
- return wl_cursor_frame_and_duration(_cursor, time, NULL);
-}
diff --git a/gdk/wayland/cursor/xcursor.c b/gdk/wayland/cursor/xcursor.c
index 689c702672..a88ad8b804 100644
--- a/gdk/wayland/cursor/xcursor.c
+++ b/gdk/wayland/cursor/xcursor.c
@@ -975,3 +975,16 @@ xcursor_load_theme(const char *theme, int size,
if (inherits)
free(inherits);
}
+
+XcursorImages *
+xcursor_load_images (const char *path, int size)
+{
+ FILE *f;
+ XcursorImages *images;
+
+ f = fopen (path, "r");
+ images = XcursorFileLoadImages (f, size);
+ fclose (f);
+
+ return images;
+}
diff --git a/gdk/wayland/cursor/xcursor.h b/gdk/wayland/cursor/xcursor.h
index 62e232202a..6a5a71648a 100644
--- a/gdk/wayland/cursor/xcursor.h
+++ b/gdk/wayland/cursor/xcursor.h
@@ -62,4 +62,8 @@ void
xcursor_load_theme(const char *theme, int size,
void (*load_callback)(XcursorImages *, void *),
void *user_data);
+
+XcursorImages *
+xcursor_load_images (const char *path, int size);
+
#endif
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 57c15281c8..4533a87fa5 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -1068,6 +1068,7 @@ gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY(display);
struct wl_cursor_theme *theme;
int i;
+ char *path;
g_assert (display_wayland);
g_assert (display_wayland->shm);
@@ -1076,7 +1077,9 @@ gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
display_wayland->cursor_theme_size == size)
return;
- theme = wl_cursor_theme_load (name, size, display_wayland->shm);
+ path = g_strconcat ("/usr/share/icons/", name, "/cursors", NULL);
+ theme = wl_cursor_theme_load (path, size, display_wayland->shm);
+ g_free (path);
if (theme == NULL)
{
g_warning ("Failed to load cursor theme %s", name);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]