diff options
Diffstat (limited to 'Utilities/cmpdcurses/pdcurses/color.c')
-rw-r--r-- | Utilities/cmpdcurses/pdcurses/color.c | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/Utilities/cmpdcurses/pdcurses/color.c b/Utilities/cmpdcurses/pdcurses/color.c new file mode 100644 index 0000000..7d4df24 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/color.c @@ -0,0 +1,362 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +color +----- + +### Synopsis + + bool has_colors(void); + int start_color(void); + int init_pair(short pair, short fg, short bg); + int pair_content(short pair, short *fg, short *bg); + bool can_change_color(void); + int init_color(short color, short red, short green, short blue); + int color_content(short color, short *red, short *green, short *blue); + + int alloc_pair(int fg, int bg); + int assume_default_colors(int f, int b); + int find_pair(int fg, int bg); + int free_pair(int pair); + int use_default_colors(void); + + int PDC_set_line_color(short color); + +### Description + + To use these routines, first, call start_color(). Colors are always + used in pairs, referred to as color-pairs. A color-pair is created by + init_pair(), and consists of a foreground color and a background + color. After initialization, COLOR_PAIR(n) can be used like any other + video attribute. + + has_colors() reports whether the terminal supports color. + + start_color() initializes eight basic colors (black, red, green, + yellow, blue, magenta, cyan, and white), and two global variables: + COLORS and COLOR_PAIRS (respectively defining the maximum number of + colors and color-pairs the terminal is capable of displaying). + + init_pair() changes the definition of a color-pair. It takes three + arguments: the number of the color-pair to be redefined, and the new + values of the foreground and background colors. The pair number must + be between 0 and COLOR_PAIRS - 1, inclusive. The foreground and + background must be between 0 and COLORS - 1, inclusive. If the color + pair was previously initialized, the screen is refreshed, and all + occurrences of that color-pair are changed to the new definition. + + pair_content() is used to determine what the colors of a given color- + pair consist of. + + can_change_color() indicates if the terminal has the capability to + change the definition of its colors. + + init_color() is used to redefine a color, if possible. Each of the + components -- red, green, and blue -- is specified in a range from 0 + to 1000, inclusive. + + color_content() reports the current definition of a color in the same + format as used by init_color(). + + assume_default_colors() and use_default_colors() emulate the ncurses + extensions of the same names. assume_default_colors(f, b) is + essentially the same as init_pair(0, f, b) (which isn't allowed); it + redefines the default colors. use_default_colors() allows the use of + -1 as a foreground or background color with init_pair(), and calls + assume_default_colors(-1, -1); -1 represents the foreground or + background color that the terminal had at startup. If the environment + variable PDC_ORIGINAL_COLORS is set at the time start_color() is + called, that's equivalent to calling use_default_colors(). + + alloc_pair(), find_pair() and free_pair() are also from ncurses. + free_pair() marks a pair as unused; find_pair() returns an existing + pair with the specified foreground and background colors, if one + exists. And alloc_pair() returns such a pair whether or not it was + previously set, overwriting the oldest initialized pair if there are + no free pairs. + + PDC_set_line_color() is used to set the color, globally, for the + color of the lines drawn for the attributes: A_UNDERLINE, A_LEFT and + A_RIGHT. A value of -1 (the default) indicates that the current + foreground color should be used. + + NOTE: COLOR_PAIR() and PAIR_NUMBER() are implemented as macros. + +### Return Value + + Most functions return OK on success and ERR on error. has_colors() + and can_change_colors() return TRUE or FALSE. alloc_pair() and + find_pair() return a pair number, or -1 on error. + +### Portability + X/Open ncurses NetBSD + has_colors Y Y Y + start_color Y Y Y + init_pair Y Y Y + pair_content Y Y Y + can_change_color Y Y Y + init_color Y Y Y + color_content Y Y Y + alloc_pair - Y - + assume_default_colors - Y Y + find_pair - Y - + free_pair - Y - + use_default_colors - Y Y + PDC_set_line_color - - - + +**man-end****************************************************************/ + +#include <stdlib.h> +#include <string.h> + +int COLORS = 0; +int COLOR_PAIRS = PDC_COLOR_PAIRS; + +static bool default_colors = FALSE; +static short first_col = 0; +static int allocnum = 0; + +int start_color(void) +{ + PDC_LOG(("start_color() - called\n")); + + if (!SP || SP->mono) + return ERR; + + SP->color_started = TRUE; + + PDC_set_blink(FALSE); /* Also sets COLORS */ + + if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS")) + default_colors = TRUE; + + PDC_init_atrtab(); + + return OK; +} + +static void _normalize(short *fg, short *bg) +{ + if (*fg == -1) + *fg = SP->orig_attr ? SP->orig_fore : COLOR_WHITE; + + if (*bg == -1) + *bg = SP->orig_attr ? SP->orig_back : COLOR_BLACK; +} + +static void _init_pair_core(short pair, short fg, short bg) +{ + PDC_PAIR *p = SP->atrtab + pair; + + _normalize(&fg, &bg); + + /* To allow the PDC_PRESERVE_SCREEN option to work, we only reset + curscr if this call to init_pair() alters a color pair created by + the user. */ + + if (p->set) + { + if (p->f != fg || p->b != bg) + curscr->_clear = TRUE; + } + + p->f = fg; + p->b = bg; + p->count = allocnum++; + p->set = TRUE; +} + +int init_pair(short pair, short fg, short bg) +{ + PDC_LOG(("init_pair() - called: pair %d fg %d bg %d\n", pair, fg, bg)); + + if (!SP || !SP->color_started || pair < 1 || pair >= COLOR_PAIRS || + fg < first_col || fg >= COLORS || bg < first_col || bg >= COLORS) + return ERR; + + _init_pair_core(pair, fg, bg); + + return OK; +} + +bool has_colors(void) +{ + PDC_LOG(("has_colors() - called\n")); + + return SP ? !(SP->mono) : FALSE; +} + +int init_color(short color, short red, short green, short blue) +{ + PDC_LOG(("init_color() - called\n")); + + if (!SP || color < 0 || color >= COLORS || !PDC_can_change_color() || + red < -1 || red > 1000 || green < -1 || green > 1000 || + blue < -1 || blue > 1000) + return ERR; + + SP->dirty = TRUE; + + return PDC_init_color(color, red, green, blue); +} + +int color_content(short color, short *red, short *green, short *blue) +{ + PDC_LOG(("color_content() - called\n")); + + if (color < 0 || color >= COLORS || !red || !green || !blue) + return ERR; + + if (PDC_can_change_color()) + return PDC_color_content(color, red, green, blue); + else + { + /* Simulated values for platforms that don't support palette + changing */ + + short maxval = (color & 8) ? 1000 : 680; + + *red = (color & COLOR_RED) ? maxval : 0; + *green = (color & COLOR_GREEN) ? maxval : 0; + *blue = (color & COLOR_BLUE) ? maxval : 0; + + return OK; + } +} + +bool can_change_color(void) +{ + PDC_LOG(("can_change_color() - called\n")); + + return PDC_can_change_color(); +} + +int pair_content(short pair, short *fg, short *bg) +{ + PDC_LOG(("pair_content() - called\n")); + + if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg) + return ERR; + + *fg = SP->atrtab[pair].f; + *bg = SP->atrtab[pair].b; + + return OK; +} + +int assume_default_colors(int f, int b) +{ + PDC_LOG(("assume_default_colors() - called: f %d b %d\n", f, b)); + + if (f < -1 || f >= COLORS || b < -1 || b >= COLORS) + return ERR; + + if (SP->color_started) + _init_pair_core(0, f, b); + + return OK; +} + +int use_default_colors(void) +{ + PDC_LOG(("use_default_colors() - called\n")); + + default_colors = TRUE; + first_col = -1; + + return assume_default_colors(-1, -1); +} + +int PDC_set_line_color(short color) +{ + PDC_LOG(("PDC_set_line_color() - called: %d\n", color)); + + if (!SP || color < -1 || color >= COLORS) + return ERR; + + SP->line_color = color; + + return OK; +} + +void PDC_init_atrtab(void) +{ + PDC_PAIR *p = SP->atrtab; + short i, fg, bg; + + if (SP->color_started && !default_colors) + { + fg = COLOR_WHITE; + bg = COLOR_BLACK; + } + else + fg = bg = -1; + + _normalize(&fg, &bg); + + for (i = 0; i < PDC_COLOR_PAIRS; i++) + { + p[i].f = fg; + p[i].b = bg; + p[i].set = FALSE; + } +} + +int free_pair(int pair) +{ + if (pair < 1 || pair >= PDC_COLOR_PAIRS || !(SP->atrtab[pair].set)) + return ERR; + + SP->atrtab[pair].set = FALSE; + return OK; +} + +int find_pair(int fg, int bg) +{ + int i; + PDC_PAIR *p = SP->atrtab; + + for (i = 0; i < PDC_COLOR_PAIRS; i++) + if (p[i].set && p[i].f == fg && p[i].b == bg) + return i; + + return -1; +} + +static int _find_oldest() +{ + int i, lowind = 0, lowval = 0; + PDC_PAIR *p = SP->atrtab; + + for (i = 1; i < PDC_COLOR_PAIRS; i++) + { + if (!p[i].set) + return i; + + if (!lowval || (p[i].count < lowval)) + { + lowind = i; + lowval = p[i].count; + } + } + + return lowind; +} + +int alloc_pair(int fg, int bg) +{ + int i = find_pair(fg, bg); + + if (-1 == i) + { + i = _find_oldest(); + + if (ERR == init_pair(i, fg, bg)) + return -1; + } + + return i; +} |