From: Johan Malm Date: Mon, 29 Jun 2020 18:27:59 +0000 (+0100) Subject: Render window close button X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=baca410560745febb574a00d8438aa9d43952500;p=proto%2Flabwc.git Render window close button --- diff --git a/include/labwc.h b/include/labwc.h index f8202fcc..2de3da6b 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -1,7 +1,7 @@ #ifndef LABWC_H #define LABWC_H -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200809L #include #include #include @@ -93,7 +93,8 @@ struct output { enum view_type { LAB_XDG_SHELL_VIEW, LAB_XWAYLAND_VIEW }; enum deco_part { - LAB_DECO_PART_TITLE = 0, + LAB_DECO_ICON_CLOSE = 0, + LAB_DECO_PART_TITLE, LAB_DECO_PART_TOP, LAB_DECO_PART_RIGHT, LAB_DECO_PART_BOTTOM, diff --git a/include/theme.h b/include/theme.h index ed39a092..827c31ce 100644 --- a/include/theme.h +++ b/include/theme.h @@ -1,12 +1,20 @@ +/* + * Theme engine for labwc - trying to be consistent with openbox + * + * Copyright Johan Malm 2020 + */ + #ifndef THEME_H #define THEME_H #include +#include struct theme { float window_active_title_bg_color[4]; float window_active_handle_bg_color[4]; float window_inactive_title_bg_color[4]; + struct wlr_texture *xbm_close; }; extern struct theme theme; diff --git a/include/theme/xbm/parse.h b/include/theme/xbm/parse.h new file mode 100644 index 00000000..faaffe02 --- /dev/null +++ b/include/theme/xbm/parse.h @@ -0,0 +1,25 @@ +/* + * Parse xbm token to create pixmap + * + * Copyright Johan Malm 2020 + */ + +#ifndef PARSE_H +#define PARSE_H + +#include +#include "theme/xbm/tokenize.h" + +struct pixmap { + uint32_t *data; + int width; + int height; +}; + +/** + * xbm_create_pixmap - parse xbm tokens and create pixmap + * @tokens: token vector + */ +struct pixmap xbm_create_pixmap(struct token *tokens); + +#endif /* PARSE_H */ diff --git a/include/xbm.h b/include/theme/xbm/tokenize.h similarity index 72% rename from include/xbm.h rename to include/theme/xbm/tokenize.h index 370f87b6..3a32b670 100644 --- a/include/xbm.h +++ b/include/theme/xbm/tokenize.h @@ -1,7 +1,11 @@ -#ifndef XBM_H -#define XBM_H +/* + * XBM file tokenizer + * + * Copyright Johan Malm 2020 + */ -#include +#ifndef TOKENIZE_H +#define TOKENIZE_H enum token_type { TOKEN_NONE = 0, @@ -18,12 +22,6 @@ struct token { enum token_type type; }; -/** - * xbm_create_bitmap - parse xbm tokens and create pixmap - * @tokens: token vector - */ -cairo_surface_t *xbm_create_bitmap(struct token *tokens); - /** * tokenize - tokenize xbm file * @buffer: buffer containing xbm file @@ -38,4 +36,4 @@ struct token *xbm_tokenize(char *buffer); */ char *xbm_read_file(const char *filename); -#endif /* XBM_H */ +#endif /* TOKENIZE_H */ diff --git a/include/theme/xbm/xbm.h b/include/theme/xbm/xbm.h new file mode 100644 index 00000000..7e7670ed --- /dev/null +++ b/include/theme/xbm/xbm.h @@ -0,0 +1,14 @@ +#ifndef XBM_H +#define XBM_H + +#include + +#include "theme.h" +#include "theme/xbm/parse.h" + +/** + * xbm_load - load theme xbm files into global theme struct + */ +void xbm_load(struct wlr_renderer *renderer); + +#endif /* XBM_H */ diff --git a/meson.build b/meson.build index 62a89284..c26a64e5 100644 --- a/meson.build +++ b/meson.build @@ -42,6 +42,8 @@ wayland_protos = dependency('wayland-protocols') xkbcommon = dependency('xkbcommon') xml2 = dependency('libxml-2.0') glib = dependency('glib-2.0') +cairo = dependency('cairo') +pango = dependency('pango') labwc_inc = include_directories('include') @@ -50,7 +52,7 @@ subdir('src') subdir('tests') labwc_deps = [ - server_protos, wayland_server, wlroots, xkbcommon, xml2, glib + server_protos, wayland_server, wlroots, xkbcommon, xml2, glib, cairo, pango ] executable( diff --git a/src/deco.c b/src/deco.c index 56235faf..824f65ab 100644 --- a/src/deco.c +++ b/src/deco.c @@ -1,3 +1,9 @@ +/* + * Helpers for handling window decorations + * + * Copyright Johan Malm 2020 + */ + #include "labwc.h" struct wlr_box deco_max_extents(struct view *view) @@ -18,6 +24,12 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part) if (!view || !view->surface) return box; switch (deco_part) { + case LAB_DECO_ICON_CLOSE: + box.x = view->x + view->surface->current.width - 8 - 1; + box.y = view->y - XWL_TITLEBAR_HEIGHT + 1; + box.width = 8; + box.height = 8; + break; case LAB_DECO_PART_TITLE: box.x = view->x; box.y = view->y - XWL_TITLEBAR_HEIGHT; diff --git a/src/main.c b/src/main.c index 9f64419b..832bcf57 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include "labwc.h" #include "theme.h" #include "spawn.h" +#include "theme/xbm/xbm.h" struct server server = { 0 }; struct rcxml rc = { 0 }; @@ -41,6 +42,8 @@ int main(int argc, char *argv[]) server_init(&server); server_start(&server); + xbm_load(server.renderer); + if (startup_cmd) spawn_async_no_shell(startup_cmd); wl_display_run(server.wl_display); diff --git a/src/output.c b/src/output.c index a668b8f7..a7c5cb8b 100644 --- a/src/output.c +++ b/src/output.c @@ -36,6 +36,15 @@ static void render_cycle_box(struct output *output) } } +static void render_icon(struct draw_data *d, struct wlr_box box, + struct wlr_texture *texture) +{ + float matrix[9]; + wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0, + d->transform_matrix); + wlr_render_texture_with_matrix(d->renderer, texture, matrix, 1); +} + static void render_decorations(struct wlr_output *output, struct view *view) { if (!view_want_deco(view)) @@ -56,6 +65,9 @@ static void render_decorations(struct wlr_output *output, struct view *view) else ddata.rgba = theme.window_inactive_title_bg_color; draw_rect(&ddata, deco_box(view, LAB_DECO_PART_TITLE)); + + render_icon(&ddata, deco_box(view, LAB_DECO_ICON_CLOSE), + theme.xbm_close); } struct render_data { diff --git a/src/theme/meson.build b/src/theme/meson.build index 3b9ec5dc..e7181a06 100644 --- a/src/theme/meson.build +++ b/src/theme/meson.build @@ -1,3 +1,5 @@ labwc_sources += files( 'theme.c', ) + +subdir('xbm') diff --git a/src/theme/xbm/meson.build b/src/theme/xbm/meson.build new file mode 100644 index 00000000..8aa98734 --- /dev/null +++ b/src/theme/xbm/meson.build @@ -0,0 +1,5 @@ +labwc_sources += files( + 'parse.c', + 'tokenize.c', + 'xbm.c', +) diff --git a/src/theme/xbm/parse.c b/src/theme/xbm/parse.c index 0d5820e5..3a26f2ac 100644 --- a/src/theme/xbm/parse.c +++ b/src/theme/xbm/parse.c @@ -1,3 +1,9 @@ +/* + * Parse xbm token to create pixmap + * + * Copyright Johan Malm 2020 + */ + #define _POSIX_C_SOURCE 200809L #include #include @@ -6,17 +12,17 @@ #include #include "buf.h" -#include "xbm.h" +#include "theme/xbm/parse.h" -static unsigned char defaultcolor[] = { 127, 127, 127, 255 }; -static unsigned char background[] = { 255, 255, 255, 255 }; +/* TODO: should be window.active.button.unpressed.image.color */ +static unsigned char defaultcolor[] = { 255, 255, 255, 255 }; -static uint32_t *pixmap; +static uint32_t *data; static void add_pixel(int position, unsigned char *rbga) { - pixmap[position] = (rbga[3] << 24) | (rbga[0] << 16) | (rbga[1] << 8) | - rbga[0]; + data[position] = (rbga[3] << 24) | (rbga[0] << 16) | (rbga[1] << 8) | + rbga[0]; } static void init_pixmap(int w, int h) @@ -25,7 +31,7 @@ static void init_pixmap(int w, int h) if (has_run) return; has_run = true; - pixmap = (uint32_t *)calloc(w * h, sizeof(uint32_t)); + data = (uint32_t *)calloc(w * h, sizeof(uint32_t)); } static void process_bytes(int height, int width, struct token *tokens) @@ -43,22 +49,16 @@ static void process_bytes(int height, int width, struct token *tokens) return; int value = (int)strtol(t->name, NULL, 0); int bit = 1 << (col % 8); - if (value & bit) { + if (value & bit) add_pixel(row * width + col, defaultcolor); - printf("."); - } else { - add_pixel(row * width + col, background); - printf(" "); - } } ++t; - printf("\n"); } } -cairo_surface_t *xbm_create_bitmap(struct token *tokens) +struct pixmap xbm_create_pixmap(struct token *tokens) { - cairo_surface_t *g_surface; + struct pixmap pixmap; int width = 0, height = 0; for (struct token *t = tokens; t->type; t++) { if (width && height) { @@ -72,20 +72,11 @@ cairo_surface_t *xbm_create_bitmap(struct token *tokens) else if (strstr(t->name, "height")) height = atoi((++t)->name); } - out: - g_surface = - cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - if (!g_surface) { - fprintf(stderr, "no surface\n"); - return NULL; - } - unsigned char *surface_data = cairo_image_surface_get_data(g_surface); - cairo_surface_flush(g_surface); - memcpy(surface_data, pixmap, width * height * 4); - free(pixmap); - cairo_surface_mark_dirty(g_surface); - return g_surface; + pixmap.data = data; + pixmap.width = width; + pixmap.height = height; + return pixmap; } char *xbm_read_file(const char *filename) diff --git a/src/theme/xbm/tokenize.c b/src/theme/xbm/tokenize.c index 74650276..f4477fa9 100644 --- a/src/theme/xbm/tokenize.c +++ b/src/theme/xbm/tokenize.c @@ -1,8 +1,14 @@ +/* + * XBM file tokenizer + * + * Copyright Johan Malm 2020 + */ + #include #include #include -#include "xbm.h" +#include "theme/xbm/tokenize.h" static char *current_buffer_position; static struct token *tokens; diff --git a/src/theme/xbm/xbm.c b/src/theme/xbm/xbm.c new file mode 100644 index 00000000..f36adf83 --- /dev/null +++ b/src/theme/xbm/xbm.c @@ -0,0 +1,34 @@ +/* + * Create wlr textures based on xbm data + * + * Copyright Johan Malm 2020 + */ + +#include +#include + +#include "theme/xbm/xbm.h" +#include "theme/xbm/parse.h" + +static char filename[] = "/usr/share/themes/Bear2/openbox-3/close.xbm"; + +void xbm_load(struct wlr_renderer *renderer) +{ + struct token *tokens; + + char *buffer = xbm_read_file(filename); + if (!buffer) { + fprintf(stderr, "no buffer\n"); + return; + } + tokens = xbm_tokenize(buffer); + free(buffer); + struct pixmap pixmap = xbm_create_pixmap(tokens); + free(tokens); + + theme.xbm_close = wlr_texture_from_pixels( + renderer, WL_SHM_FORMAT_ARGB8888, pixmap.width * 4, + pixmap.width, pixmap.height, pixmap.data); + if (pixmap.data) + free(pixmap.data); +} diff --git a/tools/xbm/.gitignore b/tools/xbm/.gitignore index 22f659d4..84e99e1c 100644 --- a/tools/xbm/.gitignore +++ b/tools/xbm/.gitignore @@ -1,2 +1,3 @@ xbm-tokenize xbm-parse +*.png diff --git a/tools/xbm/xbm-parse.c b/tools/xbm/xbm-parse.c index a3fcc162..71cd6aeb 100644 --- a/tools/xbm/xbm-parse.c +++ b/tools/xbm/xbm-parse.c @@ -1,7 +1,9 @@ #include #include +#include +#include -#include "xbm.h" +#include "theme/xbm/parse.h" int main(int argc, char **argv) { @@ -17,18 +19,29 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); tokens = xbm_tokenize(buffer); free(buffer); - - cairo_surface_t *surface = xbm_create_bitmap(tokens); + struct pixmap pixmap = xbm_create_pixmap(tokens); free(tokens); - if (!surface) + cairo_surface_t *g_surface; + g_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + pixmap.width, pixmap.height); + if (!g_surface) { fprintf(stderr, "no surface\n"); + exit(EXIT_FAILURE); + } + unsigned char *surface_data = cairo_image_surface_get_data(g_surface); + cairo_surface_flush(g_surface); + memcpy(surface_data, pixmap.data, pixmap.width * pixmap.height * 4); + if (pixmap.data) + free(pixmap.data); + cairo_surface_mark_dirty(g_surface); + char png_name[1024]; snprintf(png_name, sizeof(png_name), "%s.png", argv[1]); - if (cairo_surface_write_to_png(surface, png_name)) { + if (cairo_surface_write_to_png(g_surface, png_name)) { fprintf(stderr, "cannot save png\n"); exit(EXIT_FAILURE); } - cairo_surface_destroy(surface); + cairo_surface_destroy(g_surface); exit(EXIT_SUCCESS); } diff --git a/tools/xbm/xbm-tokenize.c b/tools/xbm/xbm-tokenize.c index d38827d6..e5e6c06b 100644 --- a/tools/xbm/xbm-tokenize.c +++ b/tools/xbm/xbm-tokenize.c @@ -4,7 +4,7 @@ #include #include "buf.h" -#include "xbm.h" +#include "theme/xbm/tokenize.h" /* Read file into buffer, because it's easier to tokenize that way */ char *read_file(const char *filename)