mirror of
https://github.com/labwc/labwc.git
synced 2026-04-07 08:21:20 -04:00
Initial use of a centralized caching border generator
This commit is contained in:
parent
c37f343377
commit
2a0ff0d5b4
7 changed files with 218 additions and 61 deletions
30
include/common/borderset.h
Normal file
30
include/common/borderset.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#ifndef LABWC_BORDERSET_H
|
||||||
|
#define LABWC_BORDERSET_H
|
||||||
|
|
||||||
|
struct borderset {
|
||||||
|
uint32_t id; // Base colour, but could be used as a tracking hash for images or whatever in the future
|
||||||
|
int size; // width (since I suspect a 2px border scaled up to 20px might look weird)
|
||||||
|
int type; // Single or double bevel
|
||||||
|
uint32_t * top;
|
||||||
|
uint32_t * left;
|
||||||
|
uint32_t * right;
|
||||||
|
uint32_t * bottom;
|
||||||
|
uint32_t * tl;
|
||||||
|
uint32_t * tr;
|
||||||
|
uint32_t * bl;
|
||||||
|
uint32_t * br;
|
||||||
|
struct borderset * next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern struct borderset * borderCache;
|
||||||
|
|
||||||
|
struct borderset * getBorders(uint32_t id, int size, int type);
|
||||||
|
|
||||||
|
struct borderset * createBuffer(uint32_t id, int size, int type);
|
||||||
|
|
||||||
|
void clearBorderCache(struct borderset *borderset);
|
||||||
|
|
||||||
|
#endif /* LABWC_LAB_SCENE_RECT_H */
|
||||||
|
|
@ -66,13 +66,16 @@
|
||||||
(WLR_VERSION_NUM >= (((major) << 16) | ((minor) << 8) | (micro)))
|
(WLR_VERSION_NUM >= (((major) << 16) | ((minor) << 8) | (micro)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PIXEL () - calculate pixel offset in an array of "bw" columns wide.
|
* PIXEL () - calculate pixel offset in an array
|
||||||
*
|
*
|
||||||
* @param x x-coordinate
|
* @param x x-coordinate
|
||||||
* @param y y-coordinate
|
* @param y y-coordinate
|
||||||
|
* @param size width of the buffer in pixes
|
||||||
* Assumes "bw" was defined externally
|
* Assumes "bw" was defined externally
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PIXEL(x, y) (bw * y + x)
|
#define PIXEL(x, y) (bw * y + x)
|
||||||
|
|
||||||
|
#define PIXELSIZED(x, y, size) (size * y + x)
|
||||||
|
|
||||||
#endif /* LABWC_MACROS_H */
|
#endif /* LABWC_MACROS_H */
|
||||||
|
|
|
||||||
115
src/common/borderset.c
Normal file
115
src/common/borderset.c
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
#include "common/borderset.h"
|
||||||
|
#include "common/mem.h"
|
||||||
|
#include "common/macros.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct borderset * getBorders(uint32_t id, int size, int type) {
|
||||||
|
struct borderset * current = borderCache;
|
||||||
|
struct borderset * last;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (current->size == size && current->id == id && current->type == type) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
last = current;
|
||||||
|
current = current -> next;
|
||||||
|
}
|
||||||
|
// Fall through, we need to create a buffer.
|
||||||
|
|
||||||
|
if (borderCache == NULL) {
|
||||||
|
borderCache = createBuffer(id, size, type);
|
||||||
|
return borderCache;
|
||||||
|
} else {
|
||||||
|
last->next = createBuffer(id, size, type);
|
||||||
|
return last->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct borderset * createBuffer(uint32_t id, int size, int type) {
|
||||||
|
struct borderset *newBorderset = znew(*newBorderset);
|
||||||
|
|
||||||
|
newBorderset->next = NULL;
|
||||||
|
newBorderset->id = id;
|
||||||
|
newBorderset->size = size;
|
||||||
|
newBorderset->type = type;
|
||||||
|
|
||||||
|
|
||||||
|
// Use ID as a AARRGGBB colour
|
||||||
|
uint8_t a = id >> 24 & 255;
|
||||||
|
uint8_t r = id >> 16 & 255;
|
||||||
|
uint8_t g = id >> 8 & 255;
|
||||||
|
uint8_t b = id & 255;
|
||||||
|
|
||||||
|
uint32_t r1 = r * 5 / 4;
|
||||||
|
if (r1 > a) r1=a;
|
||||||
|
uint32_t g1 = g * 5 / 4;
|
||||||
|
if (g1 > a) g1=a;
|
||||||
|
uint32_t b1 = b * 5 / 4;
|
||||||
|
if (b1 > a) b1=a;
|
||||||
|
|
||||||
|
/* darker outline */
|
||||||
|
uint32_t r0 = r / 2;
|
||||||
|
uint32_t g0 = g / 2;
|
||||||
|
uint32_t b0 = b / 2;
|
||||||
|
|
||||||
|
uint32_t hl32 = ((uint32_t)a << 24) | ((uint32_t)r1 << 16)
|
||||||
|
| ((uint32_t)g1 << 8) | (uint32_t)b1;
|
||||||
|
uint32_t ll32 = ((uint32_t)a << 24) | ((uint32_t)r0 << 16)
|
||||||
|
| ((uint32_t)g0 << 8) | (uint32_t)b0;
|
||||||
|
|
||||||
|
|
||||||
|
newBorderset->tl = znew_n(uint32_t, size*size);
|
||||||
|
newBorderset->tr = znew_n(uint32_t, size*size);
|
||||||
|
newBorderset->bl = znew_n(uint32_t, size*size);
|
||||||
|
newBorderset->br = znew_n(uint32_t, size*size);
|
||||||
|
newBorderset->top = znew(uint32_t);
|
||||||
|
newBorderset->left = znew(uint32_t);
|
||||||
|
newBorderset->right = znew(uint32_t);
|
||||||
|
newBorderset->bottom = znew(uint32_t);
|
||||||
|
switch(type) {
|
||||||
|
case 1:
|
||||||
|
*newBorderset->top = hl32;
|
||||||
|
*newBorderset->left = hl32;
|
||||||
|
*newBorderset->right = ll32;
|
||||||
|
*newBorderset->bottom = ll32;
|
||||||
|
|
||||||
|
// Fill with solid
|
||||||
|
for (int j=0; j<size;j++) {
|
||||||
|
for (int k=0; k<size;k++) {
|
||||||
|
newBorderset->tl[PIXELSIZED(j, k, size)] = hl32;
|
||||||
|
newBorderset->tr[PIXELSIZED(size - 1 - j, k, size)] = (j > k) ? hl32 : ll32;
|
||||||
|
newBorderset->bl[PIXELSIZED(size - 1 -j, k, size)] = (j > k) ? hl32 : ll32;
|
||||||
|
newBorderset->br[PIXELSIZED(j, k, size)] = ll32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return newBorderset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearBorderCache(struct borderset * borderset)
|
||||||
|
{
|
||||||
|
if (borderset == NULL)
|
||||||
|
return;
|
||||||
|
if (borderset->next != NULL) {
|
||||||
|
clearBorderCache(borderset->next);
|
||||||
|
}
|
||||||
|
free(borderset->top);
|
||||||
|
free(borderset->left);
|
||||||
|
free(borderset->right);
|
||||||
|
free(borderset->bottom);
|
||||||
|
free(borderset->tl);
|
||||||
|
free(borderset->tr);
|
||||||
|
free(borderset->bl);
|
||||||
|
free(borderset->br);
|
||||||
|
free(borderset);
|
||||||
|
}
|
||||||
|
|
@ -5,12 +5,14 @@
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
#include "common/macros.h"
|
#include "common/macros.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
struct border_scene {
|
struct border_scene {
|
||||||
struct wlr_scene_tree *tree;
|
struct wlr_scene_tree *tree;
|
||||||
struct wlr_scene_rect *top, *bottom, *left, *right;
|
struct wlr_scene_rect *top, *bottom, *left, *right;
|
||||||
struct wlr_scene_buffer *tlcorner, *trcorner, *blcorner, *brcorner;
|
struct wlr_scene_buffer *tlcorner, *trcorner, *blcorner, *brcorner,
|
||||||
|
*ttexture, *ltexture, *rtexture, *btexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -43,90 +45,65 @@ lab_scene_rect_create(struct wlr_scene_tree *parent,
|
||||||
// Beveled mode 0 = normal outline
|
// Beveled mode 0 = normal outline
|
||||||
// Beveled mode 1 = full bevel with sharp internal corners
|
// Beveled mode 1 = full bevel with sharp internal corners
|
||||||
if (opts->beveled > 0) {
|
if (opts->beveled > 0) {
|
||||||
/* From Pull request 3382 */
|
|
||||||
|
|
||||||
int bw = rect->border_width;
|
|
||||||
|
|
||||||
// Floats for the rect versions.
|
|
||||||
float r = color[0];
|
float r = color[0];
|
||||||
float g = color[1];
|
float g = color[1];
|
||||||
float b = color[2];
|
float b = color[2];
|
||||||
float a = color[3];
|
float a = color[3];
|
||||||
|
int bw = rect->border_width;
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 | (uint32_t)(r*255) << 16 | (uint32_t)(g*255) << 8 | (uint32_t)(b*255);
|
||||||
float r1 = r * 5 / 4;
|
struct borderset * renderedborders = getBorders(colour32, bw, 1);
|
||||||
if (r1 > a) r1=a;
|
|
||||||
float g1 = g * 5 / 4;
|
|
||||||
if (g1 > a) g1=a;
|
|
||||||
float b1 = b * 5 / 4;
|
|
||||||
if (b1 > a) b1=a;
|
|
||||||
|
|
||||||
/* darker outline */
|
|
||||||
float r0 = r / 2;
|
|
||||||
float g0 = g / 2;
|
|
||||||
float b0 = b / 2;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Buffers are AARRGGBB 32-bit packed int
|
|
||||||
uint32_t ll32 = ((uint32_t)(255*a) << 24) | ((uint32_t)(255*r0) << 16)
|
|
||||||
| ((uint32_t)(255*g0) << 8) | (uint32_t)(255*b0);
|
|
||||||
uint32_t hl32 = ((uint32_t)(255*a) << 24) | ((uint32_t)(255*r1) << 16)
|
|
||||||
| ((uint32_t)(255*g1) << 8) | (uint32_t)(255*b1);
|
|
||||||
|
|
||||||
|
|
||||||
const float highlight[4] = {r1, g1, b1, a};
|
|
||||||
const float lowlight[4] = {r0, g0, b0, a};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
border->top = lab_wlr_scene_rect_create(border->tree, 0, 0, highlight);
|
|
||||||
border->right = lab_wlr_scene_rect_create(border->tree, 0, 0, lowlight);
|
|
||||||
border->bottom = lab_wlr_scene_rect_create(border->tree, 0, 0, lowlight);
|
|
||||||
border->left = lab_wlr_scene_rect_create(border->tree, 0, 0, highlight);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t *tl_data = znew_n(uint32_t, bw*bw);
|
|
||||||
uint32_t *tr_data = znew_n(uint32_t, bw*bw);
|
|
||||||
uint32_t *bl_data = znew_n(uint32_t, bw*bw);
|
|
||||||
uint32_t *br_data = znew_n(uint32_t, bw*bw);
|
|
||||||
|
|
||||||
|
|
||||||
// Fill with solid
|
|
||||||
for (int j=0; j<bw;j++) {
|
|
||||||
for (int k=0; k<bw;k++) {
|
|
||||||
tl_data[PIXEL(j, k)] = hl32;
|
|
||||||
tr_data[PIXEL(bw - 1 - j, k)] = (j > k) ? hl32 : ll32;
|
|
||||||
bl_data[PIXEL(bw - 1 -j, k)] = (j > k) ? hl32 : ll32;
|
|
||||||
br_data[PIXEL(j, k)] = ll32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
border->top = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
|
border->right = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
|
border->bottom = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
|
border->left = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
|
|
||||||
|
struct lab_data_buffer *ttexture_buffer =
|
||||||
|
buffer_create_from_data(renderedborders->top, 1, 1, 4);
|
||||||
|
border->ttexture = wlr_scene_buffer_create(border->tree, &ttexture_buffer->base);
|
||||||
|
|
||||||
|
struct lab_data_buffer *ltexture_buffer =
|
||||||
|
buffer_create_from_data(renderedborders->left, 1, 1, 4);
|
||||||
|
border->ltexture = wlr_scene_buffer_create(border->tree, <exture_buffer->base);
|
||||||
|
|
||||||
|
struct lab_data_buffer *rtexture_buffer =
|
||||||
|
buffer_create_from_data(renderedborders->right, 1, 1, 4);
|
||||||
|
border->rtexture = wlr_scene_buffer_create(border->tree, &rtexture_buffer->base);
|
||||||
|
|
||||||
|
struct lab_data_buffer *btexture_buffer =
|
||||||
|
buffer_create_from_data(renderedborders->bottom, 1, 1, 4);
|
||||||
|
border->btexture = wlr_scene_buffer_create(border->tree, &btexture_buffer->base);
|
||||||
|
|
||||||
|
|
||||||
struct lab_data_buffer *tltexture_buffer =
|
struct lab_data_buffer *tltexture_buffer =
|
||||||
buffer_create_from_data(tl_data, bw, bw, 4*bw);
|
buffer_create_from_data(renderedborders->tl, bw, bw, 4*bw);
|
||||||
border->tlcorner = wlr_scene_buffer_create(border->tree, &tltexture_buffer->base);
|
border->tlcorner = wlr_scene_buffer_create(border->tree, &tltexture_buffer->base);
|
||||||
wlr_buffer_drop(&tltexture_buffer->base);
|
|
||||||
|
|
||||||
|
|
||||||
struct lab_data_buffer *trtexture_buffer =
|
struct lab_data_buffer *trtexture_buffer =
|
||||||
buffer_create_from_data(tr_data, bw, bw, 4*bw);
|
buffer_create_from_data(renderedborders->tr, bw, bw, 4*bw);
|
||||||
border->trcorner = wlr_scene_buffer_create(border->tree, &trtexture_buffer->base);
|
border->trcorner = wlr_scene_buffer_create(border->tree, &trtexture_buffer->base);
|
||||||
wlr_buffer_drop(&trtexture_buffer->base);
|
|
||||||
|
|
||||||
|
|
||||||
struct lab_data_buffer *bltexture_buffer =
|
struct lab_data_buffer *bltexture_buffer =
|
||||||
buffer_create_from_data(bl_data, bw, bw, 4*bw);
|
buffer_create_from_data(renderedborders->bl, bw, bw, 4*bw);
|
||||||
border->blcorner = wlr_scene_buffer_create(border->tree, &bltexture_buffer->base);
|
border->blcorner = wlr_scene_buffer_create(border->tree, &bltexture_buffer->base);
|
||||||
wlr_buffer_drop(&bltexture_buffer->base);
|
|
||||||
|
|
||||||
struct lab_data_buffer *brtexture_buffer =
|
struct lab_data_buffer *brtexture_buffer =
|
||||||
buffer_create_from_data(br_data, bw, bw, 4*bw);
|
buffer_create_from_data(renderedborders->br, bw, bw, 4*bw);
|
||||||
border->brcorner = wlr_scene_buffer_create(border->tree, &brtexture_buffer->base);
|
border->brcorner = wlr_scene_buffer_create(border->tree, &brtexture_buffer->base);
|
||||||
wlr_buffer_drop(&brtexture_buffer->base);
|
|
||||||
} else {
|
} else {
|
||||||
border->top = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
border->top = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
border->right = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
border->right = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
|
|
@ -181,6 +158,31 @@ resize_border(struct border_scene *border, int border_width, int width, int heig
|
||||||
wlr_scene_rect_set_size(border->right, border_width, height - border_width * 2);
|
wlr_scene_rect_set_size(border->right, border_width, height - border_width * 2);
|
||||||
|
|
||||||
if (border->tlcorner != NULL) {
|
if (border->tlcorner != NULL) {
|
||||||
|
wlr_scene_buffer_set_dest_size(border->ttexture,
|
||||||
|
width, border_width);
|
||||||
|
wlr_scene_node_set_position(&border->ttexture->node,
|
||||||
|
0,0);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(border->btexture,
|
||||||
|
width, border_width);
|
||||||
|
wlr_scene_node_set_position(&border->btexture->node,
|
||||||
|
0, height - border_width);
|
||||||
|
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(border->ltexture,
|
||||||
|
border_width, height - border_width * 2);
|
||||||
|
wlr_scene_node_set_position(&border->ltexture->node,
|
||||||
|
0, border_width);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(border->rtexture,
|
||||||
|
border_width, height - border_width * 2);
|
||||||
|
wlr_scene_node_set_position(&border->rtexture->node,
|
||||||
|
width - border_width, border_width);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
wlr_scene_buffer_set_dest_size(border->tlcorner,
|
wlr_scene_buffer_set_dest_size(border->tlcorner,
|
||||||
border_width, border_width);
|
border_width, border_width);
|
||||||
wlr_scene_node_set_position(&border->tlcorner->node,
|
wlr_scene_node_set_position(&border->tlcorner->node,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
labwc_sources += files(
|
labwc_sources += files(
|
||||||
|
'borderset.c',
|
||||||
'box.c',
|
'box.c',
|
||||||
'buf.c',
|
'buf.c',
|
||||||
'dir.c',
|
'dir.c',
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "translate.h"
|
#include "translate.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
|
|
@ -40,6 +41,8 @@ static const struct option long_options[] = {
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct borderset * borderCache = NULL;
|
||||||
|
|
||||||
static const char labwc_usage[] =
|
static const char labwc_usage[] =
|
||||||
"Usage: labwc [options...]\n"
|
"Usage: labwc [options...]\n"
|
||||||
" -c, --config <file> Specify config file (with path)\n"
|
" -c, --config <file> Specify config file (with path)\n"
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
#include "xwayland.h"
|
#include "xwayland.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
#define LAB_EXT_DATA_CONTROL_VERSION 1
|
#define LAB_EXT_DATA_CONTROL_VERSION 1
|
||||||
#define LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION 1
|
#define LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION 1
|
||||||
|
|
@ -100,6 +101,8 @@ reload_config_and_theme(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle_finish(/*switch_focus*/ false);
|
cycle_finish(/*switch_focus*/ false);
|
||||||
|
clearBorderCache(borderCache);
|
||||||
|
borderCache = NULL;
|
||||||
menu_reconfigure();
|
menu_reconfigure();
|
||||||
seat_reconfigure();
|
seat_reconfigure();
|
||||||
regions_reconfigure();
|
regions_reconfigure();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue