diff --git a/src/lib/debug.c b/src/lib/debug.c index 7133b1472..a412a8262 100644 --- a/src/lib/debug.c +++ b/src/lib/debug.c @@ -15,7 +15,9 @@ tinfo_debug_caps(const tinfo* ti, FILE* debugfp, int rows, int cols, unsigned images, unsigned videos){ const char indent[] = " "; fprintf(debugfp, "%sColors: %u rgb: %c ccc: %c setaf: %c setab: %c\n", - indent, ti->colors, capbool(ti->RGBflag), capbool(ti->CCCflag), capyn(ti->setaf), capyn(ti->setab)); + indent, ti->colors, capbool(ti->RGBflag), capbool(ti->CCCflag), + capyn(get_escape(ti, ESCAPE_SETAF)), + capyn(get_escape(ti, ESCAPE_SETAB))); fprintf(debugfp, "%ssgr: %c sgr0: %c\n", indent, capyn(ti->sgr), capyn(ti->sgr0)); fprintf(debugfp, "%sop: %c fgop: %c bgop: %c\n", diff --git a/src/lib/direct.c b/src/lib/direct.c index 17bdea348..436a11c2a 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -647,17 +647,25 @@ int ncdirect_render_image(ncdirect* n, const char* file, ncalign_e align, } int ncdirect_set_fg_palindex(ncdirect* nc, int pidx){ + const char* setaf = get_escape(&nc->tcache, ESCAPE_SETAF); + if(!setaf){ + return -1; + } if(ncchannels_set_fg_palindex(&nc->channels, pidx) < 0){ return -1; } - return term_emit(tiparm(nc->tcache.setaf, pidx), nc->ttyfp, false); + return term_emit(tiparm(setaf, pidx), nc->ttyfp, false); } int ncdirect_set_bg_palindex(ncdirect* nc, int pidx){ + const char* setab = get_escape(&nc->tcache, ESCAPE_SETAB); + if(!setab){ + return -1; + } if(ncchannels_set_bg_palindex(&nc->channels, pidx) < 0){ return -1; } - return term_emit(tiparm(nc->tcache.setab, pidx), nc->ttyfp, false); + return term_emit(tiparm(setab, pidx), nc->ttyfp, false); } int ncdirect_vprintf_aligned(ncdirect* n, int y, ncalign_e align, const char* fmt, va_list ap){ diff --git a/src/lib/internal.h b/src/lib/internal.h index cf0462ab0..dec996802 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -803,18 +803,20 @@ term_emit(const char* seq, FILE* out, bool flush){ static inline int term_bg_palindex(const notcurses* nc, FILE* out, unsigned pal){ - if(nc->tcache.setab == NULL){ - return 0; + const char* setab = get_escape(&nc->tcache, ESCAPE_SETAB); + if(setab){ + return term_emit(tiparm(setab, pal), out, false); } - return term_emit(tiparm(nc->tcache.setab, pal), out, false); + return 0; } static inline int term_fg_palindex(const notcurses* nc, FILE* out, unsigned pal){ - if(nc->tcache.setaf == NULL){ - return 0; + const char* setaf = get_escape(&nc->tcache, ESCAPE_SETAF); + if(setaf){ + return term_emit(tiparm(setaf, pal), out, false); } - return term_emit(tiparm(nc->tcache.setaf, pal), out, false); + return 0; } static inline const char* @@ -1578,8 +1580,7 @@ ncdirect_bg_default_p(const struct ncdirect* nc){ return ncchannels_bg_default_p(ncdirect_channels(nc)); } -int term_fg_rgb8(bool RGBflag, const char* setaf, int colors, FILE* out, - unsigned r, unsigned g, unsigned b); +int term_fg_rgb8(const tinfo* ti, FILE* out, unsigned r, unsigned g, unsigned b); const struct blitset* lookup_blitset(const tinfo* tcache, ncblitter_e setid, bool may_degrade); diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 1512a34f6..4f9e2f8da 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -841,13 +841,14 @@ init_banner(const notcurses* nc, const char* shortname_term){ bprefix(nc->stats.fbbytes, 1, prefixbuf, 0), sizeof(struct crender), nc->tcache.colors); } - if(nc->tcache.RGBflag){ + const char* setaf; + if(nc->tcache.RGBflag && (setaf = get_escape(&nc->tcache, ESCAPE_SETAF))){ putc('+', stdout); - term_fg_rgb8(true, nc->tcache.setaf, nc->tcache.colors, stdout, 0xe0, 0x60, 0x60); + term_fg_rgb8(&nc->tcache, stdout, 0xe0, 0x60, 0x60); putc('R', stdout); - term_fg_rgb8(true, nc->tcache.setaf, nc->tcache.colors, stdout, 0x60, 0xe0, 0x60); + term_fg_rgb8(&nc->tcache, stdout, 0x60, 0xe0, 0x60); putc('G', stdout); - term_fg_rgb8(true, nc->tcache.setaf, nc->tcache.colors, stdout, 0x20, 0x80, 0xff); + term_fg_rgb8(&nc->tcache, stdout, 0x20, 0x80, 0xff); putc('B', stdout); term_fg_palindex(nc, stdout, nc->tcache.colors <= 256 ? 12 % nc->tcache.colors : 0x2080e0); } diff --git a/src/lib/render.c b/src/lib/render.c index 3efc632f5..4466c2967 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -718,60 +718,58 @@ term_esc_rgb(FILE* out, bool foreground, unsigned r, unsigned g, unsigned b){ } static inline int -term_bg_rgb8(bool RGBflag, const char* setab, int colors, FILE* out, - unsigned r, unsigned g, unsigned b, uint32_t bg_collides_default){ +term_bg_rgb8(const tinfo* ti, FILE* out, unsigned r, unsigned g, unsigned b){ // We typically want to use tputs() and tiperm() to acquire and write the // escapes, as these take into account terminal-specific delays, padding, // etc. For the case of DirectColor, there is no suitable terminfo entry, but // we're also in that case working with hopefully more robust terminals. // If it doesn't work, eh, it doesn't work. Fuck the world; save yourself. - if(RGBflag){ - if(bg_collides_default){ - if((r == (bg_collides_default & 0xff0000lu)) && - (g == (bg_collides_default & 0xff00lu)) && - (b == (bg_collides_default & 0xfflu))){ + if(ti->RGBflag){ + if(ti->bg_collides_default){ + if((r == (ti->bg_collides_default & 0xff0000lu)) && + (g == (ti->bg_collides_default & 0xff00lu)) && + (b == (ti->bg_collides_default & 0xfflu))){ ++b; // what if it's 255 FIXME } } return term_esc_rgb(out, false, r, g, b); }else{ - if(setab == NULL){ - return 0; - } - // For 256-color indexed mode, start constructing a palette based off - // the inputs *if we can change the palette*. If more than 256 are used on - // a single screen, start... combining close ones? For 8-color mode, simple - // interpolation. I have no idea what to do for 88 colors. FIXME - if(colors >= 256){ - return term_emit(tiparm(setab, rgb_quantize_256(r, g, b)), out, false); - }else if(colors >= 8){ - return term_emit(tiparm(setab, rgb_quantize_8(r, g, b)), out, false); + const char* setab = get_escape(ti, ESCAPE_SETAB); + if(setab){ + // For 256-color indexed mode, start constructing a palette based off + // the inputs *if we can change the palette*. If more than 256 are used on + // a single screen, start... combining close ones? For 8-color mode, simple + // interpolation. I have no idea what to do for 88 colors. FIXME + if(ti->colors >= 256){ + return term_emit(tiparm(setab, rgb_quantize_256(r, g, b)), out, false); + }else if(ti->colors >= 8){ + return term_emit(tiparm(setab, rgb_quantize_8(r, g, b)), out, false); + } } } return 0; } -int term_fg_rgb8(bool RGBflag, const char* setaf, int colors, FILE* out, - unsigned r, unsigned g, unsigned b){ +int term_fg_rgb8(const tinfo* ti, FILE* out, unsigned r, unsigned g, unsigned b){ // We typically want to use tputs() and tiperm() to acquire and write the // escapes, as these take into account terminal-specific delays, padding, // etc. For the case of DirectColor, there is no suitable terminfo entry, but // we're also in that case working with hopefully more robust terminals. // If it doesn't work, eh, it doesn't work. Fuck the world; save yourself. - if(RGBflag){ + if(ti->RGBflag){ return term_esc_rgb(out, true, r, g, b); }else{ - if(setaf == NULL){ - return 0; - } - // For 256-color indexed mode, start constructing a palette based off - // the inputs *if we can change the palette*. If more than 256 are used on - // a single screen, start... combining close ones? For 8-color mode, simple - // interpolation. I have no idea what to do for 88 colors. FIXME - if(colors >= 256){ - return term_emit(tiparm(setaf, rgb_quantize_256(r, g, b)), out, false); - }else if(colors >= 8){ - return term_emit(tiparm(setaf, rgb_quantize_8(r, g, b)), out, false); + const char* setaf = get_escape(ti, ESCAPE_SETAF); + if(setaf){ + // For 256-color indexed mode, start constructing a palette based off + // the inputs *if we can change the palette*. If more than 256 are used on + // a single screen, start... combining close ones? For 8-color mode, simple + // interpolation. I have no idea what to do for 88 colors. FIXME + if(ti->colors >= 256){ + return term_emit(tiparm(setaf, rgb_quantize_256(r, g, b)), out, false); + }else if(ti->colors >= 8){ + return term_emit(tiparm(setaf, rgb_quantize_8(r, g, b)), out, false); + } } } return 0; @@ -1044,7 +1042,7 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){ if(nc->rstate.fgelidable && nc->rstate.lastr == r && nc->rstate.lastg == g && nc->rstate.lastb == b){ ++nc->stats.fgelisions; }else{ - if(term_fg_rgb8(nc->tcache.RGBflag, nc->tcache.setaf, nc->tcache.colors, out, r, g, b)){ + if(term_fg_rgb8(&nc->tcache, out, r, g, b)){ return -1; } ++nc->stats.fgemissions; @@ -1069,9 +1067,7 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){ if(nc->rstate.bgelidable && nc->rstate.lastbr == br && nc->rstate.lastbg == bg && nc->rstate.lastbb == bb){ ++nc->stats.bgelisions; }else{ - if(term_bg_rgb8(nc->tcache.RGBflag, nc->tcache.setab, - nc->tcache.colors, out, br, bg, bb, - nc->tcache.bg_collides_default)){ + if(term_bg_rgb8(&nc->tcache, out, br, bg, bb)){ return -1; } ++nc->stats.bgemissions; @@ -1443,9 +1439,7 @@ int ncdirect_set_bg_rgb(ncdirect* nc, unsigned rgb){ if(!ncdirect_bg_default_p(nc) && ncchannels_bg_rgb(nc->channels) == rgb){ return 0; } - if(term_bg_rgb8(nc->tcache.RGBflag, nc->tcache.setab, nc->tcache.colors, nc->ttyfp, - (rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu, - nc->tcache.bg_collides_default)){ + if(term_bg_rgb8(&nc->tcache, nc->ttyfp, (rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu)){ return -1; } ncchannels_set_bg_rgb(&nc->channels, rgb); @@ -1460,8 +1454,7 @@ int ncdirect_set_fg_rgb(ncdirect* nc, unsigned rgb){ if(!ncdirect_fg_default_p(nc) && ncchannels_fg_rgb(nc->channels) == rgb){ return 0; } - if(term_fg_rgb8(nc->tcache.RGBflag, nc->tcache.setaf, nc->tcache.colors, nc->ttyfp, - (rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu)){ + if(term_fg_rgb8(&nc->tcache, nc->ttyfp, (rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu)){ return -1; } ncchannels_set_fg_rgb(&nc->channels, rgb); diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index ac63779cb..3e192483f 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -45,8 +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* setaf; // set foreground color (ANSI) - char* setab; // set background color (ANSI) char* op; // set foreground and background color to default char* sgr; // set many graphics properties at once unsigned colors;// number of colors terminfo reported usable for this screen diff --git a/src/lib/terminfo.c b/src/lib/terminfo.c index d6bfeb990..e1e630821 100644 --- a/src/lib/terminfo.c +++ b/src/lib/terminfo.c @@ -198,6 +198,9 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, { ESCAPE_CUP, "cup", }, { ESCAPE_HPA, "hpa", }, { ESCAPE_VPA, "vpa", }, + // Not all terminals support setting the fore/background independently + { ESCAPE_SETAF, "setaf", }, + { ESCAPE_SETAB, "setab", }, { ESCAPE_MAX, NULL, }, }; size_t tablelen = 0; @@ -283,9 +286,6 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, // can't do anything about struck! :/ } terminfostr(&ti->getm, "getm"); // get mouse events - // Not all terminals support setting the fore/background independently - terminfostr(&ti->setaf, "setaf"); // set forground color - terminfostr(&ti->setab, "setab"); // set background color terminfostr(&ti->smkx, "smkx"); // enable keypad transmit terminfostr(&ti->rmkx, "rmkx"); // disable keypad transmit terminfostr(&ti->struck, "smxx"); // strikeout