summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2019-11-28 12:35:18 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2019-11-30 09:30:21 +0000
commit968382aa6a4b9c71fbc221aa4f0e899f6a83a260 (patch)
treef7ed283e9d8b865ce303ec3990ed9efa40af27c3
parent866b053f25227d39c975f187a8ad54bd70efd139 (diff)
Pass through SIXEL DCS sequences (treat similarly to the passthrough escape
sequence) if it appears the terminal outside supports them.
-rw-r--r--input.c18
-rw-r--r--screen-write.c15
-rw-r--r--tmux.12
-rw-r--r--tmux.h7
-rw-r--r--tty-keys.c9
-rw-r--r--tty-term.c1
-rw-r--r--tty.c15
7 files changed, 57 insertions, 10 deletions
diff --git a/input.c b/input.c
index 452eac7f..b8d2f102 100644
--- a/input.c
+++ b/input.c
@@ -1305,8 +1305,8 @@ input_csi_dispatch(struct input_ctx *ictx)
if (ictx->flags & INPUT_DISCARD)
return (0);
- log_debug("%s: '%c' \"%s\" \"%s\"",
- __func__, ictx->ch, ictx->interm_buf, ictx->param_buf);
+ log_debug("%s: '%c' \"%s\" \"%s\"", __func__, ictx->ch,
+ ictx->interm_buf, ictx->param_buf);
if (input_split(ictx) != 0)
return (0);
@@ -2151,19 +2151,27 @@ static int
input_dcs_dispatch(struct input_ctx *ictx)
{
struct screen_write_ctx *sctx = &ictx->ctx;
- u_char *buf = ictx->input_buf;
- size_t len = ictx->input_len;
+ u_char *buf = ictx->input_buf, *pbuf = ictx->param_buf;
+ size_t len = ictx->input_len, plen = ictx->param_len;
const char prefix[] = "tmux;";
const u_int prefixlen = (sizeof prefix) - 1;
if (ictx->flags & INPUT_DISCARD)
return (0);
- log_debug("%s: \"%s\"", __func__, buf);
+ log_debug("%s: \"%s\" \"%s\" \"%s\"", __func__, buf, ictx->interm_buf,
+ ictx->param_buf);
if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0)
screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen);
+ if (buf[0] == 'q') {
+ screen_write_rawsixel(sctx, (char *)"\033P", 2, 1);
+ screen_write_rawsixel(sctx, pbuf, plen, 1);
+ screen_write_rawsixel(sctx, buf, len, 1);
+ screen_write_rawsixel(sctx, (char *)"\033\\", 2, 0);
+ }
+
return (0);
}
diff --git a/screen-write.c b/screen-write.c
index 43cb42b4..9bd28836 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -1671,3 +1671,18 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
tty_write(tty_cmd_rawstring, &ttyctx);
}
+
+/* Write unmodified SIXEL data. */
+void
+screen_write_rawsixel(struct screen_write_ctx *ctx, u_char *str, u_int len,
+ int more)
+{
+ struct tty_ctx ttyctx;
+
+ screen_write_initctx(ctx, &ttyctx);
+ ttyctx.ptr = str;
+ ttyctx.num = len;
+ ttyctx.more = more;
+
+ tty_write(tty_cmd_rawsixel, &ttyctx);
+}
diff --git a/tmux.1 b/tmux.1
index 9513bd79..aac4625c 100644
--- a/tmux.1
+++ b/tmux.1
@@ -5200,6 +5200,8 @@ $ printf '\e033[4 q'
If
.Em Se
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
+.It Em \&Sxl
+Indicates that the terminal supports SIXEL.
.It Em \&Tc
Indicate that the terminal supports the
.Ql direct colour
diff --git a/tmux.h b/tmux.h
index b7220b88..7c901b9d 100644
--- a/tmux.h
+++ b/tmux.h
@@ -446,6 +446,7 @@ enum tty_code_code {
TTYC_SMULX,
TTYC_SMUL,
TTYC_SMXX,
+ TTYC_SXL,
TTYC_SS,
TTYC_TC,
TTYC_TSL,
@@ -1145,6 +1146,7 @@ struct tty_term {
#define TERM_256COLOURS 0x1
#define TERM_EARLYWRAP 0x2
+#define TERM_SIXEL 0x4
int flags;
LIST_ENTRY(tty_term) entry;
@@ -1248,6 +1250,7 @@ struct tty_ctx {
u_int num;
void *ptr;
+ int more;
/*
* Cursor and region position before the screen was updated - this is
@@ -1947,7 +1950,7 @@ void tty_draw_line(struct tty *, struct window_pane *, struct screen *,
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
-void tty_set_type(struct tty *, int);
+void tty_set_type(struct tty *, int, int);
void tty_write(void (*)(struct tty *, const struct tty_ctx *),
struct tty_ctx *);
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
@@ -1971,6 +1974,7 @@ void tty_cmd_scrolldown(struct tty *, const struct tty_ctx *);
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
+void tty_cmd_rawsixel(struct tty *, const struct tty_ctx *);
/* tty-term.c */
extern struct tty_terms tty_terms;
@@ -2357,6 +2361,7 @@ void screen_write_collect_add(struct screen_write_ctx *,
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
+void screen_write_rawsixel(struct screen_write_ctx *, u_char *, u_int, int);
/* screen-redraw.c */
void screen_redraw_screen(struct client *);
diff --git a/tty-keys.c b/tty-keys.c
index 6be40d0e..e644addb 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -1005,7 +1005,7 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
u_int i, n = 0;
char tmp[64], *endptr, p[32] = { 0 }, *cp, *next;
static const char *types[] = TTY_TYPES;
- int type;
+ int type, flags = 0;
*size = 0;
@@ -1068,9 +1068,12 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
type = TTY_VT520;
break;
}
- for (i = 2; i < n; i++)
+ for (i = 2; i < n; i++) {
log_debug("%s: DA feature: %d", c->name, p[i]);
- tty_set_type(tty, type);
+ if (p[i] == 4)
+ flags |= TERM_SIXEL;
+ }
+ tty_set_type(tty, type, flags);
log_debug("%s: received DA %.*s (%s)", c->name, (int)*size, buf,
types[type]);
diff --git a/tty-term.c b/tty-term.c
index 3ac9bc6c..ce3d690a 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -252,6 +252,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_SETRGBF] = { TTYCODE_STRING, "setrgbf" },
[TTYC_SETULC] = { TTYCODE_STRING, "Setulc" },
[TTYC_SE] = { TTYCODE_STRING, "Se" },
+ [TTYC_SXL] = { TTYCODE_FLAG, "Sxl" },
[TTYC_SGR0] = { TTYCODE_STRING, "sgr0" },
[TTYC_SITM] = { TTYCODE_STRING, "sitm" },
[TTYC_SMACS] = { TTYCODE_STRING, "smacs" },
diff --git a/tty.c b/tty.c
index 594f02fa..cae2fd24 100644
--- a/tty.c
+++ b/tty.c
@@ -436,9 +436,10 @@ tty_free(struct tty *tty)
}
void
-tty_set_type(struct tty *tty, int type)
+tty_set_type(struct tty *tty, int type, int flags)
{
tty->term_type = type;
+ tty->term_flags |= flags;
if (tty_use_margin(tty))
tty_puts(tty, "\033[?69h"); /* DECLRMM */
@@ -1865,6 +1866,18 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty_invalidate(tty);
}
+void
+tty_cmd_rawsixel(struct tty *tty, const struct tty_ctx *ctx)
+{
+ int flags = (tty->term->flags|tty->term_flags);
+
+ if ((flags & TERM_SIXEL) || tty_term_has(tty->term, TTYC_SXL)) {
+ tty_add(tty, ctx->ptr, ctx->num);
+ if (!ctx->more)
+ tty_invalidate(tty);
+ }
+}
+
static void
tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp)
{