move terminfo cache into its own shared struct #614

This commit is contained in:
nick black 2020-05-19 05:49:49 -04:00
parent bd4d4ef321
commit 8ff3402166
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
5 changed files with 217 additions and 231 deletions

View File

@ -8,47 +8,47 @@ int ncdirect_cursor_up(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cuu){
if(!nc->tcache.cuu){
return -1;
}
return term_emit("cuu", tiparm(nc->cuu, num), nc->ttyfp, false);
return term_emit("cuu", tiparm(nc->tcache.cuu, num), nc->ttyfp, false);
}
int ncdirect_cursor_left(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cub){
if(!nc->tcache.cub){
return -1;
}
return term_emit("cub", tiparm(nc->cub, num), nc->ttyfp, false);
return term_emit("cub", tiparm(nc->tcache.cub, num), nc->ttyfp, false);
}
int ncdirect_cursor_right(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cuf){ // FIXME fall back to cuf1
if(!nc->tcache.cuf){ // FIXME fall back to cuf1
return -1;
}
return term_emit("cuf", tiparm(nc->cuf, num), nc->ttyfp, false);
return term_emit("cuf", tiparm(nc->tcache.cuf, num), nc->ttyfp, false);
}
int ncdirect_cursor_down(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cud){
if(!nc->tcache.cud){
return -1;
}
return term_emit("cud", tiparm(nc->cud, num), nc->ttyfp, false);
return term_emit("cud", tiparm(nc->tcache.cud, num), nc->ttyfp, false);
}
int ncdirect_clear(ncdirect* nc){
if(!nc->clear){
if(!nc->tcache.clear){
return -1; // FIXME scroll output off the screen
}
return term_emit("clear", nc->clear, nc->ttyfp, true);
return term_emit("clear", nc->tcache.clear, nc->ttyfp, true);
}
int ncdirect_dim_x(const ncdirect* nc){
@ -68,36 +68,36 @@ int ncdirect_dim_y(const ncdirect* nc){
}
int ncdirect_cursor_enable(ncdirect* nc){
if(!nc->cnorm){
if(!nc->tcache.cnorm){
return -1;
}
return term_emit("cnorm", nc->cnorm, nc->ttyfp, true);
return term_emit("cnorm", nc->tcache.cnorm, nc->ttyfp, true);
}
int ncdirect_cursor_disable(ncdirect* nc){
if(!nc->civis){
if(!nc->tcache.civis){
return -1;
}
return term_emit("civis", nc->civis, nc->ttyfp, true);
return term_emit("civis", nc->tcache.civis, nc->ttyfp, true);
}
int ncdirect_cursor_move_yx(ncdirect* n, int y, int x){
if(y == -1){ // keep row the same, horizontal move only
if(!n->hpa){
if(!n->tcache.hpa){
return -1;
}
return term_emit("hpa", tiparm(n->hpa, x), n->ttyfp, false);
return term_emit("hpa", tiparm(n->tcache.hpa, x), n->ttyfp, false);
}else if(x == -1){ // keep column the same, vertical move only
if(!n->vpa){
if(!n->tcache.vpa){
return -1;
}
return term_emit("vpa", tiparm(n->vpa, y), n->ttyfp, false);
return term_emit("vpa", tiparm(n->tcache.vpa, y), n->ttyfp, false);
}
if(n->cup){
return term_emit("cup", tiparm(n->cup, y, x), n->ttyfp, false);
}else if(n->vpa && n->hpa){
if(term_emit("hpa", tiparm(n->hpa, x), n->ttyfp, false) == 0 &&
term_emit("vpa", tiparm(n->vpa, y), n->ttyfp, false) == 0){
if(n->tcache.cup){
return term_emit("cup", tiparm(n->tcache.cup, y, x), n->ttyfp, false);
}else if(n->tcache.vpa && n->tcache.hpa){
if(term_emit("hpa", tiparm(n->tcache.hpa, x), n->ttyfp, false) == 0 &&
term_emit("vpa", tiparm(n->tcache.vpa, y), n->ttyfp, false) == 0){
return 0;
}
}
@ -197,29 +197,29 @@ int ncdirect_cursor_yx(ncdirect* n, int* y, int* x){
}
int ncdirect_cursor_push(ncdirect* n){
if(n->sc == NULL){
if(n->tcache.sc == NULL){
return -1;
}
return term_emit("sc", n->sc, n->ttyfp, false);
return term_emit("sc", n->tcache.sc, n->ttyfp, false);
}
int ncdirect_cursor_pop(ncdirect* n){
if(n->rc == NULL){
if(n->tcache.rc == NULL){
return -1;
}
return term_emit("rc", n->rc, n->ttyfp, false);
return term_emit("rc", n->tcache.rc, n->ttyfp, false);
}
int ncdirect_stop(ncdirect* nc){
int ret = 0;
if(nc){
if(nc->op && term_emit("op", nc->op, nc->ttyfp, true)){
if(nc->tcache.op && term_emit("op", nc->tcache.op, nc->ttyfp, true)){
ret = -1;
}
if(nc->sgr0 && term_emit("sgr0", nc->sgr0, nc->ttyfp, true)){
if(nc->tcache.sgr0 && term_emit("sgr0", nc->tcache.sgr0, nc->ttyfp, true)){
ret = -1;
}
if(nc->oc && term_emit("oc", nc->oc, nc->ttyfp, true)){
if(nc->tcache.oc && term_emit("oc", nc->tcache.oc, nc->ttyfp, true)){
ret = -1;
}
free(nc);

View File

@ -157,7 +157,7 @@ ncplane_fadein_internal(ncplane* n, const struct timespec* ts,
int ncplane_fadeout(ncplane* n, const struct timespec* ts, fadecb fader, void* curry){
planepalette pp;
if(!n->nc->RGBflag && !n->nc->CCCflag){ // terminal can't fade
if(!n->nc->tcache.RGBflag && !n->nc->tcache.CCCflag){ // terminal can't fade
return -1;
}
if(alloc_ncplane_palette(n, &pp)){
@ -255,7 +255,7 @@ int ncplane_fadeout(ncplane* n, const struct timespec* ts, fadecb fader, void* c
int ncplane_fadein(ncplane* n, const struct timespec* ts, fadecb fader, void* curry){
planepalette pp;
if(!n->nc->RGBflag && !n->nc->CCCflag){ // terminal can't fade
if(!n->nc->tcache.RGBflag && !n->nc->tcache.CCCflag){ // terminal can't fade
if(fader){
fader(n->nc, n, curry);
}else{
@ -274,7 +274,7 @@ int ncplane_fadein(ncplane* n, const struct timespec* ts, fadecb fader, void* cu
int ncplane_pulse(ncplane* n, const struct timespec* ts, fadecb fader, void* curry){
planepalette pp;
int ret;
if(!n->nc->RGBflag && !n->nc->CCCflag){ // terminal can't fade
if(!n->nc->tcache.RGBflag && !n->nc->tcache.CCCflag){ // terminal can't fade
return -1;
}
if(alloc_ncplane_palette(n, &pp)){

View File

@ -211,8 +211,8 @@ typedef struct ncmultiselector {
int uarrowy, darrowy, arrowx; // location of scrollarrows, even if not present
} ncmultiselector;
typedef struct ncdirect {
int attrword; // current styles
// terminfo cache
typedef struct tinfo {
int colors; // number of colors terminfo reported usable for this screen
char* sgr; // set many graphics properties at once
char* sgr0; // restore default presentation properties
@ -220,10 +220,13 @@ typedef struct ncdirect {
char* setab; // set background color (ANSI)
char* op; // set foreground and background color to default
char* cup; // move cursor
char* cuu; // move N up
char* cub; // move N left
char* cuf; // move N right
char* cud; // move N down
char* cuu; // move N cells up
char* cub; // move N cells left
char* cuf; // move N cells right
char* cud; // move N cells down
char* cuf1; // move 1 cell right
char* cub1; // move 1 cell left
char* home; // home cursor
char* civis; // hide cursor
char* cnorm; // restore cursor to default state
char* hpa; // horizontal position adjusment (move cursor on row)
@ -239,13 +242,27 @@ typedef struct ncdirect {
char* initc; // set a palette entry's RGB value
char* oc; // restore original colors
char* clear; // clear the screen
FILE* ttyfp; // FILE* for controlling tty, from opts->ttyfp
char* clearscr; // erase screen and home cursor
char* cleareol; // clear to end of line
char* clearbol; // clear to beginning of line
char* sc; // push the cursor location onto the stack
char* rc; // pop the cursor location off the stack
bool RGBflag; // terminfo-reported "RGB" flag for 24bpc truecolor
bool CCCflag; // terminfo-reported "CCC" flag for palette set capability
palette256 palette; // 256-indexed palette can be used instead of/with RGB
uint16_t fgrgb, bgrgb; // last RGB values of foreground/background
char* smkx; // enter keypad transmit mode (keypad_xmit)
char* rmkx; // leave keypad transmit mode (keypad_local)
char* getm; // get mouse events
bool RGBflag; // ti-reported "RGB" flag for 24bpc truecolor
bool CCCflag; // ti-reported "CCC" flag for palette set capability
bool AMflag; // ti-reported "AM" flag for automatic movement to next line
char* smcup; // enter alternate mode
char* rmcup; // restore primary mode
} tinfo;
typedef struct ncdirect {
int attrword; // current styles
palette256 palette; // 256-indexed palette can be used instead of/with RGB
FILE* ttyfp; // FILE* for controlling tty
tinfo tcache; // terminfo cache
uint16_t fgrgb, bgrgb; // last RGB values of foreground/background
bool fgdefault, bgdefault; // are FG/BG currently using default colors?
} ncdirect;
@ -270,45 +287,10 @@ typedef struct notcurses {
// used only to see if output motion takes us to the next
// line thanks to terminal action alone.
int colors; // number of colors terminfo reported usable for this screen
char* cup; // move cursor
char* cuf; // move n cells right
char* cub; // move n cells right
char* cuf1; // move 1 cell right
char* cub1; // move 1 cell left
char* civis; // hide cursor
// These might be NULL, and we can more or less work without them. Check!
char* clearscr; // erase screen and home cursor
char* cleareol; // clear to end of line
char* clearbol; // clear to beginning of line
char* home; // home cursor
char* cnorm; // restore cursor to default state
char* sgr; // set many graphics properties at once
char* sgr0; // restore default presentation properties
char* smcup; // enter alternate mode
char* rmcup; // restore primary mode
char* setaf; // set foreground color (ANSI)
char* setab; // set background color (ANSI)
char* op; // set foreground and background color to default
char* standout; // CELL_STYLE_STANDOUT
char* uline; // CELL_STYLE_UNDERLINK
char* reverse; // CELL_STYLE_REVERSE
char* blink; // CELL_STYLE_BLINK
char* dim; // CELL_STYLE_DIM
char* bold; // CELL_STYLE_BOLD
char* italics; // CELL_STYLE_ITALIC
char* italoff; // CELL_STYLE_ITALIC (disable)
char* smkx; // enter keypad transmit mode (keypad_xmit)
char* rmkx; // leave keypad transmit mode (keypad_local)
char* getm; // get mouse events
char* initc; // set a palette entry's RGB value
char* oc; // restore original colors
bool RGBflag; // terminfo-reported "RGB" flag for 24bpc truecolor
bool CCCflag; // terminfo-reported "CCC" flag for palette set capability
bool AMflag; // ti-reported "AM" flag for automatic movement to next line
tinfo tcache; // terminfo cache
int ttyfd; // file descriptor for controlling tty, from opts->ttyfp
FILE* ttyfp; // FILE* for controlling tty, from opts->ttyfp
FILE* ttyfp; // FILE* for controlling tty
int ttyfd; // file descriptor for controlling tty
FILE* ttyinfp; // FILE* for processing input
FILE* renderfp; // debugging FILE* to which renderings are written
struct termios tpreserved; // terminal state upon entry
@ -363,13 +345,13 @@ mbstr_find_codepoint(const char* s, char32_t cp, int* col){
return -1;
}
static inline struct ncplane*
ncplane_stdplane(struct ncplane* n){
static inline ncplane*
ncplane_stdplane(ncplane* n){
return notcurses_stdplane(n->nc);
}
static inline const struct ncplane*
ncplane_stdplane_const(const struct ncplane* n){
static inline const ncplane*
ncplane_stdplane_const(const ncplane* n){
return notcurses_stdplane_const(n->nc);
}
@ -525,12 +507,12 @@ term_emit(const char* name __attribute__ ((unused)), const char* seq,
static inline int
term_bg_palindex(const notcurses* nc, FILE* out, unsigned pal){
return term_emit("setab", tiparm(nc->setab, pal), out, false);
return term_emit("setab", tiparm(nc->tcache.setab, pal), out, false);
}
static inline int
term_fg_palindex(const notcurses* nc, FILE* out, unsigned pal){
return term_emit("setaf", tiparm(nc->setaf, pal), out, false);
return term_emit("setaf", tiparm(nc->tcache.setaf, pal), out, false);
}
static inline const char*

View File

@ -42,19 +42,19 @@ static int
notcurses_stop_minimal(notcurses* nc){
int ret = 0;
drop_signals(nc);
if(nc->rmcup && term_emit("rmcup", nc->rmcup, nc->ttyfp, true)){
if(nc->tcache.rmcup && term_emit("rmcup", nc->tcache.rmcup, nc->ttyfp, true)){
ret = -1;
}
if(nc->cnorm && term_emit("cnorm", nc->cnorm, nc->ttyfp, true)){
if(nc->tcache.cnorm && term_emit("cnorm", nc->tcache.cnorm, nc->ttyfp, true)){
ret = -1;
}
if(nc->op && term_emit("op", nc->op, nc->ttyfp, true)){
if(nc->tcache.op && term_emit("op", nc->tcache.op, nc->ttyfp, true)){
ret = -1;
}
if(nc->sgr0 && term_emit("sgr0", nc->sgr0, nc->ttyfp, true)){
if(nc->tcache.sgr0 && term_emit("sgr0", nc->tcache.sgr0, nc->ttyfp, true)){
ret = -1;
}
if(nc->oc && term_emit("oc", nc->oc, nc->ttyfp, true)){
if(nc->tcache.oc && term_emit("oc", nc->tcache.oc, nc->ttyfp, true)){
ret = -1;
}
ret |= notcurses_mouse_disable(nc);
@ -558,58 +558,58 @@ interrogate_terminfo(notcurses* nc, const notcurses_options* opts, int* dimy, in
shortname_term ? shortname_term : "?",
longname_term ? longname_term : "?");
}
nc->RGBflag = query_rgb();
if((nc->colors = tigetnum("colors")) <= 0){
nc->tcache.RGBflag = query_rgb();
if((nc->tcache.colors = tigetnum("colors")) <= 0){
if(!opts->suppress_banner){
fprintf(stderr, "This terminal doesn't appear to support colors\n");
}
nc->colors = 1;
nc->CCCflag = false;
nc->RGBflag = false;
nc->initc = NULL;
nc->tcache.colors = 1;
nc->tcache.CCCflag = false;
nc->tcache.RGBflag = false;
nc->tcache.initc = NULL;
}else{
term_verify_seq(&nc->initc, "initc");
if(nc->initc){
nc->CCCflag = tigetflag("ccc") == 1;
term_verify_seq(&nc->tcache.initc, "initc");
if(nc->tcache.initc){
nc->tcache.CCCflag = tigetflag("ccc") == 1;
}else{
nc->CCCflag = false;
nc->tcache.CCCflag = false;
}
}
term_verify_seq(&nc->cup, "cup");
if(nc->cup == NULL){
term_verify_seq(&nc->tcache.cup, "cup");
if(nc->tcache.cup == NULL){
fprintf(stderr, "Required terminfo capability 'cup' not defined\n");
return -1;
}
nc->AMflag = tigetflag("am") == 1;
if(!nc->AMflag){
nc->tcache.AMflag = tigetflag("am") == 1;
if(!nc->tcache.AMflag){
fprintf(stderr, "Required terminfo capability 'am' not defined\n");
return -1;
}
term_verify_seq(&nc->civis, "civis");
term_verify_seq(&nc->cnorm, "cnorm");
term_verify_seq(&nc->standout, "smso"); // smso / rmso
term_verify_seq(&nc->uline, "smul");
term_verify_seq(&nc->reverse, "reverse");
term_verify_seq(&nc->blink, "blink");
term_verify_seq(&nc->dim, "dim");
term_verify_seq(&nc->bold, "bold");
term_verify_seq(&nc->italics, "sitm");
term_verify_seq(&nc->italoff, "ritm");
term_verify_seq(&nc->sgr, "sgr");
term_verify_seq(&nc->sgr0, "sgr0");
term_verify_seq(&nc->op, "op");
term_verify_seq(&nc->oc, "oc");
term_verify_seq(&nc->home, "home");
term_verify_seq(&nc->clearscr, "clear");
term_verify_seq(&nc->cleareol, "el");
term_verify_seq(&nc->clearbol, "el1");
term_verify_seq(&nc->cuf, "cuf"); // n non-destructive spaces
term_verify_seq(&nc->cub, "cub"); // n non-destructive backspaces
term_verify_seq(&nc->cuf1, "cuf1"); // non-destructive space
term_verify_seq(&nc->cub1, "cub1"); // non-destructive backspace
term_verify_seq(&nc->smkx, "smkx"); // set application mode
if(nc->smkx){
if(putp(tiparm(nc->smkx)) != OK){
term_verify_seq(&nc->tcache.civis, "civis");
term_verify_seq(&nc->tcache.cnorm, "cnorm");
term_verify_seq(&nc->tcache.standout, "smso"); // smso / rmso
term_verify_seq(&nc->tcache.uline, "smul");
term_verify_seq(&nc->tcache.reverse, "reverse");
term_verify_seq(&nc->tcache.blink, "blink");
term_verify_seq(&nc->tcache.dim, "dim");
term_verify_seq(&nc->tcache.bold, "bold");
term_verify_seq(&nc->tcache.italics, "sitm");
term_verify_seq(&nc->tcache.italoff, "ritm");
term_verify_seq(&nc->tcache.sgr, "sgr");
term_verify_seq(&nc->tcache.sgr0, "sgr0");
term_verify_seq(&nc->tcache.op, "op");
term_verify_seq(&nc->tcache.oc, "oc");
term_verify_seq(&nc->tcache.home, "home");
term_verify_seq(&nc->tcache.clearscr, "clear");
term_verify_seq(&nc->tcache.cleareol, "el");
term_verify_seq(&nc->tcache.clearbol, "el1");
term_verify_seq(&nc->tcache.cuf, "cuf"); // n non-destructive spaces
term_verify_seq(&nc->tcache.cub, "cub"); // n non-destructive backspaces
term_verify_seq(&nc->tcache.cuf1, "cuf1"); // non-destructive space
term_verify_seq(&nc->tcache.cub1, "cub1"); // non-destructive backspace
term_verify_seq(&nc->tcache.smkx, "smkx"); // set application mode
if(nc->tcache.smkx){
if(putp(tiparm(nc->tcache.smkx)) != OK){
fprintf(stderr, "Error entering application mode\n");
return -1;
}
@ -622,39 +622,39 @@ interrogate_terminfo(notcurses* nc, const notcurses_options* opts, int* dimy, in
int nocolor_stylemask = tigetnum("ncv");
if(nocolor_stylemask > 0){
if(nocolor_stylemask & WA_STANDOUT){ // ncv is composed of terminfo bits, not ours
nc->standout = NULL;
nc->tcache.standout = NULL;
}
if(nocolor_stylemask & WA_UNDERLINE){
nc->uline = NULL;
nc->tcache.uline = NULL;
}
if(nocolor_stylemask & WA_REVERSE){
nc->reverse = NULL;
nc->tcache.reverse = NULL;
}
if(nocolor_stylemask & WA_BLINK){
nc->blink = NULL;
nc->tcache.blink = NULL;
}
if(nocolor_stylemask & WA_DIM){
nc->dim = NULL;
nc->tcache.dim = NULL;
}
if(nocolor_stylemask & WA_BOLD){
nc->bold = NULL;
nc->tcache.bold = NULL;
}
if(nocolor_stylemask & WA_ITALIC){
nc->italics = NULL;
nc->tcache.italics = NULL;
}
}
term_verify_seq(&nc->getm, "getm"); // get mouse events
term_verify_seq(&nc->tcache.getm, "getm"); // get mouse events
// Not all terminals support setting the fore/background independently
term_verify_seq(&nc->setaf, "setaf");
term_verify_seq(&nc->setab, "setab");
term_verify_seq(&nc->smkx, "smkx");
term_verify_seq(&nc->rmkx, "rmkx");
term_verify_seq(&nc->tcache.setaf, "setaf");
term_verify_seq(&nc->tcache.setab, "setab");
term_verify_seq(&nc->tcache.smkx, "smkx");
term_verify_seq(&nc->tcache.rmkx, "rmkx");
// Neither of these is supported on e.g. the "linux" virtual console.
if(!opts->inhibit_alternate_screen){
term_verify_seq(&nc->smcup, "smcup");
term_verify_seq(&nc->rmcup, "rmcup");
term_verify_seq(&nc->tcache.smcup, "smcup");
term_verify_seq(&nc->tcache.rmcup, "rmcup");
}else{
nc->smcup = nc->rmcup = NULL;
nc->tcache.smcup = nc->tcache.rmcup = NULL;
}
nc->top = nc->stdscr = NULL;
return 0;
@ -769,42 +769,42 @@ ncdirect* ncdirect_init(const char* termtype, FILE* outfp){
free(ret);
return NULL;
}
term_verify_seq(&ret->standout, "smso"); // smso / rmso
term_verify_seq(&ret->uline, "smul");
term_verify_seq(&ret->reverse, "reverse");
term_verify_seq(&ret->blink, "blink");
term_verify_seq(&ret->dim, "dim");
term_verify_seq(&ret->bold, "bold");
term_verify_seq(&ret->italics, "sitm");
term_verify_seq(&ret->italoff, "ritm");
term_verify_seq(&ret->sgr, "sgr");
term_verify_seq(&ret->sgr0, "sgr0");
term_verify_seq(&ret->op, "op");
term_verify_seq(&ret->oc, "oc");
term_verify_seq(&ret->setaf, "setaf");
term_verify_seq(&ret->setab, "setab");
term_verify_seq(&ret->clear, "clear");
term_verify_seq(&ret->cup, "cup");
term_verify_seq(&ret->cuu, "cuu"); // move N up
term_verify_seq(&ret->cuf, "cuf"); // move N right
term_verify_seq(&ret->cud, "cud"); // move N down
term_verify_seq(&ret->cub, "cub"); // move N left
term_verify_seq(&ret->hpa, "hpa");
term_verify_seq(&ret->vpa, "vpa");
term_verify_seq(&ret->civis, "civis");
term_verify_seq(&ret->cnorm, "cnorm");
ret->RGBflag = query_rgb();
if((ret->colors = tigetnum("colors")) <= 0){
ret->colors = 1;
ret->CCCflag = false;
ret->RGBflag = false;
ret->initc = NULL;
term_verify_seq(&ret->tcache.standout, "smso"); // smso / rmso
term_verify_seq(&ret->tcache.uline, "smul");
term_verify_seq(&ret->tcache.reverse, "reverse");
term_verify_seq(&ret->tcache.blink, "blink");
term_verify_seq(&ret->tcache.dim, "dim");
term_verify_seq(&ret->tcache.bold, "bold");
term_verify_seq(&ret->tcache.italics, "sitm");
term_verify_seq(&ret->tcache.italoff, "ritm");
term_verify_seq(&ret->tcache.sgr, "sgr");
term_verify_seq(&ret->tcache.sgr0, "sgr0");
term_verify_seq(&ret->tcache.op, "op");
term_verify_seq(&ret->tcache.oc, "oc");
term_verify_seq(&ret->tcache.setaf, "setaf");
term_verify_seq(&ret->tcache.setab, "setab");
term_verify_seq(&ret->tcache.clear, "clear");
term_verify_seq(&ret->tcache.cup, "cup");
term_verify_seq(&ret->tcache.cuu, "cuu"); // move N up
term_verify_seq(&ret->tcache.cuf, "cuf"); // move N right
term_verify_seq(&ret->tcache.cud, "cud"); // move N down
term_verify_seq(&ret->tcache.cub, "cub"); // move N left
term_verify_seq(&ret->tcache.hpa, "hpa");
term_verify_seq(&ret->tcache.vpa, "vpa");
term_verify_seq(&ret->tcache.civis, "civis");
term_verify_seq(&ret->tcache.cnorm, "cnorm");
ret->tcache.RGBflag = query_rgb();
if((ret->tcache.colors = tigetnum("colors")) <= 0){
ret->tcache.colors = 1;
ret->tcache.CCCflag = false;
ret->tcache.RGBflag = false;
ret->tcache.initc = NULL;
}else{
term_verify_seq(&ret->initc, "initc");
if(ret->initc){
ret->CCCflag = tigetflag("ccc") == 1;
term_verify_seq(&ret->tcache.initc, "initc");
if(ret->tcache.initc){
ret->tcache.CCCflag = tigetflag("ccc") == 1;
}else{
ret->CCCflag = false;
ret->tcache.CCCflag = false;
}
}
ret->fgdefault = ret->bgdefault = true;
@ -819,15 +819,15 @@ static void
init_banner(const notcurses* nc){
if(!nc->suppress_banner){
char prefixbuf[BPREFIXSTRLEN + 1];
term_fg_palindex(nc, nc->ttyfp, nc->colors <= 256 ? 50 % nc->colors : 0x20e080);
term_fg_palindex(nc, nc->ttyfp, nc->tcache.colors <= 256 ? 50 % nc->tcache.colors : 0x20e080);
printf("\n notcurses %s by nick black et al", notcurses_version());
term_fg_palindex(nc, nc->ttyfp, nc->colors <= 256 ? 12 % nc->colors : 0x2080e0);
term_fg_palindex(nc, nc->ttyfp, nc->tcache.colors <= 256 ? 12 % nc->tcache.colors : 0x2080e0);
printf("\n %d rows, %d columns (%sB), %d colors (%s)\n"
" compiled with gcc-%s\n"
" terminfo from %s\n",
nc->stdscr->leny, nc->stdscr->lenx,
bprefix(nc->stats.fbbytes, 1, prefixbuf, 0),
nc->colors, nc->RGBflag ? "direct" : "palette",
nc->tcache.colors, nc->tcache.RGBflag ? "direct" : "palette",
__VERSION__, curses_version());
#ifdef USE_FFMPEG
printf(" avformat %u.%u.%u\n avutil %u.%u.%u\n swscale %u.%u.%u\n",
@ -838,17 +838,17 @@ init_banner(const notcurses* nc){
#ifdef USE_OIIO
printf(" openimageio %s\n", oiio_version());
#else
term_fg_palindex(nc, nc->ttyfp, nc->colors <= 88 ? 1 % nc->colors : 0xcb);
term_fg_palindex(nc, nc->ttyfp, nc->tcache.colors <= 88 ? 1 % nc->tcache.colors : 0xcb);
fprintf(stderr, "\n Warning! Notcurses was built without multimedia support.\n");
#endif
#endif
fflush(stdout);
term_fg_palindex(nc, nc->ttyfp, nc->colors <= 88 ? 1 % nc->colors : 0xcb);
if(!nc->RGBflag){ // FIXME
term_fg_palindex(nc, nc->ttyfp, nc->tcache.colors <= 88 ? 1 % nc->tcache.colors : 0xcb);
if(!nc->tcache.RGBflag){ // FIXME
fprintf(stderr, "\n Warning! Colors subject to https://github.com/dankamongmen/notcurses/issues/4");
fprintf(stderr, "\n Specify a (correct) TrueColor TERM, or COLORTERM=24bit.\n");
}else{
if(!nc->CCCflag){
if(!nc->tcache.CCCflag){
fprintf(stderr, "\n Warning! Advertised TrueColor but no 'ccc' flag\n");
}
}
@ -998,12 +998,12 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
goto err;
}
if(!opts->retain_cursor){
if(ret->civis && term_emit("civis", ret->civis, ret->ttyfp, false)){
if(ret->tcache.civis && term_emit("civis", ret->tcache.civis, ret->ttyfp, false)){
free_plane(ret->top);
goto err;
}
}
if(ret->smkx && term_emit("smkx", ret->smkx, ret->ttyfp, false)){
if(ret->tcache.smkx && term_emit("smkx", ret->tcache.smkx, ret->ttyfp, false)){
free_plane(ret->top);
goto err;
}
@ -1014,7 +1014,7 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
ret->suppress_banner = opts->suppress_banner;
init_banner(ret);
// flush on the switch to alternate screen, lest initial output be swept away
if(ret->smcup && term_emit("smcup", ret->smcup, ret->ttyfp, true)){
if(ret->tcache.smcup && term_emit("smcup", ret->tcache.smcup, ret->ttyfp, true)){
free_plane(ret->top);
goto err;
}
@ -1465,18 +1465,18 @@ int cell_load(ncplane* n, cell* c, const char* gcluster){
unsigned notcurses_supported_styles(const notcurses* nc){
unsigned styles = 0;
styles |= nc->standout ? NCSTYLE_STANDOUT : 0;
styles |= nc->uline ? NCSTYLE_UNDERLINE : 0;
styles |= nc->reverse ? NCSTYLE_REVERSE : 0;
styles |= nc->blink ? NCSTYLE_BLINK : 0;
styles |= nc->dim ? NCSTYLE_DIM : 0;
styles |= nc->bold ? NCSTYLE_BOLD : 0;
styles |= nc->italics ? NCSTYLE_ITALIC : 0;
styles |= nc->tcache.standout ? NCSTYLE_STANDOUT : 0;
styles |= nc->tcache.uline ? NCSTYLE_UNDERLINE : 0;
styles |= nc->tcache.reverse ? NCSTYLE_REVERSE : 0;
styles |= nc->tcache.blink ? NCSTYLE_BLINK : 0;
styles |= nc->tcache.dim ? NCSTYLE_DIM : 0;
styles |= nc->tcache.bold ? NCSTYLE_BOLD : 0;
styles |= nc->tcache.italics ? NCSTYLE_ITALIC : 0;
return styles;
}
int notcurses_palette_size(const notcurses* nc){
return nc->colors;
return nc->tcache.colors;
}
// turn on any specified stylebits
@ -1841,14 +1841,14 @@ void ncplane_erase(ncplane* n){
}
void notcurses_cursor_enable(notcurses* nc){
if(nc->cnorm){
term_emit("cnorm", nc->cnorm, nc->ttyfp, false);
if(nc->tcache.cnorm){
term_emit("cnorm", nc->tcache.cnorm, nc->ttyfp, false);
}
}
void notcurses_cursor_disable(notcurses* nc){
if(nc->civis){
term_emit("civis", nc->civis, nc->ttyfp, false);
if(nc->tcache.civis){
term_emit("civis", nc->tcache.civis, nc->ttyfp, false);
}
}
@ -1883,15 +1883,15 @@ bool notcurses_canutf8(const notcurses* nc){
}
bool notcurses_canfade(const notcurses* nc){
return nc->CCCflag || nc->RGBflag;
return nc->tcache.CCCflag || nc->tcache.RGBflag;
}
bool notcurses_canchangecolor(const notcurses* nc){
if(!nc->CCCflag){
if(!nc->tcache.CCCflag){
return false;
}
palette256* p;
if((unsigned)nc->colors < sizeof(p->chans) / sizeof(*p->chans)){
if((unsigned)nc->tcache.colors < sizeof(p->chans) / sizeof(*p->chans)){
return false;
}
return true;

View File

@ -707,32 +707,35 @@ ncdirect_style_emit(ncdirect* n, const char* sgr, unsigned stylebits, FILE* out)
int ncdirect_styles_on(ncdirect* n, unsigned stylebits){
n->attrword |= stylebits;
if(ncdirect_style_emit(n, n->sgr, n->attrword, n->ttyfp)){
if(ncdirect_style_emit(n, n->tcache.sgr, n->attrword, n->ttyfp)){
return 0;
}
return term_setstyle(n->ttyfp, n->attrword, stylebits, NCSTYLE_ITALIC, n->italics, n->italoff);
return term_setstyle(n->ttyfp, n->attrword, stylebits, NCSTYLE_ITALIC,
n->tcache.italics, n->tcache.italoff);
}
// turn off any specified stylebits
int ncdirect_styles_off(ncdirect* n, unsigned stylebits){
n->attrword &= ~stylebits;
if(ncdirect_style_emit(n, n->sgr, n->attrword, n->ttyfp)){
if(ncdirect_style_emit(n, n->tcache.sgr, n->attrword, n->ttyfp)){
return 0;
}
return term_setstyle(n->ttyfp, n->attrword, stylebits, NCSTYLE_ITALIC, n->italics, n->italoff);
return term_setstyle(n->ttyfp, n->attrword, stylebits, NCSTYLE_ITALIC,
n->tcache.italics, n->tcache.italoff);
}
// set the current stylebits to exactly those provided
int ncdirect_styles_set(ncdirect* n, unsigned stylebits){
n->attrword = stylebits;
if(ncdirect_style_emit(n, n->sgr, n->attrword, n->ttyfp)){
if(ncdirect_style_emit(n, n->tcache.sgr, n->attrword, n->ttyfp)){
return 0;
}
return term_setstyle(n->ttyfp, n->attrword, stylebits, NCSTYLE_ITALIC, n->italics, n->italoff);
return term_setstyle(n->ttyfp, n->attrword, stylebits, NCSTYLE_ITALIC,
n->tcache.italics, n->tcache.italoff);
}
int ncdirect_fg_default(ncdirect* nc){
if(term_emit("op", nc->op, nc->ttyfp, false) == 0){
if(term_emit("op", nc->tcache.op, nc->ttyfp, false) == 0){
nc->fgdefault = true;
if(nc->bgdefault){
return 0;
@ -743,7 +746,7 @@ int ncdirect_fg_default(ncdirect* nc){
}
int ncdirect_bg_default(ncdirect* nc){
if(term_emit("op", nc->op, nc->ttyfp, false) == 0){
if(term_emit("op", nc->tcache.op, nc->ttyfp, false) == 0){
nc->bgdefault = true;
if(nc->fgdefault){
return 0;
@ -757,7 +760,7 @@ int ncdirect_bg(ncdirect* nc, unsigned rgb){
if(rgb > 0xffffffu){
return -1;
}
if(term_bg_rgb8(nc->RGBflag, nc->setab, nc->colors, nc->ttyfp,
if(term_bg_rgb8(nc->tcache.RGBflag, nc->tcache.setab, nc->tcache.colors, nc->ttyfp,
(rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu)){
return -1;
}
@ -770,7 +773,7 @@ int ncdirect_fg(ncdirect* nc, unsigned rgb){
if(rgb > 0xffffffu){
return -1;
}
if(term_fg_rgb8(nc->RGBflag, nc->setaf, nc->colors, nc->ttyfp,
if(term_fg_rgb8(nc->tcache.RGBflag, nc->tcache.setaf, nc->tcache.colors, nc->ttyfp,
(rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu)){
return -1;
}
@ -781,7 +784,7 @@ int ncdirect_fg(ncdirect* nc, unsigned rgb){
static inline int
update_palette(notcurses* nc, FILE* out){
if(nc->CCCflag){
if(nc->tcache.CCCflag){
for(size_t damageidx = 0 ; damageidx < sizeof(nc->palette.chans) / sizeof(*nc->palette.chans) ; ++damageidx){
unsigned r, g, b;
if(nc->palette_damage[damageidx]){
@ -791,7 +794,7 @@ update_palette(notcurses* nc, FILE* out){
r = r * 1000 / 255;
g = g * 1000 / 255;
b = b * 1000 / 255;
term_emit("initc", tiparm(nc->initc, damageidx, r, g, b), out, false);
term_emit("initc", tiparm(nc->tcache.initc, damageidx, r, g, b), out, false);
nc->palette_damage[damageidx] = false;
}
}
@ -810,9 +813,9 @@ stage_cursor(notcurses* nc, FILE* out, int y, int x){
const int xdiff = x - nc->rstate.x;
if(xdiff > 0){
if(xdiff == 1){
ret = term_emit("cuf1", tiparm(nc->cuf1), out, false);
ret = term_emit("cuf1", tiparm(nc->tcache.cuf1), out, false);
}else{
ret = term_emit("cuf", tiparm(nc->cuf, xdiff), out, false);
ret = term_emit("cuf", tiparm(nc->tcache.cuf, xdiff), out, false);
}
nc->rstate.x = x;
return ret;
@ -821,7 +824,7 @@ stage_cursor(notcurses* nc, FILE* out, int y, int x){
}
// cub1/cub tend to be destructive in my experiments :/
}
ret = term_emit("cup", tiparm(nc->cup, y, x), out, false);
ret = term_emit("cup", tiparm(nc->tcache.cup, y, x), out, false);
if(ret == 0){
nc->rstate.x = x;
nc->rstate.y = y;
@ -879,7 +882,8 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec){
// does, we need update our elision possibilities.
bool normalized;
ret |= term_setstyles(out, &nc->rstate.curattr, srccell, &normalized,
nc->sgr0, nc->sgr, nc->italics, nc->italoff);
nc->tcache.sgr0, nc->tcache.sgr,
nc->tcache.italics, nc->tcache.italoff);
if(normalized){
nc->rstate.defaultelidable = true;
nc->rstate.bgelidable = false;
@ -902,7 +906,7 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec){
if((!noforeground && cell_fg_default_p(srccell)) || (!nobackground && cell_bg_default_p(srccell))){
if(!nc->rstate.defaultelidable){
++nc->stats.defaultemissions;
ret |= term_emit("op", nc->op, out, false);
ret |= term_emit("op", nc->tcache.op, out, false);
}else{
++nc->stats.defaultelisions;
}
@ -937,7 +941,7 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec){
if(nc->rstate.fgelidable && nc->rstate.lastr == r && nc->rstate.lastg == g && nc->rstate.lastb == b){
++nc->stats.fgelisions;
}else{
ret |= term_fg_rgb8(nc->RGBflag, nc->setaf, nc->colors, out, r, g, b);
ret |= term_fg_rgb8(nc->tcache.RGBflag, nc->tcache.setaf, nc->tcache.colors, out, r, g, b);
++nc->stats.fgemissions;
nc->rstate.fgelidable = true;
}
@ -965,7 +969,7 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec){
if(nc->rstate.bgelidable && nc->rstate.lastbr == br && nc->rstate.lastbg == bg && nc->rstate.lastbb == bb){
++nc->stats.bgelisions;
}else{
ret |= term_bg_rgb8(nc->RGBflag, nc->setab, nc->colors, out, br, bg, bb);
ret |= term_bg_rgb8(nc->tcache.RGBflag, nc->tcache.setab, nc->tcache.colors, out, br, bg, bb);
++nc->stats.bgemissions;
nc->rstate.bgelidable = true;
}
@ -1018,12 +1022,12 @@ fprintf(stderr, "RAST %u [%s] to %d/%d\n", srccell->gcluster, egcpool_extended_g
static int
home_cursor(notcurses* nc, bool flush){
int ret = -1;
if(nc->home){
ret = term_emit("home", nc->home, nc->ttyfp, flush);
}else if(nc->cup){
ret = term_emit("cup", tiparm(nc->cup, 1, 1), nc->ttyfp, flush);
}else if(nc->clearscr){
ret = term_emit("clear", nc->clearscr, nc->ttyfp, flush);
if(nc->tcache.home){
ret = term_emit("home", nc->tcache.home, nc->ttyfp, flush);
}else if(nc->tcache.cup){
ret = term_emit("cup", tiparm(nc->tcache.cup, 1, 1), nc->ttyfp, flush);
}else if(nc->tcache.clearscr){
ret = term_emit("clear", nc->tcache.clearscr, nc->ttyfp, flush);
}
if(ret >= 0){
nc->rstate.x = 0;