summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm@openbsd.org>2020-05-16 16:44:54 +0000
committernicm <nicm@openbsd.org>2020-05-16 16:44:54 +0000
commitdcf80b09e8a616f8efd8d4c98be6d11b4a148cb8 (patch)
treefef3786ea0568644f0e70ea1ef6433a7cfb2d31c
parentSend CSI u sequences for any keys that do not have a defined sequence (diff)
downloadwireguard-openbsd-dcf80b09e8a616f8efd8d4c98be6d11b4a148cb8.tar.xz
wireguard-openbsd-dcf80b09e8a616f8efd8d4c98be6d11b4a148cb8.zip
Add a terminal feature for enable/disable extended keys (supported by
xterm and mintty) and add an option to make tmux send it. Only forward extended keys if the application has requested them, even though we use the CSI u sequence and xterm uses CSI 27 ~ - this is what mintty does as well.
-rw-r--r--usr.bin/tmux/input-keys.c68
-rw-r--r--usr.bin/tmux/input.c21
-rw-r--r--usr.bin/tmux/options-table.c10
-rw-r--r--usr.bin/tmux/tmux.110
-rw-r--r--usr.bin/tmux/tmux.h11
-rw-r--r--usr.bin/tmux/tty-features.c19
-rw-r--r--usr.bin/tmux/tty-keys.c4
-rw-r--r--usr.bin/tmux/tty-term.c4
-rw-r--r--usr.bin/tmux/tty.c23
9 files changed, 83 insertions, 87 deletions
diff --git a/usr.bin/tmux/input-keys.c b/usr.bin/tmux/input-keys.c
index 11b48768a7a..4936fa35b36 100644
--- a/usr.bin/tmux/input-keys.c
+++ b/usr.bin/tmux/input-keys.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: input-keys.c,v 1.75 2020/05/16 16:38:55 nicm Exp $ */
+/* $OpenBSD: input-keys.c,v 1.76 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -497,67 +497,13 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key)
}
/* No builtin key sequence; construct an extended key sequence. */
- outkey = (key & KEYC_MASK_KEY);
- if (outkey >= KEYC_BASE) {
- switch (outkey) {
- case KEYC_IC:
- outkey = 2;
- break;
- case KEYC_DC:
- outkey = 3;
- break;
- case KEYC_PPAGE:
- outkey = 5;
- break;
- case KEYC_NPAGE:
- outkey = 6;
- break;
- case KEYC_HOME:
- outkey = 7;
- break;
- case KEYC_END:
- outkey = 8;
- break;
- case KEYC_F1:
- outkey = 11;
- break;
- case KEYC_F2:
- outkey = 12;
- break;
- case KEYC_F3:
- outkey = 13;
- break;
- case KEYC_F4:
- outkey = 14;
- break;
- case KEYC_F5:
- outkey = 15;
- break;
- case KEYC_F6:
- outkey = 17;
- break;
- case KEYC_F7:
- outkey = 18;
- break;
- case KEYC_F8:
- outkey = 19;
- break;
- case KEYC_F9:
- outkey = 20;
- break;
- case KEYC_F10:
- outkey = 21;
- break;
- case KEYC_F11:
- outkey = 23;
- break;
- case KEYC_F12:
- outkey = 24;
- break;
- default:
- goto missing;
- }
+ if (~s->mode & MODE_KEXTENDED) {
+ if ((key & KEYC_MASK_MODIFIERS) == KEYC_CTRL &&
+ (key & KEYC_MASK_KEY) < KEYC_BASE)
+ return (input_key(s, bev, key & ~KEYC_CTRL));
+ goto missing;
}
+ outkey = (key & KEYC_MASK_KEY);
switch (key & KEYC_MASK_MODIFIERS) {
case KEYC_SHIFT:
modifier = '2';
diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c
index 61023dbecd9..c1e9e0c650c 100644
--- a/usr.bin/tmux/input.c
+++ b/usr.bin/tmux/input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: input.c,v 1.177 2020/05/16 15:34:08 nicm Exp $ */
+/* $OpenBSD: input.c,v 1.178 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -241,6 +241,8 @@ enum input_csi_type {
INPUT_CSI_HPA,
INPUT_CSI_ICH,
INPUT_CSI_IL,
+ INPUT_CSI_MODOFF,
+ INPUT_CSI_MODSET,
INPUT_CSI_RCP,
INPUT_CSI_REP,
INPUT_CSI_RM,
@@ -289,7 +291,9 @@ static const struct input_table_entry input_csi_table[] = {
{ 'l', "", INPUT_CSI_RM },
{ 'l', "?", INPUT_CSI_RM_PRIVATE },
{ 'm', "", INPUT_CSI_SGR },
+ { 'm', ">", INPUT_CSI_MODSET },
{ 'n', "", INPUT_CSI_DSR },
+ { 'n', ">", INPUT_CSI_MODOFF },
{ 'q', " ", INPUT_CSI_DECSCUSR },
{ 'q', ">", INPUT_CSI_XDA },
{ 'r', "", INPUT_CSI_DECSTBM },
@@ -1380,6 +1384,19 @@ input_csi_dispatch(struct input_ctx *ictx)
if (n != -1 && m != -1)
screen_write_cursormove(sctx, m - 1, n - 1, 1);
break;
+ case INPUT_CSI_MODSET:
+ n = input_get(ictx, 0, 0, 0);
+ m = input_get(ictx, 1, 0, 0);
+ if (n == 0 || (n == 4 && m == 0))
+ screen_write_mode_clear(sctx, MODE_KEXTENDED);
+ else if (n == 4 && (m == 1 || m == 2))
+ screen_write_mode_set(sctx, MODE_KEXTENDED);
+ break;
+ case INPUT_CSI_MODOFF:
+ n = input_get(ictx, 0, 0, 0);
+ if (n == 4)
+ screen_write_mode_clear(sctx, MODE_KEXTENDED);
+ break;
case INPUT_CSI_WINOPS:
input_csi_dispatch_winops(ictx);
break;
@@ -1593,7 +1610,7 @@ input_csi_dispatch(struct input_ctx *ictx)
break;
case INPUT_CSI_XDA:
n = input_get(ictx, 0, 0, 0);
- if (n != 0)
+ if (n == 0)
input_reply(ictx, "\033P>|tmux %s\033\\", getversion());
break;
diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c
index cfd4d304bb6..f414cb974f1 100644
--- a/usr.bin/tmux/options-table.c
+++ b/usr.bin/tmux/options-table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.130 2020/05/16 16:30:59 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.131 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -252,6 +252,14 @@ const struct options_table_entry options_table[] = {
"clients."
},
+ { .name = "extended-keys",
+ .type = OPTIONS_TABLE_FLAG,
+ .scope = OPTIONS_TABLE_SERVER,
+ .default_num = 0,
+ .text = "Whether to request extended key sequences from terminals "
+ "that support it."
+ },
+
{ .name = "focus-events",
.type = OPTIONS_TABLE_FLAG,
.scope = OPTIONS_TABLE_SERVER,
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index 972dec9dcef..14b58319ca5 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.771 2020/05/16 16:30:59 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.772 2020/05/16 16:44:54 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -3225,6 +3225,12 @@ sessions.
.Op Ic on | off
.Xc
If enabled, the server will exit when there are no attached clients.
+.It Xo Ic extended-keys
+.Op Ic on | off
+.Xc
+When enabled, extended keys are requested from the terminal and if supported
+are recognised by
+.Nm .
.It Xo Ic focus-events
.Op Ic on | off
.Xc
@@ -5744,6 +5750,8 @@ Disable and enable bracketed paste.
These are set automatically if the
.Em XT
capability is present.
+.It Em \&Dseks , \&Eneks
+Disable and enable extended keys.
.It Em \&Dsfcs , \&Enfcs
Disable and enable focus reporting.
These are set automatically if the
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index de896a47d46..114c649f075 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1046 2020/05/16 16:35:13 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1047 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -290,6 +290,7 @@ enum tty_code_code {
TTYC_DL,
TTYC_DL1,
TTYC_DSBP,
+ TTYC_DSEKS,
TTYC_DSFCS,
TTYC_DSMG,
TTYC_E3,
@@ -299,6 +300,7 @@ enum tty_code_code {
TTYC_EL1,
TTYC_ENACS,
TTYC_ENBP,
+ TTYC_ENEKS,
TTYC_ENFCS,
TTYC_ENMG,
TTYC_FSL,
@@ -575,8 +577,8 @@ struct msg_write_close {
#define MODE_CURSOR 0x1
#define MODE_INSERT 0x2
#define MODE_KCURSOR 0x4
-#define MODE_KKEYPAD 0x8 /* set = application, clear = number */
-#define MODE_WRAP 0x10 /* whether lines wrap */
+#define MODE_KKEYPAD 0x8
+#define MODE_WRAP 0x10
#define MODE_MOUSE_STANDARD 0x20
#define MODE_MOUSE_BUTTON 0x40
#define MODE_BLINKING 0x80
@@ -587,6 +589,7 @@ struct msg_write_close {
#define MODE_MOUSE_ALL 0x1000
#define MODE_ORIGIN 0x2000
#define MODE_CRLF 0x4000
+#define MODE_KEXTENDED 0x8000
#define ALL_MODES 0xffffff
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
@@ -1284,7 +1287,7 @@ struct tty {
/* 0x8 unused */
#define TTY_STARTED 0x10
#define TTY_OPENED 0x20
-#define TTY_FOCUS 0x40
+/* 0x40 unused */
#define TTY_BLOCK 0x80
#define TTY_HAVEDA 0x100
#define TTY_HAVEXDA 0x200
diff --git a/usr.bin/tmux/tty-features.c b/usr.bin/tmux/tty-features.c
index ab4d640c03d..efa3037fef4 100644
--- a/usr.bin/tmux/tty-features.c
+++ b/usr.bin/tmux/tty-features.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty-features.c,v 1.13 2020/05/16 14:46:14 nicm Exp $ */
+/* $OpenBSD: tty-features.c,v 1.14 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -190,6 +190,18 @@ static const struct tty_feature tty_feature_sync = {
0
};
+/* Terminal supports extended keys. */
+static const char *tty_feature_extkeys_capabilities[] = {
+ "Eneks=\\E[>4;1m",
+ "Dseks=\\E[>4m",
+ NULL
+};
+static const struct tty_feature tty_feature_extkeys = {
+ "extkeys",
+ tty_feature_extkeys_capabilities,
+ 0
+};
+
/* Terminal supports DECSLRM margins. */
static const char *tty_feature_margins_capabilities[] = {
"Enmg=\\E[?69h",
@@ -218,6 +230,7 @@ static const struct tty_feature *tty_features[] = {
&tty_feature_ccolour,
&tty_feature_clipboard,
&tty_feature_cstyle,
+ &tty_feature_extkeys,
&tty_feature_focus,
&tty_feature_margins,
&tty_feature_overline,
@@ -321,7 +334,7 @@ tty_default_features(int *feat, const char *name, u_int version)
} table[] = {
#define TTY_FEATURES_BASE_MODERN_XTERM "256,RGB,bpaste,clipboard,strikethrough,title"
{ .name = "mintty",
- .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,margins,overline"
+ .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,extkeys,margins,overline"
},
{ .name = "tmux",
.features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,focus,overline,usstyle"
@@ -333,7 +346,7 @@ tty_default_features(int *feat, const char *name, u_int version)
.features = TTY_FEATURES_BASE_MODERN_XTERM ",cstyle,margins,sync"
},
{ .name = "XTerm",
- .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,focus,margins,rectfill"
+ .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,extkeys,focus,margins,rectfill"
}
};
u_int i;
diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c
index beb94ed83ca..80b59c0d720 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.135 2020/05/16 16:35:13 nicm Exp $ */
+/* $OpenBSD: tty-keys.c,v 1.136 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1293,7 +1293,7 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
else if (strncmp(tmp, "tmux ", 5) == 0)
tty_default_features(&c->term_features, "tmux", 0);
else if (strncmp(tmp, "XTerm(", 6) == 0)
- tty_default_features(&c->term_features, "xterm", 0);
+ tty_default_features(&c->term_features, "XTerm", 0);
else if (strncmp(tmp, "mintty ", 7) == 0)
tty_default_features(&c->term_features, "mintty", 0);
log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);
diff --git a/usr.bin/tmux/tty-term.c b/usr.bin/tmux/tty-term.c
index 2ca3c99123f..9fc710fc98a 100644
--- a/usr.bin/tmux/tty-term.c
+++ b/usr.bin/tmux/tty-term.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty-term.c,v 1.80 2020/05/16 14:46:14 nicm Exp $ */
+/* $OpenBSD: tty-term.c,v 1.81 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -83,6 +83,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_DIM] = { TTYCODE_STRING, "dim" },
[TTYC_DL1] = { TTYCODE_STRING, "dl1" },
[TTYC_DL] = { TTYCODE_STRING, "dl" },
+ [TTYC_DSEKS] = { TTYCODE_STRING, "Dseks" },
[TTYC_DSFCS] = { TTYCODE_STRING, "Dsfcs" },
[TTYC_DSBP] = { TTYCODE_STRING, "Dsbp" },
[TTYC_DSMG] = { TTYCODE_STRING, "Dsmg" },
@@ -93,6 +94,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_EL] = { TTYCODE_STRING, "el" },
[TTYC_ENACS] = { TTYCODE_STRING, "enacs" },
[TTYC_ENBP] = { TTYCODE_STRING, "Enbp" },
+ [TTYC_ENEKS] = { TTYCODE_STRING, "Eneks" },
[TTYC_ENFCS] = { TTYCODE_STRING, "Enfcs" },
[TTYC_ENMG] = { TTYCODE_STRING, "Enmg" },
[TTYC_FSL] = { TTYCODE_STRING, "fsl" },
diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c
index 730bcc2d6b4..f5fe6374c46 100644
--- a/usr.bin/tmux/tty.c
+++ b/usr.bin/tmux/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.377 2020/05/16 16:26:34 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.378 2020/05/16 16:44:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -286,6 +286,8 @@ tty_start_timer_callback(__unused int fd, __unused short events, void *data)
struct client *c = tty->client;
log_debug("%s: start timer fired", c->name);
+ if ((tty->flags & (TTY_HAVEDA|TTY_HAVEXDA)) == 0)
+ tty_update_features(tty);
tty->flags |= (TTY_HAVEDA|TTY_HAVEXDA);
}
@@ -329,13 +331,6 @@ tty_start_tty(struct tty *tty)
tty_puts(tty, "\033[?1006l\033[?1005l");
}
- if (options_get_number(global_options, "focus-events")) {
- tty->flags |= TTY_FOCUS;
- tty_raw(tty, tty_term_string(tty->term, TTYC_ENFCS));
- }
- if (tty->term->flags & TERM_VT100LIKE)
- tty_puts(tty, "\033[?7727h");
-
evtimer_set(&tty->start_timer, tty_start_timer_callback, tty);
evtimer_add(&tty->start_timer, &tv);
@@ -415,12 +410,10 @@ tty_stop_tty(struct tty *tty)
tty_raw(tty, "\033[?1006l\033[?1005l");
}
- if (tty->flags & TTY_FOCUS) {
- tty->flags &= ~TTY_FOCUS;
- tty_raw(tty, tty_term_string(tty->term, TTYC_DSFCS));
- }
if (tty->term->flags & TERM_VT100LIKE)
tty_raw(tty, "\033[?7727l");
+ tty_raw(tty, tty_term_string(tty->term, TTYC_DSFCS));
+ tty_raw(tty, tty_term_string(tty->term, TTYC_DSEKS));
if (tty_use_margin(tty))
tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG));
@@ -471,6 +464,12 @@ tty_update_features(struct tty *tty)
if (tty_use_margin(tty))
tty_putcode(tty, TTYC_ENMG);
+ if (options_get_number(global_options, "extended-keys"))
+ tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS));
+ if (options_get_number(global_options, "focus-events"))
+ tty_raw(tty, tty_term_string(tty->term, TTYC_ENFCS));
+ if (tty->term->flags & TERM_VT100LIKE)
+ tty_puts(tty, "\033[?7727h");
}
void