From d7f3800009c0d5bde5717544a28e5c2c926cdc2f Mon Sep 17 00:00:00 2001 From: nick black Date: Sun, 20 Jun 2021 04:06:20 -0400 Subject: [PATCH] [kitty] introduce kitty_move #1395 --- src/lib/internal.h | 13 +++++++++++++ src/lib/kitty.c | 14 +++++++++++++- src/lib/render.c | 5 ++--- src/lib/termdesc.c | 1 + src/lib/termdesc.h | 2 ++ 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/lib/internal.h b/src/lib/internal.h index 7e9c0cfac..30003da5f 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -849,6 +849,7 @@ void sprixel_free(sprixel* s); void sprixel_hide(sprixel* s); int kitty_draw(const ncpile *p, sprixel* s, FILE* out); +int kitty_move(const ncpile *p, sprixel* s, FILE* out); int sixel_draw(const ncpile *p, sprixel* s, FILE* out); // dimy and dimx are cell geometry, not pixel. sprixel* sprixel_alloc(ncplane* n, int dimy, int dimx); @@ -895,6 +896,18 @@ sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ return n->tcache.pixel_draw(p, s, out); } +// precondition: s->invalidated is SPRIXEL_MOVED or SPRIXEL_INVALIDATED +// returns -1 on error, or the number of bytes written. +static inline int +sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ +//sprixel_debug(stderr, s); + if(s->invalidated == SPRIXEL_MOVED && n->tcache.pixel_move){ + return n->tcache.pixel_move(p, s, out); + }else{ + return n->tcache.pixel_draw(p, s, out); + } +} + static inline int sprite_rebuild(const notcurses* nc, sprixel* s, int ycell, int xcell){ const int idx = s->dimx * ycell + xcell; diff --git a/src/lib/kitty.c b/src/lib/kitty.c index 5bb96e146..25cdf567b 100644 --- a/src/lib/kitty.c +++ b/src/lib/kitty.c @@ -612,7 +612,7 @@ int kitty_destroy(const notcurses* nc __attribute__ ((unused)), // returns the number of bytes written int kitty_draw(const ncpile* p, sprixel* s, FILE* out){ -//fprintf(stderr, "DRAWING %d\n", s->id); +fprintf(stderr, "DRAWING %d\n", s->id); (void)p; int ret = s->glyphlen; if(fwrite(s->glyph, s->glyphlen, 1, out) != 1){ @@ -622,6 +622,18 @@ int kitty_draw(const ncpile* p, sprixel* s, FILE* out){ return ret; } +int kitty_move(const ncpile* p, sprixel* s, FILE* out){ +fprintf(stderr, "MOVING %d\n", s->id); + (void)p; + int ret = 0; + if(fprintf(out, "\e_Ga=p,i=%d,p=1,q=2\e\\", s->id) < 0){ + ret = -1; + } + s->invalidated = SPRIXEL_QUIESCENT; + return ret; + //return kitty_draw(p, s, out); +} + // clears all kitty bitmaps int kitty_clear_all(int fd){ //fprintf(stderr, "KITTY UNIVERSAL ERASE\n"); diff --git a/src/lib/render.c b/src/lib/render.c index 8af96079a..100cae6fa 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -918,14 +918,13 @@ clean_sprixels(notcurses* nc, ncpile* p, FILE* out){ }else if(s->invalidated == SPRIXEL_MOVED || s->invalidated == SPRIXEL_INVALIDATED){ int y, x; ncplane_yx(s->n, &y, &x); - // FIXME clean this up, don't use sprite_draw, etc. - // without this, kitty flickers //fprintf(stderr, "1 MOVING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->margin_t, x + nc->margin_l, s->n); + // without this, kitty flickers if(s->invalidated == SPRIXEL_MOVED){ sprite_destroy(nc, p, out, s); } if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l) == 0){ - int r = sprite_draw(nc, p, s, out); + int r = sprite_redraw(nc, p, s, out); if(r < 0){ return -1; } diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 3c4591fad..eb090abab 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -25,6 +25,7 @@ setup_kitty_bitmaps(tinfo* ti, int fd){ ti->pixel_destroy = kitty_destroy; ti->pixel_remove = kitty_remove; ti->pixel_draw = kitty_draw; + ti->pixel_move = kitty_move; ti->pixel_shutdown = kitty_shutdown; ti->sprixel_scale_height = 1; ti->pixel_rebuild = kitty_rebuild; diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index bca482418..6bf7592fd 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -140,6 +140,8 @@ typedef struct tinfo { int (*pixel_remove)(int id, FILE* out); // kitty only, issue actual delete command int (*pixel_init)(const struct tinfo*, int fd); // called when support is detected 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_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