mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-02 09:40:15 +00:00
init: pipe detected terminal through to heuristics #1761
This commit is contained in:
parent
c13c613f32
commit
9cbcc6c273
@ -1023,7 +1023,7 @@ pump_control_read(init_state* inits, unsigned char c){
|
|||||||
|
|
||||||
// complete the terminal detection process
|
// complete the terminal detection process
|
||||||
static int
|
static int
|
||||||
control_read(tinfo* tcache, int ttyfd){
|
control_read(tinfo* tcache, int ttyfd, queried_terminals_e* detected){
|
||||||
init_state inits = {
|
init_state inits = {
|
||||||
.tcache = tcache,
|
.tcache = tcache,
|
||||||
.state = STATE_NULL,
|
.state = STATE_NULL,
|
||||||
@ -1032,6 +1032,7 @@ control_read(tinfo* tcache, int ttyfd){
|
|||||||
unsigned char* buf;
|
unsigned char* buf;
|
||||||
ssize_t s;
|
ssize_t s;
|
||||||
|
|
||||||
|
*detected = TERMINAL_UNKNOWN;
|
||||||
if((buf = malloc(BUFSIZ)) == NULL){
|
if((buf = malloc(BUFSIZ)) == NULL){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1040,6 +1041,7 @@ control_read(tinfo* tcache, int ttyfd){
|
|||||||
int r = pump_control_read(&inits, buf[idx]);
|
int r = pump_control_read(&inits, buf[idx]);
|
||||||
if(r == 1){ // success!
|
if(r == 1){ // success!
|
||||||
free(buf);
|
free(buf);
|
||||||
|
*detected = inits.qterm;
|
||||||
//fprintf(stderr, "at end, derived terminal %d\n", inits.qterm);
|
//fprintf(stderr, "at end, derived terminal %d\n", inits.qterm);
|
||||||
return 0;
|
return 0;
|
||||||
}else if(r < 0){
|
}else if(r < 0){
|
||||||
@ -1053,7 +1055,7 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ncinputlayer_init(tinfo* tcache, FILE* infp){
|
int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected){
|
||||||
ncinputlayer* nilayer = &tcache->input;
|
ncinputlayer* nilayer = &tcache->input;
|
||||||
setbuffer(infp, NULL, 0);
|
setbuffer(infp, NULL, 0);
|
||||||
nilayer->inputescapes = NULL;
|
nilayer->inputescapes = NULL;
|
||||||
@ -1068,7 +1070,7 @@ int ncinputlayer_init(tinfo* tcache, FILE* infp){
|
|||||||
nilayer->input_events = 0;
|
nilayer->input_events = 0;
|
||||||
int csifd = nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd;
|
int csifd = nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd;
|
||||||
if(isatty(csifd)){
|
if(isatty(csifd)){
|
||||||
if(control_read(tcache, csifd)){
|
if(control_read(tcache, csifd, detected)){
|
||||||
input_free_esctrie(&nilayer->inputescapes);
|
input_free_esctrie(&nilayer->inputescapes);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1496,8 +1496,9 @@ cellcmp_and_dupfar(egcpool* dampool, nccell* damcell,
|
|||||||
// sets up the input layer, building a trie of escape sequences and their
|
// 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
|
// nckey equivalents. if we are connected to a tty, this also completes the
|
||||||
// terminal detection sequence (we ought have already written our initial
|
// terminal detection sequence (we ought have already written our initial
|
||||||
// queries, ideally as early as possible).
|
// queries, ideally as early as possible). if we are able to determine the
|
||||||
int ncinputlayer_init(tinfo* tcache, FILE* infp);
|
// terminal conclusively, it will be written to |detected|.
|
||||||
|
int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected);
|
||||||
|
|
||||||
void ncinputlayer_stop(ncinputlayer* nilayer);
|
void ncinputlayer_stop(ncinputlayer* nilayer);
|
||||||
|
|
||||||
|
@ -74,15 +74,31 @@ terminfostr(char** gseq, const char* name){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we couldn't get a terminal from interrogation, so let's see if the TERM
|
||||||
|
// matches any of our known terminals. this can only be as accurate as the
|
||||||
|
// TERM setting is (and as up-to-date and complete as we are).
|
||||||
|
static int
|
||||||
|
match_termname(const char* termname, queried_terminals_e* qterm){
|
||||||
|
if(strstr(termname, "alacritty")){
|
||||||
|
*qterm = TERMINAL_ALACRITTY;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Qui si convien lasciare ogne sospetto; ogne viltà convien che qui sia morta.
|
// Qui si convien lasciare ogne sospetto; ogne viltà convien che qui sia morta.
|
||||||
static int
|
static int
|
||||||
apply_term_heuristics(tinfo* ti, const char* termname, int fd){
|
apply_term_heuristics(tinfo* ti, const char* termname, int fd,
|
||||||
|
queried_terminals_e qterm){
|
||||||
if(!termname){
|
if(!termname){
|
||||||
// setupterm interprets a missing/empty TERM variable as the special value “unknown”.
|
// setupterm interprets a missing/empty TERM variable as the special value “unknown”.
|
||||||
termname = "unknown";
|
termname = "unknown";
|
||||||
}
|
}
|
||||||
|
if(qterm == TERMINAL_UNKNOWN){
|
||||||
|
match_termname(termname, &qterm);
|
||||||
|
}
|
||||||
|
// st had neithersextants nor quadrants last i checked (0.8.4)
|
||||||
ti->braille = true; // most everyone has working braille, even from fonts
|
ti->braille = true; // most everyone has working braille, even from fonts
|
||||||
if(strstr(termname, "kitty")){ // kitty (https://sw.kovidgoyal.net/kitty/)
|
if(qterm == TERMINAL_KITTY){ // kitty (https://sw.kovidgoyal.net/kitty/)
|
||||||
termname = "Kitty";
|
termname = "Kitty";
|
||||||
// see https://sw.kovidgoyal.net/kitty/protocol-extensions.html
|
// see https://sw.kovidgoyal.net/kitty/protocol-extensions.html
|
||||||
// FIXME detect the actual default background color; this assumes it to
|
// FIXME detect the actual default background color; this assumes it to
|
||||||
@ -92,45 +108,33 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd){
|
|||||||
ti->quadrants = true;
|
ti->quadrants = true;
|
||||||
ti->RGBflag = true;
|
ti->RGBflag = true;
|
||||||
setup_kitty_bitmaps(ti, fd);
|
setup_kitty_bitmaps(ti, fd);
|
||||||
}else if(strstr(termname, "alacritty")){
|
}else if(qterm == TERMINAL_ALACRITTY){
|
||||||
termname = "Alacritty";
|
termname = "Alacritty";
|
||||||
ti->quadrants = true;
|
ti->quadrants = true;
|
||||||
// ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */
|
// ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */
|
||||||
ti->RGBflag = true;
|
ti->RGBflag = true;
|
||||||
}else if(strstr(termname, "vte") || strstr(termname, "gnome") || strstr(termname, "xfce")){
|
}else if(qterm == TERMINAL_VTE){
|
||||||
termname = "VTE";
|
termname = "VTE";
|
||||||
ti->sextants = true; // VTE has long enjoyed good sextant support
|
|
||||||
ti->quadrants = true;
|
ti->quadrants = true;
|
||||||
}else if(strncmp(termname, "foot", 4) == 0){
|
ti->sextants = true; // VTE has long enjoyed good sextant support
|
||||||
|
}else if(qterm == TERMINAL_FOOT){
|
||||||
termname = "foot";
|
termname = "foot";
|
||||||
ti->sextants = true;
|
ti->sextants = true;
|
||||||
ti->quadrants = true;
|
ti->quadrants = true;
|
||||||
ti->RGBflag = true;
|
ti->RGBflag = true;
|
||||||
}else if(strncmp(termname, "st", 2) == 0){
|
}else if(qterm == TERMINAL_MLTERM){
|
||||||
termname = "simple terminal";
|
|
||||||
// st had neithersextants nor quadrants last i checked (0.8.4)
|
|
||||||
}else if(strstr(termname, "mlterm")){
|
|
||||||
termname = "MLterm";
|
termname = "MLterm";
|
||||||
ti->quadrants = true; // good quadrants, no sextants as of 3.9.0
|
ti->quadrants = true; // good quadrants, no sextants as of 3.9.0
|
||||||
ti->sprixel_cursor_hack = true;
|
ti->sprixel_cursor_hack = true;
|
||||||
}else if(strstr(termname, "xterm")){
|
}else if(qterm == TERMINAL_WEZTERM){
|
||||||
// xterm has nothing beyond halfblocks. this is going to catch all kinds
|
|
||||||
// of people using xterm when they shouldn't be, or even real database
|
|
||||||
// entries like "xterm-kitty" (if we don't catch them above), giving a
|
|
||||||
// pretty minimal (but safe) experience. set your TERM correctly!
|
|
||||||
// wezterm wants a TERM of xterm-256color, and identifies itself based
|
|
||||||
// off TERM_PROGRAM and TERM_PROGRAM_VERSION.
|
|
||||||
const char* term_program = getenv("TERM_PROGRAM");
|
|
||||||
if(term_program && strcmp(term_program, "WezTerm") == 0){
|
|
||||||
termname = "WezTerm";
|
termname = "WezTerm";
|
||||||
ti->quadrants = true;
|
ti->quadrants = true;
|
||||||
const char* termver = getenv("TERM_PROGRAM_VERSION");
|
const char* termver = getenv("TERM_PROGRAM_VERSION");
|
||||||
if(termver && strcmp(termver, "20210610") >= 0){
|
if(termver && strcmp(termver, "20210610") >= 0){
|
||||||
ti->sextants = true; // good sextants as of 2021-06-10
|
ti->sextants = true; // good sextants as of 2021-06-10
|
||||||
}
|
}
|
||||||
}else{
|
}else if(qterm == TERMINAL_XTERM){
|
||||||
termname = "XTerm";
|
termname = "XTerm";
|
||||||
}
|
|
||||||
}else if(strcmp(termname, "linux") == 0){
|
}else if(strcmp(termname, "linux") == 0){
|
||||||
termname = "Linux console";
|
termname = "Linux console";
|
||||||
ti->braille = false; // no braille, no sextants in linux console
|
ti->braille = false; // no braille, no sextants in linux console
|
||||||
@ -399,7 +403,8 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ncinputlayer_init(ti, stdin)){
|
queried_terminals_e detected;
|
||||||
|
if(ncinputlayer_init(ti, stdin, &detected)){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
// our current sixel quantization algorithm requires at least 64 color
|
// our current sixel quantization algorithm requires at least 64 color
|
||||||
@ -415,7 +420,8 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(apply_term_heuristics(ti, termname, fd)){
|
//fprintf(stderr, "DETECTED TERM: %d\n", detected);
|
||||||
|
if(apply_term_heuristics(ti, termname, fd, detected)){
|
||||||
ncinputlayer_stop(&ti->input);
|
ncinputlayer_stop(&ti->input);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,7 @@ typedef enum {
|
|||||||
TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\"
|
TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\"
|
||||||
TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm'
|
TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm'
|
||||||
TERMINAL_WEZTERM,
|
TERMINAL_WEZTERM,
|
||||||
|
TERMINAL_ALACRITTY, // can't be detected; match TERM
|
||||||
} queried_terminals_e;
|
} queried_terminals_e;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user