Parse primary device attributes as well as secondary and add a SIXEL

flag (not used yet), from Anindya Mukherjee.
This commit is contained in:
nicm 2022-11-11 08:37:55 +00:00
parent 079f48e8a6
commit fe475bd856
7 changed files with 125 additions and 23 deletions

View File

@ -1345,8 +1345,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);

4
tmux.1
View File

@ -3687,6 +3687,8 @@ Supports the overline SGR attribute.
Supports the DECFRA rectangle fill escape sequence. Supports the DECFRA rectangle fill escape sequence.
.It RGB .It RGB
Supports RGB colour with the SGR escape sequences. Supports RGB colour with the SGR escape sequences.
.It sixel
Supports SIXEL graphics.
.It strikethrough .It strikethrough
Supports the strikethrough SGR escape sequence. Supports the strikethrough SGR escape sequence.
.It sync .It sync
@ -6491,6 +6493,8 @@ Set the opening sequence for the working directory notification.
The sequence is terminated using the standard The sequence is terminated using the standard
.Em fsl .Em fsl
capability. capability.
.It Em \&Sxl
Indicates that the terminal supports SIXEL.
.It Em \&Sync .It Em \&Sync
Start (parameter is 1) or end (parameter is 2) a synchronized update. Start (parameter is 1) or end (parameter is 2) a synchronized update.
.It Em \&Tc .It Em \&Tc

5
tmux.h
View File

@ -543,6 +543,7 @@ enum tty_code_code {
TTYC_SMUL, TTYC_SMUL,
TTYC_SMULX, TTYC_SMULX,
TTYC_SMXX, TTYC_SMXX,
TTYC_SXL,
TTYC_SS, TTYC_SS,
TTYC_SWD, TTYC_SWD,
TTYC_SYNC, TTYC_SYNC,
@ -1349,6 +1350,7 @@ struct tty_term {
#define TERM_DECFRA 0x8 #define TERM_DECFRA 0x8
#define TERM_RGBCOLOURS 0x10 #define TERM_RGBCOLOURS 0x10
#define TERM_VT100LIKE 0x20 #define TERM_VT100LIKE 0x20
#define TERM_SIXEL 0x40
int flags; int flags;
LIST_ENTRY(tty_term) entry; LIST_ENTRY(tty_term) entry;
@ -1405,9 +1407,10 @@ struct tty {
#define TTY_OPENED 0x20 #define TTY_OPENED 0x20
#define TTY_OSC52QUERY 0x40 #define TTY_OSC52QUERY 0x40
#define TTY_BLOCK 0x80 #define TTY_BLOCK 0x80
#define TTY_HAVEDA 0x100 #define TTY_HAVEDA 0x100 /* Primary DA. */
#define TTY_HAVEXDA 0x200 #define TTY_HAVEXDA 0x200
#define TTY_SYNCING 0x400 #define TTY_SYNCING 0x400
#define TTY_HAVEDA2 0x800 /* Seconday DA. */
int flags; int flags;
struct tty_term *term; struct tty_term *term;

View File

@ -335,6 +335,17 @@ static const struct tty_feature tty_feature_ignorefkeys = {
0 0
}; };
/* Terminal has sixel capability. */
static const char *const tty_feature_sixel_capabilities[] = {
"Sxl",
NULL
};
static const struct tty_feature tty_feature_sixel = {
"sixel",
tty_feature_sixel_capabilities,
0
};
/* Available terminal features. */ /* Available terminal features. */
static const struct tty_feature *const tty_features[] = { static const struct tty_feature *const tty_features[] = {
&tty_feature_256, &tty_feature_256,
@ -352,6 +363,7 @@ static const struct tty_feature *const tty_features[] = {
&tty_feature_overline, &tty_feature_overline,
&tty_feature_rectfill, &tty_feature_rectfill,
&tty_feature_rgb, &tty_feature_rgb,
&tty_feature_sixel,
&tty_feature_strikethrough, &tty_feature_strikethrough,
&tty_feature_sync, &tty_feature_sync,
&tty_feature_title, &tty_feature_title,

View File

@ -55,6 +55,8 @@ static int tty_keys_clipboard(struct tty *, const char *, size_t,
size_t *); size_t *);
static int tty_keys_device_attributes(struct tty *, const char *, size_t, static int tty_keys_device_attributes(struct tty *, const char *, size_t,
size_t *); size_t *);
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 *, static int tty_keys_extended_device_attributes(struct tty *, const char *,
size_t, size_t *); size_t, size_t *);
@ -684,7 +686,7 @@ tty_keys_next(struct tty *tty)
goto partial_key; goto partial_key;
} }
/* Is this a device attributes response? */ /* Is this a primary device attributes response? */
switch (tty_keys_device_attributes(tty, buf, len, &size)) { switch (tty_keys_device_attributes(tty, buf, len, &size)) {
case 0: /* yes */ case 0: /* yes */
key = KEYC_UNKNOWN; key = KEYC_UNKNOWN;
@ -695,6 +697,17 @@ tty_keys_next(struct tty *tty)
goto partial_key; goto partial_key;
} }
/* Is this a secondary device attributes response? */
switch (tty_keys_device_attributes2(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 an extended device attributes response? */ /* Is this an extended device attributes response? */
switch (tty_keys_extended_device_attributes(tty, buf, len, &size)) { switch (tty_keys_extended_device_attributes(tty, buf, len, &size)) {
case 0: /* yes */ case 0: /* yes */
@ -1235,7 +1248,7 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
} }
/* /*
* Handle secondary device attributes input. Returns 0 for success, -1 for * Handle primary device attributes input. Returns 0 for success, -1 for
* failure, 1 for partial. * failure, 1 for partial.
*/ */
static int static int
@ -1244,16 +1257,13 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
{ {
struct client *c = tty->client; struct client *c = tty->client;
u_int i, n = 0; u_int i, n = 0;
char tmp[64], *endptr, p[32] = { 0 }, *cp, *next; char tmp[128], *endptr, p[32] = { 0 }, *cp, *next;
*size = 0; *size = 0;
if (tty->flags & TTY_HAVEDA) if (tty->flags & TTY_HAVEDA)
return (-1); return (-1);
/* /* First three bytes are always \033[?. */
* First three bytes are always \033[>. Some older Terminal.app
* versions respond as for DA (\033[?) so accept and ignore that.
*/
if (buf[0] != '\033') if (buf[0] != '\033')
return (-1); return (-1);
if (len == 1) if (len == 1)
@ -1262,35 +1272,105 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
return (-1); return (-1);
if (len == 2) if (len == 2)
return (1); return (1);
if (buf[2] != '>' && buf[2] != '?') if (buf[2] != '?')
return (-1); return (-1);
if (len == 3) if (len == 3)
return (1); return (1);
/* Copy the rest up to a 'c'. */ /* Copy the rest up to a 'c'. */
for (i = 0; i < (sizeof tmp) - 1; i++) { for (i = 0; i < (sizeof tmp); i++) {
if (3 + i == len) if (3 + i == len)
return (1); return (1);
if (buf[3 + i] == 'c') if (buf[3 + i] == 'c')
break; break;
tmp[i] = buf[3 + i]; tmp[i] = buf[3 + i];
} }
if (i == (sizeof tmp) - 1) if (i == (sizeof tmp))
return (-1); return (-1);
tmp[i] = '\0'; tmp[i] = '\0';
*size = 4 + i; *size = 4 + i;
/* Ignore DA response. */
if (buf[2] == '?')
return (0);
/* Convert all arguments to numbers. */ /* Convert all arguments to numbers. */
cp = tmp; cp = tmp;
while ((next = strsep(&cp, ";")) != NULL) { while ((next = strsep(&cp, ";")) != NULL) {
p[n] = strtoul(next, &endptr, 10); p[n] = strtoul(next, &endptr, 10);
if (*endptr != '\0') if (*endptr != '\0')
p[n] = 0; p[n] = 0;
n++; if (++n == nitems(p))
break;
}
/* Add terminal features. */
switch (p[0]) {
case 62: /* VT220 */
case 63: /* VT320 */
case 64: /* VT420 */
for (i = 1; i < n; i++) {
log_debug("%s: DA feature: %d", c->name, p[i]);
if (p[i] == 4)
tty->term->flags |= TERM_SIXEL;
}
break;
}
log_debug("%s: received primary DA %.*s", c->name, (int)*size, buf);
tty_update_features(tty);
tty->flags |= TTY_HAVEDA;
return (0);
}
/*
* Handle secondary device attributes input. Returns 0 for success, -1 for
* failure, 1 for partial.
*/
static int
tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len,
size_t *size)
{
struct client *c = tty->client;
u_int i, n = 0;
char tmp[128], *endptr, p[32] = { 0 }, *cp, *next;
*size = 0;
if (tty->flags & TTY_HAVEDA2)
return (-1);
/* First three bytes are always \033[>. */
if (buf[0] != '\033')
return (-1);
if (len == 1)
return (1);
if (buf[1] != '[')
return (-1);
if (len == 2)
return (1);
if (buf[2] != '>')
return (-1);
if (len == 3)
return (1);
/* Copy the rest up to a 'c'. */
for (i = 0; i < (sizeof tmp); i++) {
if (3 + i == len)
return (1);
if (buf[3 + i] == 'c')
break;
tmp[i] = buf[3 + i];
}
if (i == (sizeof tmp))
return (-1);
tmp[i] = '\0';
*size = 4 + i;
/* Convert all arguments to numbers. */
cp = tmp;
while ((next = strsep(&cp, ";")) != NULL) {
p[n] = strtoul(next, &endptr, 10);
if (*endptr != '\0')
p[n] = 0;
if (++n == nitems(p))
break;
} }
/* Add terminal features. */ /* Add terminal features. */
@ -1311,7 +1391,7 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
log_debug("%s: received secondary DA %.*s", c->name, (int)*size, buf); log_debug("%s: received secondary DA %.*s", c->name, (int)*size, buf);
tty_update_features(tty); tty_update_features(tty);
tty->flags |= TTY_HAVEDA; tty->flags |= TTY_HAVEDA2;
return (0); return (0);
} }

View File

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

10
tty.c
View File

@ -299,9 +299,9 @@ tty_start_timer_callback(__unused int fd, __unused short events, void *data)
struct client *c = tty->client; struct client *c = tty->client;
log_debug("%s: start timer fired", c->name); log_debug("%s: start timer fired", c->name);
if ((tty->flags & (TTY_HAVEDA|TTY_HAVEXDA)) == 0) if ((tty->flags & (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA)) == 0)
tty_update_features(tty); tty_update_features(tty);
tty->flags |= (TTY_HAVEDA|TTY_HAVEXDA); tty->flags |= (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA);
} }
void void
@ -363,12 +363,14 @@ tty_send_requests(struct tty *tty)
return; return;
if (tty->term->flags & TERM_VT100LIKE) { if (tty->term->flags & TERM_VT100LIKE) {
if (~tty->flags & TTY_HAVEDA) if (~tty->term->flags & TTY_HAVEDA)
tty_puts(tty, "\033[c");
if (~tty->flags & TTY_HAVEDA2)
tty_puts(tty, "\033[>c"); tty_puts(tty, "\033[>c");
if (~tty->flags & TTY_HAVEXDA) if (~tty->flags & TTY_HAVEXDA)
tty_puts(tty, "\033[>q"); tty_puts(tty, "\033[>q");
} else } else
tty->flags |= (TTY_HAVEDA|TTY_HAVEXDA); tty->flags |= (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA);
} }
void void