diff options
Diffstat (limited to 'Src/Modules/curses.c')
-rw-r--r-- | Src/Modules/curses.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c index 06ad463e1..273bb9e19 100644 --- a/Src/Modules/curses.c +++ b/Src/Modules/curses.c @@ -43,6 +43,7 @@ #ifndef MULTIBYTE_SUPPORT # undef HAVE_SETCCHAR # undef HAVE_WADDWSTR +# undef HAVE_WGET_WCH #endif #ifdef HAVE_SETCCHAR @@ -122,6 +123,9 @@ static const struct zcurses_namenumberpair zcurses_colors[] = { {NULL, 0} }; +/* Autogenerated keypad string/number mapping*/ +#include "curses_keys.h" + static char ** zcurses_pairs_to_array(const struct zcurses_namenumberpair *nnps) { @@ -335,6 +339,16 @@ zccmd_init(const char *nam, char **args) zcurses_colorpairs->printnode = NULL; } + /* + * We use cbreak mode because we don't want line buffering + * on input since we'd just need to loop over characters. + * We use noecho since the manual says that's the right + * thing to do with cbreak. + * + * Turn these on immediately to catch typeahead. + */ + cbreak(); + noecho(); gettyinfo(&curses_tty_state); } else { settyinfo(&curses_tty_state); @@ -669,6 +683,105 @@ zccmd_scroll(const char *nam, char **args) } +static int +zccmd_input(const char *nam, char **args) +{ + LinkNode node; + ZCWin w; + char *var; + int keypadnum = -1; +#ifdef HAVE_WGET_WCH + int ret; + wint_t wi; + VARARR(char, instr, 2*MB_CUR_MAX+1); +#else + int ci; + instr[3]; +#endif + + node = zcurses_validate_window(args[0], ZCURSES_USED); + if (node == NULL) { + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0]); + return 1; + } + + w = (ZCWin)getdata(node); + + if (args[1] && args[2]) { + keypad(w->win, TRUE); + } else { + keypad(w->win, FALSE); + } + +#ifdef HAVE_WGET_WCH + switch (wget_wch(w->win, &wi)) { + case OK: + ret = wctomb(instr, (wchar_t)wi); + if (ret == 0) { + instr[0] = Meta; + instr[1] = '\0' ^ 32; + instr[2] = '\0'; + } else { + (void)metafy(instr, ret, META_NOALLOC); + } + break; + + case KEY_CODE_YES: + keypadnum = (int)wi; + break; + + case ERR: + default: + return 1; + } +#else + ci = wgetch(w->win); + if (ci >= 256) { + keypadnum = ci; + } else { + if (imeta(ci)) { + instr[0] = Meta; + instr[1] = (char)ci ^ 32; + instr[2] = '\0'; + } else { + instr[0] = (char)ci; + instr[1] = '\0'; + } + } +#endif + if (args[1]) + var = args[1]; + else + var = "REPLY"; + if (!setsparam(var, ztrdup(keypadnum > 0 ? "" : instr))) + return 1; + if (args[2]) { + if (keypadnum > 0) { + const struct zcurses_namenumberpair *nnptr; + char fbuf[DIGBUFSIZE+1]; + + for (nnptr = keypad_names; nnptr->name; nnptr++) { + if (keypadnum == nnptr->number) { + setsparam(args[2], ztrdup(nnptr->name)); + return 0; + } + } + if (keypadnum > KEY_F0) { + /* assume it's a function key */ + sprintf(fbuf, "F%d", keypadnum - KEY_F0); + } else { + /* print raw number */ + sprintf(fbuf, "%d", keypadnum); + } + setsparam(args[2], ztrdup(fbuf)); + } else { + setsparam(args[2], ztrdup("")); + } + } + return 0; +} + + /********************* Main builtin handler *********************/ @@ -693,6 +806,7 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func)) {"end", zccmd_endwin, 0, 0}, {"attr", zccmd_attr, 2, -1}, {"scroll", zccmd_scroll, 2, 2}, + {"input", zccmd_input, 1, 3}, {NULL, (zccmd_t)0, 0, 0} }; |