From 0f10eaf9fcfdfd75cf2363582e241f262e2641ba Mon Sep 17 00:00:00 2001 From: nick black Date: Wed, 26 May 2021 02:34:50 -0400 Subject: [PATCH] termdesc: move smcup/rmcup lookup into interrogate_terminfo() #1525 --- src/lib/direct.c | 2 +- src/lib/internal.h | 6 ++++-- src/lib/notcurses.c | 8 ++------ src/lib/terminfo.c | 24 +++++++++++++++--------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/lib/direct.c b/src/lib/direct.c index 7daa51f91..be6c33a99 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -767,7 +767,7 @@ ncdirect* ncdirect_core_init(const char* termtype, FILE* outfp, uint64_t flags){ if(ncvisual_init(NCLOGLEVEL_SILENT)){ goto err; } - if(interrogate_terminfo(&ret->tcache, ret->ctermfd, shortname_term, utf8)){ + if(interrogate_terminfo(&ret->tcache, ret->ctermfd, shortname_term, utf8, 1)){ goto err; } update_term_dimensions(ret->ctermfd, NULL, NULL, &ret->tcache); diff --git a/src/lib/internal.h b/src/lib/internal.h index 9cd6a5ea0..cf0462ab0 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -605,11 +605,13 @@ void update_write_stats(const struct timespec* time1, const struct timespec* tim void sigwinch_handler(int signo); void init_lang(notcurses* nc); // nc may be NULL, only used for logging -int terminfostr(char** gseq, const char* name); // load |ti| from the terminfo database, which must already have been // initialized. set |utf8| if we've verified UTF8 output encoding. -int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8); +// set |noaltscreen| to inhibit alternate screen detection. |fd| ought +// be connected to a terminal device, or -1 if no terminal is available. +int interrogate_terminfo(tinfo* ti, int fd, const char* termname, + unsigned utf8, unsigned noaltscreen); void free_terminfo_cache(tinfo* ti); diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index f5929cf07..8f75d91b0 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1056,7 +1056,8 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ } const char* shortname_term = termname(); // const char* longname_term = longname(); - if(interrogate_terminfo(&ret->tcache, ret->ttyfd, shortname_term, utf8)){ + if(interrogate_terminfo(&ret->tcache, ret->ttyfd, shortname_term, utf8, + opts->flags & NCOPTION_NO_ALTERNATE_SCREEN)){ goto err; } int dimy, dimx; @@ -1070,11 +1071,6 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ if(set_fd_nonblocking(ret->input.ttyinfd, 1, &ret->stdio_blocking_save)){ goto err; } - // Neither of these is supported on e.g. the "linux" virtual console. - if(!(opts->flags & NCOPTION_NO_ALTERNATE_SCREEN)){ - terminfostr(&ret->tcache.smcup, "smcup"); - terminfostr(&ret->tcache.rmcup, "rmcup"); - } if(ncvisual_init(ret->loglevel)){ goto err; } diff --git a/src/lib/terminfo.c b/src/lib/terminfo.c index 0a200ac86..ac46570f5 100644 --- a/src/lib/terminfo.c +++ b/src/lib/terminfo.c @@ -54,11 +54,8 @@ query_rgb(void){ return rgb; } -int terminfostr(char** gseq, const char* name){ - char* seq; - if(gseq == NULL){ - gseq = &seq; - } +static int +terminfostr(char** gseq, const char* name){ *gseq = tigetstr(name); if(*gseq == NULL || *gseq == (char*)-1){ *gseq = NULL; @@ -66,10 +63,13 @@ int terminfostr(char** gseq, const char* name){ } // terminfo syntax allows a number N of milliseconds worth of pause to be // specified using $ syntax. this is then honored by tputs(). but we don't - // use tputs(), instead preferring the much faster stdio+tiparm(). to avoid - // dumping "$" sequences all over stdio, we chop them out. + // use tputs(), instead preferring the much faster stdio+tiparm() (at the + // expense of terminals which do require these delays). to avoid dumping + // "$" sequences all over stdio, we chop them out. char* pause; if( (pause = strchr(*gseq, '$')) ){ + // FIXME can there ever be further content following a pause? + // tighten this up to match the precise spec in terminfo(5)! *pause = '\0'; } return 0; @@ -140,7 +140,8 @@ void free_terminfo_cache(tinfo* ti){ // termname is just the TERM environment variable. some details are not // exposed via terminfo, and we must make heuristic decisions based on // the detected terminal type, yuck :/. -int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8){ +int interrogate_terminfo(tinfo* ti, int fd, const char* termname, + unsigned utf8, unsigned noaltscreen){ memset(ti, 0, sizeof(*ti)); ti->utf8 = utf8; // allow the "rgb" boolean terminfo capability, a COLORTERM environment @@ -162,12 +163,17 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8) ti->CCCflag = false; } } - // check that the terminal provides cursor addressing (absolute movement) + // verify that the terminal provides cursor addressing (absolute movement) terminfostr(&ti->cup, "cup"); if(ti->cup == NULL){ fprintf(stderr, "Required terminfo capability 'cup' not defined\n"); return -1; } + // neither of these is supported on e.g. the "linux" virtual console. + if(!noaltscreen){ + terminfostr(&ti->smcup, "smcup"); + terminfostr(&ti->rmcup, "rmcup"); + } // check that the terminal provides automatic margins ti->AMflag = tigetflag("am") == 1; if(!ti->AMflag){