--- /dev/null
+/* 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 */
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 */
--- /dev/null
+// 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);
+}
--- /dev/null
+labwc_sources += files(
+ 'button-xbm.c',
+)
subdir('common')
subdir('config')
subdir('decorations')
-subdir('xbm')
+subdir('button')
subdir('menu')
subdir('ssd')
#include "common/string-helpers.h"
#include "config/rcxml.h"
#include "button-png.h"
+#include "button/button-xbm.h"
#include "theme.h"
-#include "xbm/xbm.h"
#include "buffer.h"
#include "ssd.h"
/* If there were no png buttons, use xbm */
snprintf(filename, sizeof(filename), "%s.xbm", b->name);
if (!*b->active.buffer) {
- xbm_load_button(filename, b->active.buffer,
+ button_xbm_load(filename, b->active.buffer,
b->fallback_button, b->active.rgba);
}
if (!*b->inactive.buffer) {
- xbm_load_button(filename, b->inactive.buffer,
+ button_xbm_load(filename, b->inactive.buffer,
b->fallback_button, b->inactive.rgba);
}
}
+++ /dev/null
-labwc_sources += files(
- 'parse.c',
- 'tokenize.c',
- 'xbm.c',
-)
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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);
-}