diff --git a/include/notcurses.h b/include/notcurses.h index 12e9da08e..64a830f96 100644 --- a/include/notcurses.h +++ b/include/notcurses.h @@ -154,11 +154,34 @@ typedef enum { NCKEY_RIGHT, NCKEY_DOWN, NCKEY_LEFT, + NCKEY_INS, NCKEY_DEL, + NCKEY_BS, // backspace (sometimes) NCKEY_PGDOWN, NCKEY_PGUP, NCKEY_HOME, NCKEY_END, + NCKEY_F00, + NCKEY_F01, + NCKEY_F02, + NCKEY_F03, + NCKEY_F04, + NCKEY_F05, + NCKEY_F06, + NCKEY_F07, + NCKEY_F08, + NCKEY_F09, + NCKEY_F10, + NCKEY_F11, + NCKEY_F12, + NCKEY_F13, + NCKEY_F14, + NCKEY_F15, + NCKEY_F16, + NCKEY_F17, + NCKEY_F18, + NCKEY_F19, + NCKEY_F20, // FIXME... } ncspecial_key; diff --git a/src/input/input.cpp b/src/input/input.cpp index 0f2be7ba0..ab875acff 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -19,6 +19,25 @@ const char* nckeystr(ncspecial_key key){ case NCKEY_UP: return "up"; case NCKEY_RIGHT: return "right"; case NCKEY_DOWN: return "down"; + case NCKEY_INS: return "insert"; + case NCKEY_DEL: return "delete"; + case NCKEY_PGDOWN: return "pgdown"; + case NCKEY_PGUP: return "pgup"; + case NCKEY_HOME: return "home"; + case NCKEY_END: return "end"; + case NCKEY_F00: return "F0"; + case NCKEY_F01: return "F1"; + case NCKEY_F02: return "F2"; + case NCKEY_F03: return "F3"; + case NCKEY_F04: return "F4"; + case NCKEY_F05: return "F5"; + case NCKEY_F06: return "F6"; + case NCKEY_F07: return "F7"; + case NCKEY_F08: return "F8"; + case NCKEY_F09: return "F9"; + case NCKEY_F10: return "F10"; + case NCKEY_F11: return "F11"; + case NCKEY_F12: return "F12"; default: return "unknown"; } } @@ -61,7 +80,7 @@ int main(void){ if(cell_simple_p(&c)){ char kp = c.gcluster; if(kp == 0){ - if(ncplane_printf(n, "Got special key: [0x%04x (%04d)] '%s'\n", + if(ncplane_printf(n, "Got special key: [0x%02x (%02d)] '%s'\n", special, special, nckeystr(special)) < 0){ break; } diff --git a/src/lib/input.c b/src/lib/input.c index d9d5b120f..bb77167eb 100644 --- a/src/lib/input.c +++ b/src/lib/input.c @@ -1,3 +1,5 @@ +#include // needed for some definitions, see terminfo(3ncurses) +#include #include #include "internal.h" @@ -104,6 +106,7 @@ handle_getc(notcurses* nc, cell* c, int kpress, ncspecial_key* special){ esc = esc->trie[candidate]; } } +//fprintf(stderr, "esc? %c special: %d\n", esc ? 'y' : 'n', esc ? esc->special : NCKEY_INVALID); if(esc && esc->special != NCKEY_INVALID){ *special = esc->special; return 1; @@ -184,3 +187,61 @@ int notcurses_getc(notcurses* nc, cell* c, ncspecial_key* special, } return r; } + +int prep_special_keys(notcurses* nc){ + static const struct { + const char* tinfo; + ncspecial_key key; + } keys[] = { + { .tinfo = "kcub1", .key = NCKEY_LEFT, }, + { .tinfo = "kcuf1", .key = NCKEY_RIGHT, }, + { .tinfo = "kcuu1", .key = NCKEY_UP, }, + { .tinfo = "kcud1", .key = NCKEY_DOWN, }, + { .tinfo = "kdch1", .key = NCKEY_DEL, }, + { .tinfo = "kbs", .key = NCKEY_BS, }, + { .tinfo = "kich1", .key = NCKEY_INS, }, + { .tinfo = "kend", .key = NCKEY_END, }, + { .tinfo = "khome", .key = NCKEY_HOME, }, + { .tinfo = "knp", .key = NCKEY_PGDOWN, }, + { .tinfo = "kpp", .key = NCKEY_PGUP, }, + { .tinfo = "kf0", .key = NCKEY_F01, }, + { .tinfo = "kf1", .key = NCKEY_F01, }, + { .tinfo = "kf2", .key = NCKEY_F02, }, + { .tinfo = "kf3", .key = NCKEY_F03, }, + { .tinfo = "kf4", .key = NCKEY_F04, }, + { .tinfo = "kf5", .key = NCKEY_F05, }, + { .tinfo = "kf6", .key = NCKEY_F06, }, + { .tinfo = "kf7", .key = NCKEY_F07, }, + { .tinfo = "kf8", .key = NCKEY_F08, }, + { .tinfo = "kf9", .key = NCKEY_F09, }, + { .tinfo = "kf10", .key = NCKEY_F10, }, + { .tinfo = "kf11", .key = NCKEY_F11, }, + { .tinfo = "kf12", .key = NCKEY_F12, }, + { .tinfo = "kf13", .key = NCKEY_F13, }, + { .tinfo = "kf14", .key = NCKEY_F14, }, + { .tinfo = "kf15", .key = NCKEY_F15, }, + { .tinfo = "kf16", .key = NCKEY_F16, }, + { .tinfo = "kf17", .key = NCKEY_F17, }, + { .tinfo = "kf18", .key = NCKEY_F18, }, + { .tinfo = "kf19", .key = NCKEY_F19, }, + { .tinfo = "kf20", .key = NCKEY_F20, }, + { .tinfo = NULL, .key = NCKEY_INVALID, } + }, *k; + for(k = keys ; k->tinfo ; ++k){ + char* seq = tigetstr(k->tinfo); + if(seq == NULL || seq == (char*)-1){ +//fprintf(stderr, "no support for terminfo's %s\n", k->tinfo); + continue; + } + if(seq[0] != ESC){ + fprintf(stderr, "Terminfo's %s is not an escape sequence: %s\n", + k->tinfo, seq); + continue; + } +//fprintf(stderr, "support for terminfo's %s: %s\n", k->tinfo, seq); + if(notcurses_add_input_escape(nc, seq, k->key)){ + return -1; + } + } + return 0; +} diff --git a/src/lib/internal.h b/src/lib/internal.h index 47d38bc6a..20afc5ef7 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -99,16 +99,6 @@ typedef struct notcurses { char* smkx; // enter keypad transmit mode (keypad_xmit) char* rmkx; // leave keypad transmit mode (keypad_local) - // special keys - char* left; // kcub1 - char* right; // kcuf1 - char* up; // kcuu1 - char* down; // kcud1 - char* del; // delete - char* home; // home - char* npage; // knp - char* ppage; // kpp - struct termios tpreserved; // terminal state upon entry bool RGBflag; // terminfo-reported "RGB" flag for 24bpc directcolor bool CCCflag; // terminfo-reported "CCC" flag for palette set capability @@ -129,6 +119,9 @@ typedef struct notcurses { extern sig_atomic_t resize_seen; +// load all known special keys from terminfo, and build the input sequence trie +int prep_special_keys(notcurses* nc); + // free up the input escapes trie void input_free_esctrie(struct esctrie** trie); diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 4e18f6147..a5d7d9c0f 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -520,32 +520,8 @@ interrogate_terminfo(notcurses* nc, const notcurses_options* opts){ term_verify_seq(&nc->italoff, "ritm"); term_verify_seq(&nc->op, "op"); term_verify_seq(&nc->clear, "clear"); - if(term_verify_seq(&nc->left, "kcub1") == 0){ - notcurses_add_input_escape(nc, nc->left, NCKEY_LEFT); - } - if(term_verify_seq(&nc->right, "kcuf1") == 0){ - notcurses_add_input_escape(nc, nc->right, NCKEY_RIGHT); - } - if(term_verify_seq(&nc->up, "kcuu1") == 0){ - notcurses_add_input_escape(nc, nc->up, NCKEY_UP); - } - if(term_verify_seq(&nc->down, "kcud1") == 0){ - notcurses_add_input_escape(nc, nc->down, NCKEY_DOWN); - } - if(term_verify_seq(&nc->del, "kdch1") == 0){ - notcurses_add_input_escape(nc, nc->down, NCKEY_DEL); - } - if(term_verify_seq(&nc->home, "kend") == 0){ - notcurses_add_input_escape(nc, nc->down, NCKEY_END); - } - if(term_verify_seq(&nc->home, "khome") == 0){ - notcurses_add_input_escape(nc, nc->down, NCKEY_HOME); - } - if(term_verify_seq(&nc->npage, "knp") == 0){ - notcurses_add_input_escape(nc, nc->down, NCKEY_PGDOWN); - } - if(term_verify_seq(&nc->ppage, "kpp") == 0){ - notcurses_add_input_escape(nc, nc->down, NCKEY_PGUP); + if(prep_special_keys(nc)){ + return -1; } // Some terminals cannot combine certain styles with colors. Don't advertise // support for the style in that case.