From 8a42bc9184ba8d13210a019d1e5b999830e3e9bd Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 13 Jul 2020 20:09:34 +0100 Subject: [PATCH] xbm.c: refactor and load builtin icons as fallback --- include/theme/theme-dir.h | 6 +++ src/theme/meson.build | 1 + src/theme/theme-dir.c | 54 ++++++++++++++++++++++++++ src/theme/xbm/parse.c | 4 +- src/theme/xbm/tokenize.c | 4 ++ src/theme/xbm/xbm.c | 80 ++++++++++----------------------------- 6 files changed, 86 insertions(+), 63 deletions(-) create mode 100644 include/theme/theme-dir.h create mode 100644 src/theme/theme-dir.c diff --git a/include/theme/theme-dir.h b/include/theme/theme-dir.h new file mode 100644 index 00000000..87c5c3d0 --- /dev/null +++ b/include/theme/theme-dir.h @@ -0,0 +1,6 @@ +#ifndef THEME_DIR_H +#define THEME_DIR_H + +char *theme_dir(const char *theme_name); + +#endif /* THEME_DIR_H */ diff --git a/src/theme/meson.build b/src/theme/meson.build index e7181a06..bbf34363 100644 --- a/src/theme/meson.build +++ b/src/theme/meson.build @@ -1,5 +1,6 @@ labwc_sources += files( 'theme.c', + 'theme-dir.c', ) subdir('xbm') diff --git a/src/theme/theme-dir.c b/src/theme/theme-dir.c new file mode 100644 index 00000000..d2d90426 --- /dev/null +++ b/src/theme/theme-dir.c @@ -0,0 +1,54 @@ +/* + * Find the openbox theme directory + * + * Copyright Johan Malm 2020 + */ + +#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 */ + +char *theme_dir(const char *theme_name) +{ + static char buf[4096] = { 0 }; + if (buf[0] != '\0') + return buf; + + struct stat st; + for (int i = 0; theme_dirs[i].path; i++) { + char *prefix = NULL; + struct dir d = theme_dirs[i]; + if (d.prefix) { + prefix = getenv(d.prefix); + if (!prefix) + continue; + snprintf(buf, sizeof(buf), "%s/%s/%s/openbox-3", + prefix, d.path, theme_name); + } else { + snprintf(buf, sizeof(buf), "%s/%s/openbox-3", d.path, + theme_name); + } + if (!stat(buf, &st) && S_ISDIR(st.st_mode)) + return buf; + } + buf[0] = '\0'; + return buf; +} diff --git a/src/theme/xbm/parse.c b/src/theme/xbm/parse.c index 78e27b61..7cc25784 100644 --- a/src/theme/xbm/parse.c +++ b/src/theme/xbm/parse.c @@ -91,10 +91,8 @@ char *xbm_read_file(const char *filename) char *line = NULL; size_t len = 0; FILE *stream = fopen(filename, "r"); - if (!stream) { - fprintf(stderr, "warn: cannot read '%s'\n", filename); + if (!stream) return NULL; - } struct buf buffer; buf_init(&buffer); while ((getline(&line, &len, stream) != -1)) { diff --git a/src/theme/xbm/tokenize.c b/src/theme/xbm/tokenize.c index 8584dec5..52209dff 100644 --- a/src/theme/xbm/tokenize.c +++ b/src/theme/xbm/tokenize.c @@ -80,6 +80,10 @@ static void get_special_char_token() struct token *xbm_tokenize(char *buffer) { + tokens = NULL; + nr_tokens = 0; + alloc_tokens = 0; + current_buffer_position = buffer; for (;;) { diff --git a/src/theme/xbm/xbm.c b/src/theme/xbm/xbm.c index 5b90167a..937a18f8 100644 --- a/src/theme/xbm/xbm.c +++ b/src/theme/xbm/xbm.c @@ -6,28 +6,12 @@ #include #include -#include #include "theme/xbm/xbm.h" #include "theme/xbm/parse.h" +#include "theme/theme-dir.h" #include "rcxml.h" -struct dir { - const char *prefix; - const char *path; -}; - -static struct dir theme_dirs[] = { - { "XDG_DATA_HOME", "themes" }, - { "HOME", ".local/share/themes" }, - { "HOME", ".themes" }, - { "XDG_DATA_HOME", "themes" }, - { NULL, "/usr/share/themes" }, - { NULL, "/usr/local/share/themes" }, - { NULL, "opt/share/themes" }, - { NULL, NULL } -}; - /* built-in 6x6 buttons */ char close_button_normal[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 }; char iconify_button_normal[] = { 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f }; @@ -44,7 +28,7 @@ static struct wlr_texture *texture_from_pixmap(struct wlr_renderer *renderer, pixmap->height, pixmap->data); } -static struct wlr_texture *builtin(struct wlr_renderer *renderer, +static struct wlr_texture *texture_from_builtin(struct wlr_renderer *renderer, const char *button) { struct pixmap pixmap = xbm_create_pixmap_builtin(button); @@ -54,61 +38,37 @@ static struct wlr_texture *builtin(struct wlr_renderer *renderer, return texture; } -static char *theme_dir(void) -{ - static char buffer[4096] = { 0 }; - if (buffer[0] != '\0') - return buffer; - - struct stat st; - for (int i = 0; theme_dirs[i].path; i++) { - char *prefix = NULL; - struct dir d = theme_dirs[i]; - if (d.prefix) { - prefix = getenv(d.prefix); - if (!prefix) - continue; - snprintf(buffer, sizeof(buffer), "%s/%s/%s/openbox-3", - prefix, d.path, rc.theme_name); - } else { - snprintf(buffer, sizeof(buffer), "%s/%s/openbox-3", - d.path, rc.theme_name); - } - if (!stat(buffer, &st) && S_ISDIR(st.st_mode)) - return buffer; - } - buffer[0] = '\0'; - return buffer; -} - static char *xbm_path(const char *button) { static char buffer[4096] = { 0 }; - snprintf(buffer, sizeof(buffer), "%s/%s", theme_dir(), button); + snprintf(buffer, sizeof(buffer), "%s/%s", theme_dir(rc.theme_name), + button); return buffer; } -void xbm_load(struct wlr_renderer *renderer) +static void load_button(struct wlr_renderer *renderer, const char *filename, + struct wlr_texture **texture, char *button) { - struct token *tokens; - - char *buffer = xbm_read_file(xbm_path("close.xbm")); - if (!buffer) { - fprintf(stderr, "no buffer\n"); + char *buffer = xbm_read_file(xbm_path(filename)); + if (!buffer) goto out; - } - tokens = xbm_tokenize(buffer); + fprintf(stderr, "loading %s\n", filename); + struct token *tokens = xbm_tokenize(buffer); free(buffer); struct pixmap pixmap = xbm_create_pixmap(tokens); - theme.xbm_close = texture_from_pixmap(renderer, &pixmap); + *texture = texture_from_pixmap(renderer, &pixmap); if (tokens) free(tokens); if (pixmap.data) free(pixmap.data); - out: - if (!theme.xbm_close) - theme.xbm_close = builtin(renderer, close_button_normal); - theme.xbm_maximize = builtin(renderer, max_button_normal); - theme.xbm_iconify = builtin(renderer, iconify_button_normal); + if (!(*texture)) + *texture = texture_from_builtin(renderer, button); +} + +void xbm_load(struct wlr_renderer *r) +{ + load_button(r, "close.xbm", &theme.xbm_close, close_button_normal); + load_button(r, "max.xbm", &theme.xbm_maximize, max_button_normal); + load_button(r, "iconify.xbm", &theme.xbm_iconify, iconify_button_normal); }