mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
Use different kitty nonces for different runs
If we always start with kitty graphics id 1, successive runs of ncplayer -bpixel -k will erase any previously- printed graphics. Initialize it with random() in sprite_init(). Break graphics erasure out from sprite_init() into new interface sprite_clear_all(), defined only for kitty. The latter is now guarded by NCOPTION_NO_CLEAR_BITMAPS. Closes #1578.
This commit is contained in:
parent
a2b5a6dc03
commit
a19e6a52de
@ -457,7 +457,6 @@ typedef struct tinfo {
|
||||
pthread_mutex_t pixel_query; // only query for pixel support once
|
||||
int color_registers; // sixel color registers (post pixel_query_done)
|
||||
int sixel_maxx, sixel_maxy; // sixel size maxima (post pixel_query_done)
|
||||
int sprixelnonce; // next sprixel id
|
||||
int (*pixel_destroy)(const struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s);
|
||||
// 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,
|
||||
@ -466,9 +465,10 @@ typedef struct tinfo {
|
||||
// perform the inverse of pixel_wipe, restoring an annihilated sprixcell.
|
||||
int (*pixel_rebuild)(sprixel* s, int y, int x, uint8_t* auxvec);
|
||||
int (*pixel_remove)(int id, FILE* out); // kitty only, issue actual delete command
|
||||
int (*pixel_init)(int fd); // called when support is detected
|
||||
int (*pixel_init)(int fd); // called when support is detected
|
||||
int (*pixel_draw)(const struct ncpile* p, sprixel* s, FILE* out);
|
||||
int (*pixel_shutdown)(int fd); // called during context shutdown
|
||||
int (*pixel_shutdown)(int fd); // called during context shutdown
|
||||
int (*pixel_clear_all)(int fd); // called during startup, kitty only
|
||||
int sprixel_scale_height; // sprixel must be a multiple of this many rows
|
||||
bool bitmap_supported; // do we support bitmaps (post pixel_query_done)?
|
||||
bool sprixel_cursor_hack; // do sprixels reset the cursor? (mlterm)
|
||||
@ -963,9 +963,10 @@ int sprixel_load(sprixel* spx, char* s, int bytes, int pixy, int pixx, int parse
|
||||
int sixel_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
|
||||
int kitty_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
|
||||
int kitty_remove(int id, FILE* out);
|
||||
int kitty_init(int fd);
|
||||
int kitty_clear_all(int fd);
|
||||
int sixel_init(int fd);
|
||||
int sprite_init(const notcurses* nc);
|
||||
int sprite_init(const tinfo* t, int fd);
|
||||
int sprite_clear_all(const tinfo* t, int fd);
|
||||
int kitty_shutdown(int fd);
|
||||
int sixel_shutdown(int fd);
|
||||
sprixel* sprixel_by_id(const ncpile* n, uint32_t id);
|
||||
|
@ -614,7 +614,8 @@ int kitty_draw(const ncpile* p, sprixel* s, FILE* out){
|
||||
}
|
||||
|
||||
// clears all kitty bitmaps
|
||||
int kitty_init(int fd){
|
||||
int kitty_clear_all(int fd){
|
||||
//fprintf(stderr, "KITTY UNIVERSAL ERASE\n");
|
||||
return tty_emit("\e_Ga=d\e\\", fd);
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1081,7 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
|
||||
if(ret->ttyfd >= 0){
|
||||
reset_term_attributes(ret);
|
||||
if(!(opts->flags & NCOPTION_NO_CLEAR_BITMAPS)){
|
||||
if(sprite_init(ret)){
|
||||
if(sprite_clear_all(&ret->tcache, ret->ttyfd)){
|
||||
free_plane(ret->stdplane);
|
||||
goto err;
|
||||
}
|
||||
|
@ -194,11 +194,19 @@ int sprite_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell){
|
||||
return r;
|
||||
}
|
||||
|
||||
int sprite_init(const notcurses* nc){
|
||||
if(!nc->tcache.pixel_init){
|
||||
int sprite_clear_all(const tinfo* t, int fd){
|
||||
if(t->pixel_clear_all == NULL){
|
||||
return 0;
|
||||
}
|
||||
return nc->tcache.pixel_init(nc->ttyfd);
|
||||
return t->pixel_clear_all(fd);
|
||||
}
|
||||
|
||||
int sprite_init(const tinfo* t, int fd){
|
||||
sprixelid_nonce = random() % 0xffffffu;
|
||||
if(t->pixel_init == NULL){
|
||||
return 0;
|
||||
}
|
||||
return t->pixel_init(fd);
|
||||
}
|
||||
|
||||
uint8_t* sprixel_auxiliary_vector(const sprixel* s){
|
||||
|
@ -20,16 +20,17 @@ setup_sixel_bitmaps(tinfo* ti){
|
||||
}
|
||||
|
||||
static inline void
|
||||
setup_kitty_bitmaps(tinfo* ti){
|
||||
setup_kitty_bitmaps(tinfo* ti, int fd){
|
||||
ti->pixel_wipe = kitty_wipe;
|
||||
ti->pixel_destroy = kitty_destroy;
|
||||
ti->pixel_init = kitty_init;
|
||||
ti->pixel_remove = kitty_remove;
|
||||
ti->pixel_draw = kitty_draw;
|
||||
ti->pixel_shutdown = kitty_shutdown;
|
||||
ti->sprixel_scale_height = 1;
|
||||
ti->pixel_rebuild = kitty_rebuild;
|
||||
ti->pixel_clear_all = kitty_clear_all;
|
||||
set_pixel_blitter(kitty_blit);
|
||||
sprite_init(ti, fd);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -76,7 +77,7 @@ int terminfostr(char** gseq, const char* name){
|
||||
|
||||
// Qui si convien lasciare ogne sospetto; ogne viltà convien che qui sia morta.
|
||||
static int
|
||||
apply_term_heuristics(tinfo* ti, const char* termname){
|
||||
apply_term_heuristics(tinfo* ti, const char* termname, int fd){
|
||||
if(!termname){
|
||||
// setupterm interprets a missing/empty TERM variable as the special value “unknown”.
|
||||
termname = "unknown";
|
||||
@ -91,7 +92,7 @@ apply_term_heuristics(tinfo* ti, const char* termname){
|
||||
ti->quadrants = true;
|
||||
ti->pixel_query_done = true;
|
||||
ti->bitmap_supported = true;
|
||||
setup_kitty_bitmaps(ti);
|
||||
setup_kitty_bitmaps(ti, fd);
|
||||
}else if(strstr(termname, "alacritty")){
|
||||
ti->alacritty_sixel_hack = true;
|
||||
ti->quadrants = true;
|
||||
@ -249,10 +250,9 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8)
|
||||
}
|
||||
pthread_mutex_init(&ti->pixel_query, NULL);
|
||||
ti->pixel_query_done = false;
|
||||
if(apply_term_heuristics(ti, termname)){
|
||||
if(apply_term_heuristics(ti, termname, fd)){
|
||||
return -1;
|
||||
}
|
||||
ti->sprixelnonce = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user