summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/tmux/cmd-queue.c5
-rw-r--r--usr.bin/tmux/colour.c44
-rw-r--r--usr.bin/tmux/input.c117
-rw-r--r--usr.bin/tmux/tmux.h9
-rw-r--r--usr.bin/tmux/tty-keys.c85
-rw-r--r--usr.bin/tmux/tty.c12
6 files changed, 205 insertions, 67 deletions
diff --git a/usr.bin/tmux/cmd-queue.c b/usr.bin/tmux/cmd-queue.c
index 2ca2eb81266..cfeb48c59c5 100644
--- a/usr.bin/tmux/cmd-queue.c
+++ b/usr.bin/tmux/cmd-queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-queue.c,v 1.112 2022/12/16 08:22:05 nicm Exp $ */
+/* $OpenBSD: cmd-queue.c,v 1.113 2023/01/03 11:43:24 nicm Exp $ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -834,7 +834,8 @@ cmdq_print_data(struct cmdq_item *item, int parse, struct evbuffer *evb)
char *sanitized, *msg, *line;
if (!parse) {
- utf8_stravisx(&msg, data, size, VIS_OCTAL|VIS_CSTYLE);
+ utf8_stravisx(&msg, data, size,
+ VIS_OCTAL|VIS_CSTYLE|VIS_NOSLASH);
log_debug("%s: %s", __func__, msg);
} else {
msg = EVBUFFER_DATA(evb);
diff --git a/usr.bin/tmux/colour.c b/usr.bin/tmux/colour.c
index 16080ae3f50..4f7a9a08d55 100644
--- a/usr.bin/tmux/colour.c
+++ b/usr.bin/tmux/colour.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: colour.c,v 1.25 2022/03/24 12:07:25 nicm Exp $ */
+/* $OpenBSD: colour.c,v 1.26 2023/01/03 11:43:24 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -960,6 +960,47 @@ colour_byname(const char *name)
return (-1);
}
+/* Parse colour from an X11 string. */
+int
+colour_parseX11(const char *p)
+{
+ double c, m, y, k = 0;
+ u_int r, g, b;
+ size_t len = strlen(p);
+ int colour = -1;
+ char *copy;
+
+ if ((len == 12 && sscanf(p, "rgb:%02x/%02x/%02x", &r, &g, &b) == 3) ||
+ (len == 7 && sscanf(p, "#%02x%02x%02x", &r, &g, &b) == 3) ||
+ sscanf(p, "%d,%d,%d", &r, &g, &b) == 3)
+ colour = colour_join_rgb(r, g, b);
+ else if ((len == 18 &&
+ sscanf(p, "rgb:%04x/%04x/%04x", &r, &g, &b) == 3) ||
+ (len == 13 && sscanf(p, "#%04x%04x%04x", &r, &g, &b) == 3))
+ colour = colour_join_rgb(r >> 8, g >> 8, b >> 8);
+ else if ((sscanf(p, "cmyk:%lf/%lf/%lf/%lf", &c, &m, &y, &k) == 4 ||
+ sscanf(p, "cmy:%lf/%lf/%lf", &c, &m, &y) == 3) &&
+ c >= 0 && c <= 1 && m >= 0 && m <= 1 &&
+ y >= 0 && y <= 1 && k >= 0 && k <= 1) {
+ colour = colour_join_rgb(
+ (1 - c) * (1 - k) * 255,
+ (1 - m) * (1 - k) * 255,
+ (1 - y) * (1 - k) * 255);
+ } else {
+ while (len != 0 && *p == ' ') {
+ p++;
+ len--;
+ }
+ while (len != 0 && p[len - 1] == ' ')
+ len--;
+ copy = xstrndup(p, len);
+ colour = colour_byname(copy);
+ free(copy);
+ }
+ log_debug("%s: %s = %s", __func__, p, colour_tostring(colour));
+ return (colour);
+}
+
/* Initialize palette. */
void
colour_palette_init(struct colour_palette *p)
@@ -1069,5 +1110,4 @@ colour_palette_from_option(struct colour_palette *p, struct options *oo)
}
a = options_array_next(a);
}
-
}
diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c
index fd3ed0744b9..6ca2f08db38 100644
--- a/usr.bin/tmux/input.c
+++ b/usr.bin/tmux/input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: input.c,v 1.212 2022/11/11 08:37:55 nicm Exp $ */
+/* $OpenBSD: input.c,v 1.213 2023/01/03 11:43:24 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1086,6 +1086,7 @@ input_reply(struct input_ctx *ictx, const char *fmt, ...)
xvasprintf(&reply, fmt, ap);
va_end(ap);
+ log_debug("%s: %s", __func__, reply);
bufferevent_write(bev, reply, strlen(reply));
free(reply);
}
@@ -2456,47 +2457,6 @@ input_top_bit_set(struct input_ctx *ictx)
return (0);
}
-/* Parse colour from OSC. */
-static int
-input_osc_parse_colour(const char *p)
-{
- double c, m, y, k = 0;
- u_int r, g, b;
- size_t len = strlen(p);
- int colour = -1;
- char *copy;
-
- if ((len == 12 && sscanf(p, "rgb:%02x/%02x/%02x", &r, &g, &b) == 3) ||
- (len == 7 && sscanf(p, "#%02x%02x%02x", &r, &g, &b) == 3) ||
- sscanf(p, "%d,%d,%d", &r, &g, &b) == 3)
- colour = colour_join_rgb(r, g, b);
- else if ((len == 18 &&
- sscanf(p, "rgb:%04x/%04x/%04x", &r, &g, &b) == 3) ||
- (len == 13 && sscanf(p, "#%04x%04x%04x", &r, &g, &b) == 3))
- colour = colour_join_rgb(r >> 8, g >> 8, b >> 8);
- else if ((sscanf(p, "cmyk:%lf/%lf/%lf/%lf", &c, &m, &y, &k) == 4 ||
- sscanf(p, "cmy:%lf/%lf/%lf", &c, &m, &y) == 3) &&
- c >= 0 && c <= 1 && m >= 0 && m <= 1 &&
- y >= 0 && y <= 1 && k >= 0 && k <= 1) {
- colour = colour_join_rgb(
- (1 - c) * (1 - k) * 255,
- (1 - m) * (1 - k) * 255,
- (1 - y) * (1 - k) * 255);
- } else {
- while (len != 0 && *p == ' ') {
- p++;
- len--;
- }
- while (len != 0 && p[len - 1] == ' ')
- len--;
- copy = xstrndup(p, len);
- colour = colour_byname(copy);
- free(copy);
- }
- log_debug("%s: %s = %s", __func__, p, colour_tostring(colour));
- return (colour);
-}
-
/* Reply to a colour request. */
static void
input_osc_colour_reply(struct input_ctx *ictx, u_int n, int c)
@@ -2545,7 +2505,7 @@ input_osc_4(struct input_ctx *ictx, const char *p)
input_osc_colour_reply(ictx, 4, c);
continue;
}
- if ((c = input_osc_parse_colour(s)) == -1) {
+ if ((c = colour_parseX11(s)) == -1) {
s = next;
continue;
}
@@ -2601,6 +2561,47 @@ bad:
free(id);
}
+/*
+ * Get a client with a foreground for the pane. There isn't much to choose
+ * between them so just use the first.
+ */
+static int
+input_get_fg_client(struct window_pane *wp)
+{
+ struct window *w = wp->window;
+ struct client *loop;
+
+ TAILQ_FOREACH(loop, &clients, entry) {
+ if (loop->flags & CLIENT_UNATTACHEDFLAGS)
+ continue;
+ if (loop->session == NULL || !session_has(loop->session, w))
+ continue;
+ if (loop->tty.fg == -1)
+ continue;
+ return (loop->tty.fg);
+ }
+ return (-1);
+}
+
+/* Get a client with a background for the pane. */
+static int
+input_get_bg_client(struct window_pane *wp)
+{
+ struct window *w = wp->window;
+ struct client *loop;
+
+ TAILQ_FOREACH(loop, &clients, entry) {
+ if (loop->flags & CLIENT_UNATTACHEDFLAGS)
+ continue;
+ if (loop->session == NULL || !session_has(loop->session, w))
+ continue;
+ if (loop->tty.bg == -1)
+ continue;
+ return (loop->tty.bg);
+ }
+ return (-1);
+}
+
/* Handle the OSC 10 sequence for setting and querying foreground colour. */
static void
input_osc_10(struct input_ctx *ictx, const char *p)
@@ -2610,14 +2611,18 @@ input_osc_10(struct input_ctx *ictx, const char *p)
int c;
if (strcmp(p, "?") == 0) {
- if (wp != NULL) {
- tty_default_colours(&defaults, wp);
- input_osc_colour_reply(ictx, 10, defaults.fg);
- }
+ if (wp == NULL)
+ return;
+ tty_default_colours(&defaults, wp);
+ if (COLOUR_DEFAULT(defaults.fg))
+ c = input_get_fg_client(wp);
+ else
+ c = defaults.fg;
+ input_osc_colour_reply(ictx, 10, c);
return;
}
- if ((c = input_osc_parse_colour(p)) == -1) {
+ if ((c = colour_parseX11(p)) == -1) {
log_debug("bad OSC 10: %s", p);
return;
}
@@ -2654,14 +2659,18 @@ input_osc_11(struct input_ctx *ictx, const char *p)
int c;
if (strcmp(p, "?") == 0) {
- if (wp != NULL) {
- tty_default_colours(&defaults, wp);
- input_osc_colour_reply(ictx, 11, defaults.bg);
- }
+ if (wp == NULL)
+ return;
+ tty_default_colours(&defaults, wp);
+ if (COLOUR_DEFAULT(defaults.bg))
+ c = input_get_bg_client(wp);
+ else
+ c = defaults.bg;
+ input_osc_colour_reply(ictx, 11, c);
return;
}
- if ((c = input_osc_parse_colour(p)) == -1) {
+ if ((c = colour_parseX11(p)) == -1) {
log_debug("bad OSC 11: %s", p);
return;
}
@@ -2706,7 +2715,7 @@ input_osc_12(struct input_ctx *ictx, const char *p)
return;
}
- if ((c = input_osc_parse_colour(p)) == -1) {
+ if ((c = colour_parseX11(p)) == -1) {
log_debug("bad OSC 12: %s", p);
return;
}
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 4c2544b7fa8..f3b57669f72 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1188 2022/12/26 19:16:03 jmc Exp $ */
+/* $OpenBSD: tmux.h,v 1.1189 2023/01/03 11:43:24 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1380,6 +1380,8 @@ struct tty {
u_int osy;
int mode;
+ int fg;
+ int bg;
u_int rlower;
u_int rupper;
@@ -1411,6 +1413,10 @@ struct tty {
#define TTY_HAVEXDA 0x200
#define TTY_SYNCING 0x400
#define TTY_HAVEDA2 0x800 /* Secondary DA. */
+#define TTY_HAVEFG 0x1000
+#define TTY_HAVEBG 0x2000
+#define TTY_ALL_REQUEST_FLAGS \
+ (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA|TTY_HAVEFG|TTY_HAVEBG)
int flags;
struct tty_term *term;
@@ -2759,6 +2765,7 @@ int colour_fromstring(const char *s);
int colour_256toRGB(int);
int colour_256to16(int);
int colour_byname(const char *);
+int colour_parseX11(const char *);
void colour_palette_init(struct colour_palette *);
void colour_palette_clear(struct colour_palette *);
void colour_palette_free(struct colour_palette *);
diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c
index 06ac22570a0..d0a423daf3c 100644
--- a/usr.bin/tmux/tty-keys.c
+++ b/usr.bin/tmux/tty-keys.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty-keys.c,v 1.162 2022/11/11 08:44:11 nicm Exp $ */
+/* $OpenBSD: tty-keys.c,v 1.163 2023/01/03 11:43:24 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -59,6 +59,7 @@ static int tty_keys_device_attributes2(struct tty *, const char *, size_t,
size_t *);
static int tty_keys_extended_device_attributes(struct tty *, const char *,
size_t, size_t *);
+static int tty_keys_colours(struct tty *, const char *, size_t, size_t *);
/* A key tree entry. */
struct tty_key {
@@ -719,6 +720,17 @@ tty_keys_next(struct tty *tty)
goto partial_key;
}
+ /* Is this a colours response? */
+ switch (tty_keys_colours(tty, buf, len, &size)) {
+ case 0: /* yes */
+ key = KEYC_UNKNOWN;
+ goto complete_key;
+ case -1: /* no, or not valid */
+ break;
+ case 1: /* partial */
+ goto partial_key;
+ }
+
/* Is this a mouse key press? */
switch (tty_keys_mouse(tty, buf, len, &size, &m)) {
case 0: /* yes */
@@ -1278,7 +1290,7 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
if (len == 3)
return (1);
- /* Copy the rest up to a 'c'. */
+ /* Copy the rest up to a c. */
for (i = 0; i < (sizeof tmp); i++) {
if (3 + i == len)
return (1);
@@ -1352,7 +1364,7 @@ tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len,
if (len == 3)
return (1);
- /* Copy the rest up to a 'c'. */
+ /* Copy the rest up to a c. */
for (i = 0; i < (sizeof tmp); i++) {
if (3 + i == len)
return (1);
@@ -1433,7 +1445,7 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
if (len == 4)
return (1);
- /* Copy the rest up to a '\033\\'. */
+ /* Copy the rest up to \033\. */
for (i = 0; i < (sizeof tmp) - 1; i++) {
if (4 + i == len)
return (1);
@@ -1465,3 +1477,68 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
return (0);
}
+
+/*
+ * Handle foreground or background input. Returns 0 for success, -1 for
+ * failure, 1 for partial.
+ */
+static int
+tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size)
+{
+ struct client *c = tty->client;
+ u_int i;
+ char tmp[128];
+ int n;
+
+ *size = 0;
+ if ((tty->flags & TTY_HAVEFG) && (tty->flags & TTY_HAVEBG))
+ return (-1);
+
+ /* First four bytes are always \033]1 and 0 or 1 and ;. */
+ if (buf[0] != '\033')
+ return (-1);
+ if (len == 1)
+ return (1);
+ if (buf[1] != ']')
+ return (-1);
+ if (len == 2)
+ return (1);
+ if (buf[2] != '1')
+ return (-1);
+ if (len == 3)
+ return (1);
+ if (buf[3] != '0' && buf[3] != '1')
+ return (-1);
+ if (len == 4)
+ return (1);
+ if (buf[4] != ';')
+ return (-1);
+ if (len == 5)
+ return (1);
+
+ /* Copy the rest up to \033\. */
+ for (i = 0; i < (sizeof tmp) - 1; i++) {
+ if (5 + i == len)
+ return (1);
+ if (buf[5 + i - 1] == '\033' && buf[5 + i] == '\\')
+ break;
+ tmp[i] = buf[5 + i];
+ }
+ if (i == (sizeof tmp) - 1)
+ return (-1);
+ tmp[i - 1] = '\0';
+ *size = 6 + i;
+
+ n = colour_parseX11(tmp);
+ if (n != -1 && buf[3] == '0') {
+ log_debug("%s: foreground is %s", c->name, colour_tostring(n));
+ tty->fg = n;
+ tty->flags |= TTY_HAVEFG;
+ } else if (n != -1) {
+ log_debug("%s: background is %s", c->name, colour_tostring(n));
+ tty->bg = n;
+ tty->flags |= TTY_HAVEBG;
+ }
+
+ return (0);
+}
diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c
index d3c6f9645fb..a810aede094 100644
--- a/usr.bin/tmux/tty.c
+++ b/usr.bin/tmux/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.425 2022/11/11 08:37:55 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.426 2023/01/03 11:43:24 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -108,6 +108,7 @@ tty_init(struct tty *tty, struct client *c)
tty->cstyle = SCREEN_CURSOR_DEFAULT;
tty->ccolour = -1;
+ tty->fg = tty->bg = -1;
if (tcgetattr(c->fd, &tty->tio) != 0)
return (-1);
@@ -286,7 +287,6 @@ tty_open(struct tty *tty, char **cause)
evtimer_set(&tty->timer, tty_timer_callback, tty);
tty_start_tty(tty);
-
tty_keys_build(tty);
return (0);
@@ -301,7 +301,7 @@ tty_start_timer_callback(__unused int fd, __unused short events, void *data)
log_debug("%s: start timer fired", c->name);
if ((tty->flags & (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA)) == 0)
tty_update_features(tty);
- tty->flags |= (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA);
+ tty->flags |= TTY_ALL_REQUEST_FLAGS;
}
void
@@ -369,8 +369,12 @@ tty_send_requests(struct tty *tty)
tty_puts(tty, "\033[>c");
if (~tty->flags & TTY_HAVEXDA)
tty_puts(tty, "\033[>q");
+ if (~tty->flags & TTY_HAVEFG)
+ tty_puts(tty, "\033]10;?\033\\");
+ if (~tty->flags & TTY_HAVEBG)
+ tty_puts(tty, "\033]11;?\033\\");
} else
- tty->flags |= (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA);
+ tty->flags |= TTY_ALL_REQUEST_FLAGS;
}
void