support OSC color sequences

cherry picked from upstream:

* a0467c8 Fix null pointer access in strhandle
* 273db5c follow-up fix for OSC color sequences, return
* 8e31030 Add support for OSC color sequences
master
alex 2 years ago
parent fc4e65b479
commit f421245c06

@ -117,18 +117,20 @@ static const char *colorname[] = {
[15] = "#ffffff", /* white */
/* special colors */
[256] = "#282a36", /* background */
[257] = "#f8f8f2", /* foreground */
[256] = "#f8f8f2", /* cursor */
[257] = "#282a36", /* reverse cursor */
[258] = "#f8f8f2", /* foreground */
[259] = "#282a36", /* background */
};
/*
* Default colors (colorname index)
* foreground, background, cursor
* cursor, reverse cursor foreground, background
*/
unsigned int defaultfg = 257;
unsigned int defaultbg = 256;
static unsigned int defaultcs = 257;
static unsigned int defaultcs = 256;
static unsigned int defaultrcs = 257;
unsigned int defaultfg = 258;
unsigned int defaultbg = 259;
/*
* Colors used, when the specific fg == defaultfg. So in reverse mode this

82
st.c

@ -1904,6 +1904,42 @@ csireset(void)
memset(&csiescseq, 0, sizeof(csiescseq));
}
void
osc4_color_response(int num)
{
int n;
char buf[32];
unsigned char r, g, b;
if (xgetcolor(num, &r, &g, &b)) {
fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num);
return;
}
n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
num, r, r, g, g, b, b);
ttywrite(buf, n, 1);
}
void
osc_color_response(int index, int num)
{
int n;
char buf[32];
unsigned char r, g, b;
if (xgetcolor(index, &r, &g, &b)) {
fprintf(stderr, "erresc: failed to fetch osc color %d\n", index);
return;
}
n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
num, r, r, g, g, b, b);
ttywrite(buf, n, 1);
}
void
strhandle(void)
{
@ -1942,14 +1978,56 @@ strhandle(void)
}
}
return;
case 10:
if (narg < 2)
break;
p = strescseq.args[1];
if (!strcmp(p, "?"))
osc_color_response(defaultfg, 10);
else if (xsetcolorname(defaultfg, p))
fprintf(stderr, "erresc: invalid foreground color: %s\n", p);
else
redraw();
return;
case 11:
if (narg < 2)
break;
p = strescseq.args[1];
if (!strcmp(p, "?"))
osc_color_response(defaultbg, 11);
else if (xsetcolorname(defaultbg, p))
fprintf(stderr, "erresc: invalid background color: %s\n", p);
else
redraw();
return;
case 12:
if (narg < 2)
break;
p = strescseq.args[1];
if (!strcmp(p, "?"))
osc_color_response(defaultcs, 12);
else if (xsetcolorname(defaultcs, p))
fprintf(stderr, "erresc: invalid cursor color: %s\n", p);
else
redraw();
return;
case 4: /* color set */
if (narg < 3)
break;
p = strescseq.args[2];
/* FALLTHROUGH */
case 104: /* color reset, here p = NULL */
case 104: /* color reset */
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
if (xsetcolorname(j, p)) {
if (p && !strcmp(p, "?"))
osc4_color_response(j);
else if (xsetcolorname(j, p)) {
if (par == 104 && narg <= 1)
return; /* color reset without parameter */
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",

@ -113,6 +113,8 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *);
int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b);
/* config.h globals */
extern char *utmp;
extern char *scroll;
@ -125,3 +127,4 @@ extern char *termname;
extern unsigned int tabspaces;
extern unsigned int defaultfg;
extern unsigned int defaultbg;
extern unsigned int defaultcs;

17
x.c

@ -790,6 +790,19 @@ xloadcols(void)
loaded = 1;
}
int
xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b)
{
if (!BETWEEN(x, 0, dc.collen))
return 1;
*r = dc.col[x].color.red >> 8;
*g = dc.col[x].color.green >> 8;
*b = dc.col[x].color.blue >> 8;
return 0;
}
int
xsetcolorname(int x, const char *name)
{
@ -2045,12 +2058,12 @@ xrdb_load(void)
// this looks confusing because we are chaining off of the if
// in the macro. probably we should be wrapping everything blocks
// so this isn't possible...
defaultcs = defaultfg;
colorname[defaultcs] = xstrdup(colorname[defaultfg]);
}
XRESOURCE_LOAD_STRING("reverse-cursor", colorname[defaultrcs])
else {
// see above.
defaultrcs = defaultbg;
colorname[defaultrcs] = xstrdup(colorname[defaultbg]);
}
XRESOURCE_LOAD_STRING("font", font);

Loading…
Cancel
Save