mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	xbm.c: refactor and load builtin icons as fallback
This commit is contained in:
		
							parent
							
								
									1330071e0c
								
							
						
					
					
						commit
						8a42bc9184
					
				
					 6 changed files with 86 additions and 63 deletions
				
			
		
							
								
								
									
										6
									
								
								include/theme/theme-dir.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/theme/theme-dir.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
#ifndef THEME_DIR_H
 | 
			
		||||
#define THEME_DIR_H
 | 
			
		||||
 | 
			
		||||
char *theme_dir(const char *theme_name);
 | 
			
		||||
 | 
			
		||||
#endif /* THEME_DIR_H */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
labwc_sources += files(
 | 
			
		||||
  'theme.c',
 | 
			
		||||
  'theme-dir.c',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
subdir('xbm')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										54
									
								
								src/theme/theme-dir.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/theme/theme-dir.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Find the openbox theme directory
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright Johan Malm 2020
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 (;;) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,28 +6,12 @@
 | 
			
		|||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue