From 8d3c0426405abf578c1fa6734f4a32bd64c56c79 Mon Sep 17 00:00:00 2001 From: nick black Date: Mon, 21 Jun 2021 22:20:58 -0400 Subject: [PATCH] turn off bitmap support if TIOCGWINSZ doesn't supply pixel info #1805 --- src/lib/blit.c | 2 +- src/lib/debug.c | 2 +- src/lib/direct.c | 2 +- src/lib/notcurses.c | 5 ++++- src/lib/termdesc.c | 2 -- src/lib/termdesc.h | 32 ++++++++++++++++---------------- src/tests/bitmap.cpp | 5 ++--- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/lib/blit.c b/src/lib/blit.c index 44b27f9d1..dc1bae50f 100644 --- a/src/lib/blit.c +++ b/src/lib/blit.c @@ -959,7 +959,7 @@ const struct blitset* lookup_blitset(const tinfo* tcache, ncblitter_e setid, boo } } // without bitmap support, NCBLIT_PIXEL decays to NCBLIT_3x2 - if(!tcache->bitmap_supported && setid == NCBLIT_PIXEL){ + if(!tcache->pixel_draw && setid == NCBLIT_PIXEL){ if(may_degrade){ setid = NCBLIT_3x2; }else{ diff --git a/src/lib/debug.c b/src/lib/debug.c index f115f3eb0..26f3f47f9 100644 --- a/src/lib/debug.c +++ b/src/lib/debug.c @@ -63,7 +63,7 @@ tinfo_debug_caps(const tinfo* ti, FILE* debugfp, int rows, int cols, capyn(get_escape(ti, ESCAPE_BGOP))); fprintf(debugfp, "%srows: %u cols: %u rpx: %u cpx: %u (%dx%d)\n", indent, rows, cols, ti->cellpixy, ti->cellpixx, rows * ti->cellpixy, cols * ti->cellpixx); - if(!ti->bitmap_supported){ + if(!ti->pixel_init){ fprintf(debugfp, "%sdidn't detect bitmap graphics support\n", indent); }else if(ti->sixel_maxy){ fprintf(debugfp, "%smax sixel size: %dx%d colorregs: %u\n", diff --git a/src/lib/direct.c b/src/lib/direct.c index 82c6db760..e75a62adb 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -1311,7 +1311,7 @@ int ncdirect_flush(const ncdirect* nc){ } int ncdirect_check_pixel_support(const ncdirect* n){ - if(n->tcache.bitmap_supported){ + if(n->tcache.pixel_draw){ return 1; } return 0; diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index a1ffb9a0e..fe2311aa1 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -254,6 +254,9 @@ int update_term_dimensions(int fd, int* rows, int* cols, tinfo* tcache, if(tcache){ tcache->cellpixy = ws.ws_row ? ws.ws_ypixel / ws.ws_row : 0; tcache->cellpixx = ws.ws_col ? ws.ws_xpixel / ws.ws_col : 0; + if(tcache->cellpixy == 0 || tcache->cellpixx == 0){ + tcache->pixel_init = NULL; // disable support + } } if(tcache->sixel_maxy_pristine){ tcache->sixel_maxy = tcache->sixel_maxy_pristine; @@ -984,7 +987,7 @@ recursive_lock_init(pthread_mutex_t *lock){ } int notcurses_check_pixel_support(const notcurses* nc){ - if(nc->tcache.bitmap_supported){ + if(nc->tcache.pixel_init){ return 1; } return 0; diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index eb090abab..cec0fd7a3 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -6,7 +6,6 @@ // we found Sixel support -- set up the API static inline void setup_sixel_bitmaps(tinfo* ti, int fd){ - ti->bitmap_supported = true; ti->pixel_init = sixel_init; ti->pixel_draw = sixel_draw; ti->pixel_remove = NULL; @@ -20,7 +19,6 @@ setup_sixel_bitmaps(tinfo* ti, int fd){ static inline void setup_kitty_bitmaps(tinfo* ti, int fd){ - ti->bitmap_supported = true; ti->pixel_wipe = kitty_wipe; ti->pixel_destroy = kitty_destroy; ti->pixel_remove = kitty_remove; diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index 6bf7592fd..94dcd1b5b 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -116,21 +116,7 @@ typedef struct tinfo { // bg_collides_default is either 0x0000000 or (if in use) 0x1RRGGBB. uint32_t bg_collides_default; - // sprixel support. there are several different sprixel protocols, of - // which we support sixel and kitty. the kitty protocol is used based - // on TERM heuristics. otherwise, we attempt to detect sixel support, and - // query the details of the implementation. - int color_registers; // sixel color registers (post pixel_query_done) - int sixel_maxx; // maximum theoretical sixel width - // in sixel, we can't render to the bottom row, lest we force a one-line - // scroll. we thus clamp sixel_maxy_pristine to the minimum of - // sixel_maxy_pristine (the reported sixel_maxy), and the number of rows - // less one times the cell height. sixel_maxy is thus recomputed whenever - // we get a resize event. it is only defined if we have sixel_maxy_pristine, - // so kitty graphics (which don't force a scroll) never deal with this. - int sixel_maxy; // maximum working sixel height - int sixel_maxy_pristine; // maximum theoretical sixel height, as queried - int (*pixel_destroy)(const struct notcurses* nc, const struct ncpile* p, FILE* out, struct sprixel* s); + // bitmap support. if we support bitmaps, pixel_draw will be non-NULL // wipe out a cell's worth of pixels from within a sprixel. for sixel, this // means leaving out the pixels (and likely resizes the string). for kitty, // this means dialing down their alpha to 0 (in equivalent space). @@ -142,14 +128,28 @@ typedef struct tinfo { int (*pixel_draw)(const struct ncpile* p, struct sprixel* s, FILE* out); // execute move (erase old graphic, place at new location) if non-NULL int (*pixel_move)(const struct ncpile* p, struct sprixel* s, FILE* out); + int (*pixel_destroy)(const struct notcurses* nc, const struct ncpile* p, FILE* out, struct sprixel* s); int (*pixel_shutdown)(int fd); // called during context shutdown int (*pixel_clear_all)(int fd); // called during startup, kitty only + // sprixel parameters. there are several different sprixel protocols, of + // which we support sixel and kitty. the kitty protocol is used based + // on TERM heuristics. otherwise, we attempt to detect sixel support, and + // query the details of the implementation. + int color_registers; // sixel color registers (post pixel_query_done) + int sixel_maxx; // maximum theoretical sixel width + // in sixel, we can't render to the bottom row, lest we force a one-line + // scroll. we thus clamp sixel_maxy_pristine to the minimum of + // sixel_maxy_pristine (the reported sixel_maxy), and the number of rows + // less one times the cell height. sixel_maxy is thus recomputed whenever + // we get a resize event. it is only defined if we have sixel_maxy_pristine, + // so kitty graphics (which don't force a scroll) never deal with this. + int sixel_maxy; // maximum working sixel height + int sixel_maxy_pristine; // maximum theoretical sixel height, as queried int sprixel_scale_height; // sprixel must be a multiple of this many rows const char* termname; // terminal name from environment variables/init char* termversion; // terminal version (freeform) from query responses struct termios tpreserved; // terminal state upon entry ncinputlayer input; // input layer - bool bitmap_supported; // do we support bitmaps (post pixel_query_done)? // mlterm resets the cursor (i.e. makes it visible) any time you print // a sprixel. we work around this spiritedly unorthodox decision. it diff --git a/src/tests/bitmap.cpp b/src/tests/bitmap.cpp index 95f78c16c..3896c557d 100644 --- a/src/tests/bitmap.cpp +++ b/src/tests/bitmap.cpp @@ -8,8 +8,7 @@ TEST_CASE("Bitmaps") { auto n_ = notcurses_stdplane(nc_); REQUIRE(n_); - if(notcurses_check_pixel_support(nc_) <= 0){ - CHECK(0 == nc_->tcache.bitmap_supported); + if(!notcurses_check_pixel_support(nc_)){ CHECK(!notcurses_stop(nc_)); return; } @@ -17,7 +16,7 @@ TEST_CASE("Bitmaps") { SUBCASE("SprixelTermValues") { CHECK(0 < nc_->tcache.cellpixy); CHECK(0 < nc_->tcache.cellpixx); - CHECK(nc_->tcache.bitmap_supported); + CHECK(nc_->tcache.pixel_init); } SUBCASE("SprixelMinimize") {