summaryrefslogtreecommitdiffstats
path: root/Utilities/cmpdcurses/pdcurses/color.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmpdcurses/pdcurses/color.c')
-rw-r--r--Utilities/cmpdcurses/pdcurses/color.c362
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;
+}