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