mirror of
https://github.com/kolunmi/dwlb.git
synced 2025-10-29 19:24:17 +00:00
allow color commands in status text
This commit is contained in:
parent
352c66ed10
commit
f1b1429015
167
dwlb.c
167
dwlb.c
@ -150,6 +150,73 @@ allocate_shm_file(size_t size)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Color parsing logic adapted from [sway] */
|
||||||
|
static int
|
||||||
|
parse_color(const char *str, pixman_color_t *clr)
|
||||||
|
{
|
||||||
|
if (*str == '#')
|
||||||
|
str++;
|
||||||
|
int len = strlen(str);
|
||||||
|
|
||||||
|
// Disallows "0x" prefix that strtoul would ignore
|
||||||
|
if ((len != 6 && len != 8) || !isxdigit(str[0]) || !isxdigit(str[1]))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
char *ptr;
|
||||||
|
uint32_t parsed = strtoul(str, &ptr, 16);
|
||||||
|
if (*ptr)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (len == 8) {
|
||||||
|
clr->alpha = (parsed & 0xff) * 0x101;
|
||||||
|
parsed >>= 8;
|
||||||
|
} else {
|
||||||
|
clr->alpha = 0xffff;
|
||||||
|
}
|
||||||
|
clr->red = ((parsed >> 16) & 0xff) * 0x101;
|
||||||
|
clr->green = ((parsed >> 8) & 0xff) * 0x101;
|
||||||
|
clr->blue = ((parsed >> 0) & 0xff) * 0x101;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
handle_cmd(char *cmd, pixman_color_t *fg, pixman_color_t *bg,
|
||||||
|
pixman_color_t *def_fg, pixman_color_t *def_bg)
|
||||||
|
{
|
||||||
|
char *arg, *end;
|
||||||
|
|
||||||
|
if (!(arg = strchr(cmd, '(')) || !(end = strchr(arg + 1, ')')))
|
||||||
|
return cmd;
|
||||||
|
|
||||||
|
*arg++ = '\0';
|
||||||
|
*end = '\0';
|
||||||
|
|
||||||
|
if (!strcmp(cmd, "bg")) {
|
||||||
|
if (bg && def_bg) {
|
||||||
|
if (!*arg) {
|
||||||
|
*bg = *def_bg;
|
||||||
|
} else if (parse_color(arg, bg)) {
|
||||||
|
fprintf(stderr, "Bad color string \"%s\"\n", arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!strcmp(cmd, "fg")) {
|
||||||
|
if (fg && def_fg) {
|
||||||
|
if (!*arg) {
|
||||||
|
*fg = *def_fg;
|
||||||
|
} else if (parse_color(arg, fg)) {
|
||||||
|
fprintf(stderr, "Bad color string \"%s\"\n", arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unrecognized command \"%s\"\n", cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore string for later redraws */
|
||||||
|
*--arg = '(';
|
||||||
|
*end = ')';
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
draw_text(char *text,
|
draw_text(char *text,
|
||||||
uint32_t xpos,
|
uint32_t xpos,
|
||||||
@ -158,26 +225,51 @@ draw_text(char *text,
|
|||||||
pixman_image_t *background,
|
pixman_image_t *background,
|
||||||
pixman_color_t *fgcolor,
|
pixman_color_t *fgcolor,
|
||||||
pixman_color_t *bgcolor,
|
pixman_color_t *bgcolor,
|
||||||
uint32_t max_x,
|
uint32_t surface_width,
|
||||||
uint32_t height,
|
uint32_t height,
|
||||||
uint32_t padding)
|
uint32_t padding,
|
||||||
|
bool commands)
|
||||||
{
|
{
|
||||||
uint32_t codepoint;
|
uint32_t codepoint;
|
||||||
uint32_t state = UTF8_ACCEPT;
|
uint32_t state = UTF8_ACCEPT;
|
||||||
uint32_t ixpos = xpos;
|
uint32_t ixpos = xpos;
|
||||||
uint32_t nxpos;
|
uint32_t nxpos;
|
||||||
uint32_t lastcp = 0;
|
uint32_t lastcp = 0;
|
||||||
pixman_image_t *fgfill = pixman_image_create_solid_fill(fgcolor);
|
|
||||||
|
|
||||||
if (!*text)
|
|
||||||
return xpos;
|
|
||||||
|
|
||||||
if ((nxpos = xpos + padding) > max_x)
|
if (!*text || !surface_width || xpos >= surface_width)
|
||||||
return xpos;
|
return xpos;
|
||||||
|
|
||||||
|
if ((nxpos = xpos + padding) >= surface_width)
|
||||||
|
return xpos;
|
||||||
xpos = nxpos;
|
xpos = nxpos;
|
||||||
|
|
||||||
|
pixman_color_t cur_fgcolor = *fgcolor;
|
||||||
|
pixman_color_t cur_bgcolor;
|
||||||
|
if (background && bgcolor) {
|
||||||
|
cur_bgcolor = *bgcolor;
|
||||||
|
pixman_image_fill_boxes(PIXMAN_OP_OVER, background,
|
||||||
|
&cur_bgcolor, 1, &(pixman_box32_t){
|
||||||
|
.x1 = ixpos,
|
||||||
|
.x2 = xpos,
|
||||||
|
.y1 = 0,
|
||||||
|
.y2 = height
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pixman_image_t *fgfill = pixman_image_create_solid_fill(fgcolor);
|
||||||
|
|
||||||
for (char *p = text; *p; p++) {
|
for (char *p = text; *p; p++) {
|
||||||
|
/* Check for inline ^ commands */
|
||||||
|
if (commands && state == UTF8_ACCEPT && *p == '^') {
|
||||||
|
p++;
|
||||||
|
if (*p != '^') {
|
||||||
|
p = handle_cmd(p, &cur_fgcolor, &cur_bgcolor, fgcolor, bgcolor);
|
||||||
|
pixman_image_unref(fgfill);
|
||||||
|
fgfill = pixman_image_create_solid_fill(&cur_fgcolor);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns nonzero if more bytes are needed */
|
/* Returns nonzero if more bytes are needed */
|
||||||
if (utf8decode(&state, &codepoint, *p))
|
if (utf8decode(&state, &codepoint, *p))
|
||||||
continue;
|
continue;
|
||||||
@ -192,13 +284,11 @@ draw_text(char *text,
|
|||||||
long x_kern = 0;
|
long x_kern = 0;
|
||||||
if (lastcp)
|
if (lastcp)
|
||||||
fcft_kerning(font, lastcp, codepoint, &x_kern, NULL);
|
fcft_kerning(font, lastcp, codepoint, &x_kern, NULL);
|
||||||
|
if ((nxpos = xpos + x_kern + glyph->advance.x) >= surface_width) {
|
||||||
if ((nxpos = xpos + x_kern + glyph->advance.x) > max_x) {
|
|
||||||
if (!lastcp)
|
if (!lastcp)
|
||||||
return ixpos;
|
return ixpos;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
xpos += x_kern;
|
xpos += x_kern;
|
||||||
lastcp = codepoint;
|
lastcp = codepoint;
|
||||||
|
|
||||||
@ -219,6 +309,15 @@ draw_text(char *text,
|
|||||||
xpos + glyph->x, ypos - glyph->y, glyph->width, glyph->height);
|
xpos + glyph->x, ypos - glyph->y, glyph->width, glyph->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (background && bgcolor)
|
||||||
|
pixman_image_fill_boxes(PIXMAN_OP_OVER, background,
|
||||||
|
&cur_bgcolor, 1, &(pixman_box32_t){
|
||||||
|
.x1 = xpos,
|
||||||
|
.x2 = nxpos,
|
||||||
|
.y1 = 0,
|
||||||
|
.y2 = height
|
||||||
|
});
|
||||||
|
|
||||||
/* increment pen position */
|
/* increment pen position */
|
||||||
xpos = nxpos;
|
xpos = nxpos;
|
||||||
ypos += glyph->advance.y;
|
ypos += glyph->advance.y;
|
||||||
@ -227,17 +326,18 @@ draw_text(char *text,
|
|||||||
if (state != UTF8_ACCEPT)
|
if (state != UTF8_ACCEPT)
|
||||||
fprintf(stderr, "malformed UTF-8 sequence\n");
|
fprintf(stderr, "malformed UTF-8 sequence\n");
|
||||||
|
|
||||||
xpos = MIN(xpos + padding, max_x);
|
nxpos = MIN(xpos + padding, surface_width - 1);
|
||||||
|
|
||||||
if (background && bgcolor)
|
if (background && bgcolor)
|
||||||
pixman_image_fill_boxes(PIXMAN_OP_OVER, background,
|
pixman_image_fill_boxes(PIXMAN_OP_OVER, background,
|
||||||
bgcolor, 1, &(pixman_box32_t){
|
bgcolor, 1, &(pixman_box32_t){
|
||||||
.x1 = ixpos,
|
.x1 = xpos,
|
||||||
.x2 = xpos,
|
.x2 = nxpos,
|
||||||
.y1 = 0,
|
.y1 = 0,
|
||||||
.y2 = height
|
.y2 = height
|
||||||
});
|
});
|
||||||
|
xpos = nxpos;
|
||||||
|
|
||||||
pixman_image_unref(fgfill);
|
pixman_image_unref(fgfill);
|
||||||
|
|
||||||
return xpos;
|
return xpos;
|
||||||
@ -304,21 +404,21 @@ draw_frame(Bar *b)
|
|||||||
|
|
||||||
if (urgent)
|
if (urgent)
|
||||||
xpos_left = draw_text(tags[i], xpos_left, ypos, foreground_left, background_left,
|
xpos_left = draw_text(tags[i], xpos_left, ypos, foreground_left, background_left,
|
||||||
&urgtextcolor, &urgbgcolor, b->width, b->height, b->textpadding);
|
&urgtextcolor, &urgbgcolor, b->width, b->height, b->textpadding, false);
|
||||||
else
|
else
|
||||||
xpos_left = draw_text(tags[i], xpos_left, ypos, foreground_left, background_left,
|
xpos_left = draw_text(tags[i], xpos_left, ypos, foreground_left, background_left,
|
||||||
&textcolor, active ? &activecolor : &inactivecolor, b->width, b->height, b->textpadding);
|
&textcolor, active ? &activecolor : &inactivecolor, b->width, b->height, b->textpadding, false);
|
||||||
}
|
}
|
||||||
xpos_left = draw_text(b->layout, xpos_left, ypos, foreground_left, background_left,
|
xpos_left = draw_text(b->layout, xpos_left, ypos, foreground_left, background_left,
|
||||||
&textcolor, &inactivecolor, b->width, b->height, b->textpadding);
|
&textcolor, &inactivecolor, b->width, b->height, b->textpadding, false);
|
||||||
|
|
||||||
xpos_right = draw_text(b->status, 0, ypos, foreground_right, background_right,
|
xpos_right = draw_text(b->status, 0, ypos, foreground_right, background_right,
|
||||||
&textcolor, &inactivecolor, b->width, b->height, b->textpadding);
|
&textcolor, &inactivecolor, b->width, b->height, b->textpadding, true);
|
||||||
if (xpos_right > b->width)
|
if (xpos_right > b->width)
|
||||||
xpos_right = b->width;
|
xpos_right = b->width;
|
||||||
|
|
||||||
draw_text(b->title, 0, ypos, foreground_title, NULL,
|
draw_text(b->title, 0, ypos, foreground_title, NULL,
|
||||||
&textcolor, NULL, b->width, b->height, b->textpadding);
|
&textcolor, NULL, b->width, b->height, b->textpadding, false);
|
||||||
|
|
||||||
/* Draw background and foreground on bar */
|
/* Draw background and foreground on bar */
|
||||||
pixman_image_composite32(PIXMAN_OP_OVER, foreground_title, NULL, bar, 0, 0, 0, 0, xpos_left, 0, b->width, b->height);
|
pixman_image_composite32(PIXMAN_OP_OVER, foreground_title, NULL, bar, 0, 0, 0, 0, xpos_left, 0, b->width, b->height);
|
||||||
@ -722,35 +822,6 @@ client_send_command(struct sockaddr_un *sock_address,
|
|||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Color parsing logic adapted from [sway] */
|
|
||||||
static int
|
|
||||||
parse_color(const char *str, pixman_color_t *clr)
|
|
||||||
{
|
|
||||||
if (*str == '#')
|
|
||||||
str++;
|
|
||||||
int len = strlen(str);
|
|
||||||
|
|
||||||
// Disallows "0x" prefix that strtoul would ignore
|
|
||||||
if ((len != 6 && len != 8) || !isxdigit(str[0]) || !isxdigit(str[1]))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
char *ptr;
|
|
||||||
uint32_t parsed = strtoul(str, &ptr, 16);
|
|
||||||
if (*ptr)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (len == 8) {
|
|
||||||
clr->alpha = (parsed & 0xff) * 0x101;
|
|
||||||
parsed >>= 8;
|
|
||||||
} else {
|
|
||||||
clr->alpha = 0xffff;
|
|
||||||
}
|
|
||||||
clr->red = ((parsed >> 16) & 0xff) * 0x101;
|
|
||||||
clr->green = ((parsed >> 8) & 0xff) * 0x101;
|
|
||||||
clr->blue = ((parsed >> 0) & 0xff) * 0x101;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sig_handler(int sig)
|
sig_handler(int sig)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user