1
0
mirror of https://git.zap.org.au/git/trader.git synced 2024-11-03 17:27:29 -05:00

Implement the single-byte equivalent of getwch()

This implementation assembles a wide character from a stream of
multibyte-forming bytes.
This commit is contained in:
John Zaitseff 2011-08-26 04:51:44 +10:00
parent 4c99f9a57f
commit dffb4c59fe
2 changed files with 77 additions and 7 deletions

View File

@ -322,7 +322,7 @@ static void mkchstr_conv (chtype *restrict chbuf, int chbufsize,
This function is either a wrapper (with modifications) for wget_wch() This function is either a wrapper (with modifications) for wget_wch()
from Curses, or an implementation of that function using wgetch(). from Curses, or an implementation of that function using wgetch().
*/ */
static int getwch (WINDOW *win, wint_t *wch); static int getwch (WINDOW *win, wint_t *restrict wch);
/* /*
@ -1755,7 +1755,7 @@ int right (WINDOW *win, int y, int x, chtype attr_norm, chtype attr_alt1,
#if defined(HAVE_CURSES_ENHANCED) || defined(HAVE_NCURSESW) #if defined(HAVE_CURSES_ENHANCED) || defined(HAVE_NCURSESW)
int getwch (WINDOW *win, wint_t *wch) int getwch (WINDOW *win, wint_t *restrict wch)
{ {
int ret = wget_wch(win, wch); int ret = wget_wch(win, wch);
@ -1768,6 +1768,7 @@ int getwch (WINDOW *win, wint_t *wch)
(due to the same codes being returned by getch()). We do (due to the same codes being returned by getch()). We do
not use iswcntrl() as certain additional Unicode not use iswcntrl() as certain additional Unicode
characters are also control characters (eg, U+2028) */ characters are also control characters (eg, U+2028) */
*wch = (unsigned char) c;
ret = KEY_CODE_YES; ret = KEY_CODE_YES;
} }
} }
@ -1777,10 +1778,79 @@ int getwch (WINDOW *win, wint_t *wch)
#else // !defined(HAVE_CURSES_ENHANCED) && !defined(HAVE_NCURSESW) #else // !defined(HAVE_CURSES_ENHANCED) && !defined(HAVE_NCURSESW)
int getwch (WINDOW *win, wint_t *wch) int getwch (WINDOW *win, wint_t *restrict wch)
{ {
#error "Single-byte version of getwch() not yet implemented" static mbstate_t *mbstate; // Current shift state
"Single-byte version of getwch() not yet implemented"
char buf[MB_LEN_MAX * 8]; // Allow space for redundant shifts
mbstate_t mbcopy;
int len, ret;
wchar_t val = 0;
if (mbstate == NULL) {
mbstate = xmalloc(sizeof(mbstate_t));
memset(mbstate, 0, sizeof(mbstate_t));
}
len = 0;
while (true) {
ret = wgetch(win);
if (ret == ERR) {
break;
} else if (ret >= 0400) {
// Assume any non-ASCII result is a function key
if (len > 0) {
// Function key is interrupting an incomplete multibyte char!
ungetch(ret);
ret = ERR;
} else {
val = ret;
ret = KEY_CODE_YES;
}
break;
} else if (len >= sizeof(buf) - 1) {
// Too many characters
ungetch(ret);
ret = ERR;
break;
} else {
buf[len++] = ret;
// Do we have a complete multibyte keypress?
memcpy(&mbcopy, mbstate, sizeof(mbstate_t));
size_t n = mbrtowc(&val, buf, len, &mbcopy);
if (n == (size_t) -1) {
// Invalid character
ungetch(ret);
ret = ERR;
break;
} else if (n == (size_t) -2) {
// Incomplete sequence: wait for more bytes to come
;
} else {
// A valid multibyte sequence
memcpy(mbstate, &mbcopy, sizeof(mbstate_t));
char c = wctob(val);
if ((c >= 0 && c < ' ') || c == 0x7F) {
/* Make control characters (and DEL) appear to be
similar to function keys. */
val = (unsigned char) c;
ret = KEY_CODE_YES;
} else {
// An ordinary key
ret = OK;
}
break;
}
}
}
if (wch != NULL) {
*wch = val;
}
return ret;
} }
#endif // !defined(HAVE_CURSES_ENHANCED) && !defined(HAVE_NCURSESW) #endif // !defined(HAVE_CURSES_ENHANCED) && !defined(HAVE_NCURSESW)
@ -1789,7 +1859,7 @@ int getwch (WINDOW *win, wint_t *wch)
/***********************************************************************/ /***********************************************************************/
// gettxchar: Read a character from the keyboard // gettxchar: Read a character from the keyboard
int gettxchar (WINDOW *win, wint_t *wch) int gettxchar (WINDOW *win, wint_t *restrict wch)
{ {
int ret; int ret;

View File

@ -578,7 +578,7 @@ extern int right (WINDOW *win, int y, int x, chtype attr_norm, chtype attr_alt1,
returned. ERR is never returned. The key is NOT echoed to the returned. ERR is never returned. The key is NOT echoed to the
terminal display, nor is the cursor visibility affected. terminal display, nor is the cursor visibility affected.
*/ */
extern int gettxchar (WINDOW *win, wint_t *wch); extern int gettxchar (WINDOW *win, wint_t *restrict wch);
/* /*