summaryrefslogtreecommitdiffstats
path: root/input.c
diff options
context:
space:
mode:
authornicm <nicm>2017-01-07 15:28:13 +0000
committernicm <nicm>2017-01-07 15:28:13 +0000
commit314e933914de4096c40e623c793049d26484d53a (patch)
tree8de850ef5c15384a8b2400af496200a235ed16ff /input.c
parentcae0fbbe8c7cc16ac38aa8149ef9b4e2a54bce0e (diff)
Add support for the OSC 4 and OSC 104 palette setting escape sequences,
from S Gilles.
Diffstat (limited to 'input.c')
-rw-r--r--input.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/input.c b/input.c
index 447c1b85..d5dcaf0e 100644
--- a/input.c
+++ b/input.c
@@ -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);
+}