| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- /* 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;
- }
|