summaryrefslogtreecommitdiff
path: root/Src/Modules/curses.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Modules/curses.c')
-rw-r--r--Src/Modules/curses.c114
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}
};