Home | History | Annotate | Line # | Download | only in libcurses
color.c revision 1.28
      1 /*	$NetBSD: color.c,v 1.28 2004/03/16 07:52:43 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.28 2004/03/16 07:52:43 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  * can_change_colors --
     93  *	Alias for can_change_color().
     94  *	To be removed at next major number increment.
     95  */
     96 bool
     97 can_change_colors(void)
     98 {
     99 	return can_change_color();
    100 }
    101 
    102 /*
    103  * start_color --
    104  *	Initialise colour support.
    105  */
    106 int
    107 start_color(void)
    108 {
    109 	int			 i;
    110 	attr_t			 temp_nc;
    111 	struct __winlist	*wlp;
    112 	WINDOW			*win;
    113 	int			 y, x;
    114 
    115 	if (has_colors() == FALSE)
    116 		return(ERR);
    117 
    118 	/* Max colours and colour pairs */
    119 	if (__tc_Co == -1)
    120 		COLORS = 0;
    121 	else {
    122 		COLORS = __tc_Co > MAX_COLORS ? MAX_COLORS : __tc_Co;
    123 		if (__tc_pa == -1) {
    124 			COLOR_PAIRS = 0;
    125 			COLORS = 0;
    126 		} else {
    127 			COLOR_PAIRS = (__tc_pa > MAX_PAIRS ?
    128 			    MAX_PAIRS : __tc_pa) - 1;
    129 			 /* Use the last colour pair for curses default. */
    130 			__default_color = COLOR_PAIR(COLOR_PAIRS);
    131 		}
    132 	}
    133 	if (!COLORS)
    134 		return (ERR);
    135 
    136 	_cursesi_screen->COLORS = COLORS;
    137 	_cursesi_screen->COLOR_PAIRS = COLOR_PAIRS;
    138 
    139 	/* Reset terminal colour and colour pairs. */
    140 	if (__tc_oc != NULL)
    141 		tputs(__tc_oc, 0, __cputchar);
    142 	if (__tc_op != NULL) {
    143 		tputs(__tc_op, 0, __cputchar);
    144 		curscr->wattr &= _cursesi_screen->mask_op;
    145 	}
    146 
    147 	/* Type of colour manipulation - ANSI/TEK/HP/other */
    148 	if (__tc_AF != NULL && __tc_AB != NULL)
    149 		_cursesi_screen->color_type = COLOR_ANSI;
    150 	else if (__tc_Ip != NULL)
    151 		_cursesi_screen->color_type = COLOR_HP;
    152 	else if (__tc_Ic != NULL)
    153 		_cursesi_screen->color_type = COLOR_TEK;
    154 	else if (__tc_Sb != NULL && __tc_Sf != NULL)
    155 		_cursesi_screen->color_type = COLOR_OTHER;
    156 	else
    157 		return(ERR);		/* Unsupported colour method */
    158 
    159 #ifdef DEBUG
    160 	__CTRACE("start_color: COLORS = %d, COLOR_PAIRS = %d",
    161 	    COLORS, COLOR_PAIRS);
    162 	switch (_cursesi_screen->color_type) {
    163 	case COLOR_ANSI:
    164 		__CTRACE(" (ANSI style)\n");
    165 		break;
    166 	case COLOR_HP:
    167 		__CTRACE(" (HP style)\n");
    168 		break;
    169 	case COLOR_TEK:
    170 		__CTRACE(" (Tektronics style)\n");
    171 		break;
    172 	case COLOR_OTHER:
    173 		__CTRACE(" (Other style)\n");
    174 		break;
    175 	}
    176 #endif
    177 
    178 	/*
    179 	 * Attributes that cannot be used with color.
    180 	 * Store these in an attr_t for wattrset()/wattron().
    181 	 */
    182 	_cursesi_screen->nca = __NORMAL;
    183 	if (__tc_NC != -1) {
    184 		temp_nc = (attr_t) t_getnum(_cursesi_screen->cursesi_genbuf, "NC");
    185 		if (temp_nc & 0x0001)
    186 			_cursesi_screen->nca |= __STANDOUT;
    187 		if (temp_nc & 0x0002)
    188 			_cursesi_screen->nca |= __UNDERSCORE;
    189 		if (temp_nc & 0x0004)
    190 			_cursesi_screen->nca |= __REVERSE;
    191 		if (temp_nc & 0x0008)
    192 			_cursesi_screen->nca |= __BLINK;
    193 		if (temp_nc & 0x0010)
    194 			_cursesi_screen->nca |= __DIM;
    195 		if (temp_nc & 0x0020)
    196 			_cursesi_screen->nca |= __BOLD;
    197 		if (temp_nc & 0x0040)
    198 			_cursesi_screen->nca |= __BLANK;
    199 		if (temp_nc & 0x0080)
    200 			_cursesi_screen->nca |= __PROTECT;
    201 		if (temp_nc & 0x0100)
    202 			_cursesi_screen->nca |= __ALTCHARSET;
    203 	}
    204 #ifdef DEBUG
    205 	__CTRACE ("start_color: _cursesi_screen->nca = %08x\n",
    206 	    _cursesi_screen->nca);
    207 #endif
    208 
    209 	/* Set up initial 8 colours */
    210 	if (COLORS >= COLOR_BLACK)
    211 		(void) init_color(COLOR_BLACK, 0, 0, 0);
    212 	if (COLORS >= COLOR_RED)
    213 		(void) init_color(COLOR_RED, 1000, 0, 0);
    214 	if (COLORS >= COLOR_GREEN)
    215 		(void) init_color(COLOR_GREEN, 0, 1000, 0);
    216 	if (COLORS >= COLOR_YELLOW)
    217 		(void) init_color(COLOR_YELLOW, 1000, 1000, 0);
    218 	if (COLORS >= COLOR_BLUE)
    219 		(void) init_color(COLOR_BLUE, 0, 0, 1000);
    220 	if (COLORS >= COLOR_MAGENTA)
    221 		(void) init_color(COLOR_MAGENTA, 1000, 0, 1000);
    222 	if (COLORS >= COLOR_CYAN)
    223 		(void) init_color(COLOR_CYAN, 0, 1000, 1000);
    224 	if (COLORS >= COLOR_WHITE)
    225 		(void) init_color(COLOR_WHITE, 1000, 1000, 1000);
    226 
    227 	/* Initialise other colours */
    228 	for (i = 8; i < COLORS; i++) {
    229 		_cursesi_screen->colours[i].red = 0;
    230 		_cursesi_screen->colours[i].green = 0;
    231 		_cursesi_screen->colours[i].blue = 0;
    232 		_cursesi_screen->colours[i].flags = 0;
    233 	}
    234 
    235 	/* Initialise pair 0 to default colours. */
    236 	_cursesi_screen->colour_pairs[0].fore = -1;
    237 	_cursesi_screen->colour_pairs[0].back = -1;
    238 	_cursesi_screen->colour_pairs[0].flags = 0;
    239 
    240 	/* Initialise user colour pairs to default (white on black) */
    241 	for (i = 1; i < COLOR_PAIRS; i++) {
    242 		_cursesi_screen->colour_pairs[i].fore = COLOR_WHITE;
    243 		_cursesi_screen->colour_pairs[i].back = COLOR_BLACK;
    244 		_cursesi_screen->colour_pairs[i].flags = 0;
    245 	}
    246 
    247 	/* Initialise default colour pair. */
    248 	_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore =
    249 	    __default_pair.fore;
    250 	_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back =
    251 	    __default_pair.back;
    252 	_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags =
    253 	    __default_pair.flags;
    254 
    255 	__using_color = 1;
    256 
    257 	/* Set all positions on all windows to curses default colours. */
    258 	for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) {
    259 		win = wlp->winp;
    260 		if (wlp->winp == curscr) {
    261 			/* Reset colour attribute on curscr */
    262 			for (y = 0; y < curscr->maxy; y++)
    263 				for (x = 0; x < curscr->maxx; x++) {
    264 					if ((curscr->lines[y]->line[x].battr & __COLOR) == __default_color)
    265 						curscr->lines[y]->line[x].battr &= ~__COLOR;
    266 				}
    267 		} else if (wlp->winp != __virtscr) {
    268 			/* Set background attribute on other windows */
    269 			if (!(win->battr & __COLOR))
    270 				win->battr |= __default_color;
    271 			for (y = 0; y < win->maxy; y++) {
    272 				for (x = 0; x < win->maxx; x++)
    273 					if (!(win->lines[y]->line[x].battr & __COLOR))
    274 						win->lines[y]->line[x].battr |= __default_color;
    275 			}
    276 			__touchwin(win);
    277 		}
    278 	}
    279 
    280 	return(OK);
    281 }
    282 
    283 /*
    284  * init_pair --
    285  *	Set pair foreground and background colors.
    286  *	Our default colour ordering is ANSI - 1 = red, 4 = blue, 3 = yellow,
    287  *	6 = cyan.  The older style (Sb/Sf) uses 1 = blue, 4 = red, 3 = cyan,
    288  *	6 = yellow, so we swap them here and in pair_content().
    289  */
    290 int
    291 init_pair(short pair, short fore, short back)
    292 {
    293 	int	changed;
    294 
    295 #ifdef DEBUG
    296 	__CTRACE("init_pair: %d, %d, %d\n", pair, fore, back);
    297 #endif
    298 
    299 	if (pair < 0 || pair >= COLOR_PAIRS)
    300 		return (ERR);
    301 	if (fore >= COLORS)
    302 		return (ERR);
    303 	if (back >= COLORS)
    304 		return (ERR);
    305 
    306 	/* Swap red/blue and yellow/cyan */
    307 	if (_cursesi_screen->color_type == COLOR_OTHER) {
    308 		switch (fore) {
    309 		case COLOR_RED:
    310 			fore = COLOR_BLUE;
    311 			break;
    312 		case COLOR_BLUE:
    313 			fore = COLOR_RED;
    314 			break;
    315 		case COLOR_YELLOW:
    316 			fore = COLOR_CYAN;
    317 			break;
    318 		case COLOR_CYAN:
    319 			fore = COLOR_YELLOW;
    320 			break;
    321 		}
    322 		switch (back) {
    323 		case COLOR_RED:
    324 			back = COLOR_BLUE;
    325 			break;
    326 		case COLOR_BLUE:
    327 			back = COLOR_RED;
    328 			break;
    329 		case COLOR_YELLOW:
    330 			back = COLOR_CYAN;
    331 			break;
    332 		case COLOR_CYAN:
    333 			back = COLOR_YELLOW;
    334 			break;
    335 		}
    336 	}
    337 
    338 	if ((_cursesi_screen->colour_pairs[pair].flags & __USED) &&
    339 	    (fore != _cursesi_screen->colour_pairs[pair].fore ||
    340 	     back != _cursesi_screen->colour_pairs[pair].back))
    341 		changed = 1;
    342 	else
    343 		changed = 0;
    344 
    345 	_cursesi_screen->colour_pairs[pair].flags |= __USED;
    346 	_cursesi_screen->colour_pairs[pair].fore = fore;
    347 	_cursesi_screen->colour_pairs[pair].back = back;
    348 
    349 	/* XXX: need to initialise HP style (Ip) */
    350 
    351 	if (changed)
    352 		__change_pair(pair);
    353 	return (OK);
    354 }
    355 
    356 /*
    357  * pair_content --
    358  *	Get pair foreground and background colours.
    359  */
    360 int
    361 pair_content(short pair, short *forep, short *backp)
    362 {
    363 	if (pair < 0 || pair > _cursesi_screen->COLOR_PAIRS)
    364 		return(ERR);
    365 
    366 	*forep = _cursesi_screen->colour_pairs[pair].fore;
    367 	*backp = _cursesi_screen->colour_pairs[pair].back;
    368 
    369 	/* Swap red/blue and yellow/cyan */
    370 	if (_cursesi_screen->color_type == COLOR_OTHER) {
    371 		switch (*forep) {
    372 		case COLOR_RED:
    373 			*forep = COLOR_BLUE;
    374 			break;
    375 		case COLOR_BLUE:
    376 			*forep = COLOR_RED;
    377 			break;
    378 		case COLOR_YELLOW:
    379 			*forep = COLOR_CYAN;
    380 			break;
    381 		case COLOR_CYAN:
    382 			*forep = COLOR_YELLOW;
    383 			break;
    384 		}
    385 		switch (*backp) {
    386 		case COLOR_RED:
    387 			*backp = COLOR_BLUE;
    388 			break;
    389 		case COLOR_BLUE:
    390 			*backp = COLOR_RED;
    391 			break;
    392 		case COLOR_YELLOW:
    393 			*backp = COLOR_CYAN;
    394 			break;
    395 		case COLOR_CYAN:
    396 			*backp = COLOR_YELLOW;
    397 			break;
    398 		}
    399 	}
    400 	return(OK);
    401 }
    402 
    403 /*
    404  * init_color --
    405  *	Set colour red, green and blue values.
    406  */
    407 int
    408 init_color(short color, short red, short green, short blue)
    409 {
    410 #ifdef DEBUG
    411 	__CTRACE("init_color: %d, %d, %d, %d\n", color, red, green, blue);
    412 #endif
    413 	if (color < 0 || color >= _cursesi_screen->COLORS)
    414 		return(ERR);
    415 
    416 	_cursesi_screen->colours[color].red = red;
    417 	_cursesi_screen->colours[color].green = green;
    418 	_cursesi_screen->colours[color].blue = blue;
    419 	/* XXX Not yet implemented */
    420 	return(ERR);
    421 	/* XXX: need to initialise Tek style (Ic) and support HLS */
    422 }
    423 
    424 /*
    425  * color_content --
    426  *	Get colour red, green and blue values.
    427  */
    428 int
    429 color_content(short color, short *redp, short *greenp, short *bluep)
    430 {
    431 	if (color < 0 || color >= _cursesi_screen->COLORS)
    432 		return(ERR);
    433 
    434 	*redp = _cursesi_screen->colours[color].red;
    435 	*greenp = _cursesi_screen->colours[color].green;
    436 	*bluep = _cursesi_screen->colours[color].blue;
    437 	return(OK);
    438 }
    439 
    440 /*
    441  * use_default_colors --
    442  *	Use terminal default colours instead of curses default colour.
    443   */
    444 int
    445 use_default_colors()
    446 {
    447 #ifdef DEBUG
    448 	__CTRACE("use_default_colors\n");
    449 #endif
    450 
    451 	return(assume_default_colors(-1, -1));
    452 }
    453 
    454 /*
    455  * assume_default_colors --
    456  *	Set the default foreground and background colours.
    457  */
    458 int
    459 assume_default_colors(short fore, short back)
    460 {
    461 #ifdef DEBUG
    462 	__CTRACE("assume_default_colors: %d, %d\n", fore, back);
    463 #endif
    464 	/* Swap red/blue and yellow/cyan */
    465 	if (_cursesi_screen->color_type == COLOR_OTHER) {
    466 		switch (fore) {
    467 		case COLOR_RED:
    468 			fore = COLOR_BLUE;
    469 			break;
    470 		case COLOR_BLUE:
    471 			fore = COLOR_RED;
    472 			break;
    473 		case COLOR_YELLOW:
    474 			fore = COLOR_CYAN;
    475 			break;
    476 		case COLOR_CYAN:
    477 			fore = COLOR_YELLOW;
    478 			break;
    479 		}
    480 		switch (back) {
    481 		case COLOR_RED:
    482 			back = COLOR_BLUE;
    483 			break;
    484 		case COLOR_BLUE:
    485 			back = COLOR_RED;
    486 			break;
    487 		case COLOR_YELLOW:
    488 			back = COLOR_CYAN;
    489 			break;
    490 		case COLOR_CYAN:
    491 			back = COLOR_YELLOW;
    492 			break;
    493 		}
    494 	}
    495 	__default_pair.fore = fore;
    496 	__default_pair.back = back;
    497 	__default_pair.flags = __USED;
    498 
    499 	if (COLOR_PAIRS) {
    500 		_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore = fore;
    501 		_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back = back;
    502 		_cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags = __USED;
    503 	}
    504 
    505 	/*
    506 	 * If we've already called start_color(), make sure all instances
    507 	 * of the curses default colour pair are dirty.
    508 	 */
    509 	if (__using_color)
    510 		__change_pair(PAIR_NUMBER(__default_color));
    511 
    512 	return(OK);
    513 }
    514 
    515 /*
    516  * no_color_video --
    517  *	Return attributes that cannot be combined with color.
    518  */
    519 attr_t
    520 no_color_video(void)
    521 {
    522 	return(_cursesi_screen->nca);
    523 }
    524 
    525 /*
    526  * __set_color --
    527  *	Set terminal foreground and background colours.
    528  */
    529 void
    530 __set_color( /*ARGSUSED*/ WINDOW *win, attr_t attr)
    531 {
    532 	short	pair;
    533 
    534 	if ((curscr->wattr & __COLOR) == (attr & __COLOR))
    535 		return;
    536 
    537 	pair = PAIR_NUMBER((u_int32_t)attr);
    538 #ifdef DEBUG
    539 	__CTRACE("__set_color: %d, %d, %d\n", pair,
    540 		 _cursesi_screen->colour_pairs[pair].fore,
    541 		 _cursesi_screen->colour_pairs[pair].back);
    542 #endif
    543 	switch (_cursesi_screen->color_type) {
    544 	/* Set ANSI forground and background colours */
    545 	case COLOR_ANSI:
    546 		if (_cursesi_screen->colour_pairs[pair].fore < 0 ||
    547 		    _cursesi_screen->colour_pairs[pair].back < 0)
    548 			__unset_color(curscr);
    549 		if (_cursesi_screen->colour_pairs[pair].fore >= 0)
    550 			tputs(__parse_cap(_cursesi_screen->tc_AF,
    551 			    _cursesi_screen->colour_pairs[pair].fore),
    552 			    0, __cputchar);
    553 		if (_cursesi_screen->colour_pairs[pair].back >= 0)
    554 			tputs(__parse_cap(_cursesi_screen->tc_AB,
    555 			    _cursesi_screen->colour_pairs[pair].back),
    556 			    0, __cputchar);
    557 		break;
    558 	case COLOR_HP:
    559 		/* XXX: need to support HP style */
    560 		break;
    561 	case COLOR_TEK:
    562 		/* XXX: need to support Tek style */
    563 		break;
    564 	case COLOR_OTHER:
    565 		if (_cursesi_screen->colour_pairs[pair].fore < 0 ||
    566 		    _cursesi_screen->colour_pairs[pair].back < 0)
    567 			__unset_color(curscr);
    568 		if (_cursesi_screen->colour_pairs[pair].fore >= 0)
    569 			tputs(__parse_cap(_cursesi_screen->tc_Sf,
    570 			    _cursesi_screen->colour_pairs[pair].fore),
    571 			    0, __cputchar);
    572 		if (_cursesi_screen->colour_pairs[pair].back >= 0)
    573 			tputs(__parse_cap(_cursesi_screen->tc_Sb,
    574 			    _cursesi_screen->colour_pairs[pair].back),
    575 			    0, __cputchar);
    576 		break;
    577 	}
    578 	curscr->wattr &= ~__COLOR;
    579 	curscr->wattr |= attr & __COLOR;
    580 }
    581 
    582 /*
    583  * __unset_color --
    584  *	Clear terminal foreground and background colours.
    585  */
    586 void
    587 __unset_color(WINDOW *win)
    588 {
    589 #ifdef DEBUG
    590 	__CTRACE("__unset_color\n");
    591 #endif
    592 	switch (_cursesi_screen->color_type) {
    593 	/* Clear ANSI forground and background colours */
    594 	case COLOR_ANSI:
    595 		if (__tc_op != NULL) {
    596 			tputs(__tc_op, 0, __cputchar);
    597 			win->wattr &= __mask_op;
    598 		}
    599 		break;
    600 	case COLOR_HP:
    601 		/* XXX: need to support HP style */
    602 		break;
    603 	case COLOR_TEK:
    604 		/* XXX: need to support Tek style */
    605 		break;
    606 	case COLOR_OTHER:
    607 		if (__tc_op != NULL) {
    608 			tputs(__tc_op, 0, __cputchar);
    609 			win->wattr &= __mask_op;
    610 		}
    611 		break;
    612 	}
    613 }
    614 
    615 /*
    616  * __restore_colors --
    617  *	Redo color definitions after restarting 'curses' mode.
    618  */
    619 void
    620 __restore_colors(void)
    621 {
    622 	if (__tc_cc != 0)
    623 		switch (_cursesi_screen->color_type) {
    624 		case COLOR_HP:
    625 			/* XXX: need to re-initialise HP style (Ip) */
    626 			break;
    627 		case COLOR_TEK:
    628 			/* XXX: need to re-initialise Tek style (Ic) */
    629 			break;
    630 		}
    631 }
    632 
    633 /*
    634  * __change_pair --
    635  *	Mark dirty all positions using pair.
    636  */
    637 void
    638 __change_pair(short pair)
    639 {
    640 	struct __winlist	*wlp;
    641 	WINDOW			*win;
    642 	int			 y, x;
    643 	__LINE			*lp;
    644 	uint32_t		cl = COLOR_PAIR(pair);
    645 
    646 
    647 	for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) {
    648 #ifdef DEBUG
    649 		__CTRACE("__change_pair: win = %p\n", wlp->winp);
    650 #endif
    651 		win = wlp->winp;
    652 		if (win == __virtscr)
    653 			continue;
    654 
    655 		if (win == curscr) {
    656 			/* Reset colour attribute on curscr */
    657 #ifdef DEBUG
    658 			__CTRACE("__change_pair: win == curscr\n");
    659 #endif
    660 			for (y = 0; y < curscr->maxy; y++) {
    661 				lp = curscr->lines[y];
    662 				for (x = 0; x < curscr->maxx; x++) {
    663 					if ((lp->line[x].attr & __COLOR) == cl)
    664 						lp->line[x].attr &= ~__COLOR;
    665 					if ((lp->line[x].battr & __COLOR) == cl)
    666 						lp->line[x].battr &= ~__COLOR;
    667 				}
    668 			}
    669 			continue;
    670 		}
    671 
    672 		/* Mark dirty those positions with colour pair "pair" */
    673 		for (y = 0; y < win->maxy; y++) {
    674 			lp = curscr->lines[y];
    675 			for (x = 0; x < win->maxx; x++)
    676 				if ((lp->line[x].attr & __COLOR) == cl ||
    677 				    (lp->line[x].battr & __COLOR) == cl) {
    678 					if (!(lp->flags & __ISDIRTY))
    679 						lp->flags |= __ISDIRTY;
    680 					/*
    681 					 * firstchp/lastchp are shared
    682 					 * between parent window and
    683 					 * sub-window.
    684 					 */
    685 					if (*lp->firstchp > x)
    686 						*lp->firstchp = x;
    687 					if (*lp->lastchp < x)
    688 						*lp->lastchp = x;
    689 				}
    690 #ifdef DEBUG
    691 			if ((win->lines[y]->flags & __ISDIRTY))
    692 				__CTRACE("__change_pair: first = %d, last = %d\n", *win->lines[y]->firstchp, *win->lines[y]->lastchp);
    693 #endif
    694 		}
    695 	}
    696 }
    697