From 9df980678139b8e04dfc83888712fe58c06f9f65 Mon Sep 17 00:00:00 2001 From: nick black Date: Thu, 29 Jul 2021 08:29:12 -0400 Subject: [PATCH] send a CSI14t, process response #1891 --- src/lib/input.c | 45 ++++++++++++++++++++++++++++++++++++++++----- src/lib/notcurses.c | 2 ++ src/lib/termdesc.c | 4 ++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/lib/input.c b/src/lib/input.c index 9b63d5ab9..1d5798f58 100644 --- a/src/lib/input.c +++ b/src/lib/input.c @@ -780,8 +780,13 @@ typedef enum { STATE_XTSMGRAPHICS_DRAIN, // drain out XTSMGRAPHICS to 'S' STATE_APPSYNC_REPORT, // got DECRPT ?2026 STATE_APPSYNC_REPORT_DRAIN, // drain out decrpt to 'y' - STATE_CURSOR, // reading row of cursor location to ';' - STATE_CURSOR_COL, // reading col of cursor location to 'R' + // a cursor location report comes back as CSI row ; col R. a pixel geometry + // report comes back as CSI 4 ; height ; width t. so we handle them the same + // until we hit either a second semicolon or an 'R'. at the second ';', we + // verify that the first variable was '4', and continue to 't'. + STATE_CURSOR_OR_PIXELGEOM, // reading row of cursor location to ';' + STATE_CURSOR_COL, // reading col of cursor location to 'R' or ';' + STATE_PIXELS_WIDTH, // reading screen width in pixels to ';' } initstates_e; typedef struct query_state { @@ -797,7 +802,11 @@ typedef struct query_state { char runstring[80]; // running string size_t stridx; // position to write in string uint32_t bg; // queried default background or 0 + int pixelwidth; // screen width in pixels + int pixelheight; // screen height in pixels int cursor_y, cursor_x;// cursor location + int cursor_or_pixel; // holding cell until we determine which state + bool xtgettcap_good; // high when we've received DCS 1 bool appsync; // application-synchronized updates advertised } query_state; @@ -1056,18 +1065,18 @@ pump_control_read(query_state* inits, unsigned char c){ if(ruts_numeric(&inits->numeric, c)){ return -1; } - inits->state = STATE_CURSOR; + inits->state = STATE_CURSOR_OR_PIXELGEOM; }else if(c >= 0x40 && c <= 0x7E){ inits->state = STATE_NULL; } break; - case STATE_CURSOR: + case STATE_CURSOR_OR_PIXELGEOM: if(isdigit(c)){ if(ruts_numeric(&inits->numeric, c)){ return -1; } }else if(c == ';'){ - inits->cursor_y = inits->numeric; + inits->cursor_or_pixel = inits->numeric; inits->state = STATE_CURSOR_COL; inits->numeric = 0; }else{ @@ -1082,6 +1091,28 @@ pump_control_read(query_state* inits, unsigned char c){ }else if(c == 'R'){ //fprintf(stderr, "CURSOR X: %d\n", inits->numeric); inits->cursor_x = inits->numeric; + inits->cursor_y = inits->cursor_or_pixel; + inits->state = STATE_NULL; + }else if(c == ';'){ + if(inits->cursor_or_pixel != 4){ + logerror("expected 4 to lead pixel report, got %d\n", inits->cursor_or_pixel); + return -1; + } + inits->pixelheight = inits->numeric; + inits->state = STATE_PIXELS_WIDTH; + inits->numeric = 0; + }else{ + inits->state = STATE_NULL; + } + break; + case STATE_PIXELS_WIDTH: + if(isdigit(c)){ + if(ruts_numeric(&inits->numeric, c)){ + return -1; + } + }else if(c == 't'){ +//fprintf(stderr, "CURSOR X: %d\n", inits->numeric); + inits->pixelwidth = inits->numeric; inits->state = STATE_NULL; }else{ inits->state = STATE_NULL; @@ -1458,6 +1489,10 @@ int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected, if(cursor_y){ *cursor_y = inits.cursor_y - 1; } + if(inits.pixelwidth && inits.pixelheight){ + tcache->pixy = inits.pixelheight; + tcache->pixx = inits.pixelwidth; + } } return 0; } diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index ad90d23a3..3c8737e5a 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -274,6 +274,8 @@ int update_term_dimensions(int fd, int* rows, int* cols, tinfo* tcache, tcache->pixx = ws.ws_xpixel; } } + // update even if we didn't get values just now, because we need set + // cellpix{y,x} up from an initial CSI14n, which set only pix{y,x}. tcache->cellpixy = ws.ws_row ? tcache->pixy / ws.ws_row : 0; tcache->cellpixx = ws.ws_col ? tcache->pixx / ws.ws_col : 0; if(tcache->cellpixy == 0 || tcache->cellpixx == 0){ diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 2d695ac2d..7475f3e56 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -356,12 +356,16 @@ grow_esc_table(tinfo* ti, const char* tstr, escape_e esc, // XTSMGRAPHICS query for the maximum supported geometry. #define GEOMXTSM "\x1b[?1;1;0S" +// non-standard CSI for total pixel geometry +#define GEOMPIXEL "\x1b[14t" + #define DIRECTIVES CSI_BGQ \ DSRCPR \ SUMQUERY \ "\x1b[?1;3;256S" /* try to set 256 cregs */ \ CREGSXTSM \ GEOMXTSM \ + GEOMPIXEL \ PRIDEVATTR // we send an XTSMGRAPHICS to set up 256 color registers (the most we can