unify capabilites_canchangecolor #1768

This commit is contained in:
nick black 2021-06-17 18:01:23 -04:00 committed by Nick Black
parent 912c897e67
commit 0cfe426785
3 changed files with 64 additions and 58 deletions

View File

@ -430,7 +430,7 @@ ncdirect_cantruecolor(const struct ncdirect* nc){
// Can we set the "hardware" palette? Requires the "ccc" terminfo capability. // Can we set the "hardware" palette? Requires the "ccc" terminfo capability.
static inline bool static inline bool
ncdirect_canchangecolor(const struct ncdirect* nc){ ncdirect_canchangecolor(const struct ncdirect* nc){
return ncdirect_capabilities(nc)->can_change_colors; return nccapability_canchangecolor(ncdirect_capabilities(nc));
} }
// Can we fade? Fading requires either the "rgb" or "ccc" terminfo capability. // Can we fade? Fading requires either the "rgb" or "ccc" terminfo capability.

View File

@ -1235,8 +1235,53 @@ API bool ncplane_translate_abs(const struct ncplane* n, int* RESTRICT y, int* RE
// previously enabled, or false if it was disabled. // previously enabled, or false if it was disabled.
API bool ncplane_set_scrolling(struct ncplane* n, bool scrollp); API bool ncplane_set_scrolling(struct ncplane* n, bool scrollp);
// Capabilities // Palette API. Some terminals only support 256 colors, but allow the full
// terminal capabilities exported to the user // palette to be specified with arbitrary RGB colors. In all cases, it's more
// performant to use indexed colors, since it's much less data to write to the
// terminal. If you can limit yourself to 256 colors, that's probably best.
typedef struct ncpalette {
uint32_t chans[NCPALETTESIZE]; // RGB values as regular ol' channels
} ncpalette;
// Create a new palette store. It will be initialized with notcurses' best
// knowledge of the currently configured palette. The palette upon startup
// cannot be reliably detected, sadly.
API ALLOC ncpalette* ncpalette_new(struct notcurses* nc);
// Attempt to configure the terminal with the provided palette 'p'. Does not
// transfer ownership of 'p'; palette256_free() can (ought) still be called.
API int ncpalette_use(struct notcurses* nc, const ncpalette* p);
// Manipulate entries in the palette store 'p'. These are *not* locked.
static inline int
ncpalette_set_rgb8(ncpalette* p, int idx, int r, int g, int b){
if(idx < 0 || (size_t)idx > sizeof(p->chans) / sizeof(*p->chans)){
return -1;
}
return ncchannel_set_rgb8(&p->chans[idx], r, g, b);
}
static inline int
ncpalette_set(ncpalette* p, int idx, unsigned rgb){
if(idx < 0 || (size_t)idx > sizeof(p->chans) / sizeof(*p->chans)){
return -1;
}
return ncchannel_set(&p->chans[idx], rgb);
}
static inline int
ncpalette_get_rgb8(const ncpalette* p, int idx, unsigned* RESTRICT r, unsigned* RESTRICT g, unsigned* RESTRICT b){
if(idx < 0 || (size_t)idx > sizeof(p->chans) / sizeof(*p->chans)){
return -1;
}
return ncchannel_rgb8(p->chans[idx], r, g, b);
}
// Free the palette store 'p'.
API void ncpalette_free(ncpalette* p);
// Capabilities, derived from terminfo, environment variables, and queries
typedef struct nccapabilities { typedef struct nccapabilities {
unsigned colors; // size of palette for indexed colors unsigned colors; // size of palette for indexed colors
bool utf8; // are we using utf-8 encoding? from nl_langinfo(3) bool utf8; // are we using utf-8 encoding? from nl_langinfo(3)
@ -1272,7 +1317,21 @@ API bool notcurses_cantruecolor(const struct notcurses* nc)
API bool notcurses_canfade(const struct notcurses* nc) API bool notcurses_canfade(const struct notcurses* nc)
__attribute__ ((nonnull (1))); __attribute__ ((nonnull (1)));
// Can we set the "hardware" palette? Requires the "ccc" terminfo capability. // Can we set the "hardware" palette? Requires the "ccc" terminfo capability,
// and that the number of colors supported is at least the size of our
// ncpalette structure.
static inline bool
nccapability_canchangecolor(const nccapabilities* caps){
if(!caps->can_change_colors){
return false;
}
ncpalette* p;
if(caps->colors < sizeof(p->chans) / sizeof(*p->chans)){
return false;
}
return true;
}
API bool notcurses_canchangecolor(const struct notcurses* nc) API bool notcurses_canchangecolor(const struct notcurses* nc)
__attribute__ ((nonnull (1))); __attribute__ ((nonnull (1)));
@ -2973,52 +3032,6 @@ API int notcurses_cursor_yx(struct notcurses* nc, int* y, int* x);
// cursor is already disabled. // cursor is already disabled.
API int notcurses_cursor_disable(struct notcurses* nc); API int notcurses_cursor_disable(struct notcurses* nc);
// Palette API. Some terminals only support 256 colors, but allow the full
// palette to be specified with arbitrary RGB colors. In all cases, it's more
// performant to use indexed colors, since it's much less data to write to the
// terminal. If you can limit yourself to 256 colors, that's probably best.
typedef struct ncpalette {
uint32_t chans[NCPALETTESIZE]; // RGB values as regular ol' channels
} ncpalette;
// Create a new palette store. It will be initialized with notcurses' best
// knowledge of the currently configured palette. The palette upon startup
// cannot be reliably detected, sadly.
API ALLOC ncpalette* ncpalette_new(struct notcurses* nc);
// Attempt to configure the terminal with the provided palette 'p'. Does not
// transfer ownership of 'p'; palette256_free() can (ought) still be called.
API int ncpalette_use(struct notcurses* nc, const ncpalette* p);
// Manipulate entries in the palette store 'p'. These are *not* locked.
static inline int
ncpalette_set_rgb8(ncpalette* p, int idx, int r, int g, int b){
if(idx < 0 || (size_t)idx > sizeof(p->chans) / sizeof(*p->chans)){
return -1;
}
return ncchannel_set_rgb8(&p->chans[idx], r, g, b);
}
static inline int
ncpalette_set(ncpalette* p, int idx, unsigned rgb){
if(idx < 0 || (size_t)idx > sizeof(p->chans) / sizeof(*p->chans)){
return -1;
}
return ncchannel_set(&p->chans[idx], rgb);
}
static inline int
ncpalette_get_rgb8(const ncpalette* p, int idx, unsigned* RESTRICT r, unsigned* RESTRICT g, unsigned* RESTRICT b){
if(idx < 0 || (size_t)idx > sizeof(p->chans) / sizeof(*p->chans)){
return -1;
}
return ncchannel_rgb8(p->chans[idx], r, g, b);
}
// Free the palette store 'p'.
API void ncpalette_free(ncpalette* p);
// Convert the plane's content to greyscale. // Convert the plane's content to greyscale.
API void ncplane_greyscale(struct ncplane* n); API void ncplane_greyscale(struct ncplane* n);

View File

@ -2151,14 +2151,7 @@ bool notcurses_canfade(const notcurses* nc){
} }
bool notcurses_canchangecolor(const notcurses* nc){ bool notcurses_canchangecolor(const notcurses* nc){
if(!nc->tcache.caps.can_change_colors){ return nccapability_canchangecolor(&nc->tcache.caps);
return false;
}
ncpalette* p;
if((unsigned)nc->tcache.caps.colors < sizeof(p->chans) / sizeof(*p->chans)){
return false;
}
return true;
} }
ncpalette* ncpalette_new(notcurses* nc){ ncpalette* ncpalette_new(notcurses* nc){