When terminal is identified, send minimal queries

We might have already unambiguously identified our terminal
by the time we start probing (the Linux console, for instance,
is identified via ioctl()s). If we have, we still want to
send non-identification-related queries in, particularly to
get the cursor position. This fixes up notcurses-info on the
Linux console (#1837).
pull/1859/head
nick black 3 years ago
parent 0d2ed04c1a
commit 7c72bb55ed
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -1213,31 +1213,29 @@ int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected,
nilayer->inputbuf_valid_starts = 0; nilayer->inputbuf_valid_starts = 0;
nilayer->inputbuf_write_at = 0; nilayer->inputbuf_write_at = 0;
nilayer->input_events = 0; nilayer->input_events = 0;
if(*detected == TERMINAL_UNKNOWN){ int csifd = nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd;
int csifd = nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd; if(isatty(csifd)){
if(isatty(csifd)){ query_state inits = {
query_state inits = { .tcache = tcache,
.tcache = tcache, .state = STATE_NULL,
.state = STATE_NULL, .qterm = TERMINAL_UNKNOWN,
.qterm = TERMINAL_UNKNOWN, .cursor_x = -1,
.cursor_x = -1, .cursor_y = -1,
.cursor_y = -1, };
}; if(control_read(csifd, &inits)){
if(control_read(csifd, &inits)){ input_free_esctrie(&nilayer->inputescapes);
input_free_esctrie(&nilayer->inputescapes); free(inits.version);
free(inits.version); return -1;
return -1; }
} tcache->bg_collides_default = inits.bg;
tcache->bg_collides_default = inits.bg; tcache->termversion = inits.version;
tcache->termversion = inits.version; *detected = inits.qterm;
*detected = inits.qterm; *appsync = inits.appsync;
*appsync = inits.appsync; if(cursor_x){
if(cursor_x){ *cursor_x = inits.cursor_x - 1;
*cursor_x = inits.cursor_x - 1; }
} if(cursor_y){
if(cursor_y){ *cursor_y = inits.cursor_y - 1;
*cursor_y = inits.cursor_y - 1;
}
} }
} }
return 0; return 0;

@ -250,29 +250,41 @@ grow_esc_table(tinfo* ti, const char* tstr, escape_e esc,
// ⇒ CSI ? 6 3 ; Ps c ("VT320") // ⇒ CSI ? 6 3 ; Ps c ("VT320")
// ⇒ CSI ? 6 4 ; Ps c ("VT420") // ⇒ CSI ? 6 4 ; Ps c ("VT420")
// these three queries (terminated with a Primary Device Attributes, to which
// all known terminals reply) hopefully can uniquely and unquestionably
// identify the terminal to which we are talking.
#define IDQUERIES "\x1b[=0c" /* Tertiary Device Attributes */ \
"\x1b[>0q" /* XTVERSION */ \
"\x1bP+q544e\x1b\\" /* XTGETTCAP['TN'] */
// query background, replies in X color https://www.x.org/releases/X11R7.7/doc/man/man7/X.7.xhtml#heading11 // query background, replies in X color https://www.x.org/releases/X11R7.7/doc/man/man7/X.7.xhtml#heading11
#define CSI_BGQ "\e]11;?\e\\" #define CSI_BGQ "\e]11;?\e\\"
// ought be using the u7 terminfo string here, if it exists. the great thing // FIXME ought be using the u7 terminfo string here, if it exists. the great
// is, if we get a response to this, we know we can use it for u7! // thing is, if we get a response to this, we know we can use it for u7!
#define DSRCPR "\e[6n" #define DSRCPR "\e[6n"
#define DIRECTIVES CSI_BGQ \
DSRCPR \
"\x1b[?2026$p" /* query for Synchronized Updates */ \
"\x1b[?1;3;256S" /* try to set 256 cregs */ \
"\x1b[?2;1;0S" /* XTSMGRAPHICS (cregs) */ \
"\x1b[?1;1;0S" /* XTSMGRAPHICS (geometry) */ \
"\x1b[c" /* Device Attributes */
// we send an XTSMGRAPHICS to set up 256 color registers (the most we can // we send an XTSMGRAPHICS to set up 256 color registers (the most we can
// currently take advantage of; we need at least 64 to use sixel at all. // currently take advantage of; we need at least 64 to use sixel at all.
// maybe that works, maybe it doesn't. then query both color registers // maybe that works, maybe it doesn't. then query both color registers
// and geometry. send XTGETTCAP for terminal name. // and geometry. send XTGETTCAP for terminal name. if 'minimal' is set, don't
// send any identification queries.
static int static int
send_initial_queries(int fd){ send_initial_queries(int fd, bool minimal){
const char queries[] = CSI_BGQ const char *queries;
DSRCPR if(minimal){
"\x1b[?2026$p" // query for App-sync updates queries = DIRECTIVES;
"\x1b[=0c" // Tertiary Device Attributes }else{
"\x1b[>0q" // XTVERSION queries = IDQUERIES DIRECTIVES;
"\x1bP+q544e\x1b\\" // XTGETTCAP['TN'] }
"\x1b[?1;3;256S" // try to set 256 cregs
"\x1b[?2;1;0S" // XTSMGRAPHICS (cregs)
"\x1b[?1;1;0S" // XTSMGRAPHICS (geometry)
"\x1b[c"; // Device Attributes
if(blocking_write(fd, queries, strlen(queries))){ if(blocking_write(fd, queries, strlen(queries))){
return -1; return -1;
} }
@ -504,11 +516,10 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
} }
} }
if(fd >= 0){ if(fd >= 0){
if(qterm == TERMINAL_UNKNOWN){ bool minimal = (qterm != TERMINAL_UNKNOWN);
if(send_initial_queries(fd)){ if(send_initial_queries(fd, minimal)){
fprintf(stderr, "Error issuing terminal queries on %d\n", fd); fprintf(stderr, "Error issuing terminal queries on %d\n", fd);
return -1; return -1;
}
} }
if(tcgetattr(fd, &ti->tpreserved)){ if(tcgetattr(fd, &ti->tpreserved)){
fprintf(stderr, "Couldn't preserve terminal state for %d (%s)\n", fd, strerror(errno)); fprintf(stderr, "Couldn't preserve terminal state for %d (%s)\n", fd, strerror(errno));

Loading…
Cancel
Save