diff --git a/include/notcurses.h b/include/notcurses.h index 16ec36fde..8253de712 100644 --- a/include/notcurses.h +++ b/include/notcurses.h @@ -2,6 +2,7 @@ #define NOTCURSES_NOTCURSES #include +#include #include #include #include @@ -147,16 +148,15 @@ API struct ncplane* notcurses_top(struct notcurses* n); // notcurses_getc_blocking() blocks until a codepoint or special key is read, // or until interrupted by a signal. // -// In the case of a valid read, a positive value is returned corresponding to -// the number of bytes in the UTF-8 character, or '1' for all special keys. -// 0 is returned to indicate that no input was available, but only by -// notcurses_getc(). Otherwise (including on EOF) -1 is returned. +// In the case of a valid read, a 32-bit Unicode codepoint is returned. 0 is +// returned to indicate that no input was available, but only by +// notcurses_getc(). Otherwise (including on EOF) (char32_t)-1 is returned. #define suppuabize(w) ((w) + 0x100000) // is this wide character a Supplementary Private Use Area-B codepoint? static inline bool -wchar_supppuab_p(wchar_t w){ +wchar_supppuab_p(char32_t w){ return w >= 0x100000 && w <= 0x10fffd; } @@ -226,11 +226,11 @@ wchar_supppuab_p(wchar_t w){ // of 0 for non-blocking operation, and otherwise a timespec to bound blocking. // Signals in sigmask (less several we handle internally) will be atomically // masked and unmasked per ppoll(2). It should generally contain all signals. -// Returns a single Unicode code point, or (wchar_t)-1 on error. 'sigmask' may +// Returns a single Unicode code point, or (char32_t)-1 on error. 'sigmask' may // be NULL. -API wchar_t notcurses_getc(struct notcurses* n, const struct timespec* ts, sigset_t* sigmask); +API char32_t notcurses_getc(struct notcurses* n, const struct timespec* ts, sigset_t* sigmask); -static inline wchar_t +static inline char32_t notcurses_getc_nblock(struct notcurses* n){ sigset_t sigmask; sigfillset(&sigmask); @@ -238,7 +238,7 @@ notcurses_getc_nblock(struct notcurses* n){ return notcurses_getc(n, &ts, &sigmask); } -static inline wchar_t +static inline char32_t notcurses_getc_blocking(struct notcurses* n){ sigset_t sigmask; sigemptyset(&sigmask); diff --git a/src/lib/input.c b/src/lib/input.c index d4726c2c0..6f08a0267 100644 --- a/src/lib/input.c +++ b/src/lib/input.c @@ -61,7 +61,7 @@ void input_free_esctrie(esctrie** eptr){ } static int -notcurses_add_input_escape(notcurses* nc, const char* esc, wchar_t special){ +notcurses_add_input_escape(notcurses* nc, const char* esc, char32_t special){ if(esc[0] != ESC || strlen(esc) < 2){ // assume ESC prefix + content fprintf(stderr, "Not an escape: %s (0x%x)\n", esc, special); return -1; @@ -103,7 +103,7 @@ notcurses_add_input_escape(notcurses* nc, const char* esc, wchar_t special){ // add the keypress we just read to our input queue (assuming there is room). // if there is a full UTF8 codepoint or keystroke (composed or otherwise), // return it, and pop it from the queue. -static wchar_t +static char32_t handle_getc(notcurses* nc, int kpress){ // fprintf(stderr, "KEYPRESS: %d\n", kpress); if(kpress < 0){ @@ -148,6 +148,7 @@ handle_getc(notcurses* nc, int kpress){ } cpoint[cpointlen] = '\0'; wchar_t w; + // FIXME how the hell does this work with 16-bit wchar_t? if(mbtowc(&w, cpoint, cpointlen) < 0){ return (wchar_t)-1; } @@ -180,7 +181,7 @@ input_queue_full(const notcurses* nc){ return nc->inputbuf_occupied == sizeof(nc->inputbuf) / sizeof(*nc->inputbuf); } -static wchar_t +static char32_t handle_input(notcurses* nc){ int r; // getc() returns unsigned chars cast to ints @@ -206,23 +207,23 @@ handle_input(notcurses* nc){ } // infp has always been set non-blocking -wchar_t notcurses_getc(notcurses* nc, const struct timespec *ts, sigset_t* sigmask){ +char32_t notcurses_getc(notcurses* nc, const struct timespec *ts, sigset_t* sigmask){ errno = 0; - int r = handle_input(nc); - if(r > 0){ + char32_t r = handle_input(nc); + if(r == (char32_t)-1){ + if(errno == EAGAIN || errno == EWOULDBLOCK){ + block_on_input(nc->ttyinfp, ts, sigmask); + return handle_input(nc); + } return r; } - if(errno == EAGAIN || errno == EWOULDBLOCK){ - block_on_input(nc->ttyinfp, ts, sigmask); - return handle_input(nc); - } return r; } int prep_special_keys(notcurses* nc){ static const struct { const char* tinfo; - wchar_t key; + char32_t key; } keys[] = { { .tinfo = "kcub1", .key = NCKEY_LEFT, }, { .tinfo = "kcuf1", .key = NCKEY_RIGHT, },