diff --git a/include/theme/theme-dir.h b/include/common/dir.h similarity index 61% rename from include/theme/theme-dir.h rename to include/common/dir.h index 310e6077..e654664d 100644 --- a/include/theme/theme-dir.h +++ b/include/common/dir.h @@ -1,5 +1,7 @@ -#ifndef __LABWC_THEME_DIR_H -#define __LABWC_THEME_DIR_H +#ifndef __LABWC_DIR_H +#define __LABWC_DIR_H + +char *config_dir(void); /** * theme_dir - find theme directory containing theme @theme_name @@ -7,4 +9,4 @@ */ char *theme_dir(const char *theme_name); -#endif /* __LABWC_THEME_DIR_H */ +#endif /* __LABWC_DIR_H */ diff --git a/include/config/config-dir.h b/include/config/config-dir.h deleted file mode 100644 index 19ae1303..00000000 --- a/include/config/config-dir.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LABWC_CONFIG_DIR_H -#define __LABWC_CONFIG_DIR_H - -char *config_dir(void); - -#endif /* __LABWC_CONFIG_DIR_H */ diff --git a/src/common/dir.c b/src/common/dir.c new file mode 100644 index 00000000..aa8cadc4 --- /dev/null +++ b/src/common/dir.c @@ -0,0 +1,135 @@ +/* + * Find the configuration and theme directories + * + * Copyright Johan Malm 2020 + */ + +#include +#include +#include +#include +#include + +#include "common/dir.h" + +struct dir { + const char *prefix; + const char *path; +}; + +/* clang-format off */ +static struct dir config_dirs[] = { + { "XDG_CONFIG_HOME", "labwc" }, + { "HOME", ".config/labwc" }, + { "XDG_CONFIG_DIRS", "labwc" }, + { NULL, "/etc/xdg/labwc" }, + { "XDG_CONFIG_HOME", "openbox" }, + { "HOME", ".config/openbox" }, + { "XDG_CONFIG_DIRS", "openbox" }, + { NULL, "/etc/xdg/openbox" }, + { NULL, NULL } +}; + +static struct dir theme_dirs[] = { + { "XDG_DATA_HOME", "themes" }, + { "HOME", ".local/share/themes" }, + { "HOME", ".themes" }, + { "XDG_DATA_DIRS", "themes" }, + { NULL, "/usr/share/themes" }, + { NULL, "/usr/local/share/themes" }, + { NULL, "opt/share/themes" }, + { NULL, NULL } +}; +/* clang-format on */ + +static bool isdir(const char *path) +{ + struct stat st; + return (!stat(path, &st) && S_ISDIR(st.st_mode)); +} + +struct ctx { + void (*build_path_fn)(struct ctx *ctx, char *prefix, const char *path); + char *buf; + size_t len; + struct dir *dirs; + const char *theme_name; +}; + +static void build_config_path(struct ctx *ctx, char *prefix, const char *path) +{ + if (!prefix) + snprintf(ctx->buf, ctx->len, "%s", path); + else + snprintf(ctx->buf, ctx->len, "%s/%s", prefix, path); +} + +static void build_theme_path(struct ctx *ctx, char *prefix, const char *path) +{ + if (!prefix) + snprintf(ctx->buf, ctx->len, "%s/%s/openbox-3", path, + ctx->theme_name); + else + snprintf(ctx->buf, ctx->len, "%s/%s/%s/openbox-3", prefix, path, + ctx->theme_name); +} + +char *find_dir(struct ctx *ctx) +{ + char *debug = getenv("LABWC_DEBUG_DIR_CONFIG_AND_THEME"); + + for (int i = 0; ctx->dirs[i].path; i++) { + struct dir d = ctx->dirs[i]; + if (!d.prefix) { + /* handle /etc/xdg... */ + ctx->build_path_fn(ctx, NULL, d.path); + if (debug) + fprintf(stderr, "DEBUG: %s\n", ctx->buf); + if (isdir(ctx->buf)) + return ctx->buf; + } else { + /* handle $HOME/.config/... and $XDG_* */ + char *prefix = getenv(d.prefix); + if (!prefix) + continue; + gchar **prefixes = g_strsplit(prefix, ":", -1); + for (gchar **p = prefixes; *p; p++) { + ctx->build_path_fn(ctx, *p, d.path); + if (debug) + fprintf(stderr, "DEBUG: %s\n", + ctx->buf); + if (isdir(ctx->buf)) + return ctx->buf; + } + } + } + /* no directory was found */ + ctx->buf[0] = '.'; + ctx->buf[1] = '\0'; + return ctx->buf; +} + +char *config_dir(void) +{ + static char buf[4096] = { 0 }; + if (buf[0] != '\0') + return buf; + struct ctx ctx = { .build_path_fn = build_config_path, + .buf = buf, + .len = sizeof(buf), + .dirs = config_dirs }; + return find_dir(&ctx); +} + +char *theme_dir(const char *theme_name) +{ + static char buf[4096] = { 0 }; + if (buf[0] != '\0') + return buf; + struct ctx ctx = { .build_path_fn = build_theme_path, + .buf = buf, + .len = sizeof(buf), + .dirs = theme_dirs, + .theme_name = theme_name }; + return find_dir(&ctx); +} diff --git a/src/common/meson.build b/src/common/meson.build index 4a471ab1..48e1dd56 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -1,5 +1,6 @@ labwc_sources += files( 'buf.c', + 'dir.c', 'font.c', 'grab-file.c', 'spawn.c', diff --git a/src/config/config-dir.c b/src/config/config-dir.c deleted file mode 100644 index f506b960..00000000 --- a/src/config/config-dir.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Find the labwc configuration directory - * - * Copyright Johan Malm 2020 - */ - -#include -#include -#include -#include -#include - -#include "config/config-dir.h" - -struct dir { - const char *prefix; - const char *path; -}; - -/* clang-format off */ -static struct dir config_dirs[] = { - { "XDG_CONFIG_HOME", "labwc" }, - { "HOME", ".config/labwc" }, - { "XDG_CONFIG_DIRS", "labwc" }, - { NULL, "/etc/xdg/labwc" }, - { "XDG_CONFIG_HOME", "openbox" }, - { "HOME", ".config/openbox" }, - { "XDG_CONFIG_DIRS", "openbox" }, - { NULL, "/etc/xdg/openbox" }, - { NULL, NULL } -}; -/* clang-format on */ - -static bool isdir(const char *path) -{ - struct stat st; - return (!stat(path, &st) && S_ISDIR(st.st_mode)); -} - -char *config_dir(void) -{ - static char buf[4096] = { 0 }; - if (buf[0] != '\0') - return buf; - - for (int i = 0; config_dirs[i].path; i++) { - struct dir d = config_dirs[i]; - if (!d.prefix) { - /* handle /etc/xdg... */ - snprintf(buf, sizeof(buf), "%s", d.path); - if (isdir(buf)) - return buf; - } else { - /* handle $HOME/.config/... and $XDG_* */ - char *prefix = getenv(d.prefix); - if (!prefix) - continue; - gchar **prefixes = g_strsplit(prefix, ":", -1); - for (gchar **p = prefixes; *p; p++) { - snprintf(buf, sizeof(buf), "%s/%s", *p, d.path); - if (isdir(buf)) - return buf; - } - } - } - /* no config directory was found */ - buf[0] = '.'; - buf[1] = '\0'; - return buf; -} diff --git a/src/config/meson.build b/src/config/meson.build index 97a67693..ac8e6012 100644 --- a/src/config/meson.build +++ b/src/config/meson.build @@ -1,5 +1,4 @@ labwc_sources += files( - 'config-dir.c', 'rcxml.c', 'keybind.c', ) diff --git a/src/config/rcxml.c b/src/config/rcxml.c index b5c86842..8b2c3698 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -12,7 +12,7 @@ #include "config/rcxml.h" #include "config/keybind.h" -#include "config/config-dir.h" +#include "common/dir.h" #include "common/bug-on.h" #include "common/font.h" diff --git a/src/theme/meson.build b/src/theme/meson.build index bbf34363..e7181a06 100644 --- a/src/theme/meson.build +++ b/src/theme/meson.build @@ -1,6 +1,5 @@ labwc_sources += files( 'theme.c', - 'theme-dir.c', ) subdir('xbm') diff --git a/src/theme/theme-dir.c b/src/theme/theme-dir.c deleted file mode 100644 index ee8b5842..00000000 --- a/src/theme/theme-dir.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Find the openbox theme directory - * - * Copyright Johan Malm 2020 - */ - -#include -#include -#include -#include -#include - -struct dir { - const char *prefix; - const char *path; -}; - -/* clang-format off */ -static struct dir theme_dirs[] = { - { "XDG_DATA_HOME", "themes" }, - { "HOME", ".local/share/themes" }, - { "HOME", ".themes" }, - { "XDG_DATA_DIRS", "themes" }, - { NULL, "/usr/share/themes" }, - { NULL, "/usr/local/share/themes" }, - { NULL, "opt/share/themes" }, - { NULL, NULL } -}; -/* clang-format on */ - -static bool isdir(const char *path) -{ - struct stat st; - return (!stat(path, &st) && S_ISDIR(st.st_mode)); -} - -char *theme_dir(const char *theme_name) -{ - static char buf[4096] = { 0 }; - if (buf[0] != '\0') - return buf; - - for (int i = 0; theme_dirs[i].path; i++) { - struct dir d = theme_dirs[i]; - if (!d.prefix) { - snprintf(buf, sizeof(buf), "%s/%s/openbox-3", d.path, - theme_name); - if (isdir(buf)) - return buf; - } else { - char *prefix = getenv(d.prefix); - if (!prefix) - continue; - gchar **prefixes = g_strsplit(prefix, ":", -1); - for (gchar **p = prefixes; *p; p++) { - snprintf(buf, sizeof(buf), - "%s/%s/%s/openbox-3", *p, d.path, - theme_name); - if (isdir(buf)) - return buf; - } - } - } - /* no config directory was found */ - buf[0] = '.'; - buf[1] = '\0'; - return buf; -} diff --git a/src/theme/theme.c b/src/theme/theme.c index 8175482d..c2ce6135 100644 --- a/src/theme/theme.c +++ b/src/theme/theme.c @@ -7,7 +7,7 @@ #include #include "theme/theme.h" -#include "theme/theme-dir.h" +#include "common/dir.h" static int hex_to_dec(char c) { diff --git a/src/theme/xbm/xbm.c b/src/theme/xbm/xbm.c index 92581146..d1256050 100644 --- a/src/theme/xbm/xbm.c +++ b/src/theme/xbm/xbm.c @@ -10,8 +10,8 @@ #include "theme/theme.h" #include "theme/xbm/xbm.h" #include "theme/xbm/parse.h" -#include "theme/theme-dir.h" #include "config/rcxml.h" +#include "common/dir.h" #include "common/grab-file.h" /* built-in 6x6 buttons */ diff --git a/tests/meson.build b/tests/meson.build index eedb43a9..44756a17 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -3,7 +3,7 @@ rcxml_lib = static_library( sources: files( '../src/config/rcxml.c', '../src/config/keybind.c', - '../src/config/config-dir.c', + '../src/common/dir.c', '../src/common/buf.c', '../src/common/font.c', ), diff --git a/tools/dirs/Makefile b/tools/dirs/Makefile new file mode 100644 index 00000000..3633b5c4 --- /dev/null +++ b/tools/dirs/Makefile @@ -0,0 +1,6 @@ +CFLAGS += -g -Wall -I../../include +CFLAGS += `pkg-config --cflags glib-2.0` +LDFLAGS += `pkg-config --libs glib-2.0` + +all: + $(CC) $(CFLAGS) -o dir-list dir-list.c ../../src/common/dir.c $(LDFLAGS) diff --git a/tools/dirs/dir-list b/tools/dirs/dir-list new file mode 100755 index 00000000..2dea97f3 Binary files /dev/null and b/tools/dirs/dir-list differ diff --git a/tools/dirs/dir-list.c b/tools/dirs/dir-list.c new file mode 100644 index 00000000..eb7eb00f --- /dev/null +++ b/tools/dirs/dir-list.c @@ -0,0 +1,12 @@ +#include +#include + +#include "common/dir.h" + +int main() +{ + setenv("LABWC_DEBUG_DIR_CONFIG_AND_THEME", "1", 1); + setenv("XDG_CONFIG_HOME", "/a:/bbb:/ccccc:/etc/foo", 1); + printf("%s\n", config_dir()); + printf("%s\n", theme_dir("Numix")); +} diff --git a/tools/rcxml/Makefile b/tools/rcxml/Makefile index 9973985e..c1ef9beb 100644 --- a/tools/rcxml/Makefile +++ b/tools/rcxml/Makefile @@ -6,14 +6,15 @@ ASAN_FLAGS = -O0 -fsanitize=address -fno-common -fno-omit-frame-pointer -rdynami CFLAGS += $(ASAN_FLAGS) LDFLAGS += $(ASAN_FLAGS) -fuse-ld=gold LDFLAGS += `xml2-config --libs` -LDFLAGS += `pkg-config --cflags --libs glib-2.0 wayland-server xkbcommon` +LDFLAGS += `pkg-config --cflags --libs glib-2.0 cairo pangocairo wayland-server xkbcommon` PROGS = rcxml-print-nodenames SRC = \ rcxml-print-nodenames.c \ ../../src/config/rcxml.c \ - ../../src/config/config-dir.c \ + ../../src/common/dir.c \ ../../src/common/buf.c \ + ../../src/common/font.c \ ../../src/config/keybind.c diff --git a/tools/theme/Makefile b/tools/theme/Makefile index 82492008..cbfeb893 100644 --- a/tools/theme/Makefile +++ b/tools/theme/Makefile @@ -10,7 +10,7 @@ LDFLAGS += -DWLR_USE_UNSTABLE SRCS = \ theme-helper.c \ ../../src/theme/theme.c \ - ../../src/theme/theme-dir.c + ../../src/common/dir.c all: gcc $(CFLAGS) -o theme-helper $(SRCS) $(LDFLAGS) diff --git a/tools/xbm/Makefile b/tools/xbm/Makefile index af07e3a2..938753d1 100644 --- a/tools/xbm/Makefile +++ b/tools/xbm/Makefile @@ -4,8 +4,14 @@ LDFLAGS += `pkg-config --cflags --libs cairo` ASAN += -fsanitize=address PROGS = xbm-tokenize xbm-parse -DEP_TOKENIZE = ../../src/common/buf.c ../../src/theme/xbm/tokenize.c -DEP_PARSE = $(DEP_TOKENIZE) ../../src/theme/xbm/parse.c + +DEP_TOKENIZE = \ + ../../src/common/buf.c \ + ../../src/theme/xbm/tokenize.c + +DEP_PARSE = $(DEP_TOKENIZE) \ + ../../src/theme/xbm/parse.c \ + ../../src/common/grab-file.c all: $(PROGS) diff --git a/tools/xbm/xbm-parse.c b/tools/xbm/xbm-parse.c index 71cd6aeb..5bdbf28f 100644 --- a/tools/xbm/xbm-parse.c +++ b/tools/xbm/xbm-parse.c @@ -4,6 +4,7 @@ #include #include "theme/xbm/parse.h" +#include "common/grab-file.h" int main(int argc, char **argv) { @@ -14,12 +15,12 @@ int main(int argc, char **argv) return 1; } - char *buffer = xbm_read_file(argv[1]); + char *buffer = grab_file(argv[1]); if (!buffer) exit(EXIT_FAILURE); - tokens = xbm_tokenize(buffer); + tokens = tokenize_xbm(buffer); free(buffer); - struct pixmap pixmap = xbm_create_pixmap(tokens); + struct pixmap pixmap = parse_xbm_tokens(tokens); free(tokens); cairo_surface_t *g_surface; diff --git a/tools/xbm/xbm-tokenize.c b/tools/xbm/xbm-tokenize.c index e5e6c06b..c299464b 100644 --- a/tools/xbm/xbm-tokenize.c +++ b/tools/xbm/xbm-tokenize.c @@ -3,7 +3,7 @@ #include #include -#include "buf.h" +#include "common/buf.h" #include "theme/xbm/tokenize.h" /* Read file into buffer, because it's easier to tokenize that way */ @@ -41,7 +41,7 @@ int main(int argc, char **argv) char *buffer = read_file(argv[1]); if (!buffer) exit(EXIT_FAILURE); - tokens = xbm_tokenize(buffer); + tokens = tokenize_xbm(buffer); free(buffer); for (struct token *t = tokens; t->type; t++) printf("%s\n", t->name);