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 */
#ifndef __LABWC_FONT_H
#define __LABWC_FONT_H
-struct server;
-struct wlr_texture;
-struct wlr_box;
+struct lab_data_buffer;
struct font {
char *name;
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
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;
/**
* theme_init - read openbox theme and generate button textures
* @theme: theme data
- * @renderer: wlr_renderer for creating button textures
* @theme_name: theme-name in <theme-dir>/<theme-name>/openbox-3/themerc
* Note <theme-dir> 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
/**
* 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 */
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);
}
};
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) {
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);
}
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;
+}
#include <wlr/util/log.h>
#include "common/font.h"
#include "labwc.h"
+#include "buffer.h"
static PangoRectangle
font_extents(struct font *font, const char *string)
}
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);
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
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);
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,
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);
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);
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);
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) {
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) {
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,
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);
}
/* 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);
#include "config/rcxml.h"
#include "theme.h"
#include "xbm/xbm.h"
+#include "buffer.h"
static int
hex_to_dec(char 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;
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);
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 = {
.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
}
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
theme_read(theme, theme_name);
post_processing(theme);
- create_corners(theme, renderer);
- xbm_load(theme, renderer);
+ create_corners(theme);
+ xbm_load(theme);
}
void
#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 };
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)
{
}
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);
}