st-flexipatch

My st-flexipatch configuration
git clone git://git.ethandl.dev/st-flexipatch
Log | Files | Refs | README | LICENSE

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:
Mst.c | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Mst.h | 3+++
Mx.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;