Home | History | Annotate | Line # | Download | only in libcurses
color.c revision 1.32
      1 /*	$NetBSD: color.c,v 1.32 2007/01/21 13:25:36 jdc Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Julian Coleman.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include <sys/cdefs.h>
     40 #ifndef lint
     41 __RCSID("$NetBSD: color.c,v 1.32 2007/01/21 13:25:36 jdc Exp $");
     42 #endif				/* not lint */
     43 
     44 #include "curses.h"
     45 #include "curses_private.h"
     46 
     47 /* Have we initialised colours? */
     48 int	__using_color = 0;
     49 
     50 /* Default colour number */
     51 attr_t	__default_color = 0;
     52 
     53 /* Default colour pair values - white on black. */
     54 struct __pair	__default_pair = {COLOR_WHITE, COLOR_BLACK, 0};
     55 
     56 /* Default colour values */
     57 /* Flags for colours and pairs */
     58 #define	__USED		0x01
     59 
     60 static void
     61 __change_pair(short);
     62 
     63 /*
     64  * has_colors --
     65  *	Check if terminal has colours.
     66  */
     67 bool
     68 has_colors(void)
     69 {
     70 	if (__tc_Co > 0 && __tc_pa > 0 && ((__tc_AF != NULL &&
     71 	    __tc_AB != NULL) || __tc_Ip != NULL || __tc_Ic != NULL ||
     72 	    (__tc_Sb != NULL && __tc_Sf != NULL)))
     73 		return(TRUE);
     74 	else
     75 		return(FALSE);
     76 }
     77 
     78 /*
     79  * can_change_color --
     80  *	Check if terminal can change colours.
     81  */
     82 bool
     83 can_change_color(void)
     84 {
     85 	if (__tc_cc)
     86 		return(TRUE);
     87 	else
     88 		return(FALSE);
     89 }
     90 
     91 /*
     92  * start_color --
     93  *	Initialise colour support.
     94  */
     95 int
     96 start_color(void)
     97 {
     98 	int			 i;
     99 	attr_t			 temp_nc;
    100 	struct __winlist	*wlp;
    101 	WINDOW			*win;
    102 	int			 y, x;
    103 
    104 	if (has_colors() == FALSE)
    105 		return(ERR);
    106 
    107 	/* Max colours and colour pairs */
    108 	if (__tc_Co == -1)
    109 		COLORS = 0;
    110 	else {
    111 		COLORS = __tc_Co > MAX_COLORS ? MAX_COLORS : __tc_Co;
    112 		if (__tc_pa == -1) {
    113 			COLOR_PAIRS = 0;
    114 			COLORS = 0;
    115 		} else {
    116 			COLOR_PAIRS = (__tc_pa > MAX_PAIRS - 1 ?
    117 			    MAX_PAIRS - 1 : __tc_pa);
    118 			 /* Use the last colour pair for curses default. */
    119 			__default_color = COLOR_PAIR(MAX_PAIRS - 1);
    120 		}
    121 	}
    122 	if (!COLORS)
    123 		return (ERR);
    124 
    125 	_cursesi_screen->COLORS = COLORS;
    126 	_cursesi_screen->COLOR_PAIRS = COLOR_PAIRS;
    127 
    128 	/* Reset terminal colour and colour pairs. */
    129 	if (__tc_oc != NULL)
    130 		tputs(__tc_oc, 0, __cputchar);
    131 	if (__tc_op != NULL) {
    132 		tputs(__tc_op, 0, __cputchar);
    133 		curscr->wattr &= _cursesi_screen->mask_op;
    134 	}
    135 
    136 	/* Type of colour manipulation - ANSI/TEK/HP/other */
    137 	if (__tc_AF != NULL && __tc_AB != NULL)
    138 		_cursesi_screen->color_type = COLOR_ANSI;
    139 	else if (__tc_Ip != NULL)
    140 		_cursesi_screen->color_type = COLOR_HP;
    141 	else if (__tc_Ic != NULL)
    142 		_cursesi_screen->color_type = COLOR_TEK;
    143 	else if (__tc_Sb != NULL && __tc_Sf != NULL)
    144 		_cursesi_screen->color_type = COLOR_OTHER;
    145 	else
    146 		return(ERR);		/* Unsupported colour method */
    147 
    148 #ifdef DEBUG
    149 	__CTRACE(__CTRACE_COLOR, "start_color: COLORS = %d, COLOR_PAIRS = %d",
    150 	    COLORS, COLOR_PAIRS);
    151 	switch (_cursesi_screen->color_type) {
    152 	case COLOR_ANSI:
    153 		__CTRACE(__CTRACE_COLOR, " (ANSI style)\n");
    154 		break;
    155 	case COLOR_HP:
    156 		__CTRACE(__CTRACE_COLOR, " (HP style)\n");
    157 		break;
    158 	case COLOR_TEK:
    159 		__CTRACE(__CTRACE_COLOR, " (Tektronics style)\n");
    160 		break;
    161 	case COLOR_OTHER:
    162 		__CTRACE(__CTRACE_COLOR, " (Other style)\n");
    163 		break;
    164 	}
    165 #endif
    166 
    167 	/*
    168 	 * Attributes that cannot be used with color.
    169 	 * Store these in an attr_t for wattrset()/wattron().
    170 	 */
    171 	_cursesi_screen->nca = __NORMAL;
    172 	if (__tc_NC != -1) {
    173 		temp_nc = (attr_t) t_getnum(_cursesi_screen->cursesi_genbuf, "NC");
    174 		if (temp_nc & 0x0001)
    175 			_cursesi_screen->nca |= __STANDOUT;
    176 		if (temp_nc & 0x0002)
    177 			_cursesi_screen->nca |= __UNDERSCORE;
    178 		if (temp_nc & 0x0004)
    179 			_cursesi_screen->nca |= __REVERSE;
    180 		if (temp_nc & 0x0008)
    181 			_cursesi_screen->nca |= __BLINK;
    182 		if (temp_nc & 0x0010)
    183 			_cursesi_screen->nca |= __DIM;
    184 		if (temp_nc & 0x0020)
    185 			_cursesi_screen->nca |= __BOLD;
    186 		if (temp_nc & 0x0040)
    187 			_cursesi_screen->nca |= __BLANK;
    188 		if (temp_nc & 0x0080)
    189 			_cursesi_screen->nca |= __PROTECT;
    190 		if (temp_nc & 0x0100)
    191 			_cursesi_screen->nca |= __ALTCHARSET;
    192 	}
    193 #ifdef DEBUG
    194 	__CTRACE(__CTRACE_COLOR, "start_color: _cursesi_screen->nca = %08x\n",
    195 	    _cursesi_screen->nca);
    196 #endif
    197 
    198 	/* Set up initial 8 colours */
    199 	if (COLORS >= COLOR_BLACK)
    200 		(void) init_color(COLOR_BLACK, 0, 0, 0);
    201 	if (COLORS >= COLOR_RED)
    202 		(void) init_color(COLOR_RED, 1000, 0, 0);
    203 	if (COLORS >= COLOR_GREEN)
    204 		(void) init_color(COLOR_GREEN, 0, 1000, 0);
    205 	if (COLORS >= COLOR_YELLOW)
    206 		(void) init_color(COLOR_YELLOW, 1000, 1000, 0);
    207 	if (COLORS >= COLOR_BLUE)
    208 		(void) init_color(COLOR_BLUE, 0, 0, 1000);
    209 	if (COLORS >= COLOR_MAGENTA)
    210 		(void) init_color(COLOR_MAGENTA, 1000, 0, 1000);
    211 	if (COLORS >= COLOR_CYAN)
    212 		(void) init_color(COLOR_CYAN, 0, 1000, 1000);
    213 	if (COLORS >= COLOR_WHITE)
    214 		(void) init_color(COLOR_WHITE, 1000, 1000, 1000);
    215 
    216 	/* Initialise other colours */
    217 	for (i = 8; i < COLORS; i++) {
    218 		_cursesi_screen->colours[i].red = 0;
    219 		_cursesi_screen->colours[i].green = 0;
    220 		_cursesi_screen->colours[i].blue = 0;
    221 		_cursesi_screen->colours[i].flags = 0;
    222 	}
    223 
    224 	/* Initialise pair 0 to default colours. */
    225 	_cursesi_screen->colour_pairs[0].fore = -1;
    226 	_cursesi_screen->colour_pairs[0].back = -1;
    227 	_cursesi_screen->colour_pairs[0].flags = 0;
    228 
    229 	/* Initialise user colour pairs to default (white on black) */
    230 	for (i = 0; i < COLOR_PAIRS; i++) {
    231 		_cursesi_screen->colour_pairs[i].fore = COLOR_WHITE;
    232 		_cursesi_screen->colour_pairs[i].back = COLOR_BLACK;
    233 		_cursesi_screen->colour_pairs[i].flags = 0;
    234 	}
    235 
    236 	/* Initialise default colour pair. */
    237 	_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore =
    238 	    __default_pair.fore;
    239 	_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back =
    240 	    __default_pair.back;
    241 	_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags =
    242 	    __default_pair.flags;
    243 
    244 	__using_color = 1;
    245 
    246 	/* Set all positions on all windows to curses default colours. */
    247 	for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) {
    248 		win = wlp->winp;
    249 		if (wlp->winp != __virtscr && wlp->winp != curscr) {
    250 			/* Set color attribute on other windows */
    251 			win->battr |= __default_color;
    252 			for (y = 0; y < win->maxy; y++) {
    253 				for (x = 0; x < win->maxx; x++) {
    254 					win->lines[y]->line[x].attr &= ~__COLOR;
    255 					win->lines[y]->line[x].attr |= __default_color;
    256 				}
    257 			}
    258 			__touchwin(win);
    259 		}
    260 	}
    261 
    262 	return(OK);
    263 }
    264 
    265 /*
    266  * init_pair --
    267  *	Set pair foreground and background colors.
    268  *	Our default colour ordering is ANSI - 1 = red, 4 = blue, 3 = yellow,
    269  *	6 = cyan.  The older style (Sb/Sf) uses 1 = blue, 4 = red, 3 = cyan,
    270  *	6 = yellow, so we swap them here and in pair_content().
    271  */
    272 int
    273 init_pair(short pair, short fore, short back)
    274 {
    275 	int	changed;
    276 
    277 #ifdef DEBUG
    278 	__CTRACE(__CTRACE_COLOR, "init_pair: %d, %d, %d\n", pair, fore, back);
    279 #endif
    280 
    281 	if (pair < 0 || pair >= COLOR_PAIRS)
    282 		return (ERR);
    283 	if (fore >= COLORS)
    284 		return (ERR);
    285 	if (back >= COLORS)
    286 		return (ERR);
    287 
    288 	/* Swap red/blue and yellow/cyan */
    289 	if (_cursesi_screen->color_type == COLOR_OTHER) {
    290 		switch (fore) {
    291 		case COLOR_RED:
    292 			fore = COLOR_BLUE;
    293 			break;
    294 		case COLOR_BLUE:
    295 			fore = COLOR_RED;
    296 			break;
    297 		case COLOR_YELLOW:
    298 			fore = COLOR_CYAN;
    299 			break;
    300 		case COLOR_CYAN:
    301 			fore = COLOR_YELLOW;
    302 			break;
    303 		}
    304 		switch (back) {
    305 		case COLOR_RED:
    306 			back = COLOR_BLUE;
    307 			break;
    308 		case COLOR_BLUE:
    309 			back = COLOR_RED;
    310 			break;
    311 		case COLOR_YELLOW:
    312 			back = COLOR_CYAN;
    313 			break;
    314 		case COLOR_CYAN:
    315 			back = COLOR_YELLOW;
    316 			break;
    317 		}
    318 	}
    319 
    320 	if ((_cursesi_screen->colour_pairs[pair].flags & __USED) &&
    321 	    (fore != _cursesi_screen->colour_pairs[pair].fore ||
    322 	     back != _cursesi_screen->colour_pairs[pair].back))
    323 		changed = 1;
    324 	else
    325 		changed = 0;
    326 
    327 	_cursesi_screen->colour_pairs[pair].flags |= __USED;
    328 	_cursesi_screen->colour_pairs[pair].fore = fore;
    329 	_cursesi_screen->colour_pairs[pair].back = back;
    330 
    331 	/* XXX: need to initialise HP style (Ip) */
    332 
    333 	if (changed)
    334 		__change_pair(pair);
    335 	return (OK);
    336 }
    337 
    338 /*
    339  * pair_content --
    340  *	Get pair foreground and background colours.
    341  */
    342 int
    343 pair_content(short pair, short *forep, short *backp)
    344 {
    345 	if (pair < 0 || pair > _cursesi_screen->COLOR_PAIRS)
    346 		return(ERR);
    347 
    348 	*forep = _cursesi_screen->colour_pairs[pair].fore;
    349 	*backp = _cursesi_screen->colour_pairs[pair].back;
    350 
    351 	/* Swap red/blue and yellow/cyan */
    352 	if (_cursesi_screen->color_type == COLOR_OTHER) {
    353 		switch (*forep) {
    354 		case COLOR_RED:
    355 			*forep = COLOR_BLUE;
    356 			break;
    357 		case COLOR_BLUE:
    358 			*forep = COLOR_RED;
    359 			break;
    360 		case COLOR_YELLOW:
    361 			*forep = COLOR_CYAN;
    362 			break;
    363 		case COLOR_CYAN:
    364 			*forep = COLOR_YELLOW;
    365 			break;
    366 		}
    367 		switch (*backp) {
    368 		case COLOR_RED:
    369 			*backp = COLOR_BLUE;
    370 			break;
    371 		case COLOR_BLUE:
    372 			*backp = COLOR_RED;
    373 			break;
    374 		case COLOR_YELLOW:
    375 			*backp = COLOR_CYAN;
    376 			break;
    377 		case COLOR_CYAN:
    378 			*backp = COLOR_YELLOW;
    379 			break;
    380 		}
    381 	}
    382 	return(OK);
    383 }
    384 
    385 /*
    386  * init_color --
    387  *	Set colour red, green and blue values.
    388  */
    389 int
    390 init_color(short color, short red, short green, short blue)
    391 {
    392 #ifdef DEBUG
    393 	__CTRACE(__CTRACE_COLOR, "init_color: %d, %d, %d, %d\n",
    394 	    color, red, green, blue);
    395 #endif
    396 	if (color < 0 || color >= _cursesi_screen->COLORS)
    397 		return(ERR);
    398 
    399 	_cursesi_screen->colours[color].red = red;
    400 	_cursesi_screen->colours[color].green = green;
    401 	_cursesi_screen->colours[color].blue = blue;
    402 	/* XXX Not yet implemented */
    403 	return(ERR);
    404 	/* XXX: need to initialise Tek style (Ic) and support HLS */
    405 }
    406 
    407 /*
    408  * color_content --
    409  *	Get colour red, green and blue values.
    410  */
    411 int
    412 color_content(short color, short *redp, short *greenp, short *bluep)
    413 {
    414 	if (color < 0 || color >= _cursesi_screen->COLORS)
    415 		return(ERR);
    416 
    417 	*redp = _cursesi_screen->colours[color].red;
    418 	*greenp = _cursesi_screen->colours[color].green;
    419 	*bluep = _cursesi_screen->colours[color].blue;
    420 	return(OK);
    421 }
    422 
    423 /*
    424  * use_default_colors --
    425  *	Use terminal default colours instead of curses default colour.
    426   */
    427 int
    428 use_default_colors()
    429 {
    430 #ifdef DEBUG
    431 	__CTRACE(__CTRACE_COLOR, "use_default_colors\n");
    432 #endif
    433 
    434 	return(assume_default_colors(-1, -1));
    435 }
    436 
    437 /*
    438  * assume_default_colors --
    439  *	Set the default foreground and background colours.
    440  */
    441 int
    442 assume_default_colors(short fore, short back)
    443 {
    444 #ifdef DEBUG
    445 	__CTRACE(__CTRACE_COLOR, "assume_default_colors: %d, %d\n",
    446 	    fore, back);
    447 #endif
    448 	/* Swap red/blue and yellow/cyan */
    449 	if (_cursesi_screen->color_type == COLOR_OTHER) {
    450 		switch (fore) {
    451 		case COLOR_RED:
    452 			fore = COLOR_BLUE;
    453 			break;
    454 		case COLOR_BLUE:
    455 			fore = COLOR_RED;
    456 			break;
    457 		case COLOR_YELLOW:
    458 			fore = COLOR_CYAN;
    459 			break;
    460 		case COLOR_CYAN:
    461 			fore = COLOR_YELLOW;
    462 			break;
    463 		}
    464 		switch (back) {
    465 		case COLOR_RED:
    466 			back = COLOR_BLUE;
    467 			break;
    468 		case COLOR_BLUE:
    469 			back = COLOR_RED;
    470 			break;
    471 		case COLOR_YELLOW:
    472 			back = COLOR_CYAN;
    473 			break;
    474 		case COLOR_CYAN:
    475 			back = COLOR_YELLOW;
    476 			break;
    477 		}
    478 	}
    479 	__default_pair.fore = fore;
    480 	__default_pair.back = back;
    481 	__default_pair.flags = __USED;
    482 
    483 	if (COLOR_PAIRS) {
    484 		_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore = fore;
    485 		_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back = back;
    486 		_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags = __USED;
    487 	}
    488 
    489 	/*
    490 	 * If we've already called start_color(), make sure all instances
    491 	 * of the curses default colour pair are dirty.
    492 	 */
    493 	if (__using_color)
    494 		__change_pair(PAIR_NUMBER(__default_color));
    495 
    496 	return(OK);
    497 }
    498 
    499 /*
    500  * no_color_video --
    501  *	Return attributes that cannot be combined with color.
    502  */
    503 attr_t
    504 no_color_video(void)
    505 {
    506 	return(_cursesi_screen->nca);
    507 }
    508 
    509 /*
    510  * __set_color --
    511  *	Set terminal foreground and background colours.
    512  */
    513 void
    514 __set_color( /*ARGSUSED*/ WINDOW *win, attr_t attr)
    515 {
    516 	short	pair;
    517 
    518 	if ((curscr->wattr & __COLOR) == (attr & __COLOR))
    519 		return;
    520 
    521 	pair = PAIR_NUMBER((u_int32_t)attr);
    522 #ifdef DEBUG
    523 	__CTRACE(__CTRACE_COLOR, "__set_color: %d, %d, %d\n", pair,
    524 		 _cursesi_screen->colour_pairs[pair].fore,
    525 		 _cursesi_screen->colour_pairs[pair].back);
    526 #endif
    527 	switch (_cursesi_screen->color_type) {
    528 	/* Set ANSI forground and background colours */
    529 	case COLOR_ANSI:
    530 		if (_cursesi_screen->colour_pairs[pair].fore < 0 ||
    531 		    _cursesi_screen->colour_pairs[pair].back < 0)
    532 			__unset_color(curscr);
    533 		if (_cursesi_screen->colour_pairs[pair].fore >= 0)
    534 			tputs(__parse_cap(_cursesi_screen->tc_AF,
    535 			    _cursesi_screen->colour_pairs[pair].fore),
    536 			    0, __cputchar);
    537 		if (_cursesi_screen->colour_pairs[pair].back >= 0)
    538 			tputs(__parse_cap(_cursesi_screen->tc_AB,
    539 			    _cursesi_screen->colour_pairs[pair].back),
    540 			    0, __cputchar);
    541 		break;
    542 	case COLOR_HP:
    543 		/* XXX: need to support HP style */
    544 		break;
    545 	case COLOR_TEK:
    546 		/* XXX: need to support Tek style */
    547 		break;
    548 	case COLOR_OTHER:
    549 		if (_cursesi_screen->colour_pairs[pair].fore < 0 ||
    550 		    _cursesi_screen->colour_pairs[pair].back < 0)
    551 			__unset_color(curscr);
    552 		if (_cursesi_screen->colour_pairs[pair].fore >= 0)
    553 			tputs(__parse_cap(_cursesi_screen->tc_Sf,
    554 			    _cursesi_screen->colour_pairs[pair].fore),
    555 			    0, __cputchar);
    556 		if (_cursesi_screen->colour_pairs[pair].back >= 0)
    557 			tputs(__parse_cap(_cursesi_screen->tc_Sb,
    558 			    _cursesi_screen->colour_pairs[pair].back),
    559 			    0, __cputchar);
    560 		break;
    561 	}
    562 	curscr->wattr &= ~__COLOR;
    563 	curscr->wattr |= attr & __COLOR;
    564 }
    565 
    566 /*
    567  * __unset_color --
    568  *	Clear terminal foreground and background colours.
    569  */
    570 void
    571 __unset_color(WINDOW *win)
    572 {
    573 #ifdef DEBUG
    574 	__CTRACE(__CTRACE_COLOR, "__unset_color\n");
    575 #endif
    576 	switch (_cursesi_screen->color_type) {
    577 	/* Clear ANSI forground and background colours */
    578 	case COLOR_ANSI:
    579 		if (__tc_op != NULL) {
    580 			tputs(__tc_op, 0, __cputchar);
    581 			win->wattr &= __mask_op;
    582 		}
    583 		break;
    584 	case COLOR_HP:
    585 		/* XXX: need to support HP style */
    586 		break;
    587 	case COLOR_TEK:
    588 		/* XXX: need to support Tek style */
    589 		break;
    590 	case COLOR_OTHER:
    591 		if (__tc_op != NULL) {
    592 			tputs(__tc_op, 0, __cputchar);
    593 			win->wattr &= __mask_op;
    594 		}
    595 		break;
    596 	}
    597 }
    598 
    599 /*
    600  * __restore_colors --
    601  *	Redo color definitions after restarting 'curses' mode.
    602  */
    603 void
    604 __restore_colors(void)
    605 {
    606 	if (__tc_cc != 0)
    607 		switch (_cursesi_screen->color_type) {
    608 		case COLOR_HP:
    609 			/* XXX: need to re-initialise HP style (Ip) */
    610 			break;
    611 		case COLOR_TEK:
    612 			/* XXX: need to re-initialise Tek style (Ic) */
    613 			break;
    614 		}
    615 }
    616 
    617 /*
    618  * __change_pair --
    619  *	Mark dirty all positions using pair.
    620  */
    621 void
    622 __change_pair(short pair)
    623 {
    624 	struct __winlist	*wlp;
    625 	WINDOW			*win;
    626 	int			 y, x;
    627 	__LINE			*lp;
    628 	uint32_t		cl = COLOR_PAIR(pair);
    629 
    630 
    631 	for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) {
    632 #ifdef DEBUG
    633 		__CTRACE(__CTRACE_COLOR, "__change_pair: win = %p\n",
    634 		    wlp->winp);
    635 #endif
    636 		win = wlp->winp;
    637 		if (win == __virtscr)
    638 			continue;
    639 		else if (win == curscr) {
    640 			/* Reset colour attribute on curscr */
    641 #ifdef DEBUG
    642 			__CTRACE(__CTRACE_COLOR,
    643 			    "__change_pair: win == curscr\n");
    644 #endif
    645 			for (y = 0; y < curscr->maxy; y++) {
    646 				lp = curscr->lines[y];
    647 				for (x = 0; x < curscr->maxx; x++) {
    648 					if ((lp->line[x].attr & __COLOR) == cl)
    649 						lp->line[x].attr &= ~__COLOR;
    650 				}
    651 			}
    652 		} else {
    653 			/* Mark dirty those positions with colour pair "pair" */
    654 			for (y = 0; y < win->maxy; y++) {
    655 				lp = win->lines[y];
    656 				for (x = 0; x < win->maxx; x++)
    657 					if ((lp->line[x].attr &
    658 					    __COLOR) == cl) {
    659 						if (!(lp->flags & __ISDIRTY))
    660 							lp->flags |= __ISDIRTY;
    661 						/*
    662 					 	* firstchp/lastchp are shared
    663 					 	* between parent window and
    664 					 	* sub-window.
    665 					 	*/
    666 						if (*lp->firstchp > x)
    667 						*lp->firstchp = x;
    668 						if (*lp->lastchp < x)
    669 							*lp->lastchp = x;
    670 					}
    671 #ifdef DEBUG
    672 				if ((win->lines[y]->flags & __ISDIRTY))
    673 					__CTRACE(__CTRACE_COLOR,
    674 					    "__change_pair: first = %d, "
    675 					    "last = %d\n",
    676 					    *win->lines[y]->firstchp,
    677 					    *win->lines[y]->lastchp);
    678 #endif
    679 			}
    680 		}
    681 	}
    682 }
    683