From c76735cb2acc2d40c68bd6b9760f485949e809a5 Mon Sep 17 00:00:00 2001 From: nick black Date: Fri, 29 Nov 2019 01:17:35 -0500 Subject: [PATCH] notcurses_getc(): read from stdin --- include/notcurses.h | 27 ++++++++++++++------------- src/input/input.cpp | 23 ++++++++++++++++++----- src/lib/notcurses.c | 10 ++++++---- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/include/notcurses.h b/include/notcurses.h index ab8c83617..93a3a7154 100644 --- a/include/notcurses.h +++ b/include/notcurses.h @@ -115,6 +115,20 @@ API int notcurses_stop(struct notcurses* nc); // successful call to notcurses_render(). API int notcurses_render(struct notcurses* nc); +// Return an input from stdin, if one is available. Note that we do *not* +// attempt to read an EGC in its entirety. 'c' will reference a single +// UTF-8-encoded Unicode codepoint. This is a non-blocking operation. If no +// input is available, 0 is returned. On other errors, -1 is returned. +// Otherwise, the number of bytes in the UTF-8 character are returned. Note +// that EOF is considered an error. +API int notcurses_getc(const struct notcurses* n, cell* c); + +// The same as notcurses_getc(), but blocking until input is read. It can still +// return early due to interruption by signal, in which case 0 is returned. On +// any other error, -1 is returned. Otherwise, the number of bytes in the UTF-8 +// character are returned. Note that EOF is considered an error. +API int notcurses_getc_blocking(const struct notcurses* n, cell* c); + // Refresh our idea of the terminal's dimensions, reshaping the standard plane // if necessary. Without a call to this function following a terminal resize // (as signaled via SIGWINCH), notcurses_render() might not function properly. @@ -211,19 +225,6 @@ API void ncplane_cursor_yx(const struct ncplane* n, int* RESTRICT y, // On failure, -1 is returned. API int ncplane_putc(struct ncplane* n, const cell* c); -// Return an input from stdin, if one is available. Note that we do *not* -// attempt to read an EGC in its entirety. 'c' will reference a single -// UTF-8-encoded Unicode codepoint. This is a non-blocking operation. If no -// input is available, 0 is returned. On other errors, -1 is returned. -// Otherwise, the number of bytes in the UTF-8 character are returned. -API int ncplane_getc(const struct ncplane* n, cell* c); - -// The same as ncplane_getc(), but blocking until input is read. It can still -// return early due to interruption by signal, in which case 0 is returned. On -// any other error, -1 is returned. Otherwise, the number of bytes in the UTF-8 -// character are returned. -API int ncplane_getc_blocking(const struct ncplane* n, cell* c); - // Write a series of cells to the current location, using the current style. // They will be interpreted as a series of columns (according to the definition // of ncplane_putc()). Advances the cursor by some positive number of cells diff --git a/src/input/input.cpp b/src/input/input.cpp index 599d0b9d8..06c6a4d29 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -1,16 +1,29 @@ +#include +#include #include +#include +#include #include int main(void){ + if(setlocale(LC_ALL, "") == nullptr){ + return EXIT_FAILURE; + } notcurses_options opts{}; opts.outfp = stdout; struct notcurses* nc = notcurses_init(&opts); - if(nc == NULL){ + if(nc == nullptr){ return EXIT_FAILURE;; } - // FIXME read input - if(notcurses_stop(nc)){ - return EXIT_FAILURE;; + int r; + cell c = CELL_TRIVIAL_INITIALIZER; + while((r = notcurses_getc_blocking(nc, &c)) >= 0){ + if(r == 0){ // interrupted by signal + continue; + } } - return EXIT_SUCCESS; + int e = errno; + notcurses_stop(nc); + std::cerr << "Error reading from terminal (" << strerror(e) << "?)\n"; + return EXIT_FAILURE; } diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index ea7be8a6e..14f967b40 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -56,6 +56,7 @@ typedef struct ncstats { typedef struct notcurses { int ttyfd; // file descriptor for controlling tty, from opts->ttyfp FILE* ttyfp; // FILE* for controlling tty, from opts->ttyfp + FILE* ttyinfp; // FILE* for processing input int colors; // number of colors usable for this screen ncstats stats; // some statistics across the lifetime of the notcurses ctx // We verify that some terminfo capabilities exist. These needn't be checked @@ -572,6 +573,7 @@ notcurses* notcurses_init(const notcurses_options* opts){ return ret; } ret->ttyfp = opts->outfp; + ret->ttyinfp = stdin; // FIXME if((ret->ttyfd = fileno(ret->ttyfp)) < 0){ fprintf(stderr, "No file descriptor was available in opts->outfp\n"); free(ret); @@ -1292,12 +1294,12 @@ void ncplane_erase(ncplane* n){ n->attrword = 0; } -int ncplane_getc(const struct ncplane* n, cell* c){ - int r = getc(n->nc->ttyfp); +int notcurses_getc(const notcurses* nc, cell* c){ + int r = getc(nc->ttyinfp); return r; } -int ncplane_getc_blocking(const struct ncplane* n, cell* c){ - int r = getc(n->nc->ttyfp); +int notcurses_getc_blocking(const notcurses* nc, cell* c){ + int r = getc(nc->ttyinfp); return r; }