150276Speter/**************************************************************************** 2174993Srafan * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * 350276Speter * * 450276Speter * Permission is hereby granted, free of charge, to any person obtaining a * 550276Speter * copy of this software and associated documentation files (the * 650276Speter * "Software"), to deal in the Software without restriction, including * 750276Speter * without limitation the rights to use, copy, modify, merge, publish, * 850276Speter * distribute, distribute with modifications, sublicense, and/or sell * 950276Speter * copies of the Software, and to permit persons to whom the Software is * 1050276Speter * furnished to do so, subject to the following conditions: * 1150276Speter * * 1250276Speter * The above copyright notice and this permission notice shall be included * 1350276Speter * in all copies or substantial portions of the Software. * 1450276Speter * * 1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2250276Speter * * 2350276Speter * Except as contained in this notice, the name(s) of the above copyright * 2450276Speter * holders shall not be used in advertising or otherwise to promote the * 2550276Speter * sale, use or other dealings in this Software without prior written * 2650276Speter * authorization. * 2750276Speter ****************************************************************************/ 2850276Speter 2950276Speter/**************************************************************************** 3050276Speter * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 3150276Speter * and: Eric S. Raymond <esr@snark.thyrsus.com> * 32166124Srafan * and: Thomas E. Dickey 1996-on * 3350276Speter ****************************************************************************/ 3450276Speter 3550276Speter/* lib_color.c 3650276Speter * 3750276Speter * Handles color emulation of SYS V curses 3850276Speter */ 3950276Speter 4050276Speter#include <curses.priv.h> 4150276Speter 4250276Speter#include <term.h> 4362449Speter#include <tic.h> 4450276Speter 45174993SrafanMODULE_ID("$Id: lib_color.c,v 1.85 2007/04/07 17:07:28 tom Exp $") 4650276Speter 4750276Speter/* 4850276Speter * These should be screen structure members. They need to be globals for 4962449Speter * historical reasons. So we assign them in start_color() and also in 5050276Speter * set_term()'s screen-switching logic. 5150276Speter */ 52174993Srafan#if USE_REENTRANT 53174993SrafanNCURSES_EXPORT(int) 54174993SrafanNCURSES_PUBLIC_VAR(COLOR_PAIRS) (void) 55174993Srafan{ 56174993Srafan return SP ? SP->_pair_count : -1; 57174993Srafan} 58174993SrafanNCURSES_EXPORT(int) 59174993SrafanNCURSES_PUBLIC_VAR(COLORS) (void) 60174993Srafan{ 61174993Srafan return SP ? SP->_color_count : -1; 62174993Srafan} 63174993Srafan#else 6497049SpeterNCURSES_EXPORT_VAR(int) COLOR_PAIRS = 0; 6597049SpeterNCURSES_EXPORT_VAR(int) COLORS = 0; 66174993Srafan#endif 6750276Speter 68166124Srafan#define DATA(r,g,b) {r,g,b, 0,0,0, 0} 69166124Srafan 70166124Srafan#define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts)) 71166124Srafan 72174993Srafan#define MAX_PALETTE 8 73174993Srafan 74166124Srafan#define OkColorHi(n) (((n) < COLORS) && ((n) < max_colors)) 75174993Srafan#define InPalette(n) ((n) >= 0 && (n) < MAX_PALETTE) 76166124Srafan 7750276Speter/* 7850276Speter * Given a RGB range of 0..1000, we'll normally set the individual values 7950276Speter * to about 2/3 of the maximum, leaving full-range for bold/bright colors. 8050276Speter */ 8150276Speter#define RGB_ON 680 8250276Speter#define RGB_OFF 0 8362449Speter/* *INDENT-OFF* */ 8450276Speterstatic const color_t cga_palette[] = 8550276Speter{ 8662449Speter /* R G B */ 87166124Srafan DATA(RGB_OFF, RGB_OFF, RGB_OFF), /* COLOR_BLACK */ 88166124Srafan DATA(RGB_ON, RGB_OFF, RGB_OFF), /* COLOR_RED */ 89166124Srafan DATA(RGB_OFF, RGB_ON, RGB_OFF), /* COLOR_GREEN */ 90166124Srafan DATA(RGB_ON, RGB_ON, RGB_OFF), /* COLOR_YELLOW */ 91166124Srafan DATA(RGB_OFF, RGB_OFF, RGB_ON), /* COLOR_BLUE */ 92166124Srafan DATA(RGB_ON, RGB_OFF, RGB_ON), /* COLOR_MAGENTA */ 93166124Srafan DATA(RGB_OFF, RGB_ON, RGB_ON), /* COLOR_CYAN */ 94166124Srafan DATA(RGB_ON, RGB_ON, RGB_ON), /* COLOR_WHITE */ 9550276Speter}; 9662449Speter 9750276Speterstatic const color_t hls_palette[] = 9850276Speter{ 99166124Srafan /* H L S */ 100166124Srafan DATA( 0, 0, 0), /* COLOR_BLACK */ 101166124Srafan DATA( 120, 50, 100), /* COLOR_RED */ 102166124Srafan DATA( 240, 50, 100), /* COLOR_GREEN */ 103166124Srafan DATA( 180, 50, 100), /* COLOR_YELLOW */ 104166124Srafan DATA( 330, 50, 100), /* COLOR_BLUE */ 105166124Srafan DATA( 60, 50, 100), /* COLOR_MAGENTA */ 106166124Srafan DATA( 300, 50, 100), /* COLOR_CYAN */ 107166124Srafan DATA( 0, 50, 100), /* COLOR_WHITE */ 10850276Speter}; 10962449Speter/* *INDENT-ON* */ 11050276Speter 11166963Speter#if NCURSES_EXT_FUNCS 11250276Speter/* 11362449Speter * These are called from _nc_do_color(), which in turn is called from 11462449Speter * vidattr - so we have to assume that SP may be null. 11562449Speter */ 11697049Speterstatic int 11797049Speterdefault_fg(void) 11862449Speter{ 11962449Speter return (SP != 0) ? SP->_default_fg : COLOR_WHITE; 12062449Speter} 12162449Speter 12262449Speterstatic int 12362449Speterdefault_bg(void) 12462449Speter{ 12562449Speter return SP != 0 ? SP->_default_bg : COLOR_BLACK; 12662449Speter} 12762449Speter#else 12862449Speter#define default_fg() COLOR_WHITE 12962449Speter#define default_bg() COLOR_BLACK 13062449Speter#endif 13162449Speter 13262449Speter/* 13350276Speter * SVr4 curses is known to interchange color codes (1,4) and (3,6), possibly 13450276Speter * to maintain compatibility with a pre-ANSI scheme. The same scheme is 13550276Speter * also used in the FreeBSD syscons. 13650276Speter */ 13797049Speterstatic int 13897049Spetertoggled_colors(int c) 13950276Speter{ 14050276Speter if (c < 16) { 14150276Speter static const int table[] = 14262449Speter {0, 4, 2, 6, 1, 5, 3, 7, 14376726Speter 8, 12, 10, 14, 9, 13, 11, 15}; 14450276Speter c = table[c]; 14550276Speter } 14650276Speter return c; 14750276Speter} 14850276Speter 14962449Speterstatic void 15062449Speterset_background_color(int bg, int (*outc) (int)) 15150276Speter{ 15262449Speter if (set_a_background) { 15362449Speter TPUTS_TRACE("set_a_background"); 154166124Srafan tputs(TPARM_1(set_a_background, bg), 1, outc); 15562449Speter } else { 15662449Speter TPUTS_TRACE("set_background"); 157166124Srafan tputs(TPARM_1(set_background, toggled_colors(bg)), 1, outc); 15862449Speter } 15950276Speter} 16050276Speter 16162449Speterstatic void 16262449Speterset_foreground_color(int fg, int (*outc) (int)) 16350276Speter{ 16462449Speter if (set_a_foreground) { 16562449Speter TPUTS_TRACE("set_a_foreground"); 166166124Srafan tputs(TPARM_1(set_a_foreground, fg), 1, outc); 16762449Speter } else { 16862449Speter TPUTS_TRACE("set_foreground"); 169166124Srafan tputs(TPARM_1(set_foreground, toggled_colors(fg)), 1, outc); 17062449Speter } 17150276Speter} 17250276Speter 173166124Srafanstatic void 174166124Srafaninit_color_table(void) 17550276Speter{ 176166124Srafan const color_t *tp; 17762449Speter int n; 17850276Speter 17962449Speter tp = (hue_lightness_saturation) ? hls_palette : cga_palette; 18062449Speter for (n = 0; n < COLORS; n++) { 181174993Srafan if (InPalette(n)) { 18262449Speter SP->_color_table[n] = tp[n]; 18362449Speter } else { 184174993Srafan SP->_color_table[n] = tp[n % MAX_PALETTE]; 18562449Speter if (hue_lightness_saturation) { 18662449Speter SP->_color_table[n].green = 100; 18762449Speter } else { 18862449Speter if (SP->_color_table[n].red) 18962449Speter SP->_color_table[n].red = 1000; 19062449Speter if (SP->_color_table[n].green) 19162449Speter SP->_color_table[n].green = 1000; 19262449Speter if (SP->_color_table[n].blue) 19362449Speter SP->_color_table[n].blue = 1000; 19462449Speter } 19562449Speter } 19662449Speter } 197166124Srafan} 19850276Speter 199166124Srafan/* 200166124Srafan * Reset the color pair, e.g., to whatever color pair 0 is. 201166124Srafan */ 202166124Srafanstatic bool 203166124Srafanreset_color_pair(void) 204166124Srafan{ 205166124Srafan bool result = FALSE; 20662449Speter 207166124Srafan if (orig_pair != 0) { 208166124Srafan TPUTS_TRACE("orig_pair"); 209166124Srafan putp(orig_pair); 210166124Srafan result = TRUE; 211166124Srafan } 212166124Srafan return result; 21350276Speter} 21450276Speter 215166124Srafan/* 216166124Srafan * Reset color pairs and definitions. Actually we do both more to accommodate 217166124Srafan * badly-written terminal descriptions than for the relatively rare case where 218166124Srafan * someone has changed the color definitions. 219166124Srafan */ 220166124Srafanbool 221166124Srafan_nc_reset_colors(void) 222166124Srafan{ 223166124Srafan int result = FALSE; 224166124Srafan 225166124Srafan T((T_CALLED("_nc_reset_colors()"))); 226166124Srafan if (SP->_color_defs > 0) 227166124Srafan SP->_color_defs = -(SP->_color_defs); 228166124Srafan 229166124Srafan if (reset_color_pair()) 230166124Srafan result = TRUE; 231166124Srafan if (orig_colors != 0) { 232166124Srafan TPUTS_TRACE("orig_colors"); 233166124Srafan putp(orig_colors); 234166124Srafan result = TRUE; 235166124Srafan } 236166124Srafan returnBool(result); 237166124Srafan} 238166124Srafan 239166124SrafanNCURSES_EXPORT(int) 240166124Srafanstart_color(void) 241166124Srafan{ 242166124Srafan int result = ERR; 243166124Srafan 244166124Srafan T((T_CALLED("start_color()"))); 245166124Srafan 246166124Srafan if (SP == 0) { 247166124Srafan result = ERR; 248166124Srafan } else if (SP->_coloron) { 249166124Srafan result = OK; 250166124Srafan } else { 251166124Srafan 252166124Srafan if (reset_color_pair() != TRUE) { 253166124Srafan set_foreground_color(default_fg(), _nc_outch); 254166124Srafan set_background_color(default_bg(), _nc_outch); 255166124Srafan } 256166124Srafan 257166124Srafan if (max_pairs > 0 && max_colors > 0) { 258174993Srafan SP->_pair_count = max_pairs; 259174993Srafan SP->_color_count = max_colors; 260174993Srafan#if !USE_REENTRANT 261174993Srafan COLOR_PAIRS = max_pairs; 262174993Srafan COLORS = max_colors; 263174993Srafan#endif 264166124Srafan 265166124Srafan if ((SP->_color_pairs = TYPE_CALLOC(colorpair_t, 266166124Srafan max_pairs)) != 0) { 267166124Srafan if ((SP->_color_table = TYPE_CALLOC(color_t, 268166124Srafan max_colors)) != 0) { 269166124Srafan SP->_color_pairs[0] = PAIR_OF(default_fg(), default_bg()); 270166124Srafan init_color_table(); 271166124Srafan 272166124Srafan T(("started color: COLORS = %d, COLOR_PAIRS = %d", 273166124Srafan COLORS, COLOR_PAIRS)); 274166124Srafan 275166124Srafan SP->_coloron = 1; 276166124Srafan result = OK; 277166124Srafan } else if (SP->_color_pairs != 0) { 278166124Srafan FreeAndNull(SP->_color_pairs); 279166124Srafan } 280166124Srafan } 281166124Srafan } else { 282166124Srafan result = OK; 283166124Srafan } 284166124Srafan } 285166124Srafan returnCode(result); 286166124Srafan} 287166124Srafan 28850276Speter/* This function was originally written by Daniel Weaver <danw@znyx.com> */ 28962449Speterstatic void 29062449Speterrgb2hls(short r, short g, short b, short *h, short *l, short *s) 29150276Speter/* convert RGB to HLS system */ 29250276Speter{ 29350276Speter short min, max, t; 29450276Speter 29562449Speter if ((min = g < r ? g : r) > b) 29662449Speter min = b; 29762449Speter if ((max = g > r ? g : r) < b) 29862449Speter max = b; 29950276Speter 30050276Speter /* calculate lightness */ 30150276Speter *l = (min + max) / 20; 30250276Speter 30362449Speter if (min == max) { /* black, white and all shades of gray */ 30450276Speter *h = 0; 30550276Speter *s = 0; 30650276Speter return; 30750276Speter } 30850276Speter 30950276Speter /* calculate saturation */ 31050276Speter if (*l < 50) 31150276Speter *s = ((max - min) * 100) / (max + min); 31262449Speter else 31362449Speter *s = ((max - min) * 100) / (2000 - max - min); 31450276Speter 31550276Speter /* calculate hue */ 31650276Speter if (r == max) 31750276Speter t = 120 + ((g - b) * 60) / (max - min); 31862449Speter else if (g == max) 31962449Speter t = 240 + ((b - r) * 60) / (max - min); 32050276Speter else 32162449Speter t = 360 + ((r - g) * 60) / (max - min); 32250276Speter 32350276Speter *h = t % 360; 32450276Speter} 32550276Speter 32650276Speter/* 32750276Speter * Extension (1997/1/18) - Allow negative f/b values to set default color 32850276Speter * values. 32950276Speter */ 33076726SpeterNCURSES_EXPORT(int) 33197049Speterinit_pair(short pair, short f, short b) 33250276Speter{ 333166124Srafan colorpair_t result; 33450276Speter 33562449Speter T((T_CALLED("init_pair(%d,%d,%d)"), pair, f, b)); 33650276Speter 337166124Srafan if ((pair < 0) || (pair >= COLOR_PAIRS) || SP == 0 || !SP->_coloron) 33862449Speter returnCode(ERR); 33966963Speter#if NCURSES_EXT_FUNCS 34062449Speter if (SP->_default_color) { 34162449Speter if (f < 0) 342166124Srafan f = COLOR_DEFAULT; 34362449Speter if (b < 0) 344166124Srafan b = COLOR_DEFAULT; 345166124Srafan if (!OkColorHi(f) && !isDefaultColor(f)) 34662449Speter returnCode(ERR); 347166124Srafan if (!OkColorHi(b) && !isDefaultColor(b)) 34862449Speter returnCode(ERR); 34962449Speter } else 35062449Speter#endif 35162449Speter { 352166124Srafan if ((f < 0) || !OkColorHi(f) 353166124Srafan || (b < 0) || !OkColorHi(b) 35462449Speter || (pair < 1)) 35562449Speter returnCode(ERR); 35662449Speter } 35750276Speter 35862449Speter /* 35962449Speter * When a pair's content is changed, replace its colors (if pair was 36062449Speter * initialized before a screen update is performed replacing original 36162449Speter * pair colors with the new ones). 36262449Speter */ 36362449Speter result = PAIR_OF(f, b); 36462449Speter if (SP->_color_pairs[pair] != 0 36562449Speter && SP->_color_pairs[pair] != result) { 36662449Speter int y, x; 36750276Speter 36862449Speter for (y = 0; y <= curscr->_maxy; y++) { 36962449Speter struct ldat *ptr = &(curscr->_line[y]); 37062449Speter bool changed = FALSE; 37162449Speter for (x = 0; x <= curscr->_maxx; x++) { 372166124Srafan if (GetPair(ptr->text[x]) == pair) { 37362449Speter /* Set the old cell to zero to ensure it will be 37462449Speter updated on the next doupdate() */ 37597049Speter SetChar(ptr->text[x], 0, 0); 37662449Speter CHANGED_CELL(ptr, x); 37762449Speter changed = TRUE; 37850276Speter } 37950276Speter } 38062449Speter if (changed) 38162449Speter _nc_make_oldhash(y); 38250276Speter } 38362449Speter } 38462449Speter SP->_color_pairs[pair] = result; 385166124Srafan if (GET_SCREEN_PAIR(SP) == pair) 386166124Srafan SET_SCREEN_PAIR(SP, (chtype) (~0)); /* force attribute update */ 38750276Speter 388174993Srafan if (initialize_pair && InPalette(f) && InPalette(b)) { 38962449Speter const color_t *tp = hue_lightness_saturation ? hls_palette : cga_palette; 39050276Speter 391174993Srafan TR(TRACE_ATTRS, 392174993Srafan ("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)", 393174993Srafan pair, 394174993Srafan tp[f].red, tp[f].green, tp[f].blue, 395174993Srafan tp[b].red, tp[b].green, tp[b].blue)); 39650276Speter 397166124Srafan TPUTS_TRACE("initialize_pair"); 398166124Srafan putp(TPARM_7(initialize_pair, 399166124Srafan pair, 400166124Srafan tp[f].red, tp[f].green, tp[f].blue, 401166124Srafan tp[b].red, tp[b].green, tp[b].blue)); 40262449Speter } 40350276Speter 40462449Speter returnCode(OK); 40550276Speter} 40650276Speter 407166124Srafan#define okRGB(n) ((n) >= 0 && (n) <= 1000) 408166124Srafan 40976726SpeterNCURSES_EXPORT(int) 41097049Speterinit_color(short color, short r, short g, short b) 41150276Speter{ 412166124Srafan int result = ERR; 413166124Srafan 41462449Speter T((T_CALLED("init_color(%d,%d,%d,%d)"), color, r, g, b)); 41550276Speter 416166124Srafan if (initialize_color != NULL 417166124Srafan && SP != 0 418166124Srafan && SP->_coloron 419166124Srafan && (color >= 0 && OkColorHi(color)) 420166124Srafan && (okRGB(r) && okRGB(g) && okRGB(b))) { 42150276Speter 422166124Srafan SP->_color_table[color].init = 1; 423166124Srafan SP->_color_table[color].r = r; 424166124Srafan SP->_color_table[color].g = g; 425166124Srafan SP->_color_table[color].b = b; 42650276Speter 427166124Srafan if (hue_lightness_saturation) { 428166124Srafan rgb2hls(r, g, b, 429166124Srafan &SP->_color_table[color].red, 430166124Srafan &SP->_color_table[color].green, 431166124Srafan &SP->_color_table[color].blue); 432166124Srafan } else { 433166124Srafan SP->_color_table[color].red = r; 434166124Srafan SP->_color_table[color].green = g; 435166124Srafan SP->_color_table[color].blue = b; 436166124Srafan } 43750276Speter 43862449Speter TPUTS_TRACE("initialize_color"); 439166124Srafan putp(TPARM_4(initialize_color, color, r, g, b)); 440166124Srafan SP->_color_defs = max(color + 1, SP->_color_defs); 441166124Srafan result = OK; 44262449Speter } 443166124Srafan returnCode(result); 44450276Speter} 44550276Speter 44676726SpeterNCURSES_EXPORT(bool) 44762449Spetercan_change_color(void) 44850276Speter{ 44962449Speter T((T_CALLED("can_change_color()"))); 45062449Speter returnCode((can_change != 0) ? TRUE : FALSE); 45150276Speter} 45250276Speter 45376726SpeterNCURSES_EXPORT(bool) 45462449Speterhas_colors(void) 45550276Speter{ 45662449Speter T((T_CALLED("has_colors()"))); 45762449Speter returnCode((VALID_NUMERIC(max_colors) && VALID_NUMERIC(max_pairs) 45876726Speter && (((set_foreground != NULL) 45976726Speter && (set_background != NULL)) 46076726Speter || ((set_a_foreground != NULL) 46176726Speter && (set_a_background != NULL)) 46276726Speter || set_color_pair)) ? TRUE : FALSE); 46350276Speter} 46450276Speter 46576726SpeterNCURSES_EXPORT(int) 46697049Spetercolor_content(short color, short *r, short *g, short *b) 46750276Speter{ 468166124Srafan int result; 469166124Srafan 47050276Speter T((T_CALLED("color_content(%d,%p,%p,%p)"), color, r, g, b)); 471166124Srafan if (color < 0 || !OkColorHi(color) || SP == 0 || !SP->_coloron) { 472166124Srafan result = ERR; 473166124Srafan } else { 474166124Srafan NCURSES_COLOR_T c_r = SP->_color_table[color].red; 475166124Srafan NCURSES_COLOR_T c_g = SP->_color_table[color].green; 476166124Srafan NCURSES_COLOR_T c_b = SP->_color_table[color].blue; 47750276Speter 478166124Srafan if (r) 479166124Srafan *r = c_r; 480166124Srafan if (g) 481166124Srafan *g = c_g; 482166124Srafan if (b) 483166124Srafan *b = c_b; 484166124Srafan 485174993Srafan TR(TRACE_ATTRS, ("...color_content(%d,%d,%d,%d)", 486174993Srafan color, c_r, c_g, c_b)); 487166124Srafan result = OK; 488166124Srafan } 489166124Srafan returnCode(result); 49050276Speter} 49150276Speter 49276726SpeterNCURSES_EXPORT(int) 49397049Speterpair_content(short pair, short *f, short *b) 49450276Speter{ 495166124Srafan int result; 496166124Srafan 49762449Speter T((T_CALLED("pair_content(%d,%p,%p)"), pair, f, b)); 49850276Speter 499166124Srafan if ((pair < 0) || (pair >= COLOR_PAIRS) || SP == 0 || !SP->_coloron) { 500166124Srafan result = ERR; 501166124Srafan } else { 502166124Srafan NCURSES_COLOR_T fg = ((SP->_color_pairs[pair] >> C_SHIFT) & C_MASK); 503166124Srafan NCURSES_COLOR_T bg = (SP->_color_pairs[pair] & C_MASK); 50450276Speter 505166124Srafan#if NCURSES_EXT_FUNCS 506166124Srafan if (fg == COLOR_DEFAULT) 507166124Srafan fg = -1; 508166124Srafan if (bg == COLOR_DEFAULT) 509166124Srafan bg = -1; 510166124Srafan#endif 511166124Srafan 512166124Srafan if (f) 513166124Srafan *f = fg; 514166124Srafan if (b) 515166124Srafan *b = bg; 516166124Srafan 517174993Srafan TR(TRACE_ATTRS, ("...pair_content(%d,%d,%d)", pair, fg, bg)); 518166124Srafan result = OK; 519166124Srafan } 520166124Srafan returnCode(result); 52150276Speter} 52250276Speter 52376726SpeterNCURSES_EXPORT(void) 524166124Srafan_nc_do_color(short old_pair, short pair, bool reverse, int (*outc) (int)) 52550276Speter{ 526166124Srafan NCURSES_COLOR_T fg = COLOR_DEFAULT; 527166124Srafan NCURSES_COLOR_T bg = COLOR_DEFAULT; 52862449Speter NCURSES_COLOR_T old_fg, old_bg; 52950276Speter 53062449Speter if (pair < 0 || pair >= COLOR_PAIRS) { 53162449Speter return; 53262449Speter } else if (pair != 0) { 53362449Speter if (set_color_pair) { 53450276Speter TPUTS_TRACE("set_color_pair"); 535166124Srafan tputs(TPARM_1(set_color_pair, pair), 1, outc); 53662449Speter return; 53762449Speter } else if (SP != 0) { 538166124Srafan pair_content((short) pair, &fg, &bg); 53950276Speter } 54062449Speter } 54162449Speter 542166124Srafan if (old_pair >= 0 543166124Srafan && SP != 0 544166124Srafan && pair_content(old_pair, &old_fg, &old_bg) != ERR) { 545166124Srafan if ((isDefaultColor(fg) && !isDefaultColor(old_fg)) 546166124Srafan || (isDefaultColor(bg) && !isDefaultColor(old_bg))) { 54766963Speter#if NCURSES_EXT_FUNCS 54862449Speter /* 54962449Speter * A minor optimization - but extension. If "AX" is specified in 55062449Speter * the terminal description, treat it as screen's indicator of ECMA 55162449Speter * SGR 39 and SGR 49, and assume the two sequences are independent. 55262449Speter */ 553166124Srafan if (SP->_has_sgr_39_49 554166124Srafan && isDefaultColor(old_bg) 555166124Srafan && !isDefaultColor(old_fg)) { 55662449Speter tputs("\033[39m", 1, outc); 557166124Srafan } else if (SP->_has_sgr_39_49 558166124Srafan && isDefaultColor(old_fg) 559166124Srafan && !isDefaultColor(old_bg)) { 56062449Speter tputs("\033[49m", 1, outc); 56162449Speter } else 56262449Speter#endif 563166124Srafan reset_color_pair(); 56450276Speter } 56562449Speter } else { 566166124Srafan reset_color_pair(); 56762449Speter if (old_pair < 0) 56862449Speter return; 56950276Speter } 57050276Speter 57166963Speter#if NCURSES_EXT_FUNCS 572166124Srafan if (isDefaultColor(fg)) 57362449Speter fg = default_fg(); 574166124Srafan if (isDefaultColor(bg)) 57562449Speter bg = default_bg(); 57662449Speter#endif 57750276Speter 57862449Speter if (reverse) { 57962449Speter NCURSES_COLOR_T xx = fg; 58062449Speter fg = bg; 58162449Speter bg = xx; 58250276Speter } 58362449Speter 58476726Speter TR(TRACE_ATTRS, ("setting colors: pair = %d, fg = %d, bg = %d", pair, 58576726Speter fg, bg)); 58662449Speter 587166124Srafan if (!isDefaultColor(fg)) { 58862449Speter set_foreground_color(fg, outc); 58962449Speter } 590166124Srafan if (!isDefaultColor(bg)) { 59162449Speter set_background_color(bg, outc); 59262449Speter } 59350276Speter} 594