mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-02-06 04:06:19 -05:00
wayland-cursor: load all cursors from a theme on wl_cursor_theme_load
This commit is contained in:
parent
f779c57be2
commit
c66f26024b
3 changed files with 145 additions and 53 deletions
|
|
@ -113,21 +113,6 @@ shm_pool_destroy(struct shm_pool *pool)
|
|||
}
|
||||
|
||||
|
||||
static const char *cursor_names[] = {
|
||||
"bottom_left_corner",
|
||||
"bottom_right_corner",
|
||||
"bottom_side",
|
||||
"grabbing",
|
||||
"left_ptr",
|
||||
"left_side",
|
||||
"right_side",
|
||||
"top_left_corner",
|
||||
"top_right_corner",
|
||||
"top_side",
|
||||
"xterm",
|
||||
"hand1",
|
||||
};
|
||||
|
||||
struct wl_cursor_theme {
|
||||
unsigned int cursor_count;
|
||||
struct wl_cursor **cursors;
|
||||
|
|
@ -192,32 +177,25 @@ wl_cursor_destroy(struct wl_cursor *cursor)
|
|||
}
|
||||
|
||||
static struct wl_cursor *
|
||||
load_cursor(struct wl_cursor_theme *theme, const char *name)
|
||||
wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
||||
struct wl_cursor_theme *theme)
|
||||
{
|
||||
XcursorImages *images;
|
||||
struct wl_cursor *cursor;
|
||||
struct cursor_image *image;
|
||||
int i, size;
|
||||
|
||||
images = XcursorLibraryLoadImages(name, theme->name, theme->size);
|
||||
if (!images)
|
||||
return NULL;
|
||||
|
||||
cursor = malloc(sizeof *cursor);
|
||||
if (!cursor) {
|
||||
XcursorImagesDestroy(images);
|
||||
if (!cursor)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cursor->image_count = images->nimage;
|
||||
cursor->images = malloc(images->nimage * sizeof cursor->images[0]);
|
||||
if (!cursor->images) {
|
||||
XcursorImagesDestroy(images);
|
||||
free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cursor->name = strdup(name);
|
||||
cursor->name = strdup(images->name);
|
||||
|
||||
for (i = 0; i < images->nimage; i++) {
|
||||
image = malloc(sizeof *image);
|
||||
|
|
@ -239,11 +217,34 @@ load_cursor(struct wl_cursor_theme *theme, const char *name)
|
|||
images->images[i]->pixels, size);
|
||||
}
|
||||
|
||||
XcursorImagesDestroy(images);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
load_callback(XcursorImages *images, void *data)
|
||||
{
|
||||
struct wl_cursor_theme *theme = data;
|
||||
struct wl_cursor *cursor;
|
||||
|
||||
if (wl_cursor_theme_get_cursor(theme, images->name)) {
|
||||
XcursorImagesDestroy(images);
|
||||
return;
|
||||
}
|
||||
|
||||
cursor = wl_cursor_create_from_xcursor_images(images, theme);
|
||||
|
||||
if (cursor) {
|
||||
theme->cursor_count++;
|
||||
theme->cursors =
|
||||
realloc(theme->cursors,
|
||||
theme->cursor_count * sizeof theme->cursors[0]);
|
||||
|
||||
theme->cursors[theme->cursor_count - 1] = cursor;
|
||||
}
|
||||
|
||||
XcursorImagesDestroy(images);
|
||||
}
|
||||
|
||||
/** Load a cursor theme to memory shared with the compositor
|
||||
*
|
||||
* \param name The name of the cursor theme to load. If %NULL, the default
|
||||
|
|
@ -258,7 +259,6 @@ WL_EXPORT struct wl_cursor_theme *
|
|||
wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
|
||||
{
|
||||
struct wl_cursor_theme *theme;
|
||||
unsigned int i;
|
||||
|
||||
theme = malloc(sizeof *theme);
|
||||
if (!theme)
|
||||
|
|
@ -269,20 +269,13 @@ wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
|
|||
|
||||
theme->name = strdup(name);
|
||||
theme->size = size;
|
||||
theme->cursor_count = ARRAY_LENGTH(cursor_names);
|
||||
|
||||
theme->cursors =
|
||||
malloc(theme->cursor_count * sizeof theme->cursors[0]);
|
||||
if (!theme->cursors) {
|
||||
free(theme);
|
||||
return NULL;
|
||||
}
|
||||
theme->cursor_count = 0;
|
||||
theme->cursors = NULL;
|
||||
|
||||
theme->pool =
|
||||
shm_pool_create(shm, theme->cursor_count * size * size * 4);
|
||||
shm_pool_create(shm, size * size * 4);
|
||||
|
||||
for (i = 0; i < theme->cursor_count; i++)
|
||||
theme->cursors[i] = load_cursor(theme, cursor_names[i]);
|
||||
xcursor_load_theme(name, size, load_callback, theme);
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
|
@ -317,23 +310,11 @@ wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
|||
const char *name)
|
||||
{
|
||||
unsigned int i;
|
||||
struct wl_cursor *cursor;
|
||||
|
||||
for (i = 0; i < theme->cursor_count; i++) {
|
||||
if (strcmp(name, theme->cursors[i]->name) == 0)
|
||||
return theme->cursors[i];
|
||||
}
|
||||
|
||||
cursor = load_cursor(theme, name);
|
||||
if (!cursor)
|
||||
return NULL;
|
||||
|
||||
theme->cursor_count++;
|
||||
theme->cursors =
|
||||
realloc(theme->cursors,
|
||||
theme->cursor_count * sizeof theme->cursors[0]);
|
||||
|
||||
theme->cursors[theme->cursor_count - 1] = cursor;
|
||||
|
||||
return cursor;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
107
cursor/xcursor.c
107
cursor/xcursor.c
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* From libXcursor/include/X11/extensions/Xcursor.h
|
||||
|
|
@ -854,3 +855,109 @@ XcursorLibraryLoadImages (const char *file, const char *theme, int size)
|
|||
}
|
||||
return images;
|
||||
}
|
||||
|
||||
static void
|
||||
load_all_cursors_from_dir(const char *path, int size,
|
||||
void (*load_callback)(XcursorImages *, void *),
|
||||
void *user_data)
|
||||
{
|
||||
FILE *f;
|
||||
DIR *dir = opendir(path);
|
||||
struct dirent *ent;
|
||||
char *full;
|
||||
XcursorImages *images;
|
||||
|
||||
if (!dir)
|
||||
return;
|
||||
|
||||
ent = readdir(dir);
|
||||
for(ent = readdir(dir); ent; ent = readdir(dir)) {
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
full = _XcursorBuildFullname(path, "", ent->d_name);
|
||||
if (!full)
|
||||
continue;
|
||||
|
||||
f = fopen(full, "r");
|
||||
if (!f)
|
||||
continue;
|
||||
|
||||
images = XcursorFileLoadImages(f, size);
|
||||
|
||||
if (images) {
|
||||
XcursorImagesSetName(images, ent->d_name);
|
||||
load_callback(images, user_data);
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
/** Load all the cursor of a theme
|
||||
*
|
||||
* This function loads all the cursor images of a given theme and its
|
||||
* inherited themes. Each cursor is loaded into an XcursorImages object
|
||||
* which is passed to the caller's load callback. If a cursor appears
|
||||
* more than once across all the inherited themes, the load callback
|
||||
* will be called multiple times, with possibly different XcursorImages
|
||||
* object which have the same name. The user is expected to destroy the
|
||||
* XcursorImages objects passed to the callback with
|
||||
* XcursorImagesDestroy().
|
||||
*
|
||||
* \param theme The name of theme that should be loaded
|
||||
* \param size The desired size of the cursor images
|
||||
* \param load_callback A callback function that will be called
|
||||
* for each cursor loaded. The first parameter is the XcursorImages
|
||||
* object representing the loaded cursor and the second is a pointer
|
||||
* to data provided by the user.
|
||||
* \param user_data The data that should be passed to the load callback
|
||||
*/
|
||||
void
|
||||
xcursor_load_theme(const char *theme, int size,
|
||||
void (*load_callback)(XcursorImages *, void *),
|
||||
void *user_data)
|
||||
{
|
||||
char *full, *dir;
|
||||
char *inherits = NULL;
|
||||
const char *path, *i;
|
||||
|
||||
if (!theme)
|
||||
theme = "default";
|
||||
|
||||
for (path = XcursorLibraryPath();
|
||||
path;
|
||||
path = _XcursorNextPath(path)) {
|
||||
dir = _XcursorBuildThemeDir(path, theme);
|
||||
if (!dir)
|
||||
continue;
|
||||
|
||||
full = _XcursorBuildFullname(dir, "cursors", "");
|
||||
|
||||
if (full) {
|
||||
load_all_cursors_from_dir(full, size, load_callback,
|
||||
user_data);
|
||||
free(full);
|
||||
}
|
||||
|
||||
if (!inherits) {
|
||||
full = _XcursorBuildFullname(dir, "", "index.theme");
|
||||
if (full) {
|
||||
inherits = _XcursorThemeInherits(full);
|
||||
free(full);
|
||||
}
|
||||
}
|
||||
|
||||
free(dir);
|
||||
}
|
||||
|
||||
for (i = inherits; i; i = _XcursorNextPath(i))
|
||||
xcursor_load_theme(i, size, load_callback, user_data);
|
||||
|
||||
if (inherits)
|
||||
free(inherits);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,4 +55,8 @@ XcursorLibraryLoadImages (const char *file, const char *theme, int size);
|
|||
void
|
||||
XcursorImagesDestroy (XcursorImages *images);
|
||||
|
||||
void
|
||||
xcursor_load_theme(const char *theme, int size,
|
||||
void (*load_callback)(XcursorImages *, void *),
|
||||
void *user_data);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue