No ASU on Linux, no cursor_hack

Pull out the dreadful 'cursor_hack' code that was
used for MLterm. If you send DECSDM the way MLterm
wants it, you don't have the problem of the cursor
becoming visible whenever you draw a Sixel. We send
it as expected now, so that's all good.

On the Linux console, we were using an uninitialized
variable for ASU detection. This has been remedied.
pull/1846/head
nick black 3 years ago
parent adc1447778
commit 4aeab4e987
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -523,10 +523,6 @@ typedef struct blitterargs {
int celldimy; // vertical pixels per cell
int colorregs; // number of color registers
sprixel* spx; // sprixel object
// in at least mlterm, emitting a sixel makes the cursor visible.
// if the cursor is hidden, and sprixel_cursor_hack is set, this
// is set to the civis capability.
const char* cursor_hack;
} pixel; // for pixels
} u;
} blitterargs;
@ -786,6 +782,7 @@ 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(const tinfo* t, int fd);
int sixel_init_inverted(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);

@ -589,8 +589,7 @@ write_sixel_header(FILE* fp, int leny, int lenx, const sixeltable* stab, sixel_p
}
static int
write_sixel_payload(FILE* fp, int lenx, const sixelmap* map,
const char* cursor_hack){
write_sixel_payload(FILE* fp, int lenx, const sixelmap* map){
int p = 0;
while(p < map->sixelcount){
int needclosure = 0;
@ -626,9 +625,6 @@ write_sixel_payload(FILE* fp, int lenx, const sixelmap* map,
p += lenx;
}
fprintf(fp, "\e\\");
if(cursor_hack){
fprintf(fp, "%s", cursor_hack);
}
return 0;
}
@ -638,12 +634,12 @@ write_sixel_payload(FILE* fp, int lenx, const sixelmap* map,
// are output geometry.
static int
write_sixel(FILE* fp, int outy, int outx, const sixeltable* stab,
int* parse_start, const char* cursor_hack, sixel_p2_e p2){
int* parse_start, sixel_p2_e p2){
*parse_start = write_sixel_header(fp, outy, outx, stab, p2);
if(*parse_start < 0){
return -1;
}
if(write_sixel_payload(fp, outx, stab->map, cursor_hack) < 0){
if(write_sixel_payload(fp, outx, stab->map) < 0){
return -1;
}
if(fclose(fp) == EOF){
@ -673,8 +669,7 @@ sixel_reblit(sprixel* s){
free(buf);
return -1;
}
// FIXME need to get cursor_hack in here for shitty mlterm!
if(write_sixel_payload(fp, s->pixx, s->smap, NULL) < 0){
if(write_sixel_payload(fp, s->pixx, s->smap) < 0){
fclose(fp);
free(buf);
return -1;
@ -712,8 +707,7 @@ sixel_blit_inner(int leny, int lenx, sixeltable* stab,
stab->p2 = SIXEL_P2_TRANS;
}
// calls fclose() on success
if(write_sixel(fp, outy, lenx, stab, &parse_start,
bargs->u.pixel.cursor_hack, stab->p2)){
if(write_sixel(fp, outy, lenx, stab, &parse_start, stab->p2)){
fclose(fp);
free(buf);
return -1;
@ -859,17 +853,20 @@ int sixel_draw(const ncpile* p, sprixel* s, FILE* out){
}
int sixel_init(const tinfo* ti, int fd){
(void)ti;
// \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);
}
int sixel_init_inverted(const tinfo* ti, int fd){
(void)ti;
// 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);
}
// only called for cells in SPRIXCELL_ANNIHILATED[_TRANS]. just post to
// wipes_outstanding, so the Sixel gets regenerated the next render cycle,
// just like wiping. this is necessary due to the complex nature of

@ -44,8 +44,12 @@ get_default_geometry(tinfo* ti){
// we found Sixel support -- set up the API
static inline void
setup_sixel_bitmaps(tinfo* ti, int fd){
ti->pixel_init = sixel_init;
setup_sixel_bitmaps(tinfo* ti, int fd, bool invert80){
if(invert80){
ti->pixel_init = sixel_init_inverted;
}else{
ti->pixel_init = sixel_init;
}
ti->pixel_draw = sixel_draw;
ti->pixel_remove = NULL;
ti->pixel_destroy = sixel_destroy;
@ -370,7 +374,6 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd,
}else if(qterm == TERMINAL_MLTERM){
termname = "MLterm";
ti->caps.quadrants = true; // good caps.quadrants, no caps.sextants as of 3.9.0
ti->sprixel_cursor_hack = true;
}else if(qterm == TERMINAL_WEZTERM){
termname = "WezTerm";
ti->caps.rgb = true;
@ -599,7 +602,7 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
goto err;
}
}
unsigned appsync_advertised;
unsigned appsync_advertised = 0;
if(cursor_x && cursor_y){
*cursor_x = *cursor_y = 0;
}
@ -633,9 +636,9 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
build_supported_styles(ti);
// our current sixel quantization algorithm requires at least 64 color
// registers. we make use of no more than 256. this needs to happen
// after heuristics, since sixel_init() depends on sprixel_cursor_hack.
// after heuristics, since the choice of sixel_init() depends on it.
if(ti->color_registers >= 64){
setup_sixel_bitmaps(ti, fd);
setup_sixel_bitmaps(ti, fd, qterm == TERMINAL_MLTERM);
}
return 0;

@ -156,12 +156,6 @@ typedef struct tinfo {
struct termios tpreserved; // terminal state upon entry
ncinputlayer input; // input layer
// mlterm resets the cursor (i.e. makes it visible) any time you print
// 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
int default_rows; // LINES environment var / lines terminfo / 24
int default_cols; // COLUMNS environment var / cols terminfo / 80
} tinfo;

@ -963,12 +963,6 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits
n->sprite = sprixel_recycle(n);
}
bargs.u.pixel.spx = n->sprite;
bargs.u.pixel.cursor_hack = NULL;
if(nc->cursory < 0){
if(nc->tcache.sprixel_cursor_hack){
bargs.u.pixel.cursor_hack = get_escape(&nc->tcache, ESCAPE_CIVIS);
}
}
// if we are kitty prior to 0.20.0, we set NCVISUAL_OPTION_SCROLL so that
// C=1 won't be supplied. we use sixel_maxy_pristine as a side channel to
// encode this version information.

Loading…
Cancel
Save