Pass through SIXEL DCS sequences (treat similarly to the passthrough escape

sequence) if it appears the terminal outside supports them.
pull/3363/head
Nicholas Marriott 2019-11-28 12:35:18 +00:00
parent e00730d149
commit b34111b3da
7 changed files with 57 additions and 10 deletions

18
input.c
View File

@ -1305,8 +1305,8 @@ input_csi_dispatch(struct input_ctx *ictx)
if (ictx->flags & INPUT_DISCARD) if (ictx->flags & INPUT_DISCARD)
return (0); return (0);
log_debug("%s: '%c' \"%s\" \"%s\"", log_debug("%s: '%c' \"%s\" \"%s\"", __func__, ictx->ch,
__func__, ictx->ch, ictx->interm_buf, ictx->param_buf); ictx->interm_buf, ictx->param_buf);
if (input_split(ictx) != 0) if (input_split(ictx) != 0)
return (0); return (0);
@ -2151,19 +2151,27 @@ static int
input_dcs_dispatch(struct input_ctx *ictx) input_dcs_dispatch(struct input_ctx *ictx)
{ {
struct screen_write_ctx *sctx = &ictx->ctx; struct screen_write_ctx *sctx = &ictx->ctx;
u_char *buf = ictx->input_buf; u_char *buf = ictx->input_buf, *pbuf = ictx->param_buf;
size_t len = ictx->input_len; size_t len = ictx->input_len, plen = ictx->param_len;
const char prefix[] = "tmux;"; const char prefix[] = "tmux;";
const u_int prefixlen = (sizeof prefix) - 1; const u_int prefixlen = (sizeof prefix) - 1;
if (ictx->flags & INPUT_DISCARD) if (ictx->flags & INPUT_DISCARD)
return (0); 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) if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0)
screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen); 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); return (0);
} }

View File

@ -1671,3 +1671,18 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
tty_write(tty_cmd_rawstring, &ttyctx); 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);
}

2
tmux.1
View File

@ -5200,6 +5200,8 @@ $ printf '\e033[4 q'
If If
.Em Se .Em Se
is not set, \&Ss with argument 0 will be used to reset the cursor style instead. 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 .It Em \&Tc
Indicate that the terminal supports the Indicate that the terminal supports the
.Ql direct colour .Ql direct colour

7
tmux.h
View File

@ -446,6 +446,7 @@ enum tty_code_code {
TTYC_SMULX, TTYC_SMULX,
TTYC_SMUL, TTYC_SMUL,
TTYC_SMXX, TTYC_SMXX,
TTYC_SXL,
TTYC_SS, TTYC_SS,
TTYC_TC, TTYC_TC,
TTYC_TSL, TTYC_TSL,
@ -1145,6 +1146,7 @@ struct tty_term {
#define TERM_256COLOURS 0x1 #define TERM_256COLOURS 0x1
#define TERM_EARLYWRAP 0x2 #define TERM_EARLYWRAP 0x2
#define TERM_SIXEL 0x4
int flags; int flags;
LIST_ENTRY(tty_term) entry; LIST_ENTRY(tty_term) entry;
@ -1248,6 +1250,7 @@ struct tty_ctx {
u_int num; u_int num;
void *ptr; void *ptr;
int more;
/* /*
* Cursor and region position before the screen was updated - this is * 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 **); int tty_open(struct tty *, char **);
void tty_close(struct tty *); void tty_close(struct tty *);
void tty_free(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 *), void tty_write(void (*)(struct tty *, const struct tty_ctx *),
struct tty_ctx *); struct tty_ctx *);
void tty_cmd_alignmenttest(struct tty *, const 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_reverseindex(struct tty *, const struct tty_ctx *);
void tty_cmd_setselection(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_rawstring(struct tty *, const struct tty_ctx *);
void tty_cmd_rawsixel(struct tty *, const struct tty_ctx *);
/* tty-term.c */ /* tty-term.c */
extern struct tty_terms tty_terms; 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_cell(struct screen_write_ctx *, const struct grid_cell *);
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int); 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_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 */ /* screen-redraw.c */
void screen_redraw_screen(struct client *); void screen_redraw_screen(struct client *);

View File

@ -1005,7 +1005,7 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
u_int i, n = 0; u_int i, n = 0;
char tmp[64], *endptr, p[32] = { 0 }, *cp, *next; char tmp[64], *endptr, p[32] = { 0 }, *cp, *next;
static const char *types[] = TTY_TYPES; static const char *types[] = TTY_TYPES;
int type; int type, flags = 0;
*size = 0; *size = 0;
@ -1068,9 +1068,12 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
type = TTY_VT520; type = TTY_VT520;
break; break;
} }
for (i = 2; i < n; i++) for (i = 2; i < n; i++) {
log_debug("%s: DA feature: %d", c->name, p[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, log_debug("%s: received DA %.*s (%s)", c->name, (int)*size, buf,
types[type]); types[type]);

View File

@ -252,6 +252,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_SETRGBF] = { TTYCODE_STRING, "setrgbf" }, [TTYC_SETRGBF] = { TTYCODE_STRING, "setrgbf" },
[TTYC_SETULC] = { TTYCODE_STRING, "Setulc" }, [TTYC_SETULC] = { TTYCODE_STRING, "Setulc" },
[TTYC_SE] = { TTYCODE_STRING, "Se" }, [TTYC_SE] = { TTYCODE_STRING, "Se" },
[TTYC_SXL] = { TTYCODE_FLAG, "Sxl" },
[TTYC_SGR0] = { TTYCODE_STRING, "sgr0" }, [TTYC_SGR0] = { TTYCODE_STRING, "sgr0" },
[TTYC_SITM] = { TTYCODE_STRING, "sitm" }, [TTYC_SITM] = { TTYCODE_STRING, "sitm" },
[TTYC_SMACS] = { TTYCODE_STRING, "smacs" }, [TTYC_SMACS] = { TTYCODE_STRING, "smacs" },

15
tty.c
View File

@ -436,9 +436,10 @@ tty_free(struct tty *tty)
} }
void 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_type = type;
tty->term_flags |= flags;
if (tty_use_margin(tty)) if (tty_use_margin(tty))
tty_puts(tty, "\033[?69h"); /* DECLRMM */ tty_puts(tty, "\033[?69h"); /* DECLRMM */
@ -1865,6 +1866,18 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty_invalidate(tty); 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 static void
tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp) tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp)
{ {