diff --git a/NEWS.md b/NEWS.md index 44a4d3a88..c45a3fe72 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,7 +8,7 @@ rearrangements of Notcurses. and `ncplane_autogrow_p()` functions. When autogrow is enabled, the plane is automatically enlarged to accommodate output at its right (no scrolling) or bottom (scrolling enabled) boundaries. - * Added the new function `notcurses_default_background()`. + * Added `notcurses_default_background()` and `notcurses_default_foreground()`. * 3.0.0 (2021-12-01) **"In the A"** * Made the ABI/API changes that have been planned/collected during 2.x diff --git a/USAGE.md b/USAGE.md index 6bf6c2d10..cc2ad68d5 100644 --- a/USAGE.md +++ b/USAGE.md @@ -293,6 +293,11 @@ notcurses_term_dim_yx(const struct notcurses* n, unsigned* restrict rows, // current screen geometry is returned in 'y' and 'x', if they are not NULL. int notcurses_refresh(struct notcurses* n, unsigned* restrict y, unsigned* restrict x); +// Get the default foreground color, if it is known. Returns -1 on error +// (unknown foreground). On success, returns 0, writing the RGB value to +// 'fg' (if non-NULL) +int notcurses_default_foreground(const struct notcurses* nc, uint32_t* fg); + // Get the default background color, if it is known. Returns -1 on error // (unknown background). On success, returns 0, writing the RGB value to // 'bg' (if non-NULL) and setting 'bgtrans' high iff the background color diff --git a/doc/man/man3/notcurses_init.3.md b/doc/man/man3/notcurses_init.3.md index e82464a13..a74240cae 100644 --- a/doc/man/man3/notcurses_init.3.md +++ b/doc/man/man3/notcurses_init.3.md @@ -53,6 +53,8 @@ typedef struct notcurses_options { **int notcurses_lex_margins(const char* ***op***, notcurses_options* ***opts***);** +**int notcurses_default_foreground(const struct notcurses* ***nc***, uint32_t* ***fg***);** + **int notcurses_default_background(const struct notcurses* ***nc***, uint32_t* ***bg***, unsigned* ***bgtrans***);** # DESCRIPTION @@ -168,8 +170,10 @@ zero. The following flags are defined: eventually prevent Notcurses from processing messages from the terminal. It will furthermore avoid wasting time processing useless input. -**notcurses_default_background** returns the default background color, and -whether the terminal treats it as transparent, if this could be detected. +**notcurses_default_foreground** returns the default foreground color, if it +could be detected. **notcurses_default_background** returns the default +background color, and whether the terminal treats it as transparent, if this +could be detected. ## Fatal signals @@ -250,6 +254,9 @@ rendered mode to be used as a normal scrolling shell application. **notcurses_cursor_disable** returns -1 if the cursor is already invisible. +**notcurses_default_foreground** returns -1 if the default foreground color +could not be detected. + **notcurses_default_background** returns -1 if the default background color could not be detected. diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index cda67867b..f288998dc 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -3629,6 +3629,12 @@ ncbprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ return ncnmetric(val, NCBPREFIXSTRLEN + 1, decimal, buf, omitdec, 1024, 'i'); } +// Get the default foreground color, if it is known. Returns -1 on error +// (unknown foreground). On success, returns 0, writing the RGB value to +// 'fg' (if non-NULL) +API int notcurses_default_foreground(const struct notcurses* nc, uint32_t* fg) + __attribute__ ((nonnull (1))); + // Get the default background color, if it is known. Returns -1 on error // (unknown background). On success, returns 0, writing the RGB value to // 'bg' (if non-NULL) and setting 'bgtrans' high iff the background color diff --git a/src/info/main.c b/src/info/main.c index fa3fa34c3..4185b2718 100644 --- a/src/info/main.c +++ b/src/info/main.c @@ -369,18 +369,23 @@ display_logo(struct ncplane* n, const char* path){ static void tinfo_debug_bitmaps(struct ncplane* n, const tinfo* ti, const char* indent){ + uint32_t fg = 0; + int r = notcurses_default_foreground(ncplane_notcurses(n), &fg); + if(r){ + ncplane_printf(n, "%sno known default fg ", indent); + }else{ + ncplane_printf(n, "%sdefault fg 0x%06x ", indent, fg); + } unsigned bgtrans = 0; uint32_t bg = 0; - int r = notcurses_default_background(ncplane_notcurses(n), &bg, &bgtrans); + r = notcurses_default_background(ncplane_notcurses(n), &bg, &bgtrans); if(r){ - ncplane_printf(n, "couldn't detect default background"); + ncplane_printf(n, "no known default fg"); }else{ if(bgtrans){ - ncplane_printf(n, "%sdefault background 0x%06lx considered transparent", indent, - ti->bg_collides_default & 0xfffffful); + ncplane_printf(n, "default bg 0x%06x (trans)", bg); }else{ - ncplane_printf(n, "%sdefault background 0x%06lx", indent, - ti->bg_collides_default & 0xfffffful); + ncplane_printf(n, "default bg 0x%06x", bg); } } finish_line(n); diff --git a/src/lib/render.c b/src/lib/render.c index a61eb3941..5550fd6ab 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -1726,6 +1726,16 @@ int ncdirect_set_fg_rgb(ncdirect* nc, unsigned rgb){ return 0; } +int notcurses_default_foreground(const struct notcurses* nc, uint32_t* fg){ + const tinfo* ti = &nc->tcache; + if(ti->fg_default & 0x80000000){ + logerror("default foreground could not be determined\n"); + return -1; + } + *fg = ti->fg_default & NC_BG_RGB_MASK; + return 0; +} + int notcurses_default_background(const struct notcurses* nc, uint32_t* bg, unsigned* bgtrans){ const tinfo* ti = &nc->tcache; diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 3a6d9feeb..5ca82f1b2 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -857,6 +857,7 @@ int interrogate_terminfo(tinfo* ti, FILE* out, unsigned utf8, } *cursor_x = *cursor_y = -1; ti->bg_collides_default = 0xfe000000; + ti->fg_default = 0xff000000; ti->kbdlevel = UINT_MAX; // see comment in tinfo definition ti->qterm = TERMINAL_UNKNOWN; // we don't need a controlling tty for everything we do; allow a failure here @@ -1109,6 +1110,9 @@ int interrogate_terminfo(tinfo* ti, FILE* out, unsigned utf8, // kitty, we'll add the 0x01000000 in during heuristics. ti->bg_collides_default = iresp->bg; } + if(iresp->got_fg){ + ti->fg_default = iresp->fg; + } // kitty trumps sixel, when both are available if((kitty_graphics = iresp->kitty_graphics) == 0){ ti->color_registers = iresp->color_registers; diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index cc0c326cf..67f0cfb05 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -123,6 +123,9 @@ typedef struct tinfo { // 0xfexxxxxxx (unknown), 0x00RRGGBB (no collide), or 0x01RRGGBB (collides). uint32_t bg_collides_default; + // 0xffxxxxxxx (unknown), or 0x00RRGGBB (foreground) + uint32_t fg_default; + // bitmap support. if we support bitmaps, pixel_implementation will be a // value other than NCPIXEL_NONE. ncpixelimpl_e pixel_implementation;