diff --git a/src/lib/input.c b/src/lib/input.c new file mode 100644 index 000000000..ee19f4daf --- /dev/null +++ b/src/lib/input.c @@ -0,0 +1,71 @@ +#include +#include "internal.h" + +sig_atomic_t resize_seen = 0; + +static int +handle_getc(const notcurses* nc __attribute__ ((unused)), cell* c, int kpress, + ncspecial_key* special){ +// fprintf(stderr, "KEYPRESS: %d\n", kpress); + if(kpress < 0){ + return -1; + } + *special = 0; + if(kpress == 0x04){ // ctrl-d + return -1; + } + // FIXME look for keypad + if(kpress < 0x80){ + c->gcluster = kpress; + }else{ + // FIXME + } + return 1; +} + +int notcurses_getc(const notcurses* nc, cell* c, ncspecial_key* special){ + if(resize_seen){ + resize_seen = 0; + c->gcluster = 0; + *special = NCKEY_RESIZE; + return 1; + } + int r = getc(nc->ttyinfp); + if(r < 0){ + return r; + } + return handle_getc(nc, c, r, special); +} + +// we set our infd to non-blocking on entry, so to do a blocking call (without +// burning cpu) we'll need to set up a poll(). +int notcurses_getc_blocking(const notcurses* nc, cell* c, ncspecial_key* special){ + struct pollfd pfd = { + .fd = fileno(nc->ttyinfp), + .events = POLLIN | POLLRDHUP, + .revents = 0, + }; + int pret, r; + sigset_t smask; + sigfillset(&smask); + sigdelset(&smask, SIGWINCH); + while((pret = ppoll(&pfd, 1, NULL, &smask)) >= 0){ + if(pret == 0){ + continue; + } + r = getc(nc->ttyinfp); + if(r < 0){ + break; // want EINTR handling below + } + return handle_getc(nc, c, r, special); + } + if(errno == EINTR){ + if(resize_seen){ + resize_seen = 0; + c->gcluster = 0; + *special = NCKEY_RESIZE; + return 1; + } + } + return -1; +} diff --git a/src/lib/internal.h b/src/lib/internal.h index 6f64c00fb..45b9b76a8 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -6,8 +6,10 @@ #include #include #include +#include #include #include +#include "notcurses.h" #include "egcpool.h" #ifdef __cplusplus @@ -121,6 +123,8 @@ typedef struct notcurses { unsigned inputbuf_write_at; } notcurses; +extern sig_atomic_t resize_seen; + #ifdef __cplusplus } #endif diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index beac01259..f258b4dbf 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -40,7 +40,6 @@ ncplane_unlock(const ncplane* n){ // only one notcurses object can be the target of signal handlers, due to their // process-wide nature. -static sig_atomic_t resize_seen; static notcurses* _Atomic signal_nc = ATOMIC_VAR_INIT(NULL); // ugh static void (*signal_sa_handler)(int); // stashed signal handler we replaced @@ -1668,73 +1667,6 @@ void ncplane_erase(ncplane* n){ ncplane_unlock(n); } -static int -handle_getc(const notcurses* nc __attribute__ ((unused)), cell* c, int kpress, - ncspecial_key* special){ -// fprintf(stderr, "KEYPRESS: %d\n", kpress); - if(kpress < 0){ - return -1; - } - *special = 0; - if(kpress == 0x04){ // ctrl-d - return -1; - } - // FIXME look for keypad - if(kpress < 0x80){ - c->gcluster = kpress; - }else{ - // FIXME - } - return 1; -} - -int notcurses_getc(const notcurses* nc, cell* c, ncspecial_key* special){ - if(resize_seen){ - resize_seen = 0; - c->gcluster = 0; - *special = NCKEY_RESIZE; - return 1; - } - int r = getc(nc->ttyinfp); - if(r < 0){ - return r; - } - return handle_getc(nc, c, r, special); -} - -// we set our infd to non-blocking on entry, so to do a blocking call (without -// burning cpu) we'll need to set up a poll(). -int notcurses_getc_blocking(const notcurses* nc, cell* c, ncspecial_key* special){ - struct pollfd pfd = { - .fd = fileno(nc->ttyinfp), - .events = POLLIN | POLLRDHUP, - .revents = 0, - }; - int pret, r; - sigset_t smask; - sigfillset(&smask); - sigdelset(&smask, SIGWINCH); - while((pret = ppoll(&pfd, 1, NULL, &smask)) >= 0){ - if(pret == 0){ - continue; - } - r = getc(nc->ttyinfp); - if(r < 0){ - break; // want EINTR handling below - } - return handle_getc(nc, c, r, special); - } - if(errno == EINTR){ - if(resize_seen){ - resize_seen = 0; - c->gcluster = 0; - *special = NCKEY_RESIZE; - return 1; - } - } - return -1; -} - int ncvisual_render(const ncvisual* ncv){ const AVFrame* f = ncv->oframe; if(f == NULL){