diff --git a/NEWS.md b/NEWS.md index d3f877fc6..00c340c3d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,7 @@ rearrangements of Notcurses. Kitty pixel graphics protocol. * Added `notcurses_debug_caps()` to dump terminal properties, both those reported and those inferred, to a `FILE*`. + * Added `NCOPTION_NO_CLEAR_BITMAPS` option for `notcurses_init()`. * 2.2.3 (2021-03-08) * Implemented **EXPERIMENTAL** `NCBLIT_PIXEL` for terminals reporting Sixel diff --git a/USAGE.md b/USAGE.md index 38dd718ef..e6abaad51 100644 --- a/USAGE.md +++ b/USAGE.md @@ -91,6 +91,12 @@ typedef enum { // doing something weird (setting a locale not based on LANG). #define NCOPTION_INHIBIT_SETLOCALE 0x0001 +// We typically try to clear any preexisting bitmaps. If we ought *not* try +// to do this, pass NCOPTION_NO_CLEAR_BITMAPS. Note that they might still +// get cleared even if this is set, and they might not get cleared even if +// this is not set. It's a tough world out there. +#define NCOPTION_NO_CLEAR_BITMAPS 0x0002ull + // We typically install a signal handler for SIGWINCH that generates a resize // event in the notcurses_getc() queue. Set to inhibit this handler. #define NCOPTION_NO_WINCH_SIGHANDLER 0x0004 diff --git a/doc/man/man3/notcurses_init.3.md b/doc/man/man3/notcurses_init.3.md index a040dde6a..5cf4597c6 100644 --- a/doc/man/man3/notcurses_init.3.md +++ b/doc/man/man3/notcurses_init.3.md @@ -12,6 +12,7 @@ notcurses_init - initialize a notcurses instance ```c #define NCOPTION_INHIBIT_SETLOCALE 0x0001ull +#define NCOPTION_NO_CLEAR_BITMAPS 0x0002ull #define NCOPTION_NO_WINCH_SIGHANDLER 0x0004ull #define NCOPTION_NO_QUIT_SIGHANDLERS 0x0008ull #define NCOPTION_SUPPRESS_BANNERS 0x0020ull @@ -110,6 +111,10 @@ zero. The following flags are defined: the **LANG** environment variable. Your program should call **setlocale(3)** itself, usually as one of the first lines. +* **NCOPTION_NO_CLEAR_BITMAPS**: On entry, make no special attempt to clear any + preexisting bitmaps. Note that they might still get cleared even if this is + set, and they might not get cleared even if this is not set. + * **NCOPTION_NO_WINCH_SIGHANDLER**: A signal handler will usually be installed for **SIGWINCH** and **SIGCONT**, resulting in **NCKEY_RESIZE** events being generated on input. With this flag, the handler will not be diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 18cca8ef2..14de9dd2d 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -832,7 +832,11 @@ typedef enum { // doing something weird (setting a locale not based on LANG). #define NCOPTION_INHIBIT_SETLOCALE 0x0001ull -// NCOPTION_VERIFY_PIXEL was removed in 2.2.3. It ought be repurposed. FIXME. +// We typically try to clear any preexisting bitmaps. If we ought *not* try +// to do this, pass NCOPTION_NO_CLEAR_BITMAPS. Note that they might still +// get cleared even if this is set, and they might not get cleared even if +// this is not set. It's a tough world out there. +#define NCOPTION_NO_CLEAR_BITMAPS 0x0002ull // We typically install a signal handler for SIGWINCH that generates a resize // event in the notcurses_getc() queue. Set to inhibit this handler. diff --git a/src/fetch/main.c b/src/fetch/main.c index c1ab6c2d1..e3bacf580 100644 --- a/src/fetch/main.c +++ b/src/fetch/main.c @@ -393,7 +393,7 @@ place_infoplane(struct ncdirect* ncd, int planeheight){ } struct notcurses_options opts = { .flags = NCOPTION_SUPPRESS_BANNERS | NCOPTION_INHIBIT_SETLOCALE - | NCOPTION_NO_ALTERNATE_SCREEN, + | NCOPTION_NO_ALTERNATE_SCREEN | NCOPTION_NO_CLEAR_BITMAPS, .margin_t = cury, .margin_b = dimy - (cury + planeheight), }; diff --git a/src/lib/internal.h b/src/lib/internal.h index 13325a343..3a2c563a1 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -321,7 +321,7 @@ typedef struct tinfo { // means leaving out the pixels (and likely resizes the string). for kitty, // this means dialing down their alpha to 0 (in equivalent space). int (*pixel_cell_wipe)(const struct notcurses* nc, sprixel* s, int y, int x); - int (*pixel_init)(const struct notcurses* nc); + int (*pixel_init)(int fd); bool pixel_query_done; // have we yet performed pixel query? bool sextants; // do we have (good, vetted) Unicode 13 sextant support? bool braille; // do we have Braille support? (linux console does not) @@ -730,8 +730,8 @@ sprixel* sprixel_create(ncplane* n, const char* s, int bytes, int placey, int pl int parse_start); API int sprite_wipe_cell(const notcurses* nc, sprixel* s, int y, int x); int sprite_kitty_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s); -int sprite_kitty_init(const notcurses* nc); -int sprite_sixel_init(const notcurses* nc); +int sprite_kitty_init(int fd); +int sprite_sixel_init(int fd); int sprite_sixel_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s); int sprite_init(const notcurses* nc); diff --git a/src/lib/kitty.c b/src/lib/kitty.c index 72bebf539..07afe7fb6 100644 --- a/src/lib/kitty.c +++ b/src/lib/kitty.c @@ -285,6 +285,6 @@ int kitty_blit(ncplane* nc, int linesize, const void* data, return r; } -int sprite_kitty_init(const notcurses* nc){ - return tty_emit("\e_Ga=d\e\\", nc->ttyfd); +int sprite_kitty_init(int fd){ + return tty_emit("\e_Ga=d\e\\", fd); } diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 7f6b58414..f90ae45b8 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1037,9 +1037,11 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ goto err; } if(ret->ttyfd >= 0){ - if(sprite_init(ret)){ - free_plane(ret->stdplane); - goto err; + if(!(opts->flags & NCOPTION_NO_CLEAR_BITMAPS)){ + if(sprite_init(ret)){ + free_plane(ret->stdplane); + goto err; + } } if(ret->tcache.smkx && tty_emit(ret->tcache.smkx, ret->ttyfd)){ free_plane(ret->stdplane); diff --git a/src/lib/sixel.c b/src/lib/sixel.c index 72e533daf..c273cb32d 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -551,9 +551,9 @@ int sixel_blit(ncplane* nc, int linesize, const void* data, return r; } -int sprite_sixel_init(const notcurses* nc){ +int sprite_sixel_init(int fd){ // \e[?8452: DECSDM private "sixel scrolling" mode keeps the sixel from // scrolling, but puts it at the current cursor location (as opposed to // the upper left corner of the screen). - return tty_emit("\e[?8452h", nc->ttyfd); + return tty_emit("\e[?8452h", fd); } diff --git a/src/lib/sprite.c b/src/lib/sprite.c index abdad54d7..2021a146c 100644 --- a/src/lib/sprite.c +++ b/src/lib/sprite.c @@ -77,5 +77,5 @@ int sprite_init(const notcurses* nc){ if(!nc->tcache.pixel_init){ return 0; } - return nc->tcache.pixel_init(nc); + return nc->tcache.pixel_init(nc->ttyfd); } diff --git a/src/lib/terminfo.c b/src/lib/terminfo.c index e6abb8a7a..365b1849d 100644 --- a/src/lib/terminfo.c +++ b/src/lib/terminfo.c @@ -384,6 +384,7 @@ int query_term(tinfo* ti, int fd){ if(ti->sixel_supported){ query_sixel_details(ti, fd); } + ti->pixel_init(fd); if(flags & O_NONBLOCK){ fcntl(fd, F_SETFL, flags); }