commit 9ab02993c3906049965c10319fc6baf403ef4456
parent 7099c6ec7345e46a4baa101342ae9e5a31556aaf
Author: bakkeby <bakkeby@gmail.com>
Date: Thu, 24 Feb 2022 13:24:00 +0100
Add support for OSC color sequences
Ref.
- https://git.suckless.org/st/commit/8e310303903792c010d03c046ba75f8b18f7d3a7.html
- https://git.suckless.org/st/commit/273db5ceaf392e68c2faf8f7dec14ea2e25e980d.html
Diffstat:
| M | st.c | | | 79 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
| M | st.h | | | 3 | +++ |
| M | x.c | | | 13 | +++++++++++++ |
3 files changed, 76 insertions(+), 19 deletions(-)
diff --git a/st.c b/st.c
@@ -168,6 +168,8 @@ static void readcolonargs(char **, int, int[][CAR_PER_ARG]);
#endif // UNDERCURL_PATCH
static void csiparse(void);
static void csireset(void);
+static void osc4_color_response(int num);
+static void osc_color_response(int index, int num);
static int eschandle(uchar);
static void strdump(void);
static void strhandle(void);
@@ -2394,6 +2396,42 @@ csireset(void)
}
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)
{
char *p = NULL, *dec;
@@ -2443,44 +2481,45 @@ strhandle(void)
}
}
return;
- case 10: /* foreground set */
- #if OSC_10_11_12_2_PATCH
+ case 10:
if (narg < 2)
break;
p = strescseq.args[1];
- if (xsetcolorname(defaultfg, p))
- fprintf(stderr, "erresc: invalid foreground color %d\n", p);
+
+ if (!strcmp(p, "?"))
+ osc_color_response(defaultfg, 10);
+ else if (xsetcolorname(defaultfg, p))
+ fprintf(stderr, "erresc: invalid foreground color: %s\n", p);
else
redraw();
- break;
return;
- #endif // OSC_10_11_12_2_PATCH
- case 11: /* background set */
- #if OSC_10_11_12_2_PATCH
+ case 11:
if (narg < 2)
break;
p = strescseq.args[1];
- if (xsetcolorname(defaultbg, p))
- fprintf(stderr, "erresc: invalid background color %d\n", p);
+
+ if (!strcmp(p, "?"))
+ osc_color_response(defaultbg, 11);
+ else if (xsetcolorname(defaultbg, p))
+ fprintf(stderr, "erresc: invalid background color: %s\n", p);
else
redraw();
- break;
return;
- #endif // OSC_10_11_12_2_PATCH
- case 12: /* cursor color */
- #if OSC_10_11_12_2_PATCH
+ case 12:
if (narg < 2)
break;
p = strescseq.args[1];
- if (xsetcolorname(defaultcs, p))
- fprintf(stderr, "erresc: invalid cursor color %d\n", p);
+
+ if (!strcmp(p, "?"))
+ osc_color_response(defaultcs, 12);
+ else if (xsetcolorname(defaultcs, p))
+ fprintf(stderr, "erresc: invalid cursor color: %s\n", p);
else
redraw();
- break;
- #endif // OSC_10_11_12_2_PATCH
+ return;
case 4: /* color set */
if ((par == 4 && narg < 3) || narg < 2)
break;
@@ -2496,7 +2535,9 @@ strhandle(void)
else
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
- if (xsetcolorname(j, p)) {
+ if (!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",
diff --git a/st.h b/st.h
@@ -325,6 +325,9 @@ size_t utf8encode(Rune, char *);
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);
+
#if BOXDRAW_PATCH
int isboxdraw(Rune);
ushort boxdrawindex(const Glyph *);
diff --git a/x.c b/x.c
@@ -935,6 +935,19 @@ xloadcols(void)
#endif // ALPHA_FOCUS_HIGHLIGHT_PATCH
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)
{
Color ncolor;