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