From fc390da020cec35fb330a3cd440314f43569dbcc Mon Sep 17 00:00:00 2001 From: nick black Date: Thu, 17 Jun 2021 19:34:39 -0400 Subject: [PATCH] invert DECSDM for terminals with sprixel_cursor_hack set #1782 --- src/lib/internal.h | 2 +- src/lib/sixel.c | 7 ++++++- src/lib/sprite.c | 2 +- src/lib/termdesc.h | 8 +++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/lib/internal.h b/src/lib/internal.h index d3949f074..f0d84fc3d 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -867,7 +867,7 @@ 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_clear_all(int fd); -int sixel_init(int fd); +int sixel_init(const tinfo* t, int fd); int sprite_init(const tinfo* t, int fd); int sprite_clear_all(const tinfo* t, int fd); int kitty_shutdown(int fd); diff --git a/src/lib/sixel.c b/src/lib/sixel.c index 678dc6a97..fc1eea253 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -859,10 +859,15 @@ int sixel_draw(const ncpile* p, sprixel* s, FILE* out){ return 0; } -int sixel_init(int fd){ +int sixel_init(const tinfo* ti, 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). + if(ti->sprixel_cursor_hack){ + // except MLterm (and a few others, possibly including the physical VT340), + // which inverts the usual sense of DECSDM. + return tty_emit("\e[?80l\e[?8452h", fd); + } return tty_emit("\e[?80;8452h", fd); } diff --git a/src/lib/sprite.c b/src/lib/sprite.c index 113622af3..a3308c1be 100644 --- a/src/lib/sprite.c +++ b/src/lib/sprite.c @@ -205,7 +205,7 @@ int sprite_init(const tinfo* t, int fd){ if(t->pixel_init == NULL){ return 0; } - return t->pixel_init(fd); + return t->pixel_init(t, fd); } uint8_t* sprixel_auxiliary_vector(const sprixel* s){ diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index dc44dbbea..38a88cb70 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -126,7 +126,7 @@ typedef struct tinfo { // perform the inverse of pixel_wipe, restoring an annihilated sprixcell. 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)(int fd); // called when support is detected + 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_shutdown)(int fd); // called during context shutdown int (*pixel_clear_all)(int fd); // called during startup, kitty only @@ -140,8 +140,10 @@ typedef struct tinfo { bool AMflag; // "AM" flag for automatic movement to next line // mlterm resets the cursor (i.e. makes it visible) any time you print - // a sprixel. we work around this spiritedly unorthodox decision. - bool sprixel_cursor_hack; // do sprixels reset the cursor? (mlterm) + // a sprixel. we work around this spiritedly unorthodox decision. it + // furthermore interprets DECSDM in the reverse sense of most terminals + // (though possibly in conformance with the actual VT340). + bool sprixel_cursor_hack; // mlterm fixes } tinfo; // retrieve the terminfo(5)-style escape 'e' from tdesc (NULL if undefined).