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)
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);
}

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);
}
/* 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
.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

7
tmux.h
View File

@ -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 *);

View File

@ -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]);

View File

@ -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" },

15
tty.c
View File

@ -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)
{