X-Git-Url: http://ncurses.scripts.mit.edu/?a=blobdiff_plain;ds=sidebyside;f=ncurses%2Fbase%2Flib_color.c;h=db560c6194d23e8e14d7f62a486ef55e1e63d91f;hb=95a30fbbfc81d5eb0a76e139c86e0a6505cad871;hp=a90ca9d3430874679b7c97f4a228316794dec382;hpb=027ae42953e3186daed8f3882da73de48291b606;p=ncurses.git diff --git a/ncurses/base/lib_color.c b/ncurses/base/lib_color.c index a90ca9d3..db560c61 100644 --- a/ncurses/base/lib_color.c +++ b/ncurses/base/lib_color.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2009 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -42,21 +42,37 @@ #include #include -MODULE_ID("$Id: lib_color.c,v 1.80 2006/11/26 01:33:16 tom Exp $") +MODULE_ID("$Id: lib_color.c,v 1.87 2009/01/25 00:25:31 tom Exp $") /* * These should be screen structure members. They need to be globals for * historical reasons. So we assign them in start_color() and also in * set_term()'s screen-switching logic. */ +#if USE_REENTRANT +NCURSES_EXPORT(int) +NCURSES_PUBLIC_VAR(COLOR_PAIRS) (void) +{ + return SP ? SP->_pair_count : -1; +} +NCURSES_EXPORT(int) +NCURSES_PUBLIC_VAR(COLORS) (void) +{ + return SP ? SP->_color_count : -1; +} +#else NCURSES_EXPORT_VAR(int) COLOR_PAIRS = 0; NCURSES_EXPORT_VAR(int) COLORS = 0; +#endif #define DATA(r,g,b) {r,g,b, 0,0,0, 0} #define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts)) +#define MAX_PALETTE 8 + #define OkColorHi(n) (((n) < COLORS) && ((n) < max_colors)) +#define InPalette(n) ((n) >= 0 && (n) < MAX_PALETTE) /* * Given a RGB range of 0..1000, we'll normally set the individual values @@ -92,6 +108,13 @@ static const color_t hls_palette[] = }; /* *INDENT-ON* */ +/* + * Ensure that we use color pairs only when colors have been started, and also + * that the index is within the limits of the table which we allocated. + */ +#define ValidPair(pair) \ + ((SP != 0) && (pair >= 0) && (pair < SP->_pair_limit) && SP->_coloron) + #if NCURSES_EXT_FUNCS /* * These are called from _nc_do_color(), which in turn is called from @@ -162,10 +185,10 @@ init_color_table(void) tp = (hue_lightness_saturation) ? hls_palette : cga_palette; for (n = 0; n < COLORS; n++) { - if (n < 8) { + if (InPalette(n)) { SP->_color_table[n] = tp[n]; } else { - SP->_color_table[n] = tp[n % 8]; + SP->_color_table[n] = tp[n % MAX_PALETTE]; if (hue_lightness_saturation) { SP->_color_table[n].green = 100; } else { @@ -239,11 +262,24 @@ start_color(void) } if (max_pairs > 0 && max_colors > 0) { - COLOR_PAIRS = SP->_pair_count = max_pairs; - COLORS = SP->_color_count = max_colors; + SP->_pair_limit = max_pairs; + +#if NCURSES_EXT_FUNCS + /* + * If using default colors, allocate extra space in table to + * allow for default-color as a component of a color-pair. + */ + SP->_pair_limit += (1 + (2 * max_colors)); +#endif + SP->_pair_count = max_pairs; + SP->_color_count = max_colors; +#if !USE_REENTRANT + COLOR_PAIRS = max_pairs; + COLORS = max_colors; +#endif if ((SP->_color_pairs = TYPE_CALLOC(colorpair_t, - max_pairs)) != 0) { + SP->_pair_limit)) != 0) { if ((SP->_color_table = TYPE_CALLOC(color_t, max_colors)) != 0) { SP->_color_pairs[0] = PAIR_OF(default_fg(), default_bg()); @@ -311,21 +347,69 @@ NCURSES_EXPORT(int) init_pair(short pair, short f, short b) { colorpair_t result; + colorpair_t previous; T((T_CALLED("init_pair(%d,%d,%d)"), pair, f, b)); - if ((pair < 0) || (pair >= COLOR_PAIRS) || SP == 0 || !SP->_coloron) + if (!ValidPair(pair)) returnCode(ERR); + + previous = SP->_color_pairs[pair]; #if NCURSES_EXT_FUNCS if (SP->_default_color) { - if (f < 0) + bool isDefault = FALSE; + bool wasDefault = FALSE; + int default_pairs = SP->_default_pairs; + + /* + * Map caller's color number, e.g., -1, 0, 1, .., 7, etc., into + * internal unsigned values which we will store in the _color_pairs[] + * table. + */ + if (isDefaultColor(f)) { f = COLOR_DEFAULT; - if (b < 0) + isDefault = TRUE; + } else if (!OkColorHi(f)) { + returnCode(ERR); + } + + if (isDefaultColor(b)) { b = COLOR_DEFAULT; - if (!OkColorHi(f) && !isDefaultColor(f)) + isDefault = TRUE; + } else if (!OkColorHi(b)) { returnCode(ERR); - if (!OkColorHi(b) && !isDefaultColor(b)) + } + + /* + * Check if the table entry that we are going to init/update used + * default colors. + */ + if ((FORE_OF(previous) == COLOR_DEFAULT) + || (BACK_OF(previous) == COLOR_DEFAULT)) + wasDefault = TRUE; + + /* + * Keep track of the number of entries in the color pair table which + * used a default color. + */ + if (isDefault && !wasDefault) { + ++default_pairs; + } else if (wasDefault && !isDefault) { + --default_pairs; + } + + /* + * As an extension, ncurses allows the pair number to exceed the + * terminal's color_pairs value for pairs using a default color. + * + * Note that updating a pair which used a default color with one + * that does not will decrement the count - and possibly interfere + * with sequentially adding new pairs. + */ + if (pair > (SP->_pair_count + default_pairs)) { returnCode(ERR); + } + SP->_default_pairs = default_pairs; } else #endif { @@ -341,8 +425,8 @@ init_pair(short pair, short f, short b) * pair colors with the new ones). */ result = PAIR_OF(f, b); - if (SP->_color_pairs[pair] != 0 - && SP->_color_pairs[pair] != result) { + if (previous != 0 + && previous != result) { int y, x; for (y = 0; y <= curscr->_maxy; y++) { @@ -365,13 +449,14 @@ init_pair(short pair, short f, short b) if (GET_SCREEN_PAIR(SP) == pair) SET_SCREEN_PAIR(SP, (chtype) (~0)); /* force attribute update */ - if (initialize_pair) { + if (initialize_pair && InPalette(f) && InPalette(b)) { const color_t *tp = hue_lightness_saturation ? hls_palette : cga_palette; - T(("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)", - pair, - tp[f].red, tp[f].green, tp[f].blue, - tp[b].red, tp[b].green, tp[b].blue)); + TR(TRACE_ATTRS, + ("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)", + pair, + tp[f].red, tp[f].green, tp[f].blue, + tp[b].red, tp[b].green, tp[b].blue)); TPUTS_TRACE("initialize_pair"); putp(TPARM_7(initialize_pair, @@ -461,7 +546,8 @@ color_content(short color, short *r, short *g, short *b) if (b) *b = c_b; - T(("...color_content(%d,%d,%d,%d)", color, c_r, c_g, c_b)); + TR(TRACE_ATTRS, ("...color_content(%d,%d,%d,%d)", + color, c_r, c_g, c_b)); result = OK; } returnCode(result); @@ -474,11 +560,11 @@ pair_content(short pair, short *f, short *b) T((T_CALLED("pair_content(%d,%p,%p)"), pair, f, b)); - if ((pair < 0) || (pair >= COLOR_PAIRS) || SP == 0 || !SP->_coloron) { + if (!ValidPair(pair)) { result = ERR; } else { - NCURSES_COLOR_T fg = ((SP->_color_pairs[pair] >> C_SHIFT) & C_MASK); - NCURSES_COLOR_T bg = (SP->_color_pairs[pair] & C_MASK); + NCURSES_COLOR_T fg = FORE_OF(SP->_color_pairs[pair]); + NCURSES_COLOR_T bg = BACK_OF(SP->_color_pairs[pair]); #if NCURSES_EXT_FUNCS if (fg == COLOR_DEFAULT) @@ -492,7 +578,7 @@ pair_content(short pair, short *f, short *b) if (b) *b = bg; - T(("...pair_content(%d,%d,%d)", pair, fg, bg)); + TR(TRACE_ATTRS, ("...pair_content(%d,%d,%d)", pair, fg, bg)); result = OK; } returnCode(result); @@ -505,7 +591,7 @@ _nc_do_color(short old_pair, short pair, bool reverse, int (*outc) (int)) NCURSES_COLOR_T bg = COLOR_DEFAULT; NCURSES_COLOR_T old_fg, old_bg; - if (pair < 0 || pair >= COLOR_PAIRS) { + if (!ValidPair(pair)) { return; } else if (pair != 0) { if (set_color_pair) {