From d9c95c900c91e1eed411f587a72e76975d4efda9 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 1 Nov 2019 09:09:53 +0000 Subject: [PATCH] Handle the various different forms of rgb colour strings. --- input.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/input.c b/input.c index fc08f42c..ee12301c 100644 --- a/input.c +++ b/input.c @@ -2338,6 +2338,54 @@ input_top_bit_set(struct input_ctx *ictx) return (0); } +/* Parse colour from OSC. */ +static int +input_osc_parse_colour(const char *p, u_int *r, u_int *g, u_int *b) +{ + u_int rsize, gsize, bsize; + const char *cp, *s = p; + + if (sscanf(p, "rgb:%x/%x/%x", r, g, b) != 3) + return (0); + p += 4; + + cp = strchr(p, '/'); + rsize = cp - p; + if (rsize == 1) + (*r) = (*r) | ((*r) << 4); + else if (rsize == 3) + (*r) >>= 4; + else if (rsize == 4) + (*r) >>= 8; + else if (rsize != 2) + return (0); + + p = cp + 1; + cp = strchr(p, '/'); + gsize = cp - p; + if (gsize == 1) + (*g) = (*g) | ((*g) << 4); + else if (gsize == 3) + (*g) >>= 4; + else if (gsize == 4) + (*g) >>= 8; + else if (gsize != 2) + return (0); + + bsize = strlen(cp + 1); + if (bsize == 1) + (*b) = (*b) | ((*b) << 4); + else if (bsize == 3) + (*b) >>= 4; + else if (bsize == 4) + (*b) >>= 8; + else if (bsize != 2) + return (0); + + log_debug("%s: %s = %02x%02x%02x", __func__, s, *r, *g, *b); + return (1); +} + /* Handle the OSC 4 sequence for setting (multiple) palette entries. */ static void input_osc_4(struct input_ctx *ictx, const char *p) @@ -2356,7 +2404,7 @@ input_osc_4(struct input_ctx *ictx, const char *p) goto bad; s = strsep(&next, ";"); - if (sscanf(s, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) { + if (!input_osc_parse_colour(s, &r, &g, &b)) { s = next; continue; } @@ -2381,8 +2429,11 @@ input_osc_10(struct input_ctx *ictx, const char *p) u_int r, g, b; char tmp[16]; - if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) - goto bad; + if (strcmp(p, "?") == 0) + return; + + if (!input_osc_parse_colour(p, &r, &g, &b)) + goto bad; xsnprintf(tmp, sizeof tmp, "fg=#%02x%02x%02x", r, g, b); options_set_style(wp->options, "window-style", 1, tmp); options_set_style(wp->options, "window-active-style", 1, tmp); @@ -2402,7 +2453,10 @@ input_osc_11(struct input_ctx *ictx, const char *p) u_int r, g, b; char tmp[16]; - if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) + if (strcmp(p, "?") == 0) + return; + + if (!input_osc_parse_colour(p, &r, &g, &b)) goto bad; xsnprintf(tmp, sizeof tmp, "bg=#%02x%02x%02x", r, g, b); options_set_style(wp->options, "window-style", 1, tmp);