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