You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
363 lines
9.4 KiB
363 lines
9.4 KiB
/* 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;
|
|
}
|