diff --git a/src/lib/input.c b/src/lib/input.c index 78bc1412e..9f76ff822 100644 --- a/src/lib/input.c +++ b/src/lib/input.c @@ -1,3 +1,4 @@ +#include "input.h" #include "internal.h" #include "notcurses/direct.h" #include @@ -648,8 +649,10 @@ typedef enum { } initstates_e; typedef struct query_state { - tinfo* tcache; - queried_terminals_e qterm; // discovered terminal + struct tinfo* tcache; + // if the terminal unambiguously identifies itself in response to our + // queries, use that identification for advanced feature support. + queried_terminals_e qterm; initstates_e state, stringstate; // stringstate is the state at which this string was initialized, and can be // one of STATE_XTVERSION1, STATE_XTGETTCAP_TERMNAME1, STATE_TDA1, and STATE_BG1 @@ -658,6 +661,7 @@ typedef struct query_state { size_t stridx; // position to write in string uint32_t bg; // queried default background or 0 bool xtgettcap_good; // high when we've received DCS 1 + bool appsync; // application-synchronized updates advertised } query_state; static int @@ -1096,7 +1100,8 @@ err: return -1; } -int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected){ +int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected, + unsigned* appsync){ ncinputlayer* nilayer = &tcache->input; setbuffer(infp, NULL, 0); nilayer->inputescapes = NULL; @@ -1122,6 +1127,7 @@ int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected){ } tcache->bg_collides_default = inits.bg; *detected = inits.qterm; + *appsync = inits.appsync; } return 0; } diff --git a/src/lib/input.h b/src/lib/input.h new file mode 100644 index 000000000..55e3dedac --- /dev/null +++ b/src/lib/input.h @@ -0,0 +1,48 @@ +#ifndef NOTCURSES_INPUT +#define NOTCURSES_INPUT + +#ifdef __cplusplus +extern "C" { +#endif + +// internal header, not installed + +#include + +struct tinfo; +struct termios; +struct ncinputlayer; + +typedef enum { + TERMINAL_UNKNOWN, // no useful information from queries; use termname + TERMINAL_LINUX, // ioctl()s + TERMINAL_XTERM, // XTVERSION == 'XTerm(ver)' + TERMINAL_VTE, // TDA: "~VTE" + TERMINAL_KITTY, // XTGETTCAP['TN'] == 'xterm-kitty' + TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\" + TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm' + TERMINAL_WEZTERM, // XTVERSION == 'WezTerm *' + TERMINAL_ALACRITTY, // can't be detected; match TERM + TERMINAL_CONTOUR, // XTVERSION == 'console *' +} queried_terminals_e; + +// sets up the input layer, building a trie of escape sequences and their +// nckey equivalents. if we are connected to a tty, this also completes the +// terminal detection sequence (we ought have already written our initial +// queries, ideally as early as possible). if we are able to determine the +// terminal conclusively, it will be written to |detected|. if the terminal +// advertised support for application-sychronized updates, |appsync| will be +// non-zero. +int ncinputlayer_init(struct tinfo* tcache, FILE* infp, + queried_terminals_e* detected, unsigned* appsync); + +void ncinputlayer_stop(struct ncinputlayer* nilayer); + +// FIXME absorb into ncinputlayer_init() +int cbreak_mode(int ttyfd, const struct termios* tpreserved); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/internal.h b/src/lib/internal.h index dc5a84a20..d415dc67c 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -1495,18 +1495,6 @@ cellcmp_and_dupfar(egcpool* dampool, nccell* damcell, return 1; } -// sets up the input layer, building a trie of escape sequences and their -// nckey equivalents. if we are connected to a tty, this also completes the -// terminal detection sequence (we ought have already written our initial -// queries, ideally as early as possible). if we are able to determine the -// terminal conclusively, it will be written to |detected|. -int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected); - -void ncinputlayer_stop(ncinputlayer* nilayer); - -// FIXME absorb into ncinputlayer_init() -int cbreak_mode(int ttyfd, const struct termios* tpreserved); - int set_fd_nonblocking(int fd, unsigned state, unsigned* oldstate); int get_tty_fd(FILE* ttyfp); diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 804b9c472..035decd52 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -1,6 +1,7 @@ #include #include // needed for some definitions, see terminfo(3ncurses) #include "internal.h" +#include "input.h" // we found Sixel support -- set up the API static inline void @@ -169,6 +170,15 @@ add_smulx_escapes(tinfo* ti, size_t* tablelen, size_t* tableused){ return 0; } +static int +add_appsync_escapes(tinfo* ti, size_t* tablelen, size_t* tableused){ + if(grow_esc_table(ti, "\x1bP=1s\x1b\\", ESCAPE_BSU, tablelen, tableused) || + grow_esc_table(ti, "\x1bP=2s\x1b\\", ESCAPE_ESU, tablelen, tableused)){ + return -1; + } + return 0; +} + // Qui si convien lasciare ogne sospetto; ogne viltà convien che qui sia morta. static int apply_term_heuristics(tinfo* ti, const char* termname, int fd, @@ -463,8 +473,9 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8, goto err; } } + unsigned appsync_advertised; queried_terminals_e detected; - if(ncinputlayer_init(ti, stdin, &detected)){ + if(ncinputlayer_init(ti, stdin, &detected, &appsync_advertised)){ goto err; } if(nocbreak){ @@ -475,6 +486,11 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8, } } } + if(appsync_advertised){ + if(add_appsync_escapes(ti, &tablelen, &tableused)){ + goto err; + } + } if(apply_term_heuristics(ti, termname, fd, detected, &tablelen, &tableused)){ ncinputlayer_stop(&ti->input); goto err; diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index 418a52c91..cf5113873 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -1,5 +1,5 @@ -#ifndef NOTCURSES_TERM -#define NOTCURSES_TERM +#ifndef NOTCURSES_TERMDESC +#define NOTCURSES_TERMDESC #ifdef __cplusplus extern "C" { @@ -170,21 +170,6 @@ term_supported_styles(const tinfo* ti){ return ti->supported_styles; } -// if the terminal unambiguously identifies itself in response to our -// queries, go ahead and trust that, overriding TERM. -typedef enum { - TERMINAL_UNKNOWN, // no useful information from queries; use termname - TERMINAL_LINUX, // ioctl()s - TERMINAL_XTERM, // XTVERSION == 'XTerm(ver)' - TERMINAL_VTE, // TDA: "~VTE" - TERMINAL_KITTY, // XTGETTCAP['TN'] == 'xterm-kitty' - TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\" - TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm' - TERMINAL_WEZTERM, // XTVERSION == 'WezTerm *' - TERMINAL_ALACRITTY, // can't be detected; match TERM - TERMINAL_CONTOUR, // XTVERSION == 'console *' -} queried_terminals_e; - #ifdef __cplusplus } #endif