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 */ [15] = "#ffffff", /* white */
/* special colors */ /* special colors */
[256] = "#282a36", /* background */ [256] = "#f8f8f2", /* cursor */
[257] = "#f8f8f2", /* foreground */ [257] = "#282a36", /* reverse cursor */
[258] = "#f8f8f2", /* foreground */
[259] = "#282a36", /* background */
}; };
/* /*
* Default colors (colorname index) * Default colors (colorname index)
* foreground, background, cursor * cursor, reverse cursor foreground, background
*/ */
unsigned int defaultfg = 257; static unsigned int defaultcs = 256;
unsigned int defaultbg = 256;
static unsigned int defaultcs = 257;
static unsigned int defaultrcs = 257; 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 * 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)); 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 void
strhandle(void) strhandle(void)
{ {
@ -1942,14 +1978,56 @@ strhandle(void)
} }
} }
return; 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 */ case 4: /* color set */
if (narg < 3) if (narg < 3)
break; break;
p = strescseq.args[2]; p = strescseq.args[2];
/* FALLTHROUGH */ /* FALLTHROUGH */
case 104: /* color reset, here p = NULL */ case 104: /* color reset */
j = (narg > 1) ? atoi(strescseq.args[1]) : -1; 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) if (par == 104 && narg <= 1)
return; /* color reset without parameter */ return; /* color reset without parameter */
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",

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

17
x.c

@ -790,6 +790,19 @@ xloadcols(void)
loaded = 1; 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 int
xsetcolorname(int x, const char *name) xsetcolorname(int x, const char *name)
{ {
@ -2045,12 +2058,12 @@ xrdb_load(void)
// this looks confusing because we are chaining off of the if // this looks confusing because we are chaining off of the if
// in the macro. probably we should be wrapping everything blocks // in the macro. probably we should be wrapping everything blocks
// so this isn't possible... // so this isn't possible...
defaultcs = defaultfg; colorname[defaultcs] = xstrdup(colorname[defaultfg]);
} }
XRESOURCE_LOAD_STRING("reverse-cursor", colorname[defaultrcs]) XRESOURCE_LOAD_STRING("reverse-cursor", colorname[defaultrcs])
else { else {
// see above. // see above.
defaultrcs = defaultbg; colorname[defaultrcs] = xstrdup(colorname[defaultbg]);
} }
XRESOURCE_LOAD_STRING("font", font); XRESOURCE_LOAD_STRING("font", font);

Loading…
Cancel
Save