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(
 | 
					labwc_sources += files(
 | 
				
			||||||
  'theme.c',
 | 
					  'theme.c',
 | 
				
			||||||
 | 
					  'theme-dir.c',
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
subdir('xbm')
 | 
					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;
 | 
						char *line = NULL;
 | 
				
			||||||
	size_t len = 0;
 | 
						size_t len = 0;
 | 
				
			||||||
	FILE *stream = fopen(filename, "r");
 | 
						FILE *stream = fopen(filename, "r");
 | 
				
			||||||
	if (!stream) {
 | 
						if (!stream)
 | 
				
			||||||
		fprintf(stderr, "warn: cannot read '%s'\n", filename);
 | 
					 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	struct buf buffer;
 | 
						struct buf buffer;
 | 
				
			||||||
	buf_init(&buffer);
 | 
						buf_init(&buffer);
 | 
				
			||||||
	while ((getline(&line, &len, stream) != -1)) {
 | 
						while ((getline(&line, &len, stream) != -1)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,6 +80,10 @@ static void get_special_char_token()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct token *xbm_tokenize(char *buffer)
 | 
					struct token *xbm_tokenize(char *buffer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						tokens = NULL;
 | 
				
			||||||
 | 
						nr_tokens = 0;
 | 
				
			||||||
 | 
						alloc_tokens = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	current_buffer_position = buffer;
 | 
						current_buffer_position = buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,28 +6,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "theme/xbm/xbm.h"
 | 
					#include "theme/xbm/xbm.h"
 | 
				
			||||||
#include "theme/xbm/parse.h"
 | 
					#include "theme/xbm/parse.h"
 | 
				
			||||||
 | 
					#include "theme/theme-dir.h"
 | 
				
			||||||
#include "rcxml.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 */
 | 
					/* built-in 6x6 buttons */
 | 
				
			||||||
char close_button_normal[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 };
 | 
					char close_button_normal[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 };
 | 
				
			||||||
char iconify_button_normal[] = { 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f };
 | 
					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);
 | 
									       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)
 | 
									   const char *button)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pixmap pixmap = xbm_create_pixmap_builtin(button);
 | 
						struct pixmap pixmap = xbm_create_pixmap_builtin(button);
 | 
				
			||||||
| 
						 | 
					@ -54,61 +38,37 @@ static struct wlr_texture *builtin(struct wlr_renderer *renderer,
 | 
				
			||||||
	return texture;
 | 
						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 *xbm_path(const char *button)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char buffer[4096] = { 0 };
 | 
						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;
 | 
						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(filename));
 | 
				
			||||||
 | 
						if (!buffer)
 | 
				
			||||||
	char *buffer = xbm_read_file(xbm_path("close.xbm"));
 | 
					 | 
				
			||||||
	if (!buffer) {
 | 
					 | 
				
			||||||
		fprintf(stderr, "no buffer\n");
 | 
					 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						fprintf(stderr, "loading %s\n", filename);
 | 
				
			||||||
	tokens = xbm_tokenize(buffer);
 | 
						struct token *tokens = xbm_tokenize(buffer);
 | 
				
			||||||
	free(buffer);
 | 
						free(buffer);
 | 
				
			||||||
	struct pixmap pixmap = xbm_create_pixmap(tokens);
 | 
						struct pixmap pixmap = xbm_create_pixmap(tokens);
 | 
				
			||||||
	theme.xbm_close = texture_from_pixmap(renderer, &pixmap);
 | 
						*texture = texture_from_pixmap(renderer, &pixmap);
 | 
				
			||||||
	if (tokens)
 | 
						if (tokens)
 | 
				
			||||||
		free(tokens);
 | 
							free(tokens);
 | 
				
			||||||
	if (pixmap.data)
 | 
						if (pixmap.data)
 | 
				
			||||||
		free(pixmap.data);
 | 
							free(pixmap.data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	if (!theme.xbm_close)
 | 
						if (!(*texture))
 | 
				
			||||||
		theme.xbm_close = builtin(renderer, close_button_normal);
 | 
							*texture = texture_from_builtin(renderer, button);
 | 
				
			||||||
	theme.xbm_maximize = builtin(renderer, max_button_normal);
 | 
					}
 | 
				
			||||||
	theme.xbm_iconify = builtin(renderer, iconify_button_normal);
 | 
					
 | 
				
			||||||
 | 
					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