work around strange kitty issue for now #1910

pull/1920/head
nick black 3 years ago committed by nick black
parent 714b288c8d
commit 37286aa707

@ -674,16 +674,18 @@ sprite_scrub(const notcurses* n, const ncpile* p, sprixel* s){
// precondition: s->invalidated is SPRIXEL_INVALIDATED or SPRIXEL_MOVED.
// returns -1 on error, or the number of bytes written.
static inline int
sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){
sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out,
int y, int x){
//sprixel_debug(s, stderr);
logdebug("Sprixel %u state %d\n", s->id, s->invalidated);
return n->tcache.pixel_draw(p, s, out);
return n->tcache.pixel_draw(p, s, out, y, x);
}
// 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){
sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out,
int y, int x){
//sprixel_debug(s, stderr);
logdebug("Sprixel %u state %d\n", s->id, s->invalidated);
if(s->invalidated == SPRIXEL_MOVED && n->tcache.pixel_move){
@ -693,7 +695,7 @@ sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){
bool noscroll = !n->tcache.sixel_maxy_pristine;
return n->tcache.pixel_move(s, out, noscroll);
}else{
return n->tcache.pixel_draw(p, s, out);
return n->tcache.pixel_draw(p, s, out, y, x);
}
}
@ -1171,6 +1173,47 @@ mouse_disable(FILE* out){
out, true);
}
// sync the drawing position to the specified location with as little overhead
// as possible (with nothing, if already at the right location). we prefer
// absolute horizontal moves (hpa) to relative ones, in the rare event that
// our understanding of our horizontal location is faulty.
// FIXME fall back to synthesized moves in the absence of capabilities (i.e.
// textronix lacks cup; fake it with horiz+vert moves)
// if hardcursorpos is non-zero, we always perform a cup
static inline int
goto_location(notcurses* nc, FILE* out, int y, int x){
//fprintf(stderr, "going to %d/%d from %d/%d hard: %u\n", y, x, nc->rstate.y, nc->rstate.x, hardcursorpos);
int ret = 0;
// if we don't have hpa, force a cup even if we're only 1 char away. the only
// terminal i know supporting cup sans hpa is vt100, and vt100 can suck it.
// you can't use cuf for backwards moves anyway; again, vt100 can suck it.
const char* hpa = get_escape(&nc->tcache, ESCAPE_HPA);
if(nc->rstate.y == y && hpa && !nc->rstate.hardcursorpos){ // only need move x
if(nc->rstate.x == x){ // needn't move shit
return 0;
}
const char* cuf1 = get_escape(&nc->tcache, ESCAPE_CUF1);
if(x == nc->rstate.x + 1 && cuf1){
ret = term_emit(cuf1, out, false);
}else{
ret = term_emit(tiparm(hpa, x), out, false);
}
}else{
// cup is required, no need to verify existence
ret = term_emit(tiparm(get_escape(&nc->tcache, ESCAPE_CUP), y, x), out, false);
nc->rstate.hardcursorpos = 0;
}
nc->rstate.x = x;
nc->rstate.y = y;
if(nc->rstate.logendy >= 0){
if(y > nc->rstate.logendy || (y == nc->rstate.logendy && x > nc->rstate.logendx)){
nc->rstate.logendy = y;
nc->rstate.logendx = x;
}
}
return ret;
}
// how many edges need touch a corner for it to be printed?
static inline unsigned
box_corner_needs(unsigned ctlword){

@ -562,7 +562,9 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx, int cols,
// q=2 has been able to go on chunks other than the last chunk since
// 2021-03, but there's no harm in this small bit of backwards compat.
if(totalout == 0){
*parse_start = fprintf(fp, "\e_Gf=32,s=%d,v=%d,i=%d,p=1,a=t,%s;",
// FIXME this move to 1;1 is ridiculous, but see
// https://github.com/dankamongmen/notcurses/issues/1910 =[
*parse_start = fprintf(fp, "\e[1;1H\e_Gf=32,s=%d,v=%d,i=%d,p=1,a=t,%s;",
lenx, leny, sprixelid, chunks ? "m=1" : "q=2");
}else{
fprintf(fp, "\e_G%sm=%d;", chunks ? "" : "q=2,", chunks ? 1 : 0);
@ -830,7 +832,7 @@ int kitty_scrub(const ncpile* p, sprixel* s){
}
// returns the number of bytes written
int kitty_draw(const ncpile* p, sprixel* s, FILE* out){
int kitty_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){
(void)p;
bool animated = false;
if(s->mstreamfp){ // active animation
@ -852,7 +854,6 @@ int kitty_draw(const ncpile* p, sprixel* s, FILE* out){
free(s->glyph);
s->glyph = NULL;
s->glyphlen = 0;
//s->invalidated = SPRIXEL_QUIESCENT;
s->invalidated = SPRIXEL_LOADED;
}else{
s->invalidated = SPRIXEL_LOADED;

@ -717,47 +717,6 @@ update_palette(notcurses* nc, FILE* out){
return 0;
}
// sync the drawing position to the specified location with as little overhead
// as possible (with nothing, if already at the right location). we prefer
// absolute horizontal moves (hpa) to relative ones, in the rare event that
// our understanding of our horizontal location is faulty.
// FIXME fall back to synthesized moves in the absence of capabilities (i.e.
// textronix lacks cup; fake it with horiz+vert moves)
// if hardcursorpos is non-zero, we always perform a cup
static inline int
goto_location(notcurses* nc, FILE* out, int y, int x){
//fprintf(stderr, "going to %d/%d from %d/%d hard: %u\n", y, x, nc->rstate.y, nc->rstate.x, hardcursorpos);
int ret = 0;
// if we don't have hpa, force a cup even if we're only 1 char away. the only
// terminal i know supporting cup sans hpa is vt100, and vt100 can suck it.
// you can't use cuf for backwards moves anyway; again, vt100 can suck it.
const char* hpa = get_escape(&nc->tcache, ESCAPE_HPA);
if(nc->rstate.y == y && hpa && !nc->rstate.hardcursorpos){ // only need move x
if(nc->rstate.x == x){ // needn't move shit
return 0;
}
const char* cuf1 = get_escape(&nc->tcache, ESCAPE_CUF1);
if(x == nc->rstate.x + 1 && cuf1){
ret = term_emit(cuf1, out, false);
}else{
ret = term_emit(tiparm(hpa, x), out, false);
}
}else{
// cup is required, no need to verify existence
ret = term_emit(tiparm(get_escape(&nc->tcache, ESCAPE_CUP), y, x), out, false);
nc->rstate.hardcursorpos = 0;
}
nc->rstate.x = x;
nc->rstate.y = y;
if(nc->rstate.logendy >= 0){
if(y > nc->rstate.logendy || (y == nc->rstate.logendy && x > nc->rstate.logendx)){
nc->rstate.logendy = y;
nc->rstate.logendx = x;
}
}
return ret;
}
// at least one of the foreground and background are the default. emit the
// necessary return to default (if one is necessary), and update rstate.
static inline int
@ -893,7 +852,7 @@ clean_sprixels(notcurses* nc, ncpile* p, FILE* out){
if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l)){
return -1;
}
int r = sprite_redraw(nc, p, s, out);
int r = sprite_redraw(nc, p, s, out, y + nc->margin_t, x + nc->margin_l);
if(r < 0){
return -1;
}
@ -952,10 +911,7 @@ rasterize_sprixels(notcurses* nc, ncpile* p, FILE* out){
//fprintf(stderr, "3 DRAWING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->margin_t, x + nc->margin_l, s->n);
int y,x;
ncplane_yx(s->n, &y, &x);
if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l)){
return -1;
}
int r = sprite_draw(nc, p, s, out);
int r = sprite_draw(nc, p, s, out, y + nc->margin_t, x + nc->margin_l);
if(r < 0){
return -1;
}

@ -827,7 +827,7 @@ int sixel_scrub(const ncpile* p, sprixel* s){
}
// returns the number of bytes written
int sixel_draw(const ncpile* p, sprixel* s, FILE* out){
int sixel_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){
// if we've wiped or rebuilt any cells, effect those changes now, or else
// we'll get flicker when we move to the new location.
if(s->wipes_outstanding){
@ -836,6 +836,9 @@ int sixel_draw(const ncpile* p, sprixel* s, FILE* out){
}
s->wipes_outstanding = false;
}
if(goto_location(p->nc, out, y, x)){
return -1;
}
if(s->invalidated == SPRIXEL_MOVED){
for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){
for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){

@ -167,9 +167,9 @@ int kitty_wipe_animation(sprixel* s, int ycell, int xcell);
int sixel_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec);
int kitty_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec);
int kitty_rebuild_animation(sprixel* s, int ycell, int xcell, uint8_t* auxvec);
int kitty_draw(const struct ncpile *p, sprixel* s, FILE* out);
int kitty_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x);
int kitty_move(sprixel* s, FILE* out, unsigned noscroll);
int sixel_draw(const struct ncpile *p, sprixel* s, FILE* out);
int sixel_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x);
int sixel_scrub(const struct ncpile* p, sprixel* s);
int kitty_scrub(const struct ncpile* p, sprixel* s);
int kitty_remove(int id, FILE* out);

@ -130,7 +130,8 @@ typedef struct tinfo {
int (*pixel_rebuild)(struct 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)(const struct tinfo*, int fd); // called when support is detected
int (*pixel_draw)(const struct ncpile* p, struct sprixel* s, FILE* out);
int (*pixel_draw)(const struct ncpile* p, struct sprixel* s, FILE* out,
int y, int x);
// execute move (erase old graphic, place at new location) if non-NULL
int (*pixel_move)(struct sprixel* s, FILE* out, unsigned noscroll);
int (*pixel_scrub)(const struct ncpile* p, struct sprixel* s);

Loading…
Cancel
Save