mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-22 16:20:23 +02:00
24024: add zcurses input with keypad handling
This commit is contained in:
parent
26461dcc1b
commit
7f8e229818
6 changed files with 207 additions and 4 deletions
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,3 +5,9 @@ load=no
|
|||
autobins="zcurses"
|
||||
|
||||
objects="curses.o"
|
||||
|
||||
:<<\Make
|
||||
curses.o curses..o: curses_keys.h
|
||||
|
||||
curses_keys.h: curses_keys.awk @CURSES_KEYS_H@
|
||||
$(AWK) -f $(sdir)/curses_keys.awk @CURSES_KEYS_H@ /dev/null >curses_keys.h
|
||||
|
|
19
Src/Modules/curses_keys.awk
Normal file
19
Src/Modules/curses_keys.awk
Normal file
|
@ -0,0 +1,19 @@
|
|||
BEGIN {nkeydefs = 0}
|
||||
|
||||
/^[\t ]*#[\t ]*define[\t _]*KEY_[A-Z0-9_]*[\t ]/ {
|
||||
keyindex = index($0, "KEY_")
|
||||
keytail = substr($0, keyindex, 80)
|
||||
split(keytail, tmp)
|
||||
keynam = substr(tmp[1], 5, 30)
|
||||
if (keynam != "MIN" && keynam != "MAX") {
|
||||
name[nkeydefs++] = keynam
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
printf("static const struct zcurses_namenumberpair keypad_names[] = {\n")
|
||||
for (i = 0; i < 0 + nkeydefs; i++)
|
||||
printf(" {\"%s\", KEY_%s},\n", name[i], name[i])
|
||||
printf(" {NULL, 0}\n")
|
||||
printf("};\n")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue