Sync OpenBSD patchset 317:

Permit embedded colour and attributes in status-left and status-right using new
#[] special characters, for example #[fg=red,bg=blue,blink].
This commit is contained in:
Tiago Cunha
2009-09-07 23:37:48 +00:00
parent ec195a4e15
commit 5edc465802
4 changed files with 219 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $Id: screen-write.c,v 1.70 2009-08-21 21:13:20 tcunha Exp $ */
/* $Id: screen-write.c,v 1.71 2009-09-07 23:37:48 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -52,6 +52,41 @@ screen_write_putc(
screen_write_cell(ctx, gc, NULL);
}
/* Calculate string length, with embedded formatting. */
size_t printflike2
screen_write_cstrlen(int utf8flag, const char *fmt, ...)
{
va_list ap;
char *msg, *msg2, *ptr, *ptr2;
size_t size;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
msg2 = xmalloc(strlen(msg) + 1);
ptr = msg;
ptr2 = msg2;
while (*ptr != '\0') {
if (ptr[0] == '#' && ptr[1] == '[') {
while (*ptr != ']' && *ptr != '\0')
ptr++;
if (*ptr == ']')
ptr++;
continue;
}
*ptr2++ = *ptr++;
}
*ptr2 = '\0';
size = screen_write_strlen(utf8flag, "%s", msg2);
xfree(msg);
xfree(msg2);
return (size);
}
/* Calculate string length. */
size_t printflike2
screen_write_strlen(int utf8flag, const char *fmt, ...)
@ -177,6 +212,143 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
xfree(msg);
}
/* Write string, similar to nputs, but with embedded formatting (#[]). */
void printflike5
screen_write_cnputs(struct screen_write_ctx *ctx,
ssize_t maxlen, struct grid_cell *gc, int utf8flag, const char *fmt, ...)
{
struct grid_cell lgc;
va_list ap;
char *msg;
u_char *ptr, *last, utf8buf[4];
size_t left, size = 0;
int width;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
memcpy(&lgc, gc, sizeof lgc);
ptr = msg;
while (*ptr != '\0') {
if (ptr[0] == '#' && ptr[1] == '[') {
ptr += 2;
last = ptr + strcspn(ptr, "]");
if (*last == '\0') {
/* No ]. Not much point in doing anything. */
break;
}
*last = '\0';
screen_write_parsestyle(gc, &lgc, ptr);
ptr = last + 1;
continue;
}
if (utf8flag && *ptr > 0x7f) {
memset(utf8buf, 0xff, sizeof utf8buf);
left = strlen(ptr);
if (*ptr >= 0xc2 && *ptr <= 0xdf && left >= 2) {
memcpy(utf8buf, ptr, 2);
ptr += 2;
} else if (*ptr >= 0xe0 && *ptr <= 0xef && left >= 3) {
memcpy(utf8buf, ptr, 3);
ptr += 3;
} else if (*ptr >= 0xf0 && *ptr <= 0xf4 && left >= 4) {
memcpy(utf8buf, ptr, 4);
ptr += 4;
} else {
*utf8buf = *ptr;
ptr++;
}
width = utf8_width(utf8buf);
if (maxlen > 0 && size + width > (size_t) maxlen) {
while (size < (size_t) maxlen) {
screen_write_putc(ctx, gc, ' ');
size++;
}
break;
}
size += width;
lgc.flags |= GRID_FLAG_UTF8;
screen_write_cell(ctx, &lgc, utf8buf);
lgc.flags &= ~GRID_FLAG_UTF8;
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
size++;
screen_write_putc(ctx, &lgc, *ptr);
ptr++;
}
}
xfree(msg);
}
/* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */
void
screen_write_parsestyle(
struct grid_cell *defgc, struct grid_cell *gc, const char *in)
{
const char delimiters[] = " ,";
char tmp[32];
int val;
size_t end;
u_char fg, bg, attr;
if (*in == '\0')
return;
if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
return;
fg = gc->fg;
bg = gc->bg;
attr = 0;
do {
end = strcspn(in, delimiters);
if (end > (sizeof tmp) - 1)
return;
memcpy(tmp, in, end);
tmp[end] = '\0';
if (strcasecmp(tmp, "default") == 0) {
fg = defgc->fg;
bg = defgc->bg;
attr = defgc->attr;
} else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
if ((val = colour_fromstring(tmp + 3)) == -1)
return;
if (*in == 'f' || *in == 'F') {
if (val != 8)
fg = val;
else
fg = defgc->fg;
} else if (*in == 'b' || *in == 'B') {
if (val != 8)
bg = val;
else
bg = defgc->bg;
} else
return;
} else {
if ((val = attributes_fromstring(tmp)) == -1)
return;
attr |= val;
}
in += end + strspn(in + end, delimiters);
} while (*in != '\0');
gc->fg = fg;
gc->bg = bg;
gc->attr = attr;
}
/* Copy from another screen. */
void
screen_write_copy(struct screen_write_ctx *ctx,