mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
692bae9ea6
20
format.c
20
format.c
@ -1962,6 +1962,23 @@ format_cb_pane_unseen_changes(struct format_tree *ft)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Callback for pane_key_mode. */
|
||||
static void *
|
||||
format_cb_pane_key_mode(struct format_tree *ft)
|
||||
{
|
||||
if (ft->wp != NULL && ft->wp->screen != NULL) {
|
||||
switch (ft->wp->screen->mode & EXTENDED_KEY_MODES) {
|
||||
case MODE_KEYS_EXTENDED:
|
||||
return (xstrdup("Ext 1"));
|
||||
case MODE_KEYS_EXTENDED_2:
|
||||
return (xstrdup("Ext 2"));
|
||||
default:
|
||||
return (xstrdup("VT10x"));
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Callback for pane_last. */
|
||||
static void *
|
||||
format_cb_pane_last(struct format_tree *ft)
|
||||
@ -2997,6 +3014,9 @@ static const struct format_table_entry format_table[] = {
|
||||
{ "pane_input_off", FORMAT_TABLE_STRING,
|
||||
format_cb_pane_input_off
|
||||
},
|
||||
{ "pane_key_mode", FORMAT_TABLE_STRING,
|
||||
format_cb_pane_key_mode
|
||||
},
|
||||
{ "pane_last", FORMAT_TABLE_STRING,
|
||||
format_cb_pane_last
|
||||
},
|
||||
|
373
input-keys.c
373
input-keys.c
@ -307,20 +307,6 @@ static struct input_key_entry input_key_defaults[] = {
|
||||
{ .key = KEYC_DC|KEYC_BUILD_MODIFIERS,
|
||||
.data = "\033[3;_~"
|
||||
},
|
||||
|
||||
/* Tab and modifiers. */
|
||||
{ .key = '\011'|KEYC_CTRL,
|
||||
.data = "\011"
|
||||
},
|
||||
{ .key = '\011'|KEYC_CTRL|KEYC_EXTENDED,
|
||||
.data = "\033[9;5u"
|
||||
},
|
||||
{ .key = '\011'|KEYC_CTRL|KEYC_SHIFT,
|
||||
.data = "\033[Z"
|
||||
},
|
||||
{ .key = '\011'|KEYC_CTRL|KEYC_SHIFT|KEYC_EXTENDED,
|
||||
.data = "\033[1;5Z"
|
||||
}
|
||||
};
|
||||
static const key_code input_key_modifiers[] = {
|
||||
0,
|
||||
@ -426,126 +412,18 @@ input_key_write(const char *from, struct bufferevent *bev, const char *data,
|
||||
bufferevent_write(bev, data, size);
|
||||
}
|
||||
|
||||
/* Translate a key code into an output key sequence. */
|
||||
int
|
||||
input_key(struct screen *s, struct bufferevent *bev, key_code key)
|
||||
/*
|
||||
* Encode and write an extended key escape sequence in one of the two
|
||||
* possible formats, depending on the configured output mode.
|
||||
*/
|
||||
static int
|
||||
input_key_extended(struct bufferevent *bev, key_code key)
|
||||
{
|
||||
struct input_key_entry *ike = NULL;
|
||||
key_code justkey, newkey, outkey, modifiers;
|
||||
struct utf8_data ud;
|
||||
char tmp[64], modifier;
|
||||
char tmp[64], modifier;
|
||||
struct utf8_data ud;
|
||||
wchar_t wc;
|
||||
|
||||
/* Mouse keys need a pane. */
|
||||
if (KEYC_IS_MOUSE(key))
|
||||
return (0);
|
||||
|
||||
/* Literal keys go as themselves (can't be more than eight bits). */
|
||||
if (key & KEYC_LITERAL) {
|
||||
ud.data[0] = (u_char)key;
|
||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Is this backspace? */
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) {
|
||||
newkey = options_get_number(global_options, "backspace");
|
||||
if (newkey >= 0x7f)
|
||||
newkey = '\177';
|
||||
key = newkey|(key & (KEYC_MASK_MODIFIERS|KEYC_MASK_FLAGS));
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a normal 7-bit key, just send it, with a leading escape
|
||||
* if necessary. If it is a UTF-8 key, split it and send it.
|
||||
*/
|
||||
justkey = (key & ~(KEYC_META|KEYC_IMPLIED_META));
|
||||
if (justkey <= 0x7f) {
|
||||
if (key & KEYC_META)
|
||||
input_key_write(__func__, bev, "\033", 1);
|
||||
ud.data[0] = justkey;
|
||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||
return (0);
|
||||
}
|
||||
if (KEYC_IS_UNICODE(justkey)) {
|
||||
if (key & KEYC_META)
|
||||
input_key_write(__func__, bev, "\033", 1);
|
||||
utf8_to_data(justkey, &ud);
|
||||
input_key_write(__func__, bev, ud.data, ud.size);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up in the tree. If not in application keypad or cursor mode,
|
||||
* remove the flags from the key.
|
||||
*/
|
||||
if (~s->mode & MODE_KKEYPAD)
|
||||
key &= ~KEYC_KEYPAD;
|
||||
if (~s->mode & MODE_KCURSOR)
|
||||
key &= ~KEYC_CURSOR;
|
||||
if (s->mode & MODE_KEXTENDED)
|
||||
ike = input_key_get(key|KEYC_EXTENDED);
|
||||
if (ike == NULL)
|
||||
ike = input_key_get(key);
|
||||
if (ike == NULL && (key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
||||
ike = input_key_get(key & ~KEYC_META);
|
||||
if (ike == NULL && (key & KEYC_CURSOR))
|
||||
ike = input_key_get(key & ~KEYC_CURSOR);
|
||||
if (ike == NULL && (key & KEYC_KEYPAD))
|
||||
ike = input_key_get(key & ~KEYC_KEYPAD);
|
||||
if (ike == NULL && (key & KEYC_EXTENDED))
|
||||
ike = input_key_get(key & ~KEYC_EXTENDED);
|
||||
if (ike != NULL) {
|
||||
log_debug("found key 0x%llx: \"%s\"", key, ike->data);
|
||||
if ((key == KEYC_PASTE_START || key == KEYC_PASTE_END) &&
|
||||
(~s->mode & MODE_BRACKETPASTE))
|
||||
return (0);
|
||||
if ((key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
||||
input_key_write(__func__, bev, "\033", 1);
|
||||
input_key_write(__func__, bev, ike->data, strlen(ike->data));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* No builtin key sequence; construct an extended key sequence. */
|
||||
if (~s->mode & MODE_KEXTENDED) {
|
||||
if ((key & KEYC_MASK_MODIFIERS) != KEYC_CTRL)
|
||||
goto missing;
|
||||
justkey = (key & KEYC_MASK_KEY);
|
||||
switch (justkey) {
|
||||
case ' ':
|
||||
case '2':
|
||||
key = 0|(key & ~KEYC_MASK_KEY);
|
||||
break;
|
||||
case '|':
|
||||
key = 28|(key & ~KEYC_MASK_KEY);
|
||||
break;
|
||||
case '6':
|
||||
key = 30|(key & ~KEYC_MASK_KEY);
|
||||
break;
|
||||
case '-':
|
||||
case '/':
|
||||
key = 31|(key & ~KEYC_MASK_KEY);
|
||||
break;
|
||||
case '?':
|
||||
key = 127|(key & ~KEYC_MASK_KEY);
|
||||
break;
|
||||
default:
|
||||
if (justkey >= 'A' && justkey <= '_')
|
||||
key = (justkey - 'A')|(key & ~KEYC_MASK_KEY);
|
||||
else if (justkey >= 'a' && justkey <= '~')
|
||||
key = (justkey - 96)|(key & ~KEYC_MASK_KEY);
|
||||
else
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
return (input_key(s, bev, key & ~KEYC_CTRL));
|
||||
}
|
||||
outkey = (key & KEYC_MASK_KEY);
|
||||
modifiers = (key & KEYC_MASK_MODIFIERS);
|
||||
if (outkey < 32 && outkey != 9 && outkey != 13 && outkey != 27) {
|
||||
outkey = 64 + outkey;
|
||||
modifiers |= KEYC_CTRL;
|
||||
}
|
||||
switch (modifiers) {
|
||||
switch (key & KEYC_MASK_MODIFIERS) {
|
||||
case KEYC_SHIFT:
|
||||
modifier = '2';
|
||||
break;
|
||||
@ -568,17 +446,240 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key)
|
||||
modifier = '8';
|
||||
break;
|
||||
default:
|
||||
goto missing;
|
||||
return (-1);
|
||||
}
|
||||
xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", outkey, modifier);
|
||||
|
||||
if (KEYC_IS_UNICODE(key)) {
|
||||
utf8_to_data(key & KEYC_MASK_KEY, &ud);
|
||||
if (utf8_towc(&ud, &wc) == UTF8_DONE)
|
||||
key = wc;
|
||||
else
|
||||
return (-1);
|
||||
} else
|
||||
key &= KEYC_MASK_KEY;
|
||||
|
||||
if (options_get_number(global_options, "extended-keys-format") == 1)
|
||||
xsnprintf(tmp, sizeof tmp, "\033[27;%c;%llu~", modifier, key);
|
||||
else
|
||||
xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", key, modifier);
|
||||
|
||||
input_key_write(__func__, bev, tmp, strlen(tmp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Outputs the key in the "standard" mode. This is by far the most
|
||||
* complicated output mode, with a lot of remapping in order to
|
||||
* emulate quirks of terminals that today can be only found in museums.
|
||||
*/
|
||||
static int
|
||||
input_key_vt10x(struct bufferevent *bev, key_code key)
|
||||
{
|
||||
struct utf8_data ud;
|
||||
key_code onlykey;
|
||||
char *p;
|
||||
static const char *standard_map[2] = {
|
||||
"1!9(0)=+;:'\",<.>/-8? 2",
|
||||
"119900=+;;'',,..\x1f\x1f\x7f\x7f\0\0",
|
||||
};
|
||||
|
||||
log_debug("%s: key in %llx", __func__, key);
|
||||
|
||||
if (key & KEYC_META)
|
||||
input_key_write(__func__, bev, "\033", 1);
|
||||
|
||||
/*
|
||||
* There's no way to report modifiers for unicode keys in standard mode
|
||||
* so lose the modifiers.
|
||||
*/
|
||||
if (KEYC_IS_UNICODE(key)) {
|
||||
utf8_to_data(key, &ud);
|
||||
input_key_write(__func__, bev, ud.data, ud.size);
|
||||
return (0);
|
||||
}
|
||||
|
||||
onlykey = key & KEYC_MASK_KEY;
|
||||
|
||||
/* Prevent TAB and RET from being swallowed by C0 remapping logic. */
|
||||
if (onlykey == '\r' || onlykey == '\t')
|
||||
key &= ~KEYC_CTRL;
|
||||
|
||||
/*
|
||||
* Convert keys with Ctrl modifier into corresponding C0 control codes,
|
||||
* with the exception of *some* keys, which are remapped into printable
|
||||
* ASCII characters.
|
||||
*
|
||||
* There is no special handling for Shift modifier, which is pretty
|
||||
* much redundant anyway, as no terminal will send <base key>|SHIFT,
|
||||
* but only <shifted key>|SHIFT.
|
||||
*/
|
||||
if (key & KEYC_CTRL) {
|
||||
p = strchr(standard_map[0], onlykey);
|
||||
if (p != NULL)
|
||||
key = standard_map[1][p - standard_map[0]];
|
||||
else if (onlykey >= '3' && onlykey <= '7')
|
||||
key = onlykey - '\030';
|
||||
else if (onlykey >= '@' && onlykey <= '~')
|
||||
key = onlykey & 0x1f;
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
||||
log_debug("%s: key out %llx", __func__, key);
|
||||
|
||||
ud.data[0] = key & 0x7f;
|
||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Pick keys that are reported as vt10x keys in modifyOtherKeys=1 mode. */
|
||||
static int
|
||||
input_key_mode1(struct bufferevent *bev, key_code key)
|
||||
{
|
||||
key_code onlykey;
|
||||
|
||||
log_debug("%s: key in %llx", __func__, key);
|
||||
|
||||
/*
|
||||
* As per
|
||||
* https://invisible-island.net/xterm/modified-keys-us-pc105.html.
|
||||
*/
|
||||
onlykey = key & KEYC_MASK_KEY;
|
||||
if ((key & (KEYC_META | KEYC_CTRL)) == KEYC_CTRL &&
|
||||
(onlykey == ' ' ||
|
||||
onlykey == '/' ||
|
||||
onlykey == '@' ||
|
||||
onlykey == '^' ||
|
||||
(onlykey >= '2' && onlykey <= '8') ||
|
||||
(onlykey >= '@' && onlykey <= '~')))
|
||||
return (input_key_vt10x(bev, key));
|
||||
|
||||
/*
|
||||
* A regular key + Meta. In the absence of a standard to back this, we
|
||||
* mimic what iTerm 2 does.
|
||||
*/
|
||||
if ((key & (KEYC_CTRL | KEYC_META)) == KEYC_META)
|
||||
return (input_key_vt10x(bev, key));
|
||||
|
||||
missing:
|
||||
log_debug("key 0x%llx missing", key);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Translate a key code into an output key sequence. */
|
||||
int
|
||||
input_key(struct screen *s, struct bufferevent *bev, key_code key)
|
||||
{
|
||||
struct input_key_entry *ike = NULL;
|
||||
key_code newkey;
|
||||
struct utf8_data ud;
|
||||
|
||||
/* Mouse keys need a pane. */
|
||||
if (KEYC_IS_MOUSE(key))
|
||||
return (0);
|
||||
|
||||
/* Literal keys go as themselves (can't be more than eight bits). */
|
||||
if (key & KEYC_LITERAL) {
|
||||
ud.data[0] = (u_char)key;
|
||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Is this backspace? */
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) {
|
||||
newkey = options_get_number(global_options, "backspace");
|
||||
if (newkey >= 0x7f)
|
||||
newkey = '\177';
|
||||
key = newkey|(key & (KEYC_MASK_MODIFIERS|KEYC_MASK_FLAGS));
|
||||
}
|
||||
|
||||
/* Is this backtab? */
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_BTAB) {
|
||||
if (s->mode & EXTENDED_KEY_MODES) {
|
||||
/* When in xterm extended mode, remap into S-Tab. */
|
||||
key = '\011' | (key & ~KEYC_MASK_KEY) | KEYC_SHIFT;
|
||||
} else {
|
||||
/* Otherwise clear modifiers. */
|
||||
key &= ~KEYC_MASK_MODIFIERS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A trivial case, that is a 7-bit key, excluding C0 control characters
|
||||
* that can't be entered from the keyboard, and no modifiers; or a UTF-8
|
||||
* key and no modifiers.
|
||||
*/
|
||||
if (!(key & ~KEYC_MASK_KEY)) {
|
||||
if (key == C0_BS || key == C0_HT ||
|
||||
key == C0_CR || key == C0_ESC ||
|
||||
(key >= 0x20 && key <= 0x7f)) {
|
||||
ud.data[0] = key;
|
||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||
return (0);
|
||||
}
|
||||
if (KEYC_IS_UNICODE(key)) {
|
||||
utf8_to_data(key, &ud);
|
||||
input_key_write(__func__, bev, ud.data, ud.size);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the standard VT10x keys in the tree. If not in application
|
||||
* keypad or cursor mode, remove the respective flags from the key.
|
||||
*/
|
||||
if (~s->mode & MODE_KKEYPAD)
|
||||
key &= ~KEYC_KEYPAD;
|
||||
if (~s->mode & MODE_KCURSOR)
|
||||
key &= ~KEYC_CURSOR;
|
||||
if (ike == NULL)
|
||||
ike = input_key_get(key);
|
||||
if (ike == NULL && (key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
||||
ike = input_key_get(key & ~KEYC_META);
|
||||
if (ike == NULL && (key & KEYC_CURSOR))
|
||||
ike = input_key_get(key & ~KEYC_CURSOR);
|
||||
if (ike == NULL && (key & KEYC_KEYPAD))
|
||||
ike = input_key_get(key & ~KEYC_KEYPAD);
|
||||
if (ike != NULL) {
|
||||
log_debug("%s: found key 0x%llx: \"%s\"", __func__, key,
|
||||
ike->data);
|
||||
if ((key == KEYC_PASTE_START || key == KEYC_PASTE_END) &&
|
||||
(~s->mode & MODE_BRACKETPASTE))
|
||||
return (0);
|
||||
if ((key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
||||
input_key_write(__func__, bev, "\033", 1);
|
||||
input_key_write(__func__, bev, ike->data, strlen(ike->data));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* No builtin key sequence; construct an extended key sequence
|
||||
* depending on the client mode.
|
||||
*
|
||||
* If something invalid reaches here, an invalid output may be
|
||||
* produced. For example Ctrl-Shift-2 is invalid (as there's
|
||||
* no way to enter it). The correct form is Ctrl-Shift-@, at
|
||||
* least in US English keyboard layout.
|
||||
*/
|
||||
switch (s->mode & EXTENDED_KEY_MODES) {
|
||||
case MODE_KEYS_EXTENDED_2:
|
||||
/*
|
||||
* The simplest mode to handle - *all* modified keys are
|
||||
* reported in the extended form.
|
||||
*/
|
||||
return (input_key_extended(bev, key));
|
||||
case MODE_KEYS_EXTENDED:
|
||||
/*
|
||||
* Some keys are still reported in standard mode, to maintain
|
||||
* compatibility with applications unaware of extended keys.
|
||||
*/
|
||||
if (input_key_mode1(bev, key) == -1)
|
||||
return (input_key_extended(bev, key));
|
||||
return (0);
|
||||
default:
|
||||
/* The standard mode. */
|
||||
return (input_key_vt10x(bev, key));
|
||||
}
|
||||
}
|
||||
|
||||
/* Get mouse event string. */
|
||||
int
|
||||
input_key_get_mouse(struct screen *s, struct mouse_event *m, u_int x, u_int y,
|
||||
|
26
input.c
26
input.c
@ -1408,17 +1408,29 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
case INPUT_CSI_MODSET:
|
||||
n = input_get(ictx, 0, 0, 0);
|
||||
m = input_get(ictx, 1, 0, 0);
|
||||
if (options_get_number(global_options, "extended-keys") == 2)
|
||||
/*
|
||||
* Set the extended key reporting mode as per the client request,
|
||||
* unless "extended-keys always" forces us into mode 1.
|
||||
*/
|
||||
if (options_get_number(global_options, "extended-keys") != 1)
|
||||
break;
|
||||
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);
|
||||
screen_write_mode_clear(sctx,
|
||||
MODE_KEYS_EXTENDED|MODE_KEYS_EXTENDED_2);
|
||||
if (n == 4 && m == 1)
|
||||
screen_write_mode_set(sctx, MODE_KEYS_EXTENDED);
|
||||
if (n == 4 && m == 2)
|
||||
screen_write_mode_set(sctx, MODE_KEYS_EXTENDED_2);
|
||||
break;
|
||||
case INPUT_CSI_MODOFF:
|
||||
n = input_get(ictx, 0, 0, 0);
|
||||
if (n == 4)
|
||||
screen_write_mode_clear(sctx, MODE_KEXTENDED);
|
||||
/*
|
||||
* Clear the extended key reporting mode as per the client request,
|
||||
* unless "extended-keys always" forces us into mode 1.
|
||||
*/
|
||||
if (n == 4) {
|
||||
screen_write_mode_clear(sctx,
|
||||
MODE_KEYS_EXTENDED|MODE_KEYS_EXTENDED_2);
|
||||
}
|
||||
break;
|
||||
case INPUT_CSI_WINOPS:
|
||||
input_csi_dispatch_winops(ictx);
|
||||
|
@ -413,6 +413,8 @@ key_bindings_init(void)
|
||||
"bind -N 'Set the main-horizontal layout' M-3 { select-layout main-horizontal }",
|
||||
"bind -N 'Set the main-vertical layout' M-4 { select-layout main-vertical }",
|
||||
"bind -N 'Select the tiled layout' M-5 { select-layout tiled }",
|
||||
"bind -N 'Set the main-horizontal-mirrored layout' M-6 { select-layout main-horizontal-mirrored }",
|
||||
"bind -N 'Set the main-vertical-mirrored layout' M-7 { select-layout main-vertical-mirrored }",
|
||||
"bind -N 'Select the next window with an alert' M-n { next-window -a }",
|
||||
"bind -N 'Rotate through the panes in reverse' M-o { rotate-window -D }",
|
||||
"bind -N 'Select the previous window with an alert' M-p { previous-window -a }",
|
||||
|
77
key-string.c
77
key-string.c
@ -56,12 +56,47 @@ static const struct {
|
||||
{ "PPage", KEYC_PPAGE|KEYC_IMPLIED_META },
|
||||
{ "PageUp", KEYC_PPAGE|KEYC_IMPLIED_META },
|
||||
{ "PgUp", KEYC_PPAGE|KEYC_IMPLIED_META },
|
||||
{ "Tab", '\011' },
|
||||
{ "BTab", KEYC_BTAB },
|
||||
{ "Space", ' ' },
|
||||
{ "BSpace", KEYC_BSPACE },
|
||||
{ "Enter", '\r' },
|
||||
{ "Escape", '\033' },
|
||||
|
||||
/*
|
||||
* C0 control characters, with the exception of Tab, Enter,
|
||||
* and Esc, should never appear as keys. We still render them,
|
||||
* so to be able to spot them in logs in case of an abnormality.
|
||||
*/
|
||||
{ "[NUL]", C0_NUL },
|
||||
{ "[SOH]", C0_SOH },
|
||||
{ "[STX]", C0_STX },
|
||||
{ "[ETX]", C0_ETX },
|
||||
{ "[EOT]", C0_EOT },
|
||||
{ "[ENQ]", C0_ENQ },
|
||||
{ "[ASC]", C0_ASC },
|
||||
{ "[BEL]", C0_BEL },
|
||||
{ "[BS]", C0_BS },
|
||||
{ "Tab", C0_HT },
|
||||
{ "[LF]", C0_LF },
|
||||
{ "[VT]", C0_VT },
|
||||
{ "[FF]", C0_FF },
|
||||
{ "Enter", C0_CR },
|
||||
{ "[SO]", C0_SO },
|
||||
{ "[SI]", C0_SI },
|
||||
{ "[DLE]", C0_DLE },
|
||||
{ "[DC1]", C0_DC1 },
|
||||
{ "[DC2]", C0_DC2 },
|
||||
{ "[DC3]", C0_DC3 },
|
||||
{ "[DC4]", C0_DC4 },
|
||||
{ "[NAK]", C0_NAK },
|
||||
{ "[SYN]", C0_SYN },
|
||||
{ "[ETB]", C0_ETB },
|
||||
{ "[CAN]", C0_CAN },
|
||||
{ "[EM]", C0_EM },
|
||||
{ "[SUB]", C0_SUB },
|
||||
{ "Escape", C0_ESC },
|
||||
{ "[FS]", C0_FS },
|
||||
{ "[GS]", C0_GS },
|
||||
{ "[RS]", C0_RS },
|
||||
{ "[US]", C0_US },
|
||||
|
||||
/* Arrow keys. */
|
||||
{ "Up", KEYC_UP|KEYC_CURSOR|KEYC_IMPLIED_META },
|
||||
@ -206,7 +241,6 @@ key_string_get_modifiers(const char **string)
|
||||
key_code
|
||||
key_string_lookup_string(const char *string)
|
||||
{
|
||||
static const char *other = "!#()+,-.0123456789:;<=>'\r\t\177`/";
|
||||
key_code key, modifiers;
|
||||
u_int u, i;
|
||||
struct utf8_data ud, *udp;
|
||||
@ -281,26 +315,6 @@ key_string_lookup_string(const char *string)
|
||||
key &= ~KEYC_IMPLIED_META;
|
||||
}
|
||||
|
||||
/* Convert the standard control keys. */
|
||||
if (key <= 127 &&
|
||||
(modifiers & KEYC_CTRL) &&
|
||||
strchr(other, key) == NULL &&
|
||||
key != 9 &&
|
||||
key != 13 &&
|
||||
key != 27) {
|
||||
if (key >= 97 && key <= 122)
|
||||
key -= 96;
|
||||
else if (key >= 64 && key <= 95)
|
||||
key -= 64;
|
||||
else if (key == 32)
|
||||
key = 0;
|
||||
else if (key == 63)
|
||||
key = 127;
|
||||
else
|
||||
return (KEYC_UNKNOWN);
|
||||
modifiers &= ~KEYC_CTRL;
|
||||
}
|
||||
|
||||
return (key|modifiers);
|
||||
}
|
||||
|
||||
@ -324,10 +338,6 @@ key_string_lookup_key(key_code key, int with_flags)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Display C-@ as C-Space. */
|
||||
if ((key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS)) == 0)
|
||||
key = ' '|KEYC_CTRL;
|
||||
|
||||
/* Fill in the modifiers. */
|
||||
if (key & KEYC_CTRL)
|
||||
strlcat(out, "C-", sizeof out);
|
||||
@ -427,13 +437,8 @@ key_string_lookup_key(key_code key, int with_flags)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check for standard or control key. */
|
||||
if (key <= 32) {
|
||||
if (key == 0 || key > 26)
|
||||
xsnprintf(tmp, sizeof tmp, "C-%c", (int)(64 + key));
|
||||
else
|
||||
xsnprintf(tmp, sizeof tmp, "C-%c", (int)(96 + key));
|
||||
} else if (key >= 32 && key <= 126) {
|
||||
/* Printable ASCII keys. */
|
||||
if (key > 32 && key <= 126) {
|
||||
tmp[0] = key;
|
||||
tmp[1] = '\0';
|
||||
} else if (key == 127)
|
||||
@ -460,8 +465,6 @@ out:
|
||||
strlcat(out, "I", sizeof out);
|
||||
if (saved & KEYC_BUILD_MODIFIERS)
|
||||
strlcat(out, "B", sizeof out);
|
||||
if (saved & KEYC_EXTENDED)
|
||||
strlcat(out, "E", sizeof out);
|
||||
if (saved & KEYC_SENT)
|
||||
strlcat(out, "S", sizeof out);
|
||||
strlcat(out, "]", sizeof out);
|
||||
|
200
layout-set.c
200
layout-set.c
@ -31,7 +31,9 @@
|
||||
static void layout_set_even_h(struct window *);
|
||||
static void layout_set_even_v(struct window *);
|
||||
static void layout_set_main_h(struct window *);
|
||||
static void layout_set_main_h_mirrored(struct window *);
|
||||
static void layout_set_main_v(struct window *);
|
||||
static void layout_set_main_v_mirrored(struct window *);
|
||||
static void layout_set_tiled(struct window *);
|
||||
|
||||
static const struct {
|
||||
@ -41,7 +43,9 @@ static const struct {
|
||||
{ "even-horizontal", layout_set_even_h },
|
||||
{ "even-vertical", layout_set_even_v },
|
||||
{ "main-horizontal", layout_set_main_h },
|
||||
{ "main-horizontal-mirrored", layout_set_main_h_mirrored },
|
||||
{ "main-vertical", layout_set_main_v },
|
||||
{ "main-vertical-mirrored", layout_set_main_v_mirrored },
|
||||
{ "tiled", layout_set_tiled },
|
||||
};
|
||||
|
||||
@ -279,6 +283,104 @@ layout_set_main_h(struct window *w)
|
||||
server_redraw_window(w);
|
||||
}
|
||||
|
||||
static void
|
||||
layout_set_main_h_mirrored(struct window *w)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
struct layout_cell *lc, *lcmain, *lcother, *lcchild;
|
||||
u_int n, mainh, otherh, sx, sy;
|
||||
char *cause;
|
||||
const char *s;
|
||||
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
if (n <= 1)
|
||||
return;
|
||||
n--; /* take off main pane */
|
||||
|
||||
/* Find available height - take off one line for the border. */
|
||||
sy = w->sy - 1;
|
||||
|
||||
/* Get the main pane height. */
|
||||
s = options_get_string(w->options, "main-pane-height");
|
||||
mainh = args_string_percentage(s, 0, sy, sy, &cause);
|
||||
if (cause != NULL) {
|
||||
mainh = 24;
|
||||
free(cause);
|
||||
}
|
||||
|
||||
/* Work out the other pane height. */
|
||||
if (mainh + PANE_MINIMUM >= sy) {
|
||||
if (sy <= PANE_MINIMUM + PANE_MINIMUM)
|
||||
mainh = PANE_MINIMUM;
|
||||
else
|
||||
mainh = sy - PANE_MINIMUM;
|
||||
otherh = PANE_MINIMUM;
|
||||
} else {
|
||||
s = options_get_string(w->options, "other-pane-height");
|
||||
otherh = args_string_percentage(s, 0, sy, sy, &cause);
|
||||
if (cause != NULL || otherh == 0) {
|
||||
otherh = sy - mainh;
|
||||
free(cause);
|
||||
} else if (otherh > sy || sy - otherh < mainh)
|
||||
otherh = sy - mainh;
|
||||
else
|
||||
mainh = sy - otherh;
|
||||
}
|
||||
|
||||
/* Work out what width is needed. */
|
||||
sx = (n * (PANE_MINIMUM + 1)) - 1;
|
||||
if (sx < w->sx)
|
||||
sx = w->sx;
|
||||
|
||||
/* Free old tree and create a new root. */
|
||||
layout_free(w);
|
||||
lc = w->layout_root = layout_create_cell(NULL);
|
||||
layout_set_size(lc, sx, mainh + otherh + 1, 0, 0);
|
||||
layout_make_node(lc, LAYOUT_TOPBOTTOM);
|
||||
|
||||
/* Create the other pane. */
|
||||
lcother = layout_create_cell(lc);
|
||||
layout_set_size(lcother, sx, otherh, 0, 0);
|
||||
if (n == 1) {
|
||||
wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
|
||||
layout_make_leaf(lcother, wp);
|
||||
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||
} else {
|
||||
layout_make_node(lcother, LAYOUT_LEFTRIGHT);
|
||||
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||
|
||||
/* Add the remaining panes as children. */
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp == TAILQ_FIRST(&w->panes))
|
||||
continue;
|
||||
lcchild = layout_create_cell(lcother);
|
||||
layout_set_size(lcchild, PANE_MINIMUM, otherh, 0, 0);
|
||||
layout_make_leaf(lcchild, wp);
|
||||
TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
|
||||
}
|
||||
layout_spread_cell(w, lcother);
|
||||
}
|
||||
|
||||
/* Create the main pane. */
|
||||
lcmain = layout_create_cell(lc);
|
||||
layout_set_size(lcmain, sx, mainh, 0, 0);
|
||||
layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
|
||||
TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
|
||||
|
||||
/* Fix cell offsets. */
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
window_resize(w, lc->sx, lc->sy, -1, -1);
|
||||
notify_window("window-layout-changed", w);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
|
||||
static void
|
||||
layout_set_main_v(struct window *w)
|
||||
{
|
||||
@ -377,6 +479,104 @@ layout_set_main_v(struct window *w)
|
||||
server_redraw_window(w);
|
||||
}
|
||||
|
||||
static void
|
||||
layout_set_main_v_mirrored(struct window *w)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
struct layout_cell *lc, *lcmain, *lcother, *lcchild;
|
||||
u_int n, mainw, otherw, sx, sy;
|
||||
char *cause;
|
||||
const char *s;
|
||||
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
if (n <= 1)
|
||||
return;
|
||||
n--; /* take off main pane */
|
||||
|
||||
/* Find available width - take off one line for the border. */
|
||||
sx = w->sx - 1;
|
||||
|
||||
/* Get the main pane width. */
|
||||
s = options_get_string(w->options, "main-pane-width");
|
||||
mainw = args_string_percentage(s, 0, sx, sx, &cause);
|
||||
if (cause != NULL) {
|
||||
mainw = 80;
|
||||
free(cause);
|
||||
}
|
||||
|
||||
/* Work out the other pane width. */
|
||||
if (mainw + PANE_MINIMUM >= sx) {
|
||||
if (sx <= PANE_MINIMUM + PANE_MINIMUM)
|
||||
mainw = PANE_MINIMUM;
|
||||
else
|
||||
mainw = sx - PANE_MINIMUM;
|
||||
otherw = PANE_MINIMUM;
|
||||
} else {
|
||||
s = options_get_string(w->options, "other-pane-width");
|
||||
otherw = args_string_percentage(s, 0, sx, sx, &cause);
|
||||
if (cause != NULL || otherw == 0) {
|
||||
otherw = sx - mainw;
|
||||
free(cause);
|
||||
} else if (otherw > sx || sx - otherw < mainw)
|
||||
otherw = sx - mainw;
|
||||
else
|
||||
mainw = sx - otherw;
|
||||
}
|
||||
|
||||
/* Work out what height is needed. */
|
||||
sy = (n * (PANE_MINIMUM + 1)) - 1;
|
||||
if (sy < w->sy)
|
||||
sy = w->sy;
|
||||
|
||||
/* Free old tree and create a new root. */
|
||||
layout_free(w);
|
||||
lc = w->layout_root = layout_create_cell(NULL);
|
||||
layout_set_size(lc, mainw + otherw + 1, sy, 0, 0);
|
||||
layout_make_node(lc, LAYOUT_LEFTRIGHT);
|
||||
|
||||
/* Create the other pane. */
|
||||
lcother = layout_create_cell(lc);
|
||||
layout_set_size(lcother, otherw, sy, 0, 0);
|
||||
if (n == 1) {
|
||||
wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
|
||||
layout_make_leaf(lcother, wp);
|
||||
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||
} else {
|
||||
layout_make_node(lcother, LAYOUT_TOPBOTTOM);
|
||||
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||
|
||||
/* Add the remaining panes as children. */
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp == TAILQ_FIRST(&w->panes))
|
||||
continue;
|
||||
lcchild = layout_create_cell(lcother);
|
||||
layout_set_size(lcchild, otherw, PANE_MINIMUM, 0, 0);
|
||||
layout_make_leaf(lcchild, wp);
|
||||
TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
|
||||
}
|
||||
layout_spread_cell(w, lcother);
|
||||
}
|
||||
|
||||
/* Create the main pane. */
|
||||
lcmain = layout_create_cell(lc);
|
||||
layout_set_size(lcmain, mainw, sy, 0, 0);
|
||||
layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
|
||||
TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
|
||||
|
||||
/* Fix cell offsets. */
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
window_resize(w, lc->sx, lc->sy, -1, -1);
|
||||
notify_window("window-layout-changed", w);
|
||||
server_redraw_window(w);
|
||||
}
|
||||
|
||||
void
|
||||
layout_set_tiled(struct window *w)
|
||||
{
|
||||
|
8
menu.c
8
menu.c
@ -335,7 +335,7 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
|
||||
c->flags |= CLIENT_REDRAWOVERLAY;
|
||||
return (0);
|
||||
case KEYC_PPAGE:
|
||||
case '\002': /* C-b */
|
||||
case 'b'|KEYC_CTRL:
|
||||
if (md->choice < 6)
|
||||
md->choice = 0;
|
||||
else {
|
||||
@ -394,13 +394,13 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
|
||||
}
|
||||
c->flags |= CLIENT_REDRAWOVERLAY;
|
||||
break;
|
||||
case '\006': /* C-f */
|
||||
case 'f'|KEYC_CTRL:
|
||||
break;
|
||||
case '\r':
|
||||
goto chosen;
|
||||
case '\033': /* Escape */
|
||||
case '\003': /* C-c */
|
||||
case '\007': /* C-g */
|
||||
case 'c'|KEYC_CTRL:
|
||||
case 'g'|KEYC_CTRL:
|
||||
case 'q':
|
||||
return (1);
|
||||
}
|
||||
|
14
mode-tree.c
14
mode-tree.c
@ -1088,22 +1088,22 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
switch (*key) {
|
||||
case 'q':
|
||||
case '\033': /* Escape */
|
||||
case '\007': /* C-g */
|
||||
case 'g'|KEYC_CTRL:
|
||||
return (1);
|
||||
case KEYC_UP:
|
||||
case 'k':
|
||||
case KEYC_WHEELUP_PANE:
|
||||
case '\020': /* C-p */
|
||||
case 'p'|KEYC_CTRL:
|
||||
mode_tree_up(mtd, 1);
|
||||
break;
|
||||
case KEYC_DOWN:
|
||||
case 'j':
|
||||
case KEYC_WHEELDOWN_PANE:
|
||||
case '\016': /* C-n */
|
||||
case 'n'|KEYC_CTRL:
|
||||
mode_tree_down(mtd, 1);
|
||||
break;
|
||||
case KEYC_PPAGE:
|
||||
case '\002': /* C-b */
|
||||
case 'b'|KEYC_CTRL:
|
||||
for (i = 0; i < mtd->height; i++) {
|
||||
if (mtd->current == 0)
|
||||
break;
|
||||
@ -1111,7 +1111,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
}
|
||||
break;
|
||||
case KEYC_NPAGE:
|
||||
case '\006': /* C-f */
|
||||
case 'f'|KEYC_CTRL:
|
||||
for (i = 0; i < mtd->height; i++) {
|
||||
if (mtd->current == mtd->line_size - 1)
|
||||
break;
|
||||
@ -1155,7 +1155,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
for (i = 0; i < mtd->line_size; i++)
|
||||
mtd->line_list[i].item->tagged = 0;
|
||||
break;
|
||||
case '\024': /* C-t */
|
||||
case 't'|KEYC_CTRL:
|
||||
for (i = 0; i < mtd->line_size; i++) {
|
||||
if ((mtd->line_list[i].item->parent == NULL &&
|
||||
!mtd->line_list[i].item->no_tag) ||
|
||||
@ -1211,7 +1211,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
break;
|
||||
case '?':
|
||||
case '/':
|
||||
case '\023': /* C-s */
|
||||
case 's'|KEYC_CTRL:
|
||||
mtd->references++;
|
||||
status_prompt_set(c, NULL, "(search) ", "",
|
||||
mode_tree_search_callback, mode_tree_search_free, mtd,
|
||||
|
@ -93,6 +93,9 @@ static const char *options_table_detach_on_destroy_list[] = {
|
||||
static const char *options_table_extended_keys_list[] = {
|
||||
"off", "on", "always", NULL
|
||||
};
|
||||
static const char *options_table_extended_keys_format_list[] = {
|
||||
"csi-u", "xterm", NULL
|
||||
};
|
||||
static const char *options_table_allow_passthrough_list[] = {
|
||||
"off", "on", "all", NULL
|
||||
};
|
||||
@ -314,6 +317,14 @@ const struct options_table_entry options_table[] = {
|
||||
"that support it."
|
||||
},
|
||||
|
||||
{ .name = "extended-keys-format",
|
||||
.type = OPTIONS_TABLE_CHOICE,
|
||||
.scope = OPTIONS_TABLE_SERVER,
|
||||
.choices = options_table_extended_keys_format_list,
|
||||
.default_num = 1,
|
||||
.text = "The format of emitted extended key sequences."
|
||||
},
|
||||
|
||||
{ .name = "focus-events",
|
||||
.type = OPTIONS_TABLE_FLAG,
|
||||
.scope = OPTIONS_TABLE_SERVER,
|
||||
@ -613,7 +624,7 @@ const struct options_table_entry options_table[] = {
|
||||
{ .name = "prefix",
|
||||
.type = OPTIONS_TABLE_KEY,
|
||||
.scope = OPTIONS_TABLE_SESSION,
|
||||
.default_num = '\002',
|
||||
.default_num = 'b'|KEYC_CTRL,
|
||||
.text = "The prefix key."
|
||||
},
|
||||
|
||||
|
2
popup.c
2
popup.c
@ -542,7 +542,7 @@ popup_key_cb(struct client *c, void *data, struct key_event *event)
|
||||
}
|
||||
if ((((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0) ||
|
||||
pd->job == NULL) &&
|
||||
(event->key == '\033' || event->key == '\003'))
|
||||
(event->key == '\033' || event->key == ('c'|KEYC_CTRL)))
|
||||
return (1);
|
||||
if (pd->job != NULL) {
|
||||
if (KEYC_IS_MOUSE(event->key)) {
|
||||
|
@ -326,8 +326,9 @@ screen_write_reset(struct screen_write_ctx *ctx)
|
||||
screen_write_scrollregion(ctx, 0, screen_size_y(s) - 1);
|
||||
|
||||
s->mode = MODE_CURSOR|MODE_WRAP;
|
||||
|
||||
if (options_get_number(global_options, "extended-keys") == 2)
|
||||
s->mode |= MODE_KEXTENDED;
|
||||
s->mode = (s->mode & ~EXTENDED_KEY_MODES)|MODE_KEYS_EXTENDED;
|
||||
|
||||
screen_write_clearscreen(ctx, 8);
|
||||
screen_write_set_cursor(ctx, 0, 0);
|
||||
|
9
screen.c
9
screen.c
@ -110,8 +110,9 @@ screen_reinit(struct screen *s)
|
||||
s->rlower = screen_size_y(s) - 1;
|
||||
|
||||
s->mode = MODE_CURSOR|MODE_WRAP|(s->mode & MODE_CRLF);
|
||||
|
||||
if (options_get_number(global_options, "extended-keys") == 2)
|
||||
s->mode |= MODE_KEXTENDED;
|
||||
s->mode = (s->mode & ~EXTENDED_KEY_MODES)|MODE_KEYS_EXTENDED;
|
||||
|
||||
if (s->saved_grid != NULL)
|
||||
screen_alternate_off(s, NULL, 0);
|
||||
@ -730,8 +731,10 @@ screen_mode_to_string(int mode)
|
||||
strlcat(tmp, "ORIGIN,", sizeof tmp);
|
||||
if (mode & MODE_CRLF)
|
||||
strlcat(tmp, "CRLF,", sizeof tmp);
|
||||
if (mode & MODE_KEXTENDED)
|
||||
strlcat(tmp, "KEXTENDED,", sizeof tmp);
|
||||
if (mode & MODE_KEYS_EXTENDED)
|
||||
strlcat(tmp, "KEYS_EXTENDED,", sizeof tmp);
|
||||
if (mode & MODE_KEYS_EXTENDED_2)
|
||||
strlcat(tmp, "KEYS_EXTENDED_2,", sizeof tmp);
|
||||
tmp[strlen(tmp) - 1] = '\0';
|
||||
return (tmp);
|
||||
}
|
||||
|
77
status.c
77
status.c
@ -839,19 +839,19 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
{
|
||||
if (c->prompt_mode == PROMPT_ENTRY) {
|
||||
switch (key) {
|
||||
case '\001': /* C-a */
|
||||
case '\003': /* C-c */
|
||||
case '\005': /* C-e */
|
||||
case '\007': /* C-g */
|
||||
case '\010': /* C-h */
|
||||
case 'a'|KEYC_CTRL:
|
||||
case 'c'|KEYC_CTRL:
|
||||
case 'e'|KEYC_CTRL:
|
||||
case 'g'|KEYC_CTRL:
|
||||
case 'h'|KEYC_CTRL:
|
||||
case '\011': /* Tab */
|
||||
case '\013': /* C-k */
|
||||
case '\016': /* C-n */
|
||||
case '\020': /* C-p */
|
||||
case '\024': /* C-t */
|
||||
case '\025': /* C-u */
|
||||
case '\027': /* C-w */
|
||||
case '\031': /* C-y */
|
||||
case 'k'|KEYC_CTRL:
|
||||
case 'n'|KEYC_CTRL:
|
||||
case 'p'|KEYC_CTRL:
|
||||
case 't'|KEYC_CTRL:
|
||||
case 'u'|KEYC_CTRL:
|
||||
case 'w'|KEYC_CTRL:
|
||||
case 'y'|KEYC_CTRL:
|
||||
case '\n':
|
||||
case '\r':
|
||||
case KEYC_LEFT|KEYC_CTRL:
|
||||
@ -890,7 +890,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
case 'S':
|
||||
c->prompt_mode = PROMPT_ENTRY;
|
||||
c->flags |= CLIENT_REDRAWSTATUS;
|
||||
*new_key = '\025'; /* C-u */
|
||||
*new_key = 'u'|KEYC_CTRL;
|
||||
return (1);
|
||||
case 'i':
|
||||
case '\033': /* Escape */
|
||||
@ -911,7 +911,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
return (1);
|
||||
case 'C':
|
||||
case 'D':
|
||||
*new_key = '\013'; /* C-k */
|
||||
*new_key = 'k'|KEYC_CTRL;
|
||||
return (1);
|
||||
case KEYC_BSPACE:
|
||||
case 'X':
|
||||
@ -924,7 +924,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
*new_key = 'B'|KEYC_VI;
|
||||
return (1);
|
||||
case 'd':
|
||||
*new_key = '\025'; /* C-u */
|
||||
*new_key = 'u'|KEYC_CTRL;
|
||||
return (1);
|
||||
case 'e':
|
||||
*new_key = 'e'|KEYC_VI;
|
||||
@ -939,10 +939,10 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
*new_key = 'W'|KEYC_VI;
|
||||
return (1);
|
||||
case 'p':
|
||||
*new_key = '\031'; /* C-y */
|
||||
*new_key = 'y'|KEYC_CTRL;
|
||||
return (1);
|
||||
case 'q':
|
||||
*new_key = '\003'; /* C-c */
|
||||
*new_key = 'c'|KEYC_CTRL;
|
||||
return (1);
|
||||
case 's':
|
||||
case KEYC_DC:
|
||||
@ -966,8 +966,8 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
case 'k':
|
||||
*new_key = KEYC_UP;
|
||||
return (1);
|
||||
case '\010' /* C-h */:
|
||||
case '\003' /* C-c */:
|
||||
case 'h'|KEYC_CTRL:
|
||||
case 'c'|KEYC_CTRL:
|
||||
case '\n':
|
||||
case '\r':
|
||||
return (1);
|
||||
@ -1263,28 +1263,28 @@ status_prompt_key(struct client *c, key_code key)
|
||||
process_key:
|
||||
switch (key) {
|
||||
case KEYC_LEFT:
|
||||
case '\002': /* C-b */
|
||||
case 'b'|KEYC_CTRL:
|
||||
if (c->prompt_index > 0) {
|
||||
c->prompt_index--;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEYC_RIGHT:
|
||||
case '\006': /* C-f */
|
||||
case 'f'|KEYC_CTRL:
|
||||
if (c->prompt_index < size) {
|
||||
c->prompt_index++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEYC_HOME:
|
||||
case '\001': /* C-a */
|
||||
case 'a'|KEYC_CTRL:
|
||||
if (c->prompt_index != 0) {
|
||||
c->prompt_index = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEYC_END:
|
||||
case '\005': /* C-e */
|
||||
case 'e'|KEYC_CTRL:
|
||||
if (c->prompt_index != size) {
|
||||
c->prompt_index = size;
|
||||
break;
|
||||
@ -1295,7 +1295,7 @@ process_key:
|
||||
goto changed;
|
||||
break;
|
||||
case KEYC_BSPACE:
|
||||
case '\010': /* C-h */
|
||||
case 'h'|KEYC_CTRL:
|
||||
if (c->prompt_index != 0) {
|
||||
if (c->prompt_index == size)
|
||||
c->prompt_buffer[--c->prompt_index].size = 0;
|
||||
@ -1310,7 +1310,7 @@ process_key:
|
||||
}
|
||||
break;
|
||||
case KEYC_DC:
|
||||
case '\004': /* C-d */
|
||||
case 'd'|KEYC_CTRL:
|
||||
if (c->prompt_index != size) {
|
||||
memmove(c->prompt_buffer + c->prompt_index,
|
||||
c->prompt_buffer + c->prompt_index + 1,
|
||||
@ -1319,17 +1319,17 @@ process_key:
|
||||
goto changed;
|
||||
}
|
||||
break;
|
||||
case '\025': /* C-u */
|
||||
case 'u'|KEYC_CTRL:
|
||||
c->prompt_buffer[0].size = 0;
|
||||
c->prompt_index = 0;
|
||||
goto changed;
|
||||
case '\013': /* C-k */
|
||||
case 'k'|KEYC_CTRL:
|
||||
if (c->prompt_index < size) {
|
||||
c->prompt_buffer[c->prompt_index].size = 0;
|
||||
goto changed;
|
||||
}
|
||||
break;
|
||||
case '\027': /* C-w */
|
||||
case 'w'|KEYC_CTRL:
|
||||
separators = options_get_string(oo, "word-separators");
|
||||
idx = c->prompt_index;
|
||||
|
||||
@ -1397,7 +1397,7 @@ process_key:
|
||||
status_prompt_backward_word(c, separators);
|
||||
goto changed;
|
||||
case KEYC_UP:
|
||||
case '\020': /* C-p */
|
||||
case 'p'|KEYC_CTRL:
|
||||
histstr = status_prompt_up_history(c->prompt_hindex,
|
||||
c->prompt_type);
|
||||
if (histstr == NULL)
|
||||
@ -1407,7 +1407,7 @@ process_key:
|
||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||
goto changed;
|
||||
case KEYC_DOWN:
|
||||
case '\016': /* C-n */
|
||||
case 'n'|KEYC_CTRL:
|
||||
histstr = status_prompt_down_history(c->prompt_hindex,
|
||||
c->prompt_type);
|
||||
if (histstr == NULL)
|
||||
@ -1416,11 +1416,11 @@ process_key:
|
||||
c->prompt_buffer = utf8_fromcstr(histstr);
|
||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||
goto changed;
|
||||
case '\031': /* C-y */
|
||||
case 'y'|KEYC_CTRL:
|
||||
if (status_prompt_paste(c))
|
||||
goto changed;
|
||||
break;
|
||||
case '\024': /* C-t */
|
||||
case 't'|KEYC_CTRL:
|
||||
idx = c->prompt_index;
|
||||
if (idx < size)
|
||||
idx++;
|
||||
@ -1443,12 +1443,12 @@ process_key:
|
||||
free(s);
|
||||
break;
|
||||
case '\033': /* Escape */
|
||||
case '\003': /* C-c */
|
||||
case '\007': /* C-g */
|
||||
case 'c'|KEYC_CTRL:
|
||||
case 'g'|KEYC_CTRL:
|
||||
if (c->prompt_inputcb(c, c->prompt_data, NULL, 1) == 0)
|
||||
status_prompt_clear(c);
|
||||
break;
|
||||
case '\022': /* C-r */
|
||||
case 'r'|KEYC_CTRL:
|
||||
if (~c->prompt_flags & PROMPT_INCREMENTAL)
|
||||
break;
|
||||
if (c->prompt_buffer[0].size == 0) {
|
||||
@ -1459,7 +1459,7 @@ process_key:
|
||||
} else
|
||||
prefix = '-';
|
||||
goto changed;
|
||||
case '\023': /* C-s */
|
||||
case 's'|KEYC_CTRL:
|
||||
if (~c->prompt_flags & PROMPT_INCREMENTAL)
|
||||
break;
|
||||
if (c->prompt_buffer[0].size == 0) {
|
||||
@ -1626,8 +1626,9 @@ status_prompt_complete_list(u_int *size, const char *s, int at_start)
|
||||
struct options_entry *o;
|
||||
struct options_array_item *a;
|
||||
const char *layouts[] = {
|
||||
"even-horizontal", "even-vertical", "main-horizontal",
|
||||
"main-vertical", "tiled", NULL
|
||||
"even-horizontal", "even-vertical",
|
||||
"main-horizontal", "main-horizontal-mirrored",
|
||||
"main-vertical", "main-vertical-mirrored", "tiled", NULL
|
||||
};
|
||||
|
||||
*size = 0;
|
||||
|
114
tmux.1
114
tmux.1
@ -372,8 +372,10 @@ Enter copy mode and scroll one page up.
|
||||
Change to the pane above, below, to the left, or to the right of the current
|
||||
pane.
|
||||
.It M-1 to M-5
|
||||
Arrange panes in one of the five preset layouts: even-horizontal,
|
||||
even-vertical, main-horizontal, main-vertical, or tiled.
|
||||
Arrange panes in one of the seven preset layouts:
|
||||
even-horizontal, even-vertical,
|
||||
main-horizontal, main-horizontal-mirrored,
|
||||
main-vertical, main-vertical, or tiled.
|
||||
.It Space
|
||||
Arrange the current window in the next preset layout.
|
||||
.It M-n
|
||||
@ -2164,14 +2166,20 @@ are spread from left to right in the leftover space at the bottom.
|
||||
Use the
|
||||
.Em main-pane-height
|
||||
window option to specify the height of the top pane.
|
||||
.It Ic main-vertical
|
||||
Similar to
|
||||
.It Ic main-horizontal-mirrored
|
||||
The same as
|
||||
.Ic main-horizontal
|
||||
but the large pane is placed on the left and the others spread from top to
|
||||
bottom along the right.
|
||||
See the
|
||||
but mirrored so the main pane is at the bottom of the window.
|
||||
.It Ic main-vertical
|
||||
A large (main) pane is shown on the left of the window and the remaining panes
|
||||
are spread from top to bottom in the leftover space on the right.
|
||||
Use the
|
||||
.Em main-pane-width
|
||||
window option.
|
||||
window option to specify the width of the left pane.
|
||||
.It Ic main-vertical-mirrored
|
||||
The same as
|
||||
.Ic main-vertical
|
||||
but mirrored so the main pane is on the right of the window.
|
||||
.It Ic tiled
|
||||
Panes are spread out as evenly as possible over the window in both rows and
|
||||
columns.
|
||||
@ -3735,6 +3743,10 @@ Note that aliases are expanded when a command is parsed rather than when it is
|
||||
executed, so binding an alias with
|
||||
.Ic bind-key
|
||||
will bind the expanded form.
|
||||
.It Ic copy-command Ar shell-command
|
||||
Give the command to pipe to if the
|
||||
.Ic copy-pipe
|
||||
copy mode command is used without arguments.
|
||||
.It Ic default-terminal Ar terminal
|
||||
Set the default terminal for new windows created in this session - the
|
||||
default value of the
|
||||
@ -3748,10 +3760,6 @@ be set to
|
||||
.Ql screen ,
|
||||
.Ql tmux
|
||||
or a derivative of them.
|
||||
.It Ic copy-command Ar shell-command
|
||||
Give the command to pipe to if the
|
||||
.Ic copy-pipe
|
||||
copy mode command is used without arguments.
|
||||
.It Ic escape-time Ar time
|
||||
Set the time in milliseconds for which
|
||||
.Nm
|
||||
@ -3773,22 +3781,53 @@ If enabled, the server will exit when there are no attached clients.
|
||||
.It Xo Ic extended-keys
|
||||
.Op Ic on | off | always
|
||||
.Xc
|
||||
When
|
||||
.Ic on
|
||||
or
|
||||
.Ic always ,
|
||||
the escape sequence to enable extended keys is sent to the terminal, if
|
||||
.Nm
|
||||
knows that it is supported.
|
||||
.Nm
|
||||
always recognises extended keys itself.
|
||||
If this option is
|
||||
Controls how modified keys (keys pressed together with Control, Meta, or Shift)
|
||||
are reported.
|
||||
This is the equivalent of the
|
||||
.Ic modifyOtherKeys
|
||||
.Xr xterm 1
|
||||
resource.
|
||||
.Pp
|
||||
When set to
|
||||
.Ic on ,
|
||||
.Nm
|
||||
will only forward extended keys to applications when they request them; if
|
||||
the program inside the pane can request one of two modes: mode 1 which changes
|
||||
the sequence for only keys which lack an existing well-known representation; or
|
||||
mode 2 which changes the sequence for all keys.
|
||||
When set to
|
||||
.Ic always ,
|
||||
mode 1 output is forced and the program cannot change it.
|
||||
When set to
|
||||
.Ic off ,
|
||||
this feature is disabled and only standard keys are reported.
|
||||
.Pp
|
||||
.Nm
|
||||
will always forward the keys.
|
||||
will always request extended keys itself if the terminal supports them.
|
||||
See also the
|
||||
.Ic extkeys
|
||||
feature for the
|
||||
.Ic terminal-features
|
||||
option, the
|
||||
.Ic extended-keys-format
|
||||
option and the
|
||||
.Ic pane_key_mode
|
||||
variable.
|
||||
.It Xo Ic extended-keys-format
|
||||
.Op Ic csi-u | xterm
|
||||
.Xc
|
||||
Selects one of the two possible formats for reporting modified keys to
|
||||
applications.
|
||||
This is the equivalent of the
|
||||
.Ic formatOtherKeys
|
||||
.Xr xterm 1
|
||||
resource.
|
||||
For example, C-S-a will be reported as
|
||||
.Ql ^[[27;6;65~
|
||||
when set to
|
||||
.Ic xterm ,
|
||||
and as
|
||||
.Ql ^[[65;6u
|
||||
when set to
|
||||
.Ic csi-u .
|
||||
.It Xo Ic focus-events
|
||||
.Op Ic on | off
|
||||
.Xc
|
||||
@ -4454,9 +4493,11 @@ Set the character used to fill areas of the terminal unused by a window.
|
||||
.It Ic main-pane-height Ar height
|
||||
.It Ic main-pane-width Ar width
|
||||
Set the width or height of the main (left or top) pane in the
|
||||
.Ic main-horizontal
|
||||
.Ic main-horizontal,
|
||||
.Ic main-horizontal-mirrored,
|
||||
.Ic main-vertical,
|
||||
or
|
||||
.Ic main-vertical
|
||||
.Ic main-vertical-mirrored
|
||||
layouts.
|
||||
If suffixed by
|
||||
.Ql % ,
|
||||
@ -4530,7 +4571,9 @@ An interval of zero disables the monitoring.
|
||||
.It Ic other-pane-height Ar height
|
||||
Set the height of the other panes (not the main pane) in the
|
||||
.Ic main-horizontal
|
||||
layout.
|
||||
and
|
||||
.Ic main-horizontal-mirrored
|
||||
layouts.
|
||||
If this option is set to 0 (the default), it will have no effect.
|
||||
If both the
|
||||
.Ic main-pane-height
|
||||
@ -4547,7 +4590,9 @@ Like
|
||||
.Ic other-pane-height ,
|
||||
but set the width of other panes in the
|
||||
.Ic main-vertical
|
||||
layout.
|
||||
and
|
||||
.Ic main-vertical-mirrored
|
||||
layouts.
|
||||
.Pp
|
||||
.It Ic pane-active-border-style Ar style
|
||||
Set the pane border style for the currently active pane.
|
||||
@ -5514,6 +5559,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "pane_in_mode" Ta "" Ta "1 if pane is in a mode"
|
||||
.It Li "pane_index" Ta "#P" Ta "Index of pane"
|
||||
.It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled"
|
||||
.It Li "pane_key_mode" Ta "" Ta "Extended key reporting mode in this pane"
|
||||
.It Li "pane_last" Ta "" Ta "1 if last pane"
|
||||
.It Li "pane_left" Ta "" Ta "Left of pane"
|
||||
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
||||
@ -6572,6 +6618,11 @@ is given, the buffer is also sent to the clipboard for
|
||||
using the
|
||||
.Xr xterm 1
|
||||
escape sequence, if possible.
|
||||
If
|
||||
.Ar path
|
||||
is
|
||||
.Ql - ,
|
||||
the contents are read from stdin.
|
||||
.Tg pasteb
|
||||
.It Xo Ic paste-buffer
|
||||
.Op Fl dpr
|
||||
@ -6609,6 +6660,11 @@ Save the contents of the specified paste buffer to
|
||||
The
|
||||
.Fl a
|
||||
option appends to rather than overwriting the file.
|
||||
If
|
||||
.Ar path
|
||||
is
|
||||
.Ql - ,
|
||||
the contents are read from stdin.
|
||||
.It Xo Ic set-buffer
|
||||
.Op Fl aw
|
||||
.Op Fl b Ar buffer-name
|
||||
|
43
tmux.h
43
tmux.h
@ -147,8 +147,7 @@ struct winlink;
|
||||
#define KEYC_IMPLIED_META 0x08000000000000ULL
|
||||
#define KEYC_BUILD_MODIFIERS 0x10000000000000ULL
|
||||
#define KEYC_VI 0x20000000000000ULL
|
||||
#define KEYC_EXTENDED 0x40000000000000ULL
|
||||
#define KEYC_SENT 0x80000000000000ULL
|
||||
#define KEYC_SENT 0x40000000000000ULL
|
||||
|
||||
/* Masks for key bits. */
|
||||
#define KEYC_MASK_MODIFIERS 0x00f00000000000ULL
|
||||
@ -196,6 +195,42 @@ struct winlink;
|
||||
*/
|
||||
typedef unsigned long long key_code;
|
||||
|
||||
/* C0 control characters */
|
||||
enum {
|
||||
C0_NUL,
|
||||
C0_SOH,
|
||||
C0_STX,
|
||||
C0_ETX,
|
||||
C0_EOT,
|
||||
C0_ENQ,
|
||||
C0_ASC,
|
||||
C0_BEL,
|
||||
C0_BS,
|
||||
C0_HT,
|
||||
C0_LF,
|
||||
C0_VT,
|
||||
C0_FF,
|
||||
C0_CR,
|
||||
C0_SO,
|
||||
C0_SI,
|
||||
C0_DLE,
|
||||
C0_DC1,
|
||||
C0_DC2,
|
||||
C0_DC3,
|
||||
C0_DC4,
|
||||
C0_NAK,
|
||||
C0_SYN,
|
||||
C0_ETB,
|
||||
C0_CAN,
|
||||
C0_EM,
|
||||
C0_SUB,
|
||||
C0_ESC,
|
||||
C0_FS,
|
||||
C0_GS,
|
||||
C0_RS,
|
||||
C0_US
|
||||
};
|
||||
|
||||
/* Special key codes. */
|
||||
enum {
|
||||
/* Focus events. */
|
||||
@ -591,14 +626,16 @@ enum tty_code_code {
|
||||
#define MODE_MOUSE_ALL 0x1000
|
||||
#define MODE_ORIGIN 0x2000
|
||||
#define MODE_CRLF 0x4000
|
||||
#define MODE_KEXTENDED 0x8000
|
||||
#define MODE_KEYS_EXTENDED 0x8000
|
||||
#define MODE_CURSOR_VERY_VISIBLE 0x10000
|
||||
#define MODE_CURSOR_BLINKING_SET 0x20000
|
||||
#define MODE_KEYS_EXTENDED_2 0x40000
|
||||
|
||||
#define ALL_MODES 0xffffff
|
||||
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
||||
#define MOTION_MOUSE_MODES (MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
||||
#define CURSOR_MODES (MODE_CURSOR|MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE)
|
||||
#define EXTENDED_KEY_MODES (MODE_KEYS_EXTENDED|MODE_KEYS_EXTENDED_2)
|
||||
|
||||
/* Mouse protocol constants. */
|
||||
#define MOUSE_PARAM_MAX 0xff
|
||||
|
@ -237,7 +237,7 @@ static const struct tty_feature tty_feature_sync = {
|
||||
|
||||
/* Terminal supports extended keys. */
|
||||
static const char *const tty_feature_extkeys_capabilities[] = {
|
||||
"Eneks=\\E[>4;1m",
|
||||
"Eneks=\\E[>4;2m",
|
||||
"Dseks=\\E[>4m",
|
||||
NULL
|
||||
};
|
||||
|
58
tty-keys.c
58
tty-keys.c
@ -664,7 +664,7 @@ tty_keys_next(struct tty *tty)
|
||||
size_t len, size;
|
||||
cc_t bspace;
|
||||
int delay, expired = 0, n;
|
||||
key_code key;
|
||||
key_code key, onlykey;
|
||||
struct mouse_event m = { 0 };
|
||||
struct key_event *event;
|
||||
|
||||
@ -801,6 +801,26 @@ first_key:
|
||||
key = (u_char)buf[0];
|
||||
size = 1;
|
||||
}
|
||||
|
||||
/* C-Space is special. */
|
||||
if ((key & KEYC_MASK_KEY) == C0_NUL)
|
||||
key = ' ' | KEYC_CTRL | (key & KEYC_META);
|
||||
|
||||
/*
|
||||
* Fix up all C0 control codes that don't have a dedicated key into
|
||||
* corresponding Ctrl keys. Convert characters in the A-Z range into
|
||||
* lowercase, so ^A becomes a|CTRL.
|
||||
*/
|
||||
onlykey = key & KEYC_MASK_KEY;
|
||||
if (onlykey < 0x20 && onlykey != C0_BS &&
|
||||
onlykey != C0_HT && onlykey != C0_CR &&
|
||||
onlykey != C0_ESC) {
|
||||
onlykey |= 0x40;
|
||||
if (onlykey >= 'A' && onlykey <= 'Z')
|
||||
onlykey |= 0x20;
|
||||
key = onlykey | KEYC_CTRL | (key & KEYC_META);
|
||||
}
|
||||
|
||||
goto complete_key;
|
||||
|
||||
partial_key:
|
||||
@ -910,7 +930,6 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
||||
char tmp[64];
|
||||
cc_t bspace;
|
||||
key_code nkey;
|
||||
key_code onlykey;
|
||||
struct utf8_data ud;
|
||||
utf8_char uc;
|
||||
|
||||
@ -974,7 +993,13 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
||||
/* Update the modifiers. */
|
||||
if (modifiers > 0) {
|
||||
modifiers--;
|
||||
if (modifiers & 1)
|
||||
/*
|
||||
* The Shift modifier may not be reported in some input modes,
|
||||
* which is unfortunate, as in general case determining if a
|
||||
* character is shifted or not requires knowing the input
|
||||
* keyboard layout. So we only fix up the trivial case.
|
||||
*/
|
||||
if (modifiers & 1 || (nkey >= 'A' && nkey <= 'Z'))
|
||||
nkey |= KEYC_SHIFT;
|
||||
if (modifiers & 2)
|
||||
nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Alt */
|
||||
@ -984,34 +1009,15 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
||||
nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Meta */
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow both KEYC_CTRL and as an implied modifier. Also convert
|
||||
* C-X into C-x and so on.
|
||||
*/
|
||||
if (nkey & KEYC_CTRL) {
|
||||
onlykey = (nkey & KEYC_MASK_KEY);
|
||||
if (onlykey < 32 &&
|
||||
onlykey != 9 &&
|
||||
onlykey != 13 &&
|
||||
onlykey != 27)
|
||||
/* nothing */;
|
||||
else if (onlykey >= 97 && onlykey <= 122)
|
||||
onlykey -= 96;
|
||||
else if (onlykey >= 64 && onlykey <= 95)
|
||||
onlykey -= 64;
|
||||
else if (onlykey == 32)
|
||||
onlykey = 0;
|
||||
else if (onlykey == 63)
|
||||
onlykey = 127;
|
||||
else
|
||||
onlykey |= KEYC_CTRL;
|
||||
nkey = onlykey|((nkey & KEYC_MASK_MODIFIERS) & ~KEYC_CTRL);
|
||||
}
|
||||
/* Convert S-Tab into Backtab. */
|
||||
if ((nkey & KEYC_MASK_KEY) == '\011' && (nkey & KEYC_SHIFT))
|
||||
nkey = KEYC_BTAB | (nkey & ~KEYC_MASK_KEY & ~KEYC_SHIFT);
|
||||
|
||||
if (log_get_level() != 0) {
|
||||
log_debug("%s: extended key %.*s is %llx (%s)", c->name,
|
||||
(int)*size, buf, nkey, key_string_lookup_key(nkey, 1));
|
||||
}
|
||||
|
||||
*key = nkey;
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user