From 935e98248783d08cc2253c54f23e558e491c1652 Mon Sep 17 00:00:00 2001 From: nick black Date: Sat, 12 Jun 2021 15:08:30 -0400 Subject: [PATCH] unify inputlayer setup/teardown --- src/lib/direct.c | 1 - src/lib/input.c | 29 +++++++++++++++++++++++++++-- src/lib/internal.h | 8 +------- src/lib/notcurses.c | 15 --------------- src/lib/termdesc.c | 1 + src/lib/termdesc.h | 9 +++++++++ 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/lib/direct.c b/src/lib/direct.c index 154dab8dc..5cae3eb8e 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -832,7 +832,6 @@ int ncdirect_stop(ncdirect* nc){ int ret = 0; if(nc){ ret |= ncdirect_stop_minimal(nc); - input_free_esctrie(&nc->tcache.input.inputescapes); free(nc); } return ret; diff --git a/src/lib/input.c b/src/lib/input.c index 8de79c1c8..6ae173659 100644 --- a/src/lib/input.c +++ b/src/lib/input.c @@ -115,7 +115,8 @@ create_esctrie_node(int special){ return e; } -void input_free_esctrie(esctrie** eptr){ +static void +input_free_esctrie(esctrie** eptr){ esctrie* e; if( (e = *eptr) ){ if(e->trie){ @@ -490,7 +491,9 @@ char32_t ncdirect_getc(ncdirect* nc, const struct timespec *ts, return r; } -int prep_special_keys(ncinputlayer* nc){ +// load all known special keys from terminfo, and build the input sequence trie +static int +prep_special_keys(ncinputlayer* nc){ static const struct { const char* tinfo; char32_t key; @@ -605,3 +608,25 @@ int prep_special_keys(ncinputlayer* nc){ } return 0; } + +void ncinputlayer_stop(ncinputlayer* nilayer){ + if(nilayer->ttyfd >= 0){ + close(nilayer->ttyfd); + } + input_free_esctrie(&nilayer->inputescapes); +} + +int ncinputlayer_init(ncinputlayer* nilayer, FILE* infp){ + setbuffer(infp, NULL, 0); + nilayer->inputescapes = NULL; + nilayer->infd = fileno(infp); + nilayer->ttyfd = isatty(nilayer->infd) ? -1 : get_tty_fd(NULL, infp); + if(prep_special_keys(nilayer)){ + return -1; + } + nilayer->inputbuf_occupied = 0; + nilayer->inputbuf_valid_starts = 0; + nilayer->inputbuf_write_at = 0; + nilayer->input_events = 0; + return 0; +} diff --git a/src/lib/internal.h b/src/lib/internal.h index a0fa6bd55..2a052c0b4 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -34,7 +34,6 @@ extern "C" { #define API __attribute__((visibility("default"))) #define ALLOC __attribute__((malloc)) __attribute__((warn_unused_result)) -struct esctrie; struct sixelmap; struct ncvisual_details; @@ -631,12 +630,6 @@ ncplane_stdplane_const(const ncplane* n){ return notcurses_stdplane_const(ncplane_notcurses_const(n)); } -// load all known special keys from terminfo, and build the input sequence trie -int prep_special_keys(ncinputlayer* nc); - -// free up the input escapes trie -void input_free_esctrie(struct esctrie** trie); - // initialize libav int ncvisual_init(int loglevel); @@ -1501,6 +1494,7 @@ cellcmp_and_dupfar(egcpool* dampool, nccell* damcell, } int ncinputlayer_init(ncinputlayer* nilayer, FILE* infp); +void ncinputlayer_stop(ncinputlayer* nilayer); // FIXME absorb into ncinputlayer_init() int cbreak_mode(int ttyfd, const struct termios* tpreserved); diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index c8a59cfe7..c0ad27cc5 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -943,20 +943,6 @@ void init_lang(struct notcurses* nc){ } } -int ncinputlayer_init(ncinputlayer* nilayer, FILE* infp){ - setbuffer(infp, NULL, 0); - nilayer->inputescapes = NULL; - nilayer->infd = fileno(infp); - if(prep_special_keys(nilayer)){ - return -1; - } - nilayer->inputbuf_occupied = 0; - nilayer->inputbuf_valid_starts = 0; - nilayer->inputbuf_write_at = 0; - nilayer->input_events = 0; - return 0; -} - // initialize a recursive mutex lock in a way that works on both glibc + musl static int recursive_lock_init(pthread_mutex_t *lock){ @@ -1226,7 +1212,6 @@ int notcurses_stop(notcurses* nc){ egcpool_dump(&nc->pool); free(nc->lastframe); free(nc->rstate.mstream); - input_free_esctrie(&nc->tcache.input.inputescapes); // get any current stats loaded into stash_stats notcurses_stats_reset(nc, NULL); if(!nc->suppress_banner){ diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 8dd795b5f..0f55f26a0 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -156,6 +156,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd){ void free_terminfo_cache(tinfo* ti){ free(ti->esctable); + ncinputlayer_stop(&ti->input); } // tlen -- size of escape table. tused -- used bytes in same. diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index 6cac5d609..7c47e2161 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -59,7 +59,16 @@ typedef enum { ESCAPE_MAX } escape_e; +// we read input from one or two places. if stdin is connected to our +// controlling tty, we read only from that file descriptor. if it is +// connected to something else, and we have a controlling tty, we will +// read data only from stdin and control only from the tty. if we have +// no connected tty, only data is available. typedef struct ncinputlayer { + // ttyfd is only valid if we are connected to a tty, *and* stdin is not + // connected to that tty. in that case, we read control sequences only + // from ttyfd. + int ttyfd; // file descriptor for connected tty int infd; // file descriptor for processing input, from stdin unsigned char inputbuf[BUFSIZ]; // we keep a wee ringbuffer of input queued up for delivery. if