From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 17 Feb 2022 00:46:32 +0000 (+0100) Subject: Prepare to move from wlr_texture to lab_data_buffer X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=044388a5cd1ccaef07b2b36e759325c3dc2aa099;p=proto%2Flabwc.git Prepare to move from wlr_texture to lab_data_buffer --- diff --git a/include/buffer.h b/include/buffer.h index 63f92f87..3ffec484 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -36,9 +36,15 @@ struct lab_data_buffer { void *data; uint32_t format; size_t stride; + bool free_on_destroy; }; -struct lab_data_buffer *buffer_create(uint32_t width, uint32_t height, - float scale); +/* Create a buffer which creates a new cairo CAIRO_FORMAT_ARGB32 surface */ +struct lab_data_buffer *buffer_create_cairo(uint32_t width, uint32_t height, + float scale, bool free_on_destroy); + +/* Create a buffer which wraps a given DRM_FORMAT_ARGB8888 pointer */ +struct lab_data_buffer *buffer_create_wrap(void *pixel_data, uint32_t width, + uint32_t height, uint32_t stride, bool free_on_destroy); #endif /* __LABWC_BUFFER_H */ diff --git a/include/common/font.h b/include/common/font.h index c7af6848..bcf5acd2 100644 --- a/include/common/font.h +++ b/include/common/font.h @@ -2,9 +2,7 @@ #ifndef __LABWC_FONT_H #define __LABWC_FONT_H -struct server; -struct wlr_texture; -struct wlr_box; +struct lab_data_buffer; struct font { char *name; @@ -18,16 +16,23 @@ struct font { int font_height(struct font *font); /** - * texture_create - Create ARGB8888 texture using pango - * @server: context (for wlr_renderer) - * @texture: texture pointer; existing pointer will be freed + * font_buffer_create - Create ARGB8888 lab_data_buffer using pango + * @buffer: buffer pointer * @max_width: max allowable width; will be ellipsized if longer * @text: text to be generated as texture * @font: font description * @color: foreground color in rgba format */ -void font_texture_create(struct server *server, struct wlr_texture **texture, - int max_width, const char *text, struct font *font, float *color); +void font_buffer_create(struct lab_data_buffer **buffer, int max_width, + const char *text, struct font *font, float *color); + +/** + * font_buffer_update - Wrapper around font_buffer_create + * Only difference is that if given buffer pointer is != NULL + * wlr_buffer_drop() will be called on the buffer. + */ +void font_buffer_update(struct lab_data_buffer **buffer, int max_width, + const char *text, struct font *font, float *color); /** * font_finish - free some font related resources diff --git a/include/theme.h b/include/theme.h index 38aae4c0..a36b9dc1 100644 --- a/include/theme.h +++ b/include/theme.h @@ -54,20 +54,20 @@ struct theme { float osd_label_text_color[4]; /* textures */ - struct wlr_texture *xbm_close_active_unpressed; - struct wlr_texture *xbm_maximize_active_unpressed; - struct wlr_texture *xbm_iconify_active_unpressed; - struct wlr_texture *xbm_menu_active_unpressed; + struct lab_data_buffer *xbm_close_active_unpressed; + struct lab_data_buffer *xbm_maximize_active_unpressed; + struct lab_data_buffer *xbm_iconify_active_unpressed; + struct lab_data_buffer *xbm_menu_active_unpressed; - struct wlr_texture *xbm_close_inactive_unpressed; - struct wlr_texture *xbm_maximize_inactive_unpressed; - struct wlr_texture *xbm_iconify_inactive_unpressed; - struct wlr_texture *xbm_menu_inactive_unpressed; + struct lab_data_buffer *xbm_close_inactive_unpressed; + struct lab_data_buffer *xbm_maximize_inactive_unpressed; + struct lab_data_buffer *xbm_iconify_inactive_unpressed; + struct lab_data_buffer *xbm_menu_inactive_unpressed; - struct wlr_texture *corner_top_left_active_normal; - struct wlr_texture *corner_top_right_active_normal; - struct wlr_texture *corner_top_left_inactive_normal; - struct wlr_texture *corner_top_right_inactive_normal; + struct lab_data_buffer *corner_top_left_active_normal; + struct lab_data_buffer *corner_top_right_active_normal; + struct lab_data_buffer *corner_top_left_inactive_normal; + struct lab_data_buffer *corner_top_right_inactive_normal; /* not set in rc.xml/themerc, but derived from font & padding_height */ int title_height; @@ -76,12 +76,10 @@ struct theme { /** * theme_init - read openbox theme and generate button textures * @theme: theme data - * @renderer: wlr_renderer for creating button textures * @theme_name: theme-name in //openbox-3/themerc * Note is obtained in theme-dir.c */ -void theme_init(struct theme *theme, struct wlr_renderer *renderer, - const char *theme_name); +void theme_init(struct theme *theme, const char *theme_name); /** * theme_finish - free button textures diff --git a/include/xbm/xbm.h b/include/xbm/xbm.h index 739d9a2c..f0957d3d 100644 --- a/include/xbm/xbm.h +++ b/include/xbm/xbm.h @@ -9,6 +9,6 @@ /** * xbm_load - load theme xbm files into global theme struct */ -void xbm_load(struct theme *theme, struct wlr_renderer *renderer); +void xbm_load(struct theme *theme); #endif /* __LABWC_XBM_H */ diff --git a/src/buffer.c b/src/buffer.c index 8ce275a5..3a70aa29 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -42,10 +42,17 @@ static void data_buffer_destroy(struct wlr_buffer *wlr_buffer) { struct lab_data_buffer *buffer = data_buffer_from_buffer(wlr_buffer); + if (!buffer->free_on_destroy) { + free(buffer); + return; + } if (buffer->cairo) { cairo_surface_t *surf = cairo_get_target(buffer->cairo); cairo_destroy(buffer->cairo); cairo_surface_destroy(surf); + } else if (buffer->data) { + free(buffer->data); + buffer->data = NULL; } free(buffer); } @@ -76,7 +83,8 @@ static const struct wlr_buffer_impl data_buffer_impl = { }; struct lab_data_buffer * -buffer_create(uint32_t width, uint32_t height, float scale) +buffer_create_cairo(uint32_t width, uint32_t height, float scale, + bool free_on_destroy) { struct lab_data_buffer *buffer = calloc(1, sizeof(*buffer)); if (!buffer) { @@ -92,6 +100,7 @@ buffer_create(uint32_t width, uint32_t height, float scale) buffer->data = cairo_image_surface_get_data(surf); buffer->format = DRM_FORMAT_ARGB8888; buffer->stride = cairo_image_surface_get_stride(surf); + buffer->free_on_destroy = free_on_destroy; if (!buffer->data) { cairo_destroy(buffer->cairo); @@ -101,3 +110,19 @@ buffer_create(uint32_t width, uint32_t height, float scale) } return buffer; } + +struct lab_data_buffer * +buffer_create_wrap(void *pixel_data, uint32_t width, uint32_t height, + uint32_t stride, bool free_on_destroy) +{ + struct lab_data_buffer *buffer = calloc(1, sizeof(*buffer)); + if (!buffer) { + return NULL; + } + wlr_buffer_init(&buffer->base, &data_buffer_impl, width, height); + buffer->data = pixel_data; + buffer->format = DRM_FORMAT_ARGB8888; + buffer->stride = stride; + buffer->free_on_destroy = free_on_destroy; + return buffer; +} diff --git a/src/common/font.c b/src/common/font.c index e5222d00..6925a504 100644 --- a/src/common/font.c +++ b/src/common/font.c @@ -7,6 +7,7 @@ #include #include "common/font.h" #include "labwc.h" +#include "buffer.h" static PangoRectangle font_extents(struct font *font, const char *string) @@ -49,25 +50,33 @@ font_height(struct font *font) } void -font_texture_create(struct server *server, struct wlr_texture **texture, - int max_width, const char *text, struct font *font, float *color) +font_buffer_update(struct lab_data_buffer **buffer, int max_width, + const char *text, struct font *font, float *color) +{ + if (*buffer) { + wlr_buffer_drop(&(*buffer)->base); + *buffer = NULL; + } + font_buffer_create(buffer, max_width, text, font, color); +} + +void +font_buffer_create(struct lab_data_buffer **buffer, int max_width, + const char *text, struct font *font, float *color) { if (!text || !*text) { return; } - if (*texture) { - wlr_texture_destroy(*texture); - *texture = NULL; - } PangoRectangle rect = font_extents(font, text); if (max_width && rect.width > max_width) { rect.width = max_width; } + /* TODO: scale */ + *buffer = buffer_create_cairo(rect.width, rect.height, 1, true); - cairo_surface_t *surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - rect.width, rect.height); - cairo_t *cairo = cairo_create(surf); + cairo_t *cairo = (*buffer)->cairo; + cairo_surface_t *surf = cairo_get_target(cairo); cairo_set_source_rgba(cairo, color[0], color[1], color[2], color[3]); cairo_move_to(cairo, 0, 0); @@ -88,13 +97,6 @@ font_texture_create(struct server *server, struct wlr_texture **texture, g_object_unref(layout); cairo_surface_flush(surf); - unsigned char *data = cairo_image_surface_get_data(surf); - *texture = wlr_texture_from_pixels(server->renderer, DRM_FORMAT_ARGB8888, - cairo_image_surface_get_stride(surf), rect.width, - rect.height, data); - - cairo_destroy(cairo); - cairo_surface_destroy(surf); } void diff --git a/src/main.c b/src/main.c index 4e419e5e..e3662f26 100644 --- a/src/main.c +++ b/src/main.c @@ -68,7 +68,7 @@ main(int argc, char *argv[]) server_start(&server); struct theme theme = { 0 }; - theme_init(&theme, server.renderer, rc.theme_name); + theme_init(&theme, rc.theme_name); server.theme = &theme; menu_init_rootmenu(&server); diff --git a/src/menu/menu.c b/src/menu/menu.c index 48b18336..5dc768c1 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -74,8 +74,11 @@ item_create(struct menu *menu, const char *text) if (!menuitem) { return NULL; } +/* FIXME */ +#if 0 struct server *server = menu->server; struct theme *theme = server->theme; +#endif struct font font = { .name = rc.font_name_menuitem, .size = rc.font_size_menuitem, @@ -84,6 +87,8 @@ item_create(struct menu *menu, const char *text) menuitem->box.width = MENUWIDTH; menuitem->box.height = font_height(&font) + 2 * MENU_ITEM_PADDING_Y; +/* FIXME */ +#if 0 int item_max_width = MENUWIDTH - 2 * MENU_ITEM_PADDING_X; font_texture_create(server, &menuitem->texture.active, item_max_width, text, &font, theme->menu_items_active_text_color); @@ -94,6 +99,7 @@ item_create(struct menu *menu, const char *text) menuitem->texture.offset_y = (menuitem->box.height - menuitem->texture.active->height) / 2; menuitem->texture.offset_x = MENU_ITEM_PADDING_X; +#endif wl_list_insert(&menu->menuitems, &menuitem->link); wl_list_init(&menuitem->actions); diff --git a/src/osd.c b/src/osd.c index 85b5e4fe..3c66d477 100644 --- a/src/osd.c +++ b/src/osd.c @@ -106,7 +106,7 @@ osd_update(struct server *server) if (output->osd_buffer) { wlr_buffer_drop(&output->osd_buffer->base); } - output->osd_buffer = buffer_create(w, h, scale); + output->osd_buffer = buffer_create_cairo(w, h, scale, true); cairo_t *cairo = output->osd_buffer->cairo; cairo_surface_t *surf = cairo_get_target(cairo); diff --git a/src/server.c b/src/server.c index 171ec6dd..fbefa0e2 100644 --- a/src/server.c +++ b/src/server.c @@ -32,7 +32,7 @@ reload_config_and_theme(void) rcxml_finish(); rcxml_read(NULL); theme_finish(g_server->theme); - theme_init(g_server->theme, g_server->renderer, rc.theme_name); + theme_init(g_server->theme, rc.theme_name); struct view *view; wl_list_for_each (view, &g_server->views, link) { diff --git a/src/ssd.c b/src/ssd.c index 0897fdaf..3edfd3b3 100644 --- a/src/ssd.c +++ b/src/ssd.c @@ -322,12 +322,16 @@ add_part(struct view *view, enum ssd_part_type type) void ssd_update_title(struct view *view) { + +/* FIXME */ +#if 0 struct theme *theme = view->server->theme; struct font font = { .name = rc.font_name_activewindow, .size = rc.font_size_activewindow, }; +#endif struct ssd_part *part; wl_list_for_each(part, &view->ssd.parts, link) { @@ -340,6 +344,8 @@ ssd_update_title(struct view *view) return; } +/* FIXME */ +#if 0 int max_width = part->box.width > 0 ? part->box.width : 1000; font_texture_create(view->server, &view->title.active, max_width, @@ -349,6 +355,7 @@ ssd_update_title(struct view *view) font_texture_create(view->server, &view->title.inactive, max_width, view_get_string_prop(view, "title"), &font, theme->window_inactive_label_text_color); +#endif part->box = ssd_visible_box(view, part->type); } @@ -387,14 +394,20 @@ ssd_create(struct view *view) /* titlebar top-left corner */ part = add_part(view, LAB_SSD_PART_CORNER_TOP_LEFT); part->box = ssd_visible_box(view, part->type); +/* FIXME */ +#if 0 part->texture.active = &theme->corner_top_left_active_normal; part->texture.inactive = &theme->corner_top_left_inactive_normal; +#endif /* titlebar top-right corner */ part = add_part(view, LAB_SSD_PART_CORNER_TOP_RIGHT); part->box = ssd_visible_box(view, part->type); +/* FIXME */ +#if 0 part->texture.active = &theme->corner_top_right_active_normal; part->texture.inactive = &theme->corner_top_right_inactive_normal; +#endif /* title text */ part = add_part(view, LAB_SSD_PART_TITLE); diff --git a/src/theme.c b/src/theme.c index ec07f9b0..948a6259 100644 --- a/src/theme.c +++ b/src/theme.c @@ -25,6 +25,7 @@ #include "config/rcxml.h" #include "theme.h" #include "xbm/xbm.h" +#include "buffer.h" static int hex_to_dec(char c) @@ -336,8 +337,8 @@ set_source(cairo_t *cairo, float *c) cairo_set_source_rgba(cairo, c[0], c[1], c[2], c[3]); } -static struct wlr_texture * -rounded_rect(struct wlr_renderer *renderer, struct rounded_corner_ctx *ctx) +static struct lab_data_buffer * +rounded_rect(struct rounded_corner_ctx *ctx) { /* 1 degree in radians (=2π/360) */ double deg = 0.017453292519943295; @@ -350,9 +351,12 @@ rounded_rect(struct wlr_renderer *renderer, struct rounded_corner_ctx *ctx) double h = ctx->box->height; double r = ctx->radius; - cairo_surface_t *surf = - cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); - cairo_t *cairo = cairo_create(surf); + struct lab_data_buffer *buffer; + /* TODO: scale */ + buffer = buffer_create_cairo(w, h, 1, true); + + cairo_t *cairo = buffer->cairo; + cairo_surface_t *surf = cairo_get_target(cairo); /* set transparent background */ cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); @@ -405,21 +409,13 @@ rounded_rect(struct wlr_renderer *renderer, struct rounded_corner_ctx *ctx) wlr_log(WLR_ERROR, "unknown corner type"); } cairo_stroke(cairo); - - /* convert to wlr_texture */ cairo_surface_flush(surf); - unsigned char *data = cairo_image_surface_get_data(surf); - struct wlr_texture *texture = wlr_texture_from_pixels(renderer, - DRM_FORMAT_ARGB8888, cairo_image_surface_get_stride(surf), - w, h, data); - - cairo_destroy(cairo); - cairo_surface_destroy(surf); - return texture; + + return buffer; } static void -create_corners(struct theme *theme, struct wlr_renderer *renderer) +create_corners(struct theme *theme) { int corner_square = theme->title_height + theme->border_width; struct wlr_box box = { @@ -437,20 +433,20 @@ create_corners(struct theme *theme, struct wlr_renderer *renderer) .border_color = theme->window_active_border_color, .corner = LAB_CORNER_TOP_LEFT, }; - theme->corner_top_left_active_normal = rounded_rect(renderer, &ctx); + theme->corner_top_left_active_normal = rounded_rect(&ctx); ctx.fill_color = theme->window_inactive_title_bg_color, ctx.border_color = theme->window_inactive_border_color, - theme->corner_top_left_inactive_normal = rounded_rect(renderer, &ctx); + theme->corner_top_left_inactive_normal = rounded_rect(&ctx); ctx.corner = LAB_CORNER_TOP_RIGHT; ctx.fill_color = theme->window_active_title_bg_color, ctx.border_color = theme->window_active_border_color, - theme->corner_top_right_active_normal = rounded_rect(renderer, &ctx); + theme->corner_top_right_active_normal = rounded_rect(&ctx); ctx.fill_color = theme->window_inactive_title_bg_color, ctx.border_color = theme->window_inactive_border_color, - theme->corner_top_right_inactive_normal = rounded_rect(renderer, &ctx); + theme->corner_top_right_inactive_normal = rounded_rect(&ctx); } static void @@ -480,8 +476,7 @@ post_processing(struct theme *theme) } void -theme_init(struct theme *theme, struct wlr_renderer *renderer, - const char *theme_name) +theme_init(struct theme *theme, const char *theme_name) { /* * Set some default values. This is particularly important on @@ -491,8 +486,8 @@ theme_init(struct theme *theme, struct wlr_renderer *renderer, theme_read(theme, theme_name); post_processing(theme); - create_corners(theme, renderer); - xbm_load(theme, renderer); + create_corners(theme); + xbm_load(theme); } void diff --git a/src/xbm/xbm.c b/src/xbm/xbm.c index 35a97cfa..a251ed44 100644 --- a/src/xbm/xbm.c +++ b/src/xbm/xbm.c @@ -15,6 +15,7 @@ #include "theme.h" #include "xbm/parse.h" #include "xbm/xbm.h" +#include "buffer.h" /* built-in 6x6 buttons */ char menu_button_normal[] = { 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00 }; @@ -23,28 +24,6 @@ char max_button_normal[] = { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f }; char max_button_toggled[] = { 0x3e, 0x22, 0x2f, 0x29, 0x39, 0x0f }; char close_button_normal[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 }; -static struct wlr_texture * -texture_from_pixmap(struct wlr_renderer *renderer, struct pixmap *pixmap) -{ - if (!pixmap) { - return NULL; - } - return wlr_texture_from_pixels(renderer, DRM_FORMAT_ARGB8888, - pixmap->width * 4, pixmap->width, - pixmap->height, pixmap->data); -} - -static struct wlr_texture * -texture_from_builtin(struct wlr_renderer *renderer, const char *button) -{ - struct pixmap pixmap = parse_xbm_builtin(button, 6); - struct wlr_texture *texture = texture_from_pixmap(renderer, &pixmap); - if (pixmap.data) { - free(pixmap.data); - } - return texture; -} - static char * xbm_path(const char *button) { @@ -55,62 +34,59 @@ xbm_path(const char *button) } static void -load_button(struct wlr_renderer *renderer, const char *filename, - struct wlr_texture **texture, char *button) +load_button(const char *filename, struct lab_data_buffer **buffer, char *button) { - if (*texture) { - wlr_texture_destroy(*texture); - *texture = NULL; + struct pixmap pixmap = {0}; + if (*buffer) { + wlr_buffer_drop(&(*buffer)->base); + *buffer = NULL; } /* Read file into memory as it's easier to tokenzie that way */ - char *buffer = grab_file(xbm_path(filename)); - if (!buffer) { - goto out; - } - struct token *tokens = tokenize_xbm(buffer); - free(buffer); - - struct pixmap pixmap = parse_xbm_tokens(tokens); - *texture = texture_from_pixmap(renderer, &pixmap); - if (tokens) { - free(tokens); - } - if (pixmap.data) { - free(pixmap.data); + 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); + } } -out: - if (!(*texture)) { - *texture = texture_from_builtin(renderer, button); + if (!pixmap.data) { + pixmap = parse_xbm_builtin(button, 6); } + + /* Create buffer with free_on_destroy being true */ + *buffer = buffer_create_wrap(pixmap.data, pixmap.width, pixmap.height, + pixmap.width * 4, true); } void -xbm_load(struct theme *theme, struct wlr_renderer *r) +xbm_load(struct theme *theme) { parse_set_color(theme->window_active_button_menu_unpressed_image_color); - load_button(r, "menu.xbm", &theme->xbm_menu_active_unpressed, + load_button("menu.xbm", &theme->xbm_menu_active_unpressed, menu_button_normal); parse_set_color(theme->window_active_button_iconify_unpressed_image_color); - load_button(r, "iconify.xbm", &theme->xbm_iconify_active_unpressed, + load_button("iconify.xbm", &theme->xbm_iconify_active_unpressed, iconify_button_normal); parse_set_color(theme->window_active_button_max_unpressed_image_color); - load_button(r, "max.xbm", &theme->xbm_maximize_active_unpressed, + load_button("max.xbm", &theme->xbm_maximize_active_unpressed, max_button_normal); parse_set_color(theme->window_active_button_close_unpressed_image_color); - load_button(r, "close.xbm", &theme->xbm_close_active_unpressed, + load_button("close.xbm", &theme->xbm_close_active_unpressed, close_button_normal); parse_set_color(theme->window_inactive_button_menu_unpressed_image_color); - load_button(r, "menu.xbm", &theme->xbm_menu_inactive_unpressed, + load_button("menu.xbm", &theme->xbm_menu_inactive_unpressed, menu_button_normal); parse_set_color(theme->window_inactive_button_iconify_unpressed_image_color); - load_button(r, "iconify.xbm", &theme->xbm_iconify_inactive_unpressed, + load_button("iconify.xbm", &theme->xbm_iconify_inactive_unpressed, iconify_button_normal); parse_set_color(theme->window_inactive_button_max_unpressed_image_color); - load_button(r, "max.xbm", &theme->xbm_maximize_inactive_unpressed, + load_button("max.xbm", &theme->xbm_maximize_inactive_unpressed, max_button_normal); parse_set_color(theme->window_inactive_button_close_unpressed_image_color); - load_button(r, "close.xbm", &theme->xbm_close_inactive_unpressed, + load_button("close.xbm", &theme->xbm_close_inactive_unpressed, close_button_normal); }