diff --git a/lib/tty/key.c b/lib/tty/key.c index 68cae9bd9..688ccc518 100644 --- a/lib/tty/key.c +++ b/lib/tty/key.c @@ -253,6 +253,14 @@ typedef struct int action; } key_define_t; +typedef struct +{ + int code; + const char *terminfo_name; + const char *termcap_name; + int action; +} term_key_define_t; + /* File descriptor monitoring add/remove routines */ typedef struct { @@ -286,6 +294,166 @@ static key_define_t mc_default_keys[] = { { 0, NULL, MCKEY_NOACTION }, }; +// Termcap/terminfo keys +/* + Based on: + https://gist.github.com/ketsuban/651e24c2d59506922d928c65c163d79c + https://man7.org/linux/man-pages/man5/terminfo.5.html + https://www.gnu.org/software/termutils/manual/termcap-1.3/html_node/termcap_37.html + */ +// clang-format off +static term_key_define_t term_key_defines[] = { + { KEY_BACKSPACE, "kbs", "kb", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_BACKSPACE, "cub1", "le", MCKEY_NOACTION }, + + { KEY_IC, "kich1", "kI", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_IC, "kIC", "#3", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_IC, "kIC3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_IC, "kIC4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_IC, "kIC5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_IC, "kIC6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_IC, "kIC7", NULL, MCKEY_NOACTION }, + + { KEY_DC, "kdch1", "kD", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_DC, "kDC", "*4", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_DC, "kDC3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_DC, "kDC4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_DC, "kDC5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_DC, "kDC6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_DC, "kDC7", NULL, MCKEY_NOACTION }, + + { KEY_HOME, "khome", "kh", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_HOME, "kHOM", "#2", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_HOME, "kHOM3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_HOME, "kHOM4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_HOME, "kHOM5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_HOME, "kHOM6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_HOME, "kHOM7", NULL, MCKEY_NOACTION }, + + { KEY_END, "kend", "@7", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_END, "kEND", "*7", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_END, "kEND3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_END, "kEND4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_END, "kEND5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_END, "kEND6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_END, "kEND7", NULL, MCKEY_NOACTION }, + + { KEY_PPAGE, "kpp", "kP", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_PPAGE, "kPRV", "%e", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_PPAGE, "kPRV3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_PPAGE, "kPRV4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_PPAGE, "kPRV5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_PPAGE, "kPRV6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_PPAGE, "kPRV7", NULL, MCKEY_NOACTION }, + + { KEY_NPAGE, "knp", "kN", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_NPAGE, "kNXT", "%c", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_NPAGE, "kNXT3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_NPAGE, "kNXT4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_NPAGE, "kNXT5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_NPAGE, "kNXT6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_NPAGE, "kNXT7", NULL, MCKEY_NOACTION }, + + { KEY_UP, "kcuu1", "ku", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_UP, "kUP", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_UP, "kUP3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_UP, "kUP4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_UP, "kUP5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_UP, "kUP6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_UP, "kUP7", NULL, MCKEY_NOACTION }, + + { KEY_DOWN, "kcud1", "kd", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_DOWN, "kDN", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_DOWN, "kDN3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_DOWN, "kDN4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_DOWN, "kDN5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_DOWN, "kDN6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_DOWN, "kDN7", NULL, MCKEY_NOACTION }, + + { KEY_RIGHT, "kcuf1", "kr", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_RIGHT, "kRIT", "%i", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_RIGHT, "kRIT3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_RIGHT, "kRIT4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_RIGHT, "kRIT5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_RIGHT, "kRIT6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_RIGHT, "kRIT7", NULL, MCKEY_NOACTION }, + + { KEY_LEFT, "kcub1", "kl", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_LEFT, "kLFT", "#4", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_LEFT, "kLFT3", NULL, MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_LEFT, "kLFT4", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_LEFT, "kLFT5", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_LEFT, "kLFT6", NULL, MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_ALT | KEY_LEFT, "kLFT7", NULL, MCKEY_NOACTION }, + + { KEY_F(1), "kf1", "k1", MCKEY_NOACTION }, + { KEY_F(2), "kf2", "k2", MCKEY_NOACTION }, + { KEY_F(3), "kf3", "k3", MCKEY_NOACTION }, + { KEY_F(4), "kf4", "k4", MCKEY_NOACTION }, + { KEY_F(5), "kf5", "k5", MCKEY_NOACTION }, + { KEY_F(6), "kf6", "k6", MCKEY_NOACTION }, + { KEY_F(7), "kf7", "k7", MCKEY_NOACTION }, + { KEY_F(8), "kf8", "k8", MCKEY_NOACTION }, + { KEY_F(9), "kf9", "k9", MCKEY_NOACTION }, + { KEY_F(10), "kf10", "k;", MCKEY_NOACTION }, + { KEY_F(11), "kf11", "F1", MCKEY_NOACTION }, + { KEY_F(12), "kf12", "F2", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(1), "kf13", "F3", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(2), "kf14", "F4", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(3), "kf15", "F5", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(4), "kf16", "F6", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(5), "kf17", "F7", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(6), "kf18", "F8", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(7), "kf19", "F9", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(8), "kf20", "FA", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(9), "kf21", "FB", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(10), "kf22", "FC", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(11), "kf23", "FD", MCKEY_NOACTION }, + { KEY_M_SHIFT | KEY_F(12), "kf24", "FE", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(1), "kf25", "FF", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(2), "kf26", "FG", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(3), "kf27", "FH", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(4), "kf28", "FI", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(5), "kf29", "FJ", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(6), "kf30", "FK", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(7), "kf31", "FL", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(8), "kf32", "FM", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(9), "kf33", "FN", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(10), "kf34", "FO", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(11), "kf35", "FP", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_F(12), "kf36", "FQ", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(1), "kf37", "FR", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(2), "kf38", "FS", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(3), "kf39", "FT", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(4), "kf40", "FU", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(5), "kf41", "FV", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(6), "kf42", "FW", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(7), "kf43", "FX", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(8), "kf44", "FY", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(9), "kf45", "FZ", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(10), "kf46", "Fa", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(11), "kf47", "Fb", MCKEY_NOACTION }, + { KEY_M_CTRL | KEY_M_SHIFT | KEY_F(12), "kf48", "Fc", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(1), "kf49", "Fd", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(2), "kf50", "Fe", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(3), "kf51", "Ff", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(4), "kf52", "Fg", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(5), "kf53", "Fh", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(6), "kf54", "Fi", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(7), "kf55", "Fj", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(8), "kf56", "Fk", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(9), "kf57", "Fl", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(10), "kf58", "Fm", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(11), "kf59", "Fn", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_F(12), "kf60", "Fo", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_F(1), "kf61", "Fp", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_F(2), "kf62", "Fq", MCKEY_NOACTION }, + { KEY_M_ALT | KEY_M_SHIFT | KEY_F(3), "kf63", "Fr", MCKEY_NOACTION }, + + { 0, NULL, NULL, MCKEY_NOACTION }, +}; +// clang-format on + /* Broken terminfo and termcap databases on xterminals */ static key_define_t xterm_key_defines[] = { { KEY_F (1), ESC_STR "OP", MCKEY_NOACTION }, @@ -697,6 +865,23 @@ define_sequences (const key_define_t *kd) /* --------------------------------------------------------------------------------------------- */ +static void +define_term_sequences (term_key_define_t *kd) +{ + int i; + + for (i = 0; kd[i].code != 0; i++) + { + char *seq; + + seq = tty_tigetstr (kd[i].terminfo_name, kd[i].termcap_name); + if (seq != NULL) + define_sequence (kd[i].code, seq, kd[i].action); + } +} + +/* --------------------------------------------------------------------------------------------- */ + #ifdef HAVE_TEXTMODE_X11_SUPPORT static void init_key_x11 (void) @@ -1320,6 +1505,8 @@ init_key (void) // So, we can assume that the first keys member has ESC define_sequences (mc_default_keys); + define_term_sequences (term_key_defines); + // Terminfo on irix does not have some keys if (mc_global.tty.xterm_flag || (term != NULL diff --git a/lib/tty/tty-ncurses.c b/lib/tty/tty-ncurses.c index 23d2cced5..4525b6b24 100644 --- a/lib/tty/tty-ncurses.c +++ b/lib/tty/tty-ncurses.c @@ -257,6 +257,7 @@ tty_init (gboolean mouse_enable, gboolean is_xterm) if (!mouse_enable) use_mouse_p = MOUSE_DISABLED; + init_key (); tty_init_xterm_support (is_xterm); // do it before tty_enter_ca_mode() call tty_enter_ca_mode (); tty_raw_mode (); @@ -273,6 +274,7 @@ void tty_shutdown (void) { tty_destroy_winch_pipe (); + done_key (); tty_reset_shell_mode (); tty_noraw_mode (); tty_keypad (FALSE); diff --git a/lib/tty/tty-slang.c b/lib/tty/tty-slang.c index 0b8e61e2f..74a0f1174 100644 --- a/lib/tty/tty-slang.c +++ b/lib/tty/tty-slang.c @@ -82,52 +82,6 @@ static gboolean no_slang_delay; static gboolean slsmg_active = FALSE; -/* This table describes which capabilities we want and which values we - * assign to them. - */ -static const struct -{ - int key_code; - const char *key_name; -} key_table[] = { - { KEY_F (0), "k0" }, - { KEY_F (1), "k1" }, - { KEY_F (2), "k2" }, - { KEY_F (3), "k3" }, - { KEY_F (4), "k4" }, - { KEY_F (5), "k5" }, - { KEY_F (6), "k6" }, - { KEY_F (7), "k7" }, - { KEY_F (8), "k8" }, - { KEY_F (9), "k9" }, - { KEY_F (10), "k;" }, - { KEY_F (11), "F1" }, - { KEY_F (12), "F2" }, - { KEY_F (13), "F3" }, - { KEY_F (14), "F4" }, - { KEY_F (15), "F5" }, - { KEY_F (16), "F6" }, - { KEY_F (17), "F7" }, - { KEY_F (18), "F8" }, - { KEY_F (19), "F9" }, - { KEY_F (20), "FA" }, - { KEY_IC, "kI" }, - { KEY_NPAGE, "kN" }, - { KEY_PPAGE, "kP" }, - { KEY_LEFT, "kl" }, - { KEY_RIGHT, "kr" }, - { KEY_UP, "ku" }, - { KEY_DOWN, "kd" }, - { KEY_DC, "kD" }, - { KEY_BACKSPACE, "kb" }, - { KEY_HOME, "kh" }, - { KEY_END, "@7" }, - { - 0, - NULL, - }, -}; - /* --------------------------------------------------------------------------------------------- */ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -156,25 +110,19 @@ sigwinch_handler (int dummy) /* --------------------------------------------------------------------------------------------- */ -static void -do_define_key (int code, const char *strcap) -{ - char *seq; - - seq = SLtt_tgetstr ((SLFUTURE_CONST char *) strcap); - if (seq != NULL) - define_sequence (code, seq, MCKEY_NOACTION); -} - -/* --------------------------------------------------------------------------------------------- */ - static void load_terminfo_keys (void) { int i; for (i = 0; key_table[i].key_code; i++) - do_define_key (key_table[i].key_code, key_table[i].key_name); + { + char *seq; + + seq = tty_tgetstr (key_table[i].key_name); + if (seq != NULL) + define_sequence (key_table[i].key_code, seq, MCKEY_NOACTION); + } } /* --------------------------------------------------------------------------------------------- */ @@ -259,7 +207,7 @@ tty_init (gboolean mouse_enable, gboolean is_xterm) tcgetattr (SLang_TT_Read_FD, &new_mode); tty_reset_prog_mode (); - load_terminfo_keys (); + init_key (); SLtt_Blink_Mode = (tty_use_256colors (NULL) || tty_use_truecolors (NULL)) ? 1 : 0; @@ -295,6 +243,7 @@ tty_shutdown (void) char *op_cap; tty_destroy_winch_pipe (); + done_key (); tty_reset_shell_mode (); tty_noraw_mode (); tty_keypad (FALSE); @@ -306,7 +255,7 @@ tty_shutdown (void) /* Load the op capability to reset the colors to those that were * active when the program was started up */ - op_cap = SLtt_tgetstr ((SLFUTURE_CONST char *) "op"); + op_cap = tty_tgetstr ("op"); if (op_cap != NULL) { fputs (op_cap, stdout); @@ -403,8 +352,7 @@ tty_keypad (gboolean set) { char *keypad_string; - keypad_string = SLtt_tgetstr ((SLFUTURE_CONST char *) (set ? "ks" : "ke")); - + keypad_string = tty_tgetstr (set ? "ks" : "ke"); if (keypad_string != NULL) SLtt_write_string (keypad_string); } diff --git a/src/main.c b/src/main.c index a67270150..b16c4f320 100644 --- a/src/main.c +++ b/src/main.c @@ -331,10 +331,6 @@ main (int argc, char *argv[]) vfs_path_free (vpath, TRUE); } - /* NOTE: This has to be called before tty_init or whatever routine - calls any define_sequence */ - init_key (); - // Must be done before installing the SIGCHLD handler [[FIXME]] handle_console (CONSOLE_INIT); @@ -484,8 +480,6 @@ main (int argc, char *argv[]) mc_shell_deinit (); - done_key (); - #ifdef USE_INTERNAL_EDIT if (macros_list != NULL) {