diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-01-07 15:28:14 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-01-07 15:28:14 +0000 |
commit | 73518b1640ec808c1cb586ebc1a3be51a0856fd5 (patch) | |
tree | a57979fb68f5aba780ec2dc34ac6fa82bdbe612d /usr.bin/tmux/input.c | |
parent | c800158f37bd780643e37fdd3ba025cec53a5cb6 (diff) |
Add support for the OSC 4 and OSC 104 palette setting escape sequences,
from S Gilles.
Diffstat (limited to 'usr.bin/tmux/input.c')
-rw-r--r-- | usr.bin/tmux/input.c | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index 853a390a6bd..44b72b3876e 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.106 2016/12/09 21:39:27 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.107 2017/01/07 15:28:13 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -105,6 +105,9 @@ static void input_set_state(struct window_pane *, const struct input_transition *); static void input_reset_cell(struct input_ctx *); +static void input_osc_4(struct window_pane *, const char *); +static void input_osc_104(struct window_pane *, const char *); + /* Transition entry/exit handlers. */ static void input_clear(struct input_ctx *); static void input_ground(struct input_ctx *); @@ -162,6 +165,7 @@ enum input_esc_type { INPUT_ESC_SCSG0_ON, INPUT_ESC_SCSG1_OFF, INPUT_ESC_SCSG1_ON, + INPUT_ESC_ST, }; /* Escape command table. */ @@ -179,6 +183,7 @@ static const struct input_table_entry input_esc_table[] = { { 'E', "", INPUT_ESC_NEL }, { 'H', "", INPUT_ESC_HTS }, { 'M', "", INPUT_ESC_RI }, + { '\\', "", INPUT_ESC_ST }, { 'c', "", INPUT_ESC_RIS }, }; @@ -1141,6 +1146,7 @@ input_esc_dispatch(struct input_ctx *ictx) switch (entry->type) { case INPUT_ESC_RIS: + window_pane_reset_palette(ictx->wp); input_reset_cell(ictx); screen_write_reset(sctx); break; @@ -1188,6 +1194,9 @@ input_esc_dispatch(struct input_ctx *ictx) case INPUT_ESC_SCSG1_OFF: ictx->cell.g1set = 0; break; + case INPUT_ESC_ST: + /* ST terminates OSC but the state transition already did it. */ + break; } return (0); @@ -1850,10 +1859,16 @@ input_exit_osc(struct input_ctx *ictx) screen_set_title(ictx->ctx.s, p); server_status_window(ictx->wp->window); break; + case 4: + input_osc_4(ictx->wp, p); + break; case 12: if (*p != '?') /* ? is colour request */ screen_set_cursor_colour(ictx->ctx.s, p); break; + case 104: + input_osc_104(ictx->wp, p); + break; case 112: if (*p == '\0') /* no arguments allowed */ screen_set_cursor_colour(ictx->ctx.s, ""); @@ -1961,3 +1976,69 @@ input_utf8_close(struct input_ctx *ictx) return (0); } + +/* Handle the OSC 4 sequence for setting (multiple) palette entries. */ +static void +input_osc_4(struct window_pane *wp, const char *p) +{ + char *copy, *s, *next = NULL; + long idx; + u_int r, g, b; + + copy = s = xstrdup(p); + while (s != NULL && *s != '\0') { + idx = strtol(s, &next, 10); + if (*next++ != ';') + goto bad; + if (idx < 0 || idx >= 0x100) + goto bad; + + s = strsep(&next, ";"); + if (sscanf(s, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) { + s = next; + continue; + } + + window_pane_set_palette(wp, idx, colour_join_rgb(r, g, b)); + s = next; + } + + free(copy); + return; + +bad: + log_debug("bad OSC 4: %s", p); + free(copy); +} + +/* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */ +static void +input_osc_104(struct window_pane *wp, const char *p) +{ + char *copy, *s; + long idx; + + if (*p == '\0') { + window_pane_reset_palette(wp); + return; + } + + copy = s = xstrdup(p); + while (*s != '\0') { + idx = strtol(s, &s, 10); + if (*s != '\0' && *s != ';') + goto bad; + if (idx < 0 || idx >= 0x100) + goto bad; + + window_pane_unset_palette(wp, idx); + if (*s == ';') + s++; + } + free(copy); + return; + +bad: + log_debug("bad OSC 104: %s", p); + free(copy); +} |