mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	button: refactor xbm code
- Rename src/xbm/ to src/button/ - Combine xbm.c parse.c tokenize.c into button-xbm.c No functional change
This commit is contained in:
		
							parent
							
								
									3111c57d6f
								
							
						
					
					
						commit
						03bc2ada47
					
				
					 12 changed files with 315 additions and 391 deletions
				
			
		
							
								
								
									
										11
									
								
								include/button/button-xbm.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								include/button/button-xbm.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					#ifndef LABWC_BUTTON_XBM_H
 | 
				
			||||||
 | 
					#define LABWC_BUTTON_XBM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct lab_data_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* button_xbm_load - Convert xbm file to buffer with cairo surface */
 | 
				
			||||||
 | 
					void button_xbm_load(const char *filename, struct lab_data_buffer **buffer,
 | 
				
			||||||
 | 
						char *fallback_button, float *rgba);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* LABWC_BUTTON_XBM_H */
 | 
				
			||||||
| 
						 | 
					@ -1,38 +0,0 @@
 | 
				
			||||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Parse xbm token to create pixmap
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright Johan Malm 2020
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef LABWC_PARSE_H
 | 
					 | 
				
			||||||
#define LABWC_PARSE_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "xbm/tokenize.h"
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct pixmap {
 | 
					 | 
				
			||||||
	uint32_t *data;
 | 
					 | 
				
			||||||
	int width;
 | 
					 | 
				
			||||||
	int height;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * parse_set_color - set color to be used when parsing icons
 | 
					 | 
				
			||||||
 * @rgba: four floats representing red, green, blue, alpha
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void parse_set_color(float *rgba);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * parse_xbm_tokens - parse xbm tokens and create pixmap
 | 
					 | 
				
			||||||
 * @tokens: token vector
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct pixmap parse_xbm_tokens(struct token *tokens);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * parse_xbm_builtin - parse builtin xbm button and create pixmap
 | 
					 | 
				
			||||||
 * @button: button byte array (xbm format)
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct pixmap parse_xbm_builtin(const char *button, int size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* LABWC_PARSE_H */
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,34 +0,0 @@
 | 
				
			||||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * XBM file tokenizer
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright Johan Malm 2020
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef LABWC_TOKENIZE_H
 | 
					 | 
				
			||||||
#define LABWC_TOKENIZE_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum token_type {
 | 
					 | 
				
			||||||
	TOKEN_NONE = 0,
 | 
					 | 
				
			||||||
	TOKEN_IDENT,
 | 
					 | 
				
			||||||
	TOKEN_INT,
 | 
					 | 
				
			||||||
	TOKEN_SPECIAL,
 | 
					 | 
				
			||||||
	TOKEN_OTHER,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_TOKEN_SIZE (256)
 | 
					 | 
				
			||||||
struct token {
 | 
					 | 
				
			||||||
	char name[MAX_TOKEN_SIZE];
 | 
					 | 
				
			||||||
	int value;
 | 
					 | 
				
			||||||
	size_t pos;
 | 
					 | 
				
			||||||
	enum token_type type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * tokenize - tokenize xbm file
 | 
					 | 
				
			||||||
 * @buffer: buffer containing xbm file
 | 
					 | 
				
			||||||
 * return token vector
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct token *tokenize_xbm(char *buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* LABWC_TOKENIZE_H */
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,15 +0,0 @@
 | 
				
			||||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
					 | 
				
			||||||
#ifndef LABWC_XBM_H
 | 
					 | 
				
			||||||
#define LABWC_XBM_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <wlr/render/wlr_renderer.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "xbm/parse.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * xbm_load - load theme xbm files into global theme struct
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void xbm_load_button(const char *filename, struct lab_data_buffer **buffer,
 | 
					 | 
				
			||||||
	char *fallback_button, float *rgba);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* LABWC_XBM_H */
 | 
					 | 
				
			||||||
							
								
								
									
										297
									
								
								src/button/button-xbm.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								src/button/button-xbm.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,297 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0-only
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Convert xbm file to buffer with cairo surface
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright Johan Malm 2020-2023
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _POSIX_C_SOURCE 200809L
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <drm_fourcc.h>
 | 
				
			||||||
 | 
					#include "button/button-xbm.h"
 | 
				
			||||||
 | 
					#include "common/dir.h"
 | 
				
			||||||
 | 
					#include "common/grab-file.h"
 | 
				
			||||||
 | 
					#include "common/mem.h"
 | 
				
			||||||
 | 
					#include "config/rcxml.h"
 | 
				
			||||||
 | 
					#include "theme.h"
 | 
				
			||||||
 | 
					#include "buffer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum token_type {
 | 
				
			||||||
 | 
						TOKEN_NONE = 0,
 | 
				
			||||||
 | 
						TOKEN_IDENT,
 | 
				
			||||||
 | 
						TOKEN_INT,
 | 
				
			||||||
 | 
						TOKEN_SPECIAL,
 | 
				
			||||||
 | 
						TOKEN_OTHER,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_TOKEN_SIZE (256)
 | 
				
			||||||
 | 
					struct token {
 | 
				
			||||||
 | 
						char name[MAX_TOKEN_SIZE];
 | 
				
			||||||
 | 
						int value;
 | 
				
			||||||
 | 
						size_t pos;
 | 
				
			||||||
 | 
						enum token_type type;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pixmap {
 | 
				
			||||||
 | 
						uint32_t *data;
 | 
				
			||||||
 | 
						int width;
 | 
				
			||||||
 | 
						int height;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t color;
 | 
				
			||||||
 | 
					static char *current_buffer_position;
 | 
				
			||||||
 | 
					static struct token *tokens;
 | 
				
			||||||
 | 
					static int nr_tokens, alloc_tokens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					add_token(enum token_type token_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (nr_tokens == alloc_tokens) {
 | 
				
			||||||
 | 
							alloc_tokens = (alloc_tokens + 16) * 2;
 | 
				
			||||||
 | 
							tokens = xrealloc(tokens, alloc_tokens * sizeof(struct token));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						struct token *token = tokens + nr_tokens;
 | 
				
			||||||
 | 
						memset(token, 0, sizeof(*token));
 | 
				
			||||||
 | 
						nr_tokens++;
 | 
				
			||||||
 | 
						token->type = token_type;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					get_identifier_token(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct token *token = tokens + nr_tokens - 1;
 | 
				
			||||||
 | 
						token->name[token->pos] = current_buffer_position[0];
 | 
				
			||||||
 | 
						token->pos++;
 | 
				
			||||||
 | 
						if (token->pos == MAX_TOKEN_SIZE - 1) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						current_buffer_position++;
 | 
				
			||||||
 | 
						switch (current_buffer_position[0]) {
 | 
				
			||||||
 | 
						case '\0':
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						case 'a' ... 'z':
 | 
				
			||||||
 | 
						case 'A' ... 'Z':
 | 
				
			||||||
 | 
						case '0' ... '9':
 | 
				
			||||||
 | 
						case '_':
 | 
				
			||||||
 | 
						case '#':
 | 
				
			||||||
 | 
							get_identifier_token();
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					get_number_token(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct token *token = tokens + nr_tokens - 1;
 | 
				
			||||||
 | 
						token->name[token->pos] = current_buffer_position[0];
 | 
				
			||||||
 | 
						token->pos++;
 | 
				
			||||||
 | 
						if (token->pos == MAX_TOKEN_SIZE - 1) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						current_buffer_position++;
 | 
				
			||||||
 | 
						switch (current_buffer_position[0]) {
 | 
				
			||||||
 | 
						case '\0':
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						case '0' ... '9':
 | 
				
			||||||
 | 
						case 'a' ... 'f':
 | 
				
			||||||
 | 
						case 'A' ... 'F':
 | 
				
			||||||
 | 
						case 'x':
 | 
				
			||||||
 | 
							get_number_token();
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					get_special_char_token(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct token *token = tokens + nr_tokens - 1;
 | 
				
			||||||
 | 
						token->name[0] = current_buffer_position[0];
 | 
				
			||||||
 | 
						current_buffer_position++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tokenize_xbm - tokenize xbm file
 | 
				
			||||||
 | 
					 * @buffer: buffer containing xbm file
 | 
				
			||||||
 | 
					 * return token vector
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static struct token *
 | 
				
			||||||
 | 
					tokenize_xbm(char *buffer)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						tokens = NULL;
 | 
				
			||||||
 | 
						nr_tokens = 0;
 | 
				
			||||||
 | 
						alloc_tokens = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						current_buffer_position = buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							switch (current_buffer_position[0]) {
 | 
				
			||||||
 | 
							case '\0':
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							case 'a' ... 'z':
 | 
				
			||||||
 | 
							case 'A' ... 'Z':
 | 
				
			||||||
 | 
							case '_':
 | 
				
			||||||
 | 
							case '#':
 | 
				
			||||||
 | 
								add_token(TOKEN_IDENT);
 | 
				
			||||||
 | 
								get_identifier_token();
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							case '0' ... '9':
 | 
				
			||||||
 | 
								add_token(TOKEN_INT);
 | 
				
			||||||
 | 
								get_number_token();
 | 
				
			||||||
 | 
								struct token *token = tokens + nr_tokens - 1;
 | 
				
			||||||
 | 
								token->value = (int)strtol(token->name, NULL, 0);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							case '{':
 | 
				
			||||||
 | 
								add_token(TOKEN_SPECIAL);
 | 
				
			||||||
 | 
								get_special_char_token();
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							++current_buffer_position;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						add_token(TOKEN_NONE); /* vector end marker */
 | 
				
			||||||
 | 
						return tokens;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t
 | 
				
			||||||
 | 
					u32(float *rgba)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t r[4] = { 0 };
 | 
				
			||||||
 | 
						for (int i = 0; i < 4; i++) {
 | 
				
			||||||
 | 
							r[i] = rgba[i] * 255;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ((r[3] & 0xff) << 24) | ((r[0] & 0xff) << 16) |
 | 
				
			||||||
 | 
							((r[1] & 0xff) << 8) | (r[2] & 0xff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					process_bytes(struct pixmap *pixmap, struct token *tokens)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pixmap->data = znew_n(uint32_t, pixmap->width * pixmap->height);
 | 
				
			||||||
 | 
						struct token *t = tokens;
 | 
				
			||||||
 | 
						for (int row = 0; row < pixmap->height; row++) {
 | 
				
			||||||
 | 
							int byte = 1;
 | 
				
			||||||
 | 
							for (int col = 0; col < pixmap->width; col++) {
 | 
				
			||||||
 | 
								if (col == byte * 8) {
 | 
				
			||||||
 | 
									++byte;
 | 
				
			||||||
 | 
									++t;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (!t->type) {
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (t->type != TOKEN_INT) {
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								int bit = 1 << (col % 8);
 | 
				
			||||||
 | 
								if (t->value & bit) {
 | 
				
			||||||
 | 
									pixmap->data[row * pixmap->width + col] = color;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							++t;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * parse_xbm_tokens - parse xbm tokens and create pixmap
 | 
				
			||||||
 | 
					 * @tokens: token vector
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static struct pixmap
 | 
				
			||||||
 | 
					parse_xbm_tokens(struct token *tokens)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pixmap pixmap = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (struct token *t = tokens; t->type; t++) {
 | 
				
			||||||
 | 
							if (pixmap.width && pixmap.height) {
 | 
				
			||||||
 | 
								if (t->type != TOKEN_INT) {
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								process_bytes(&pixmap, t);
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (strstr(t->name, "width")) {
 | 
				
			||||||
 | 
								pixmap.width = atoi((++t)->name);
 | 
				
			||||||
 | 
							} else if (strstr(t->name, "height")) {
 | 
				
			||||||
 | 
								pixmap.height = atoi((++t)->name);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return pixmap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Openbox built-in icons are not bigger than 8x8, so have only written this
 | 
				
			||||||
 | 
					 * function to cope wit that max size
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define LABWC_BUILTIN_ICON_MAX_SIZE (8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * parse_xbm_builtin - parse builtin xbm button and create pixmap
 | 
				
			||||||
 | 
					 * @button: button byte array (xbm format)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static struct pixmap
 | 
				
			||||||
 | 
					parse_xbm_builtin(const char *button, int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pixmap pixmap = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(size <= LABWC_BUILTIN_ICON_MAX_SIZE);
 | 
				
			||||||
 | 
						pixmap.width = size;
 | 
				
			||||||
 | 
						pixmap.height = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct token t[LABWC_BUILTIN_ICON_MAX_SIZE + 1];
 | 
				
			||||||
 | 
						for (int i = 0; i < size; i++) {
 | 
				
			||||||
 | 
							t[i].value = button[i];
 | 
				
			||||||
 | 
							t[i].type = TOKEN_INT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t[size].type = 0;
 | 
				
			||||||
 | 
						process_bytes(&pixmap, t);
 | 
				
			||||||
 | 
						return pixmap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *
 | 
				
			||||||
 | 
					xbm_path(const char *button)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char buffer[4096] = { 0 };
 | 
				
			||||||
 | 
						snprintf(buffer, sizeof(buffer), "%s/%s", theme_dir(rc.theme_name), button);
 | 
				
			||||||
 | 
						return buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					button_xbm_load(const char *filename, struct lab_data_buffer **buffer,
 | 
				
			||||||
 | 
							char *fallback_button, float *rgba)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pixmap pixmap = {0};
 | 
				
			||||||
 | 
						if (*buffer) {
 | 
				
			||||||
 | 
							wlr_buffer_drop(&(*buffer)->base);
 | 
				
			||||||
 | 
							*buffer = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						color = u32(rgba);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Read file into memory as it's easier to tokenzie that way */
 | 
				
			||||||
 | 
						char *token_buffer = grab_file(xbm_path(filename));
 | 
				
			||||||
 | 
						if (token_buffer) {
 | 
				
			||||||
 | 
							struct token *tokens = tokenize_xbm(token_buffer);
 | 
				
			||||||
 | 
							free(token_buffer);
 | 
				
			||||||
 | 
							pixmap = parse_xbm_tokens(tokens);
 | 
				
			||||||
 | 
							if (tokens) {
 | 
				
			||||||
 | 
								free(tokens);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!pixmap.data) {
 | 
				
			||||||
 | 
							pixmap = parse_xbm_builtin(fallback_button, 6);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Create buffer with free_on_destroy being true */
 | 
				
			||||||
 | 
						*buffer = buffer_create_wrap(pixmap.data, pixmap.width, pixmap.height,
 | 
				
			||||||
 | 
							pixmap.width * 4, true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								src/button/meson.build
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/button/meson.build
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					labwc_sources += files(
 | 
				
			||||||
 | 
					  'button-xbm.c',
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,6 @@ endif
 | 
				
			||||||
subdir('common')
 | 
					subdir('common')
 | 
				
			||||||
subdir('config')
 | 
					subdir('config')
 | 
				
			||||||
subdir('decorations')
 | 
					subdir('decorations')
 | 
				
			||||||
subdir('xbm')
 | 
					subdir('button')
 | 
				
			||||||
subdir('menu')
 | 
					subdir('menu')
 | 
				
			||||||
subdir('ssd')
 | 
					subdir('ssd')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,8 +25,8 @@
 | 
				
			||||||
#include "common/string-helpers.h"
 | 
					#include "common/string-helpers.h"
 | 
				
			||||||
#include "config/rcxml.h"
 | 
					#include "config/rcxml.h"
 | 
				
			||||||
#include "button-png.h"
 | 
					#include "button-png.h"
 | 
				
			||||||
 | 
					#include "button/button-xbm.h"
 | 
				
			||||||
#include "theme.h"
 | 
					#include "theme.h"
 | 
				
			||||||
#include "xbm/xbm.h"
 | 
					 | 
				
			||||||
#include "buffer.h"
 | 
					#include "buffer.h"
 | 
				
			||||||
#include "ssd.h"
 | 
					#include "ssd.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,11 +106,11 @@ load_buttons(struct theme *theme)
 | 
				
			||||||
		/* If there were no png buttons, use xbm */
 | 
							/* If there were no png buttons, use xbm */
 | 
				
			||||||
		snprintf(filename, sizeof(filename), "%s.xbm", b->name);
 | 
							snprintf(filename, sizeof(filename), "%s.xbm", b->name);
 | 
				
			||||||
		if (!*b->active.buffer) {
 | 
							if (!*b->active.buffer) {
 | 
				
			||||||
			xbm_load_button(filename, b->active.buffer,
 | 
								button_xbm_load(filename, b->active.buffer,
 | 
				
			||||||
				b->fallback_button, b->active.rgba);
 | 
									b->fallback_button, b->active.rgba);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!*b->inactive.buffer) {
 | 
							if (!*b->inactive.buffer) {
 | 
				
			||||||
			xbm_load_button(filename, b->inactive.buffer,
 | 
								button_xbm_load(filename, b->inactive.buffer,
 | 
				
			||||||
				b->fallback_button, b->inactive.rgba);
 | 
									b->fallback_button, b->inactive.rgba);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +0,0 @@
 | 
				
			||||||
labwc_sources += files(
 | 
					 | 
				
			||||||
  'parse.c',
 | 
					 | 
				
			||||||
  'tokenize.c',
 | 
					 | 
				
			||||||
  'xbm.c',
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										110
									
								
								src/xbm/parse.c
									
										
									
									
									
								
							
							
						
						
									
										110
									
								
								src/xbm/parse.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,110 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: GPL-2.0-only
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Parse xbm token to create pixmap
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright Johan Malm 2020
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define _POSIX_C_SOURCE 200809L
 | 
					 | 
				
			||||||
#include <assert.h>
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "common/mem.h"
 | 
					 | 
				
			||||||
#include "xbm/parse.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint32_t color;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint32_t
 | 
					 | 
				
			||||||
u32(float *rgba)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint32_t r[4] = { 0 };
 | 
					 | 
				
			||||||
	for (int i = 0; i < 4; i++) {
 | 
					 | 
				
			||||||
		r[i] = rgba[i] * 255;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ((r[3] & 0xff) << 24) | ((r[0] & 0xff) << 16) |
 | 
					 | 
				
			||||||
		((r[1] & 0xff) << 8) | (r[2] & 0xff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
parse_set_color(float *rgba)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	color = u32(rgba);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
process_bytes(struct pixmap *pixmap, struct token *tokens)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	pixmap->data = znew_n(uint32_t, pixmap->width * pixmap->height);
 | 
					 | 
				
			||||||
	struct token *t = tokens;
 | 
					 | 
				
			||||||
	for (int row = 0; row < pixmap->height; row++) {
 | 
					 | 
				
			||||||
		int byte = 1;
 | 
					 | 
				
			||||||
		for (int col = 0; col < pixmap->width; col++) {
 | 
					 | 
				
			||||||
			if (col == byte * 8) {
 | 
					 | 
				
			||||||
				++byte;
 | 
					 | 
				
			||||||
				++t;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (!t->type) {
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (t->type != TOKEN_INT) {
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			int bit = 1 << (col % 8);
 | 
					 | 
				
			||||||
			if (t->value & bit) {
 | 
					 | 
				
			||||||
				pixmap->data[row * pixmap->width + col] = color;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		++t;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct pixmap
 | 
					 | 
				
			||||||
parse_xbm_tokens(struct token *tokens)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct pixmap pixmap = { 0 };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (struct token *t = tokens; t->type; t++) {
 | 
					 | 
				
			||||||
		if (pixmap.width && pixmap.height) {
 | 
					 | 
				
			||||||
			if (t->type != TOKEN_INT) {
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			process_bytes(&pixmap, t);
 | 
					 | 
				
			||||||
			goto out;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (strstr(t->name, "width")) {
 | 
					 | 
				
			||||||
			pixmap.width = atoi((++t)->name);
 | 
					 | 
				
			||||||
		} else if (strstr(t->name, "height")) {
 | 
					 | 
				
			||||||
			pixmap.height = atoi((++t)->name);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	return pixmap;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Openbox built-in icons are not bigger than 8x8, so have only written this
 | 
					 | 
				
			||||||
 * function to cope wit that max size
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define LABWC_BUILTIN_ICON_MAX_SIZE (8)
 | 
					 | 
				
			||||||
struct pixmap
 | 
					 | 
				
			||||||
parse_xbm_builtin(const char *button, int size)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct pixmap pixmap = { 0 };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	assert(size <= LABWC_BUILTIN_ICON_MAX_SIZE);
 | 
					 | 
				
			||||||
	pixmap.width = size;
 | 
					 | 
				
			||||||
	pixmap.height = size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct token t[LABWC_BUILTIN_ICON_MAX_SIZE + 1];
 | 
					 | 
				
			||||||
	for (int i = 0; i < size; i++) {
 | 
					 | 
				
			||||||
		t[i].value = button[i];
 | 
					 | 
				
			||||||
		t[i].type = TOKEN_INT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t[size].type = 0;
 | 
					 | 
				
			||||||
	process_bytes(&pixmap, t);
 | 
					 | 
				
			||||||
	return pixmap;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,127 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: GPL-2.0-only
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * XBM file tokenizer
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright Johan Malm 2020
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "common/mem.h"
 | 
					 | 
				
			||||||
#include "xbm/tokenize.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char *current_buffer_position;
 | 
					 | 
				
			||||||
static struct token *tokens;
 | 
					 | 
				
			||||||
static int nr_tokens, alloc_tokens;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
add_token(enum token_type token_type)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (nr_tokens == alloc_tokens) {
 | 
					 | 
				
			||||||
		alloc_tokens = (alloc_tokens + 16) * 2;
 | 
					 | 
				
			||||||
		tokens = xrealloc(tokens, alloc_tokens * sizeof(struct token));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	struct token *token = tokens + nr_tokens;
 | 
					 | 
				
			||||||
	memset(token, 0, sizeof(*token));
 | 
					 | 
				
			||||||
	nr_tokens++;
 | 
					 | 
				
			||||||
	token->type = token_type;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
get_identifier_token(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct token *token = tokens + nr_tokens - 1;
 | 
					 | 
				
			||||||
	token->name[token->pos] = current_buffer_position[0];
 | 
					 | 
				
			||||||
	token->pos++;
 | 
					 | 
				
			||||||
	if (token->pos == MAX_TOKEN_SIZE - 1) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	current_buffer_position++;
 | 
					 | 
				
			||||||
	switch (current_buffer_position[0]) {
 | 
					 | 
				
			||||||
	case '\0':
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	case 'a' ... 'z':
 | 
					 | 
				
			||||||
	case 'A' ... 'Z':
 | 
					 | 
				
			||||||
	case '0' ... '9':
 | 
					 | 
				
			||||||
	case '_':
 | 
					 | 
				
			||||||
	case '#':
 | 
					 | 
				
			||||||
		get_identifier_token();
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
get_number_token(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct token *token = tokens + nr_tokens - 1;
 | 
					 | 
				
			||||||
	token->name[token->pos] = current_buffer_position[0];
 | 
					 | 
				
			||||||
	token->pos++;
 | 
					 | 
				
			||||||
	if (token->pos == MAX_TOKEN_SIZE - 1) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	current_buffer_position++;
 | 
					 | 
				
			||||||
	switch (current_buffer_position[0]) {
 | 
					 | 
				
			||||||
	case '\0':
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	case '0' ... '9':
 | 
					 | 
				
			||||||
	case 'a' ... 'f':
 | 
					 | 
				
			||||||
	case 'A' ... 'F':
 | 
					 | 
				
			||||||
	case 'x':
 | 
					 | 
				
			||||||
		get_number_token();
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
get_special_char_token(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct token *token = tokens + nr_tokens - 1;
 | 
					 | 
				
			||||||
	token->name[0] = current_buffer_position[0];
 | 
					 | 
				
			||||||
	current_buffer_position++;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct token *
 | 
					 | 
				
			||||||
tokenize_xbm(char *buffer)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	tokens = NULL;
 | 
					 | 
				
			||||||
	nr_tokens = 0;
 | 
					 | 
				
			||||||
	alloc_tokens = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	current_buffer_position = buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (;;) {
 | 
					 | 
				
			||||||
		switch (current_buffer_position[0]) {
 | 
					 | 
				
			||||||
		case '\0':
 | 
					 | 
				
			||||||
			goto out;
 | 
					 | 
				
			||||||
		case 'a' ... 'z':
 | 
					 | 
				
			||||||
		case 'A' ... 'Z':
 | 
					 | 
				
			||||||
		case '_':
 | 
					 | 
				
			||||||
		case '#':
 | 
					 | 
				
			||||||
			add_token(TOKEN_IDENT);
 | 
					 | 
				
			||||||
			get_identifier_token();
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		case '0' ... '9':
 | 
					 | 
				
			||||||
			add_token(TOKEN_INT);
 | 
					 | 
				
			||||||
			get_number_token();
 | 
					 | 
				
			||||||
			struct token *token = tokens + nr_tokens - 1;
 | 
					 | 
				
			||||||
			token->value = (int)strtol(token->name, NULL, 0);
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		case '{':
 | 
					 | 
				
			||||||
			add_token(TOKEN_SPECIAL);
 | 
					 | 
				
			||||||
			get_special_char_token();
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		++current_buffer_position;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	add_token(TOKEN_NONE); /* vector end marker */
 | 
					 | 
				
			||||||
	return tokens;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,58 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: GPL-2.0-only
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Create wlr textures based on xbm data
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright Johan Malm 2020-2023
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <drm_fourcc.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "common/dir.h"
 | 
					 | 
				
			||||||
#include "common/grab-file.h"
 | 
					 | 
				
			||||||
#include "config/rcxml.h"
 | 
					 | 
				
			||||||
#include "theme.h"
 | 
					 | 
				
			||||||
#include "xbm/parse.h"
 | 
					 | 
				
			||||||
#include "xbm/xbm.h"
 | 
					 | 
				
			||||||
#include "buffer.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char *
 | 
					 | 
				
			||||||
xbm_path(const char *button)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	static char buffer[4096] = { 0 };
 | 
					 | 
				
			||||||
	snprintf(buffer, sizeof(buffer), "%s/%s",
 | 
					 | 
				
			||||||
		theme_dir(rc.theme_name), button);
 | 
					 | 
				
			||||||
	return buffer;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
xbm_load_button(const char *filename, struct lab_data_buffer **buffer,
 | 
					 | 
				
			||||||
		char *fallback_button, float *rgba)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct pixmap pixmap = {0};
 | 
					 | 
				
			||||||
	if (*buffer) {
 | 
					 | 
				
			||||||
		wlr_buffer_drop(&(*buffer)->base);
 | 
					 | 
				
			||||||
		*buffer = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	parse_set_color(rgba);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Read file into memory as it's easier to tokenzie that way */
 | 
					 | 
				
			||||||
	char *token_buffer = grab_file(xbm_path(filename));
 | 
					 | 
				
			||||||
	if (token_buffer) {
 | 
					 | 
				
			||||||
		struct token *tokens = tokenize_xbm(token_buffer);
 | 
					 | 
				
			||||||
		free(token_buffer);
 | 
					 | 
				
			||||||
		pixmap = parse_xbm_tokens(tokens);
 | 
					 | 
				
			||||||
		if (tokens) {
 | 
					 | 
				
			||||||
			free(tokens);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!pixmap.data) {
 | 
					 | 
				
			||||||
		pixmap = parse_xbm_builtin(fallback_button, 6);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create buffer with free_on_destroy being true */
 | 
					 | 
				
			||||||
	*buffer = buffer_create_wrap(pixmap.data, pixmap.width, pixmap.height,
 | 
					 | 
				
			||||||
		pixmap.width * 4, true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue