mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-03-19 05:34:02 -04:00
cursor: add XDG_DATA_DIRS to xcursor search path
For XDG Base Directory Specification
The XDG_DATA_HOME is already supported.
This patch adds XDG_DATA_DIRS support.
As specifications:
1.$XDG_DATA_DIRS defines the preference-ordered set of base directories
to search for data files in addition to the $XDG_DATA_HOME base directory.
2.if $XDG_DATA_DIRS is either not set or empty, a value equal to
/usr/local/share/:/usr/share/ should be used.
3.look in $HOME/.icons (for backwards compatibility) at first.
Related:
https://github.com/alacritty/alacritty/issues/4371
ad87b12264
XDG Base Directory Specification
Icon Theme Specification
Signed-off-by: catsout outline941@live.com
This commit is contained in:
parent
73468bab7d
commit
91a92e5085
1 changed files with 126 additions and 14 deletions
140
cursor/xcursor.c
140
cursor/xcursor.c
|
|
@ -479,6 +479,31 @@ xcursor_xc_file_load_images(FILE *file, int size)
|
||||||
return images;
|
return images;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
xcursor_next_path(const char *path);
|
||||||
|
|
||||||
|
static void
|
||||||
|
xcursor_add_path_elt(char *path, const char *elt, int len)
|
||||||
|
{
|
||||||
|
int pathlen = strlen (path);
|
||||||
|
/* append / if the path doesn't currently have one */
|
||||||
|
if (pathlen == 0 || path[pathlen - 1] != '/')
|
||||||
|
{
|
||||||
|
strcat(path, "/");
|
||||||
|
pathlen++;
|
||||||
|
}
|
||||||
|
/* may be unsafe? */
|
||||||
|
if (len == -1)
|
||||||
|
len = strlen(elt);
|
||||||
|
/* strip leading slashes */
|
||||||
|
while (len && elt[0] == '/')
|
||||||
|
{
|
||||||
|
elt++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
snprintf(path + pathlen, len + 1, "%s", elt);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From libXcursor/src/library.c
|
* From libXcursor/src/library.c
|
||||||
*/
|
*/
|
||||||
|
|
@ -488,11 +513,72 @@ xcursor_xc_file_load_images(FILE *file, int size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef XCURSORPATH
|
#ifndef XCURSORPATH
|
||||||
#define XCURSORPATH "~/.icons:/usr/share/icons:/usr/share/pixmaps:~/.cursors:/usr/share/cursors/xorg-x11:"ICONDIR
|
#define XCURSORPATH "/usr/share/icons:/usr/share/pixmaps:~/.cursors:/usr/share/cursors/xorg-x11:"ICONDIR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define XCURSORPATH_BACKWARDS_COMPATIBILITY "~/.icons"
|
||||||
#define XDG_DATA_HOME_FALLBACK "~/.local/share"
|
#define XDG_DATA_HOME_FALLBACK "~/.local/share"
|
||||||
#define CURSORDIR "/icons"
|
#define XDG_DATA_DIRS_FALLBACK "/usr/local/share"
|
||||||
|
#define XCURSORPATH_FALLBACK "~/.icons:~/.local/share/icons:/usr/local/share/icons:"XCURSORPATH
|
||||||
|
#define CURSORDIR "icons"
|
||||||
|
|
||||||
|
static char *
|
||||||
|
xcursor_library_colon_append_dir (const char *in_path, const char *dir)
|
||||||
|
{
|
||||||
|
const char *colon_start;
|
||||||
|
const char *colon_end;
|
||||||
|
char *path = NULL;
|
||||||
|
int path_len = 0;
|
||||||
|
int max_path_len = 0;
|
||||||
|
int append_len = 0;
|
||||||
|
int dir_len = strlen (dir);
|
||||||
|
|
||||||
|
// max for adding max num of '/dir', use 'dir_len + 1' as '/' is uncertain
|
||||||
|
max_path_len = strlen(in_path) + 1;
|
||||||
|
for (colon_start = in_path; colon_start; colon_start = xcursor_next_path(colon_start))
|
||||||
|
{
|
||||||
|
max_path_len += dir_len + 1;
|
||||||
|
}
|
||||||
|
path = malloc(max_path_len);
|
||||||
|
if (path == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
path[0] = '\0';
|
||||||
|
path_len = 0;
|
||||||
|
|
||||||
|
colon_start = in_path;
|
||||||
|
while (colon_start != NULL)
|
||||||
|
{
|
||||||
|
/* end at null terminal if not found */
|
||||||
|
colon_end = strchrnul(colon_start, ':');
|
||||||
|
/* copy a path between colon */
|
||||||
|
append_len = snprintf(path + path_len, max_path_len - path_len, "%.*s",
|
||||||
|
(int)(colon_end - colon_start), colon_start);
|
||||||
|
|
||||||
|
if (append_len > 0 && append_len + (dir_len + 1) < max_path_len - path_len)
|
||||||
|
{
|
||||||
|
path_len += append_len;
|
||||||
|
/* join dir, safe here as already checked max_path_len */
|
||||||
|
xcursor_add_path_elt(path + path_len - 1, dir, dir_len);
|
||||||
|
path_len += strlen(path + path_len);
|
||||||
|
/* add ':' */
|
||||||
|
snprintf(path + path_len, max_path_len - path_len, ":");
|
||||||
|
path_len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(colon_end[0] == ':') {
|
||||||
|
colon_start = colon_end + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* end and replace last ':' */
|
||||||
|
colon_start = NULL;
|
||||||
|
if (path_len > 0 && path[path_len - 1] == ':')
|
||||||
|
path[path_len - 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Get search path for cursor themes
|
/** Get search path for cursor themes
|
||||||
*
|
*
|
||||||
|
|
@ -506,24 +592,50 @@ xcursor_xc_file_load_images(FILE *file, int size)
|
||||||
static char *
|
static char *
|
||||||
xcursor_library_path(void)
|
xcursor_library_path(void)
|
||||||
{
|
{
|
||||||
const char *env_var, *suffix;
|
const char *env_var, *xdg_data_home;
|
||||||
char *path;
|
char *path, *xdg_path;
|
||||||
size_t path_size;
|
int path_len;
|
||||||
|
|
||||||
env_var = getenv("XCURSOR_PATH");
|
env_var = getenv("XCURSOR_PATH");
|
||||||
if (env_var)
|
if (env_var)
|
||||||
return strdup(env_var);
|
return strdup(env_var);
|
||||||
|
|
||||||
env_var = getenv("XDG_DATA_HOME");
|
env_var = getenv("XCURSOR_PATH");
|
||||||
if (!env_var || env_var[0] != '/')
|
if (env_var)
|
||||||
env_var = XDG_DATA_HOME_FALLBACK;
|
path = strdup(env_var);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
env_var = getenv("XDG_DATA_HOME");
|
||||||
|
if (!env_var || env_var[0] != '/')
|
||||||
|
env_var = XDG_DATA_HOME_FALLBACK;
|
||||||
|
xdg_data_home = env_var;
|
||||||
|
|
||||||
suffix = CURSORDIR ":" XCURSORPATH;
|
env_var = getenv("XDG_DATA_DIRS");
|
||||||
path_size = strlen(env_var) + strlen(suffix) + 1;
|
if (!env_var)
|
||||||
path = malloc(path_size);
|
env_var = XDG_DATA_DIRS_FALLBACK;
|
||||||
if (!path)
|
|
||||||
return NULL;
|
do
|
||||||
snprintf(path, path_size, "%s%s", env_var, suffix);
|
{
|
||||||
|
path_len = asprintf(&xdg_path, "%s:%s", xdg_data_home, env_var);
|
||||||
|
if (path_len == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
path = xcursor_library_colon_append_dir(xdg_path, CURSORDIR);
|
||||||
|
free(xdg_path);
|
||||||
|
if (path == NULL)
|
||||||
|
break;
|
||||||
|
xdg_path = path;
|
||||||
|
|
||||||
|
path_len = asprintf(&path, "%s%s%s", XCURSORPATH_BACKWARDS_COMPATIBILITY ":",
|
||||||
|
xdg_path, ":" XCURSORPATH);
|
||||||
|
free(xdg_path);
|
||||||
|
if (path_len == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
return path;
|
||||||
|
} while (0);
|
||||||
|
return strdup(XCURSORPATH_FALLBACK);
|
||||||
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue