diff --git a/config.c b/config.c index dd39862d..e7597831 100644 --- a/config.c +++ b/config.c @@ -2010,12 +2010,18 @@ void setup_config_box(struct controlbox *b, bool midsession, conf_radiobutton_bool_handler, I(CONF_rxvt_homeend), "Standard", I(false), "rxvt", I(true), NULL); - ctrl_radiobuttons(s, "The Function keys and keypad", 'f', 3, + ctrl_radiobuttons(s, "The Function keys and keypad", 'f', 4, HELPCTX(keyboard_funkeys), conf_radiobutton_handler, I(CONF_funky_type), - "ESC[n~", I(0), "Linux", I(1), "Xterm R6", I(2), - "VT400", I(3), "VT100+", I(4), "SCO", I(5), NULL); + "ESC[n~", I(FUNKY_TILDE), + "Linux", I(FUNKY_LINUX), + "Xterm R6", I(FUNKY_XTERM), + "VT400", I(FUNKY_VT400), + "VT100+", I(FUNKY_VT100P), + "SCO", I(FUNKY_SCO), + "Xterm 216+", I(FUNKY_XTERM_216), + NULL); ctrl_radiobuttons(s, "Shift/Ctrl/Alt with the arrow keys", 'w', 2, HELPCTX(keyboard_sharrow), conf_radiobutton_handler, diff --git a/doc/config.but b/doc/config.but index a6a14ce9..df935388 100644 --- a/doc/config.but +++ b/doc/config.but @@ -596,6 +596,15 @@ through to \c{ESC [j}. With control they generate \c{ESC [k} through to \c{ESC [v}, and with shift and control together they generate \c{ESC [w} through to \c{ESC [\{}. +\b In \I{xterm}Xterm 216 mode, the unshifted function keys behave the +same as Xterm R6 mode. But pressing a function key together with Shift +or Alt or Ctrl generates a different sequence containing an extra +numeric parameter of the form (1 for Shift) + (2 for Alt) + (4 for +Ctrl) + 1. For F1-F4, the basic sequences like \c{ESC OP} become +\cw{ESC [1;}\e{bitmap}\cw{P} and similar; for F5 and above, +\cw{ESC[}\e{index}\cw{~} becomes +\cw{ESC[}\e{index}\cw{;}\e{bitmap}\cw{~}. + If you don't know what any of this means, you probably don't need to fiddle with it. diff --git a/putty.h b/putty.h index 1719e8db..ff679752 100644 --- a/putty.h +++ b/putty.h @@ -530,7 +530,8 @@ enum { FUNKY_XTERM, FUNKY_VT400, FUNKY_VT100P, - FUNKY_SCO + FUNKY_SCO, + FUNKY_XTERM_216 }; enum { @@ -1947,7 +1948,7 @@ typedef enum SmallKeypadKey { int format_arrow_key(char *buf, Terminal *term, int xkey, bool shift, bool ctrl, bool alt, bool *consumed_alt); int format_function_key(char *buf, Terminal *term, int key_number, - bool shift, bool ctrl); + bool shift, bool ctrl, bool alt, bool *consumed_alt); int format_small_keypad_key(char *buf, Terminal *term, SmallKeypadKey key); int format_numeric_keypad_key(char *buf, Terminal *term, char key, bool shift, bool ctrl); diff --git a/terminal/terminal.c b/terminal/terminal.c index dc12755c..424683dc 100644 --- a/terminal/terminal.c +++ b/terminal/terminal.c @@ -7301,7 +7301,7 @@ int format_arrow_key(char *buf, Terminal *term, int xkey, } int format_function_key(char *buf, Terminal *term, int key_number, - bool shift, bool ctrl) + bool shift, bool ctrl, bool alt, bool *consumed_alt) { char *p = buf; @@ -7314,7 +7314,14 @@ int format_function_key(char *buf, Terminal *term, int key_number, assert(key_number > 0); assert(key_number < lenof(key_number_to_tilde_code)); - int index = (shift && key_number <= 10) ? key_number + 10 : key_number; + int index = key_number; + if (term->funky_type != FUNKY_XTERM_216) { + if (shift && index <= 10) { + shift = false; + index += 10; + } + } + int code = key_number_to_tilde_code[index]; if (term->funky_type == FUNKY_SCO) { @@ -7338,13 +7345,28 @@ int format_function_key(char *buf, Terminal *term, int key_number, p += sprintf(p, "\x1BO%c", code + 'P' - 11 - offt); } else if (term->funky_type == FUNKY_LINUX && code >= 11 && code <= 15) { p += sprintf(p, "\x1B[[%c", code + 'A' - 11); - } else if (term->funky_type == FUNKY_XTERM && code >= 11 && code <= 14) { + } else if ((term->funky_type == FUNKY_XTERM || + term->funky_type == FUNKY_XTERM_216) && + code >= 11 && code <= 14) { if (term->vt52_mode) p += sprintf(p, "\x1B%c", code + 'P' - 11); - else - p += sprintf(p, "\x1BO%c", code + 'P' - 11); + else { + int bitmap = 0; + if (term->funky_type == FUNKY_XTERM_216) + bitmap = shift_bitmap(shift, ctrl, alt, consumed_alt); + if (bitmap) + p += sprintf(p, "\x1B[1;%d%c", bitmap, code + 'P' - 11); + else + p += sprintf(p, "\x1BO%c", code + 'P' - 11); + } } else { - p += sprintf(p, "\x1B[%d~", code); + int bitmap = 0; + if (term->funky_type == FUNKY_XTERM_216) + bitmap = shift_bitmap(shift, ctrl, alt, consumed_alt); + if (bitmap) + p += sprintf(p, "\x1B[%d;%d~", code, bitmap); + else + p += sprintf(p, "\x1B[%d~", code); } return p - buf; diff --git a/unix/window.c b/unix/window.c index 73ff5760..8740bc50 100644 --- a/unix/window.c +++ b/unix/window.c @@ -1831,9 +1831,14 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) case GDK_KEY_F19: fkey_number = 19; goto numbered_function_key; case GDK_KEY_F20: fkey_number = 20; goto numbered_function_key; numbered_function_key: + consumed_meta_key = false; end = 1 + format_function_key(output+1, inst->term, fkey_number, event->state & GDK_SHIFT_MASK, - event->state & GDK_CONTROL_MASK); + event->state & GDK_CONTROL_MASK, + event->state & inst->meta_mod_mask, + &consumed_meta_key); + if (consumed_meta_key) + start = 1; /* supersedes the usual prefixing of Esc */ #ifdef KEY_EVENT_DIAGNOSTICS debug(" - function key F%d", fkey_number); #endif diff --git a/windows/window.c b/windows/window.c index a5bad374..2f7cb274 100644 --- a/windows/window.c +++ b/windows/window.c @@ -4512,8 +4512,12 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, case VK_F19: fkey_number = 19; goto numbered_function_key; case VK_F20: fkey_number = 20; goto numbered_function_key; numbered_function_key: + consumed_alt = false; p += format_function_key((char *)p, term, fkey_number, - shift_state & 1, shift_state & 2); + shift_state & 1, shift_state & 2, + left_alt, &consumed_alt); + if (consumed_alt) + left_alt = false; /* supersedes the usual prefixing of Esc */ return p - output; SmallKeypadKey sk_key;