move ESCAPE_CUP into dense pack #1525

pull/1693/head
nick black 3 years ago committed by Nick Black
parent 0f10eaf9fc
commit a5b597cfef

@ -44,7 +44,7 @@ tinfo_debug_caps(const tinfo* ti, FILE* debugfp, int rows, int cols,
fprintf(debugfp, "%sbackground isn't interpreted as transparent\n", indent);
}
fprintf(debugfp, "%scup: %c vpa: %c hpa: %c\n",
indent, capyn(ti->cup), capyn(ti->vpa), capyn(ti->hpa));
indent, capyn(get_escape(ti, ESCAPE_CUP)), capyn(ti->vpa), capyn(ti->hpa));
}
void notcurses_debug_caps(const notcurses* nc, FILE* debugfp){

@ -232,15 +232,16 @@ int ncdirect_cursor_move_yx(ncdirect* n, int y, int x){
x = 0;
}
}
if(n->tcache.cup){
return term_emit(tiparm(n->tcache.cup, y, x), n->ttyfp, false);
const char* cup = get_escape(&n->tcache, ESCAPE_CUP);
if(cup){
return term_emit(tiparm(cup, y, x), n->ttyfp, false);
}else if(n->tcache.vpa && n->tcache.hpa){
if(term_emit(tiparm(n->tcache.hpa, x), n->ttyfp, false) == 0 &&
term_emit(tiparm(n->tcache.vpa, y), n->ttyfp, false) == 0){
return 0;
}
}
return -1;
return -1; // we will not be moving the cursor today
}
// an algorithm to detect inverted cursor reporting on terminals 2x2 or larger:

@ -821,8 +821,8 @@ goto_location(notcurses* nc, FILE* out, int y, int x){
ret = term_emit(tiparm(nc->tcache.hpa, x), out, false);
}
}else{
// cup is required, no need to check for existence
ret = term_emit(tiparm(nc->tcache.cup, y, x), out, false);
// 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;
@ -1188,10 +1188,13 @@ home_cursor(notcurses* nc, bool flush){
int ret = -1;
if(nc->tcache.home){
ret = term_emit(nc->tcache.home, nc->ttyfp, flush);
}else if(nc->tcache.cup){
ret = term_emit(tiparm(nc->tcache.cup, 1, 1), nc->ttyfp, flush);
}else if(nc->tcache.clearscr){
ret = term_emit(nc->tcache.clearscr, nc->ttyfp, flush);
}else{
const char* cup = get_escape(&nc->tcache, ESCAPE_CUP);
if(cup){
ret = term_emit(tiparm(cup, 1, 1), nc->ttyfp, flush);
}else if(nc->tcache.clearscr){
ret = term_emit(nc->tcache.clearscr, nc->ttyfp, flush);
}
}
if(ret >= 0){
nc->rstate.x = 0;

@ -45,7 +45,6 @@ typedef enum {
typedef struct tinfo {
uint16_t escindices[ESCAPE_MAX]; // table of 1-biased indices into esctable
char* esctable; // packed table of escape sequences
char* cup; // move cursor
char* hpa; // horizontal position adjusment (move cursor on row)
char* vpa; // vertical position adjustment (move cursor on column)
char* setaf; // set foreground color (ANSI)

@ -137,6 +137,33 @@ void free_terminfo_cache(tinfo* ti){
pthread_mutex_destroy(&ti->pixel_query);
}
// tlen -- size of escape table. tused -- used bytes in same.
// returns -1 if the starting location is >= 65535. otherwise,
// copies tstr into the table, and sets up 1-biased index.
static int
grow_esc_table(tinfo* ti, const char* tstr, escape_e esc,
size_t* tlen, size_t* tused){
if(*tused >= 65535){
return -1;
}
size_t slen = strlen(tstr) + 1; // count the nul term
if(*tlen - *tused < slen){
// guaranteed to give us enough space to add tstr (and then some)
size_t newsize = *tlen + 4096 + slen;
char* tmp = realloc(ti->esctable, newsize);
if(tmp == NULL){
return -1;
}
ti->esctable = tmp;
*tlen = newsize;
}
// we now are guaranteed sufficient space to copy tstr
memcpy(ti->esctable + *tused, tstr, slen);
ti->escindices[esc] = *tused + 1; // one-bias
*tused += slen;
return 0;
}
// termname is just the TERM environment variable. some details are not
// exposed via terminfo, and we must make heuristic decisions based on
// the detected terminal type, yuck :/.
@ -164,8 +191,27 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname,
}
}
// verify that the terminal provides cursor addressing (absolute movement)
terminfostr(&ti->cup, "cup");
if(ti->cup == NULL){
const struct strtdesc {
escape_e esc;
const char* tinfo;
} strtdescs[] = {
{ ESCAPE_CUP, "cup", },
{ ESCAPE_MAX, NULL, },
};
size_t tablelen = 0;
size_t tableused = 0;
for(typeof(*strtdescs)* strtdesc = strtdescs ; strtdesc->esc < ESCAPE_MAX ; ++strtdesc){
char* tstr;
if(terminfostr(&tstr, strtdesc->tinfo) == 0){
if(grow_esc_table(ti, tstr, strtdesc->esc, &tablelen, &tableused)){
free(ti->esctable);
return -1;
}
}else{
ti->escindices[strtdesc->esc] = 0;
}
}
if(ti->escindices[ESCAPE_CUP] == 0){
fprintf(stderr, "Required terminfo capability 'cup' not defined\n");
return -1;
}

Loading…
Cancel
Save