From b9fa29247a460ee5ed4d89d4877fab9f044e1ea1 Mon Sep 17 00:00:00 2001 From: nick black Date: Mon, 11 Oct 2021 19:05:50 -0400 Subject: [PATCH] [automaton] detect GNU screen + version #2261 --- src/lib/in.c | 29 +++++++++++++++++++++++++++++ src/lib/in.h | 3 ++- src/lib/termdesc.c | 10 ++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/lib/in.c b/src/lib/in.c index 8942e07ba..6248d7002 100644 --- a/src/lib/in.c +++ b/src/lib/in.c @@ -981,6 +981,34 @@ da1_attrs_cb(inputctx* ictx){ return 1; } +// GNU screen primarily identifies itself via an "83" as the first parameter +// of its DA2 reply. the version is the second parameter. +static int +da2_screen_cb(inputctx* ictx){ + if(ictx->initdata == NULL){ + return 2; + } + if(ictx->initdata->qterm != TERMINAL_UNKNOWN){ + logwarn("already identified term (%d)\n", ictx->initdata->qterm); + return 2; + } + unsigned ver = amata_next_numeric(&ictx->amata, "\x1b[>83;", ';'); + if(ver < 10000){ + logwarn("version %u doesn't look like GNU screen\n", ver); + return 2; + } + char verstr[9]; // three two-digit components plus two delims + int s = snprintf(verstr, sizeof(verstr), "%u.%02u.%02u", + ver / 10000, ver / 100 % 100, ver % 100); + if(s < 0 || (unsigned)s >= sizeof(verstr)){ + logwarn("bad screen version %u\n", ver); + return 2; + } + ictx->initdata->version = strdup(verstr); + ictx->initdata->qterm = TERMINAL_GNUSCREEN; + return 2; +} + // we use secondary device attributes to recognize the alacritty crate // version, and to ascertain the version of old, pre-XTVERSION XTerm. static int @@ -1268,6 +1296,7 @@ build_cflow_automaton(inputctx* ictx){ { "[?\\N;\\Dc", da1_attrs_cb, }, { "[?1;0;\\NS", xtsmgraphics_cregs_cb, }, { "[?2;0;\\N;\\NS", xtsmgraphics_sixel_cb, }, + { "[>83;\\N;0c", da2_screen_cb, }, { "[>\\N;\\N;\\Nc", da2_cb, }, { "[=\\Sc", da3_cb, }, // CSI da3 form as issued by WezTerm // DCS (\eP...ST) diff --git a/src/lib/in.h b/src/lib/in.h index 73cf82f5b..12fb4e5f0 100644 --- a/src/lib/in.h +++ b/src/lib/in.h @@ -41,8 +41,9 @@ typedef enum { TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\" TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm' TERMINAL_TMUX, // XTVERSION == "tmux ver" + TERMINAL_GNUSCREEN, // SDA: "83;ver;0c" TERMINAL_WEZTERM, // XTVERSION == 'WezTerm *' - TERMINAL_ALACRITTY, // can't be detected; match TERM+DA2 + TERMINAL_ALACRITTY, // can't be detected; match TERM+SDA TERMINAL_CONTOUR, // XTVERSION == 'contour ver' TERMINAL_ITERM, // XTVERSION == 'iTerm2 [ver]' TERMINAL_TERMINOLOGY, // TDA: "~~TY" diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 233877040..63deba55b 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -341,6 +341,9 @@ init_terminfo_esc(tinfo* ti, const char* name, escape_e idx, SECDEVATTR // query background, replies in X color https://www.x.org/releases/X11R7.7/doc/man/man7/X.7.xhtml#heading11 +// GNU screen passes this on to the underlying terminal rather than answering +// itself, unlike most other queries, so send this first since it will take +// longer to be answered. #define CSI_BGQ "\x1b]11;?\e\\" // FIXME ought be using the u7 terminfo string here, if it exists. the great @@ -367,8 +370,8 @@ init_terminfo_esc(tinfo* ti, const char* name, escape_e idx, // request the cell geometry of the textual area #define GEOMCELL "\x1b[18t" -#define DIRECTIVES KBDQUERY \ - CSI_BGQ \ +#define DIRECTIVES CSI_BGQ \ + KBDQUERY \ SUMQUERY \ "\x1b[?1;3;256S" /* try to set 256 cregs */ \ KITTYQUERY \ @@ -604,6 +607,9 @@ apply_term_heuristics(tinfo* ti, const char* termname, queried_terminals_e qterm }else if(qterm == TERMINAL_TMUX){ termname = "tmux"; // FIXME what, oh what to do with tmux? + }else if(qterm == TERMINAL_GNUSCREEN){ + termname = "GNU screen"; + // FIXME disable rgb? }else if(qterm == TERMINAL_MLTERM){ termname = "MLterm"; ti->caps.quadrants = true; // good caps.quadrants, no caps.sextants as of 3.9.0