1*0c3ae37fSLionel Sambuc /* $NetBSD: color.c,v 1.38 2011/10/03 12:32:15 roy Exp $ */
251ffecc1SBen Gras
351ffecc1SBen Gras /*
451ffecc1SBen Gras * Copyright (c) 2000 The NetBSD Foundation, Inc.
551ffecc1SBen Gras * All rights reserved.
651ffecc1SBen Gras *
751ffecc1SBen Gras * This code is derived from software contributed to The NetBSD Foundation
851ffecc1SBen Gras * by Julian Coleman.
951ffecc1SBen Gras *
1051ffecc1SBen Gras * Redistribution and use in source and binary forms, with or without
1151ffecc1SBen Gras * modification, are permitted provided that the following conditions
1251ffecc1SBen Gras * are met:
1351ffecc1SBen Gras * 1. Redistributions of source code must retain the above copyright
1451ffecc1SBen Gras * notice, this list of conditions and the following disclaimer.
1551ffecc1SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
1651ffecc1SBen Gras * notice, this list of conditions and the following disclaimer in the
1751ffecc1SBen Gras * documentation and/or other materials provided with the distribution.
1851ffecc1SBen Gras *
1951ffecc1SBen Gras * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2051ffecc1SBen Gras * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2151ffecc1SBen Gras * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2251ffecc1SBen Gras * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2351ffecc1SBen Gras * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2451ffecc1SBen Gras * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2551ffecc1SBen Gras * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2651ffecc1SBen Gras * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2751ffecc1SBen Gras * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2851ffecc1SBen Gras * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2951ffecc1SBen Gras * POSSIBILITY OF SUCH DAMAGE.
3051ffecc1SBen Gras */
3151ffecc1SBen Gras
3251ffecc1SBen Gras #include <sys/cdefs.h>
3351ffecc1SBen Gras #ifndef lint
34*0c3ae37fSLionel Sambuc __RCSID("$NetBSD: color.c,v 1.38 2011/10/03 12:32:15 roy Exp $");
3551ffecc1SBen Gras #endif /* not lint */
3651ffecc1SBen Gras
3751ffecc1SBen Gras #include "curses.h"
3851ffecc1SBen Gras #include "curses_private.h"
3951ffecc1SBen Gras
4051ffecc1SBen Gras /* Have we initialised colours? */
4151ffecc1SBen Gras int __using_color = 0;
4251ffecc1SBen Gras
4351ffecc1SBen Gras /* Default colour number */
4451ffecc1SBen Gras attr_t __default_color = 0;
4551ffecc1SBen Gras
4651ffecc1SBen Gras /* Default colour pair values - white on black. */
4751ffecc1SBen Gras struct __pair __default_pair = {COLOR_WHITE, COLOR_BLACK, 0};
4851ffecc1SBen Gras
4951ffecc1SBen Gras /* Default colour values */
5051ffecc1SBen Gras /* Flags for colours and pairs */
5151ffecc1SBen Gras #define __USED 0x01
5251ffecc1SBen Gras
5351ffecc1SBen Gras static void
5451ffecc1SBen Gras __change_pair(short);
5551ffecc1SBen Gras
5651ffecc1SBen Gras /*
5751ffecc1SBen Gras * has_colors --
5851ffecc1SBen Gras * Check if terminal has colours.
5951ffecc1SBen Gras */
6051ffecc1SBen Gras bool
has_colors(void)6151ffecc1SBen Gras has_colors(void)
6251ffecc1SBen Gras {
6351ffecc1SBen Gras if (max_colors > 0 && max_pairs > 0 &&
6451ffecc1SBen Gras ((set_a_foreground != NULL && set_a_background != NULL) ||
6551ffecc1SBen Gras initialize_pair != NULL || initialize_color != NULL ||
6651ffecc1SBen Gras (set_background != NULL && set_foreground != NULL)))
6751ffecc1SBen Gras return(TRUE);
6851ffecc1SBen Gras else
6951ffecc1SBen Gras return(FALSE);
7051ffecc1SBen Gras }
7151ffecc1SBen Gras
7251ffecc1SBen Gras /*
7351ffecc1SBen Gras * can_change_color --
7451ffecc1SBen Gras * Check if terminal can change colours.
7551ffecc1SBen Gras */
7651ffecc1SBen Gras bool
can_change_color(void)7751ffecc1SBen Gras can_change_color(void)
7851ffecc1SBen Gras {
7951ffecc1SBen Gras if (can_change)
8051ffecc1SBen Gras return(TRUE);
8151ffecc1SBen Gras else
8251ffecc1SBen Gras return(FALSE);
8351ffecc1SBen Gras }
8451ffecc1SBen Gras
8551ffecc1SBen Gras /*
8651ffecc1SBen Gras * start_color --
8751ffecc1SBen Gras * Initialise colour support.
8851ffecc1SBen Gras */
8951ffecc1SBen Gras int
start_color(void)9051ffecc1SBen Gras start_color(void)
9151ffecc1SBen Gras {
9251ffecc1SBen Gras int i;
9351ffecc1SBen Gras attr_t temp_nc;
9451ffecc1SBen Gras struct __winlist *wlp;
9551ffecc1SBen Gras WINDOW *win;
9651ffecc1SBen Gras int y, x;
9751ffecc1SBen Gras
9851ffecc1SBen Gras if (has_colors() == FALSE)
9951ffecc1SBen Gras return(ERR);
10051ffecc1SBen Gras
10151ffecc1SBen Gras /* Max colours and colour pairs */
10251ffecc1SBen Gras if (max_colors == -1)
10351ffecc1SBen Gras COLORS = 0;
10451ffecc1SBen Gras else {
10551ffecc1SBen Gras COLORS = max_colors > MAX_COLORS ? MAX_COLORS : max_colors;
10651ffecc1SBen Gras if (max_pairs == -1) {
10751ffecc1SBen Gras COLOR_PAIRS = 0;
10851ffecc1SBen Gras COLORS = 0;
10951ffecc1SBen Gras } else {
11051ffecc1SBen Gras COLOR_PAIRS = (max_pairs > MAX_PAIRS - 1 ?
11151ffecc1SBen Gras MAX_PAIRS - 1 : max_pairs);
11251ffecc1SBen Gras /* Use the last colour pair for curses default. */
11351ffecc1SBen Gras __default_color = COLOR_PAIR(MAX_PAIRS - 1);
11451ffecc1SBen Gras }
11551ffecc1SBen Gras }
11651ffecc1SBen Gras if (!COLORS)
11751ffecc1SBen Gras return (ERR);
11851ffecc1SBen Gras
11951ffecc1SBen Gras _cursesi_screen->COLORS = COLORS;
12051ffecc1SBen Gras _cursesi_screen->COLOR_PAIRS = COLOR_PAIRS;
12151ffecc1SBen Gras
12251ffecc1SBen Gras /* Reset terminal colour and colour pairs. */
12351ffecc1SBen Gras if (orig_colors != NULL)
12451ffecc1SBen Gras tputs(orig_colors, 0, __cputchar);
12551ffecc1SBen Gras if (orig_pair != NULL) {
12651ffecc1SBen Gras tputs(orig_pair, 0, __cputchar);
12751ffecc1SBen Gras curscr->wattr &= _cursesi_screen->mask_op;
12851ffecc1SBen Gras }
12951ffecc1SBen Gras
13051ffecc1SBen Gras /* Type of colour manipulation - ANSI/TEK/HP/other */
13151ffecc1SBen Gras if (set_a_foreground != NULL && set_a_background != NULL)
13251ffecc1SBen Gras _cursesi_screen->color_type = COLOR_ANSI;
13351ffecc1SBen Gras else if (initialize_pair != NULL)
13451ffecc1SBen Gras _cursesi_screen->color_type = COLOR_HP;
13551ffecc1SBen Gras else if (initialize_color != NULL)
13651ffecc1SBen Gras _cursesi_screen->color_type = COLOR_TEK;
13751ffecc1SBen Gras else if (set_foreground != NULL && set_background != NULL)
13851ffecc1SBen Gras _cursesi_screen->color_type = COLOR_OTHER;
13951ffecc1SBen Gras else
14051ffecc1SBen Gras return(ERR); /* Unsupported colour method */
14151ffecc1SBen Gras
14251ffecc1SBen Gras #ifdef DEBUG
14351ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "start_color: COLORS = %d, COLOR_PAIRS = %d",
14451ffecc1SBen Gras COLORS, COLOR_PAIRS);
14551ffecc1SBen Gras switch (_cursesi_screen->color_type) {
14651ffecc1SBen Gras case COLOR_ANSI:
14751ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, " (ANSI style)\n");
14851ffecc1SBen Gras break;
14951ffecc1SBen Gras case COLOR_HP:
15051ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, " (HP style)\n");
15151ffecc1SBen Gras break;
15251ffecc1SBen Gras case COLOR_TEK:
15351ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, " (Tektronics style)\n");
15451ffecc1SBen Gras break;
15551ffecc1SBen Gras case COLOR_OTHER:
15651ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, " (Other style)\n");
15751ffecc1SBen Gras break;
15851ffecc1SBen Gras }
15951ffecc1SBen Gras #endif
16051ffecc1SBen Gras
16151ffecc1SBen Gras /*
16251ffecc1SBen Gras * Attributes that cannot be used with color.
16351ffecc1SBen Gras * Store these in an attr_t for wattrset()/wattron().
16451ffecc1SBen Gras */
16551ffecc1SBen Gras _cursesi_screen->nca = __NORMAL;
16651ffecc1SBen Gras if (no_color_video != -1) {
16751ffecc1SBen Gras temp_nc = (attr_t) t_no_color_video(_cursesi_screen->term);
16851ffecc1SBen Gras if (temp_nc & 0x0001)
16951ffecc1SBen Gras _cursesi_screen->nca |= __STANDOUT;
17051ffecc1SBen Gras if (temp_nc & 0x0002)
17151ffecc1SBen Gras _cursesi_screen->nca |= __UNDERSCORE;
17251ffecc1SBen Gras if (temp_nc & 0x0004)
17351ffecc1SBen Gras _cursesi_screen->nca |= __REVERSE;
17451ffecc1SBen Gras if (temp_nc & 0x0008)
17551ffecc1SBen Gras _cursesi_screen->nca |= __BLINK;
17651ffecc1SBen Gras if (temp_nc & 0x0010)
17751ffecc1SBen Gras _cursesi_screen->nca |= __DIM;
17851ffecc1SBen Gras if (temp_nc & 0x0020)
17951ffecc1SBen Gras _cursesi_screen->nca |= __BOLD;
18051ffecc1SBen Gras if (temp_nc & 0x0040)
18151ffecc1SBen Gras _cursesi_screen->nca |= __BLANK;
18251ffecc1SBen Gras if (temp_nc & 0x0080)
18351ffecc1SBen Gras _cursesi_screen->nca |= __PROTECT;
18451ffecc1SBen Gras if (temp_nc & 0x0100)
18551ffecc1SBen Gras _cursesi_screen->nca |= __ALTCHARSET;
18651ffecc1SBen Gras }
18751ffecc1SBen Gras #ifdef DEBUG
18851ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "start_color: _cursesi_screen->nca = %08x\n",
18951ffecc1SBen Gras _cursesi_screen->nca);
19051ffecc1SBen Gras #endif
19151ffecc1SBen Gras
19251ffecc1SBen Gras /* Set up initial 8 colours */
19351ffecc1SBen Gras if (COLORS >= COLOR_BLACK)
19451ffecc1SBen Gras (void) init_color(COLOR_BLACK, 0, 0, 0);
19551ffecc1SBen Gras if (COLORS >= COLOR_RED)
19651ffecc1SBen Gras (void) init_color(COLOR_RED, 1000, 0, 0);
19751ffecc1SBen Gras if (COLORS >= COLOR_GREEN)
19851ffecc1SBen Gras (void) init_color(COLOR_GREEN, 0, 1000, 0);
19951ffecc1SBen Gras if (COLORS >= COLOR_YELLOW)
20051ffecc1SBen Gras (void) init_color(COLOR_YELLOW, 1000, 1000, 0);
20151ffecc1SBen Gras if (COLORS >= COLOR_BLUE)
20251ffecc1SBen Gras (void) init_color(COLOR_BLUE, 0, 0, 1000);
20351ffecc1SBen Gras if (COLORS >= COLOR_MAGENTA)
20451ffecc1SBen Gras (void) init_color(COLOR_MAGENTA, 1000, 0, 1000);
20551ffecc1SBen Gras if (COLORS >= COLOR_CYAN)
20651ffecc1SBen Gras (void) init_color(COLOR_CYAN, 0, 1000, 1000);
20751ffecc1SBen Gras if (COLORS >= COLOR_WHITE)
20851ffecc1SBen Gras (void) init_color(COLOR_WHITE, 1000, 1000, 1000);
20951ffecc1SBen Gras
21051ffecc1SBen Gras /* Initialise other colours */
21151ffecc1SBen Gras for (i = 8; i < COLORS; i++) {
21251ffecc1SBen Gras _cursesi_screen->colours[i].red = 0;
21351ffecc1SBen Gras _cursesi_screen->colours[i].green = 0;
21451ffecc1SBen Gras _cursesi_screen->colours[i].blue = 0;
21551ffecc1SBen Gras _cursesi_screen->colours[i].flags = 0;
21651ffecc1SBen Gras }
21751ffecc1SBen Gras
21851ffecc1SBen Gras /* Initialise pair 0 to default colours. */
21951ffecc1SBen Gras _cursesi_screen->colour_pairs[0].fore = -1;
22051ffecc1SBen Gras _cursesi_screen->colour_pairs[0].back = -1;
22151ffecc1SBen Gras _cursesi_screen->colour_pairs[0].flags = 0;
22251ffecc1SBen Gras
22351ffecc1SBen Gras /* Initialise user colour pairs to default (white on black) */
22451ffecc1SBen Gras for (i = 0; i < COLOR_PAIRS; i++) {
22551ffecc1SBen Gras _cursesi_screen->colour_pairs[i].fore = COLOR_WHITE;
22651ffecc1SBen Gras _cursesi_screen->colour_pairs[i].back = COLOR_BLACK;
22751ffecc1SBen Gras _cursesi_screen->colour_pairs[i].flags = 0;
22851ffecc1SBen Gras }
22951ffecc1SBen Gras
23051ffecc1SBen Gras /* Initialise default colour pair. */
23151ffecc1SBen Gras _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore =
23251ffecc1SBen Gras __default_pair.fore;
23351ffecc1SBen Gras _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back =
23451ffecc1SBen Gras __default_pair.back;
23551ffecc1SBen Gras _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags =
23651ffecc1SBen Gras __default_pair.flags;
23751ffecc1SBen Gras
23851ffecc1SBen Gras __using_color = 1;
23951ffecc1SBen Gras
24051ffecc1SBen Gras /* Set all positions on all windows to curses default colours. */
24151ffecc1SBen Gras for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) {
24251ffecc1SBen Gras win = wlp->winp;
24351ffecc1SBen Gras if (wlp->winp != __virtscr && wlp->winp != curscr) {
24451ffecc1SBen Gras /* Set color attribute on other windows */
24551ffecc1SBen Gras win->battr |= __default_color;
24651ffecc1SBen Gras for (y = 0; y < win->maxy; y++) {
24751ffecc1SBen Gras for (x = 0; x < win->maxx; x++) {
24851ffecc1SBen Gras win->alines[y]->line[x].attr &= ~__COLOR;
24951ffecc1SBen Gras win->alines[y]->line[x].attr |= __default_color;
25051ffecc1SBen Gras }
25151ffecc1SBen Gras }
25251ffecc1SBen Gras __touchwin(win);
25351ffecc1SBen Gras }
25451ffecc1SBen Gras }
25551ffecc1SBen Gras
25651ffecc1SBen Gras return(OK);
25751ffecc1SBen Gras }
25851ffecc1SBen Gras
25951ffecc1SBen Gras /*
26051ffecc1SBen Gras * init_pair --
26151ffecc1SBen Gras * Set pair foreground and background colors.
26251ffecc1SBen Gras * Our default colour ordering is ANSI - 1 = red, 4 = blue, 3 = yellow,
26351ffecc1SBen Gras * 6 = cyan. The older style (Sb/Sf) uses 1 = blue, 4 = red, 3 = cyan,
26451ffecc1SBen Gras * 6 = yellow, so we swap them here and in pair_content().
26551ffecc1SBen Gras */
26651ffecc1SBen Gras int
init_pair(short pair,short fore,short back)26751ffecc1SBen Gras init_pair(short pair, short fore, short back)
26851ffecc1SBen Gras {
26951ffecc1SBen Gras int changed;
27051ffecc1SBen Gras
27151ffecc1SBen Gras #ifdef DEBUG
27251ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "init_pair: %d, %d, %d\n", pair, fore, back);
27351ffecc1SBen Gras #endif
27451ffecc1SBen Gras
27551ffecc1SBen Gras if (pair < 0 || pair >= COLOR_PAIRS)
27651ffecc1SBen Gras return (ERR);
27751ffecc1SBen Gras
27851ffecc1SBen Gras if (pair == 0) /* Ignore request for pair 0, it is default. */
27951ffecc1SBen Gras return OK;
28051ffecc1SBen Gras
28151ffecc1SBen Gras if (fore >= COLORS)
28251ffecc1SBen Gras return (ERR);
28351ffecc1SBen Gras if (back >= COLORS)
28451ffecc1SBen Gras return (ERR);
28551ffecc1SBen Gras
28651ffecc1SBen Gras /* Swap red/blue and yellow/cyan */
28751ffecc1SBen Gras if (_cursesi_screen->color_type == COLOR_OTHER) {
28851ffecc1SBen Gras switch (fore) {
28951ffecc1SBen Gras case COLOR_RED:
29051ffecc1SBen Gras fore = COLOR_BLUE;
29151ffecc1SBen Gras break;
29251ffecc1SBen Gras case COLOR_BLUE:
29351ffecc1SBen Gras fore = COLOR_RED;
29451ffecc1SBen Gras break;
29551ffecc1SBen Gras case COLOR_YELLOW:
29651ffecc1SBen Gras fore = COLOR_CYAN;
29751ffecc1SBen Gras break;
29851ffecc1SBen Gras case COLOR_CYAN:
29951ffecc1SBen Gras fore = COLOR_YELLOW;
30051ffecc1SBen Gras break;
30151ffecc1SBen Gras }
30251ffecc1SBen Gras switch (back) {
30351ffecc1SBen Gras case COLOR_RED:
30451ffecc1SBen Gras back = COLOR_BLUE;
30551ffecc1SBen Gras break;
30651ffecc1SBen Gras case COLOR_BLUE:
30751ffecc1SBen Gras back = COLOR_RED;
30851ffecc1SBen Gras break;
30951ffecc1SBen Gras case COLOR_YELLOW:
31051ffecc1SBen Gras back = COLOR_CYAN;
31151ffecc1SBen Gras break;
31251ffecc1SBen Gras case COLOR_CYAN:
31351ffecc1SBen Gras back = COLOR_YELLOW;
31451ffecc1SBen Gras break;
31551ffecc1SBen Gras }
31651ffecc1SBen Gras }
31751ffecc1SBen Gras
31851ffecc1SBen Gras if ((_cursesi_screen->colour_pairs[pair].flags & __USED) &&
31951ffecc1SBen Gras (fore != _cursesi_screen->colour_pairs[pair].fore ||
32051ffecc1SBen Gras back != _cursesi_screen->colour_pairs[pair].back))
32151ffecc1SBen Gras changed = 1;
32251ffecc1SBen Gras else
32351ffecc1SBen Gras changed = 0;
32451ffecc1SBen Gras
32551ffecc1SBen Gras _cursesi_screen->colour_pairs[pair].flags |= __USED;
32651ffecc1SBen Gras _cursesi_screen->colour_pairs[pair].fore = fore;
32751ffecc1SBen Gras _cursesi_screen->colour_pairs[pair].back = back;
32851ffecc1SBen Gras
32951ffecc1SBen Gras /* XXX: need to initialise HP style (Ip) */
33051ffecc1SBen Gras
33151ffecc1SBen Gras if (changed)
33251ffecc1SBen Gras __change_pair(pair);
33351ffecc1SBen Gras return (OK);
33451ffecc1SBen Gras }
33551ffecc1SBen Gras
33651ffecc1SBen Gras /*
33751ffecc1SBen Gras * pair_content --
33851ffecc1SBen Gras * Get pair foreground and background colours.
33951ffecc1SBen Gras */
34051ffecc1SBen Gras int
pair_content(short pair,short * forep,short * backp)34151ffecc1SBen Gras pair_content(short pair, short *forep, short *backp)
34251ffecc1SBen Gras {
34351ffecc1SBen Gras if (pair < 0 || pair > _cursesi_screen->COLOR_PAIRS)
34451ffecc1SBen Gras return(ERR);
34551ffecc1SBen Gras
34651ffecc1SBen Gras *forep = _cursesi_screen->colour_pairs[pair].fore;
34751ffecc1SBen Gras *backp = _cursesi_screen->colour_pairs[pair].back;
34851ffecc1SBen Gras
34951ffecc1SBen Gras /* Swap red/blue and yellow/cyan */
35051ffecc1SBen Gras if (_cursesi_screen->color_type == COLOR_OTHER) {
35151ffecc1SBen Gras switch (*forep) {
35251ffecc1SBen Gras case COLOR_RED:
35351ffecc1SBen Gras *forep = COLOR_BLUE;
35451ffecc1SBen Gras break;
35551ffecc1SBen Gras case COLOR_BLUE:
35651ffecc1SBen Gras *forep = COLOR_RED;
35751ffecc1SBen Gras break;
35851ffecc1SBen Gras case COLOR_YELLOW:
35951ffecc1SBen Gras *forep = COLOR_CYAN;
36051ffecc1SBen Gras break;
36151ffecc1SBen Gras case COLOR_CYAN:
36251ffecc1SBen Gras *forep = COLOR_YELLOW;
36351ffecc1SBen Gras break;
36451ffecc1SBen Gras }
36551ffecc1SBen Gras switch (*backp) {
36651ffecc1SBen Gras case COLOR_RED:
36751ffecc1SBen Gras *backp = COLOR_BLUE;
36851ffecc1SBen Gras break;
36951ffecc1SBen Gras case COLOR_BLUE:
37051ffecc1SBen Gras *backp = COLOR_RED;
37151ffecc1SBen Gras break;
37251ffecc1SBen Gras case COLOR_YELLOW:
37351ffecc1SBen Gras *backp = COLOR_CYAN;
37451ffecc1SBen Gras break;
37551ffecc1SBen Gras case COLOR_CYAN:
37651ffecc1SBen Gras *backp = COLOR_YELLOW;
37751ffecc1SBen Gras break;
37851ffecc1SBen Gras }
37951ffecc1SBen Gras }
38051ffecc1SBen Gras return(OK);
38151ffecc1SBen Gras }
38251ffecc1SBen Gras
38351ffecc1SBen Gras /*
38451ffecc1SBen Gras * init_color --
38551ffecc1SBen Gras * Set colour red, green and blue values.
38651ffecc1SBen Gras */
38751ffecc1SBen Gras int
init_color(short color,short red,short green,short blue)38851ffecc1SBen Gras init_color(short color, short red, short green, short blue)
38951ffecc1SBen Gras {
39051ffecc1SBen Gras #ifdef DEBUG
39151ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "init_color: %d, %d, %d, %d\n",
39251ffecc1SBen Gras color, red, green, blue);
39351ffecc1SBen Gras #endif
39451ffecc1SBen Gras if (color < 0 || color >= _cursesi_screen->COLORS)
39551ffecc1SBen Gras return(ERR);
39651ffecc1SBen Gras
39751ffecc1SBen Gras _cursesi_screen->colours[color].red = red;
39851ffecc1SBen Gras _cursesi_screen->colours[color].green = green;
39951ffecc1SBen Gras _cursesi_screen->colours[color].blue = blue;
40051ffecc1SBen Gras /* XXX Not yet implemented */
40151ffecc1SBen Gras return(ERR);
40251ffecc1SBen Gras /* XXX: need to initialise Tek style (Ic) and support HLS */
40351ffecc1SBen Gras }
40451ffecc1SBen Gras
40551ffecc1SBen Gras /*
40651ffecc1SBen Gras * color_content --
40751ffecc1SBen Gras * Get colour red, green and blue values.
40851ffecc1SBen Gras */
40951ffecc1SBen Gras int
color_content(short color,short * redp,short * greenp,short * bluep)41051ffecc1SBen Gras color_content(short color, short *redp, short *greenp, short *bluep)
41151ffecc1SBen Gras {
41251ffecc1SBen Gras if (color < 0 || color >= _cursesi_screen->COLORS)
41351ffecc1SBen Gras return(ERR);
41451ffecc1SBen Gras
41551ffecc1SBen Gras *redp = _cursesi_screen->colours[color].red;
41651ffecc1SBen Gras *greenp = _cursesi_screen->colours[color].green;
41751ffecc1SBen Gras *bluep = _cursesi_screen->colours[color].blue;
41851ffecc1SBen Gras return(OK);
41951ffecc1SBen Gras }
42051ffecc1SBen Gras
42151ffecc1SBen Gras /*
42251ffecc1SBen Gras * use_default_colors --
42351ffecc1SBen Gras * Use terminal default colours instead of curses default colour.
42451ffecc1SBen Gras */
42551ffecc1SBen Gras int
use_default_colors()42651ffecc1SBen Gras use_default_colors()
42751ffecc1SBen Gras {
42851ffecc1SBen Gras #ifdef DEBUG
42951ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "use_default_colors\n");
43051ffecc1SBen Gras #endif
43151ffecc1SBen Gras
43251ffecc1SBen Gras return(assume_default_colors(-1, -1));
43351ffecc1SBen Gras }
43451ffecc1SBen Gras
43551ffecc1SBen Gras /*
43651ffecc1SBen Gras * assume_default_colors --
43751ffecc1SBen Gras * Set the default foreground and background colours.
43851ffecc1SBen Gras */
43951ffecc1SBen Gras int
assume_default_colors(short fore,short back)44051ffecc1SBen Gras assume_default_colors(short fore, short back)
44151ffecc1SBen Gras {
44251ffecc1SBen Gras #ifdef DEBUG
44351ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "assume_default_colors: %d, %d\n",
44451ffecc1SBen Gras fore, back);
44551ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "assume_default_colors: default_colour = %d, pair_number = %d\n", __default_color, PAIR_NUMBER(__default_color));
44651ffecc1SBen Gras #endif
44751ffecc1SBen Gras
44851ffecc1SBen Gras /* Swap red/blue and yellow/cyan */
44951ffecc1SBen Gras if (_cursesi_screen->color_type == COLOR_OTHER) {
45051ffecc1SBen Gras switch (fore) {
45151ffecc1SBen Gras case COLOR_RED:
45251ffecc1SBen Gras fore = COLOR_BLUE;
45351ffecc1SBen Gras break;
45451ffecc1SBen Gras case COLOR_BLUE:
45551ffecc1SBen Gras fore = COLOR_RED;
45651ffecc1SBen Gras break;
45751ffecc1SBen Gras case COLOR_YELLOW:
45851ffecc1SBen Gras fore = COLOR_CYAN;
45951ffecc1SBen Gras break;
46051ffecc1SBen Gras case COLOR_CYAN:
46151ffecc1SBen Gras fore = COLOR_YELLOW;
46251ffecc1SBen Gras break;
46351ffecc1SBen Gras }
46451ffecc1SBen Gras switch (back) {
46551ffecc1SBen Gras case COLOR_RED:
46651ffecc1SBen Gras back = COLOR_BLUE;
46751ffecc1SBen Gras break;
46851ffecc1SBen Gras case COLOR_BLUE:
46951ffecc1SBen Gras back = COLOR_RED;
47051ffecc1SBen Gras break;
47151ffecc1SBen Gras case COLOR_YELLOW:
47251ffecc1SBen Gras back = COLOR_CYAN;
47351ffecc1SBen Gras break;
47451ffecc1SBen Gras case COLOR_CYAN:
47551ffecc1SBen Gras back = COLOR_YELLOW;
47651ffecc1SBen Gras break;
47751ffecc1SBen Gras }
47851ffecc1SBen Gras }
47951ffecc1SBen Gras __default_pair.fore = fore;
48051ffecc1SBen Gras __default_pair.back = back;
48151ffecc1SBen Gras __default_pair.flags = __USED;
48251ffecc1SBen Gras
48351ffecc1SBen Gras if (COLOR_PAIRS) {
48451ffecc1SBen Gras _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore = fore;
48551ffecc1SBen Gras _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back = back;
48651ffecc1SBen Gras _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags = __USED;
48751ffecc1SBen Gras }
48851ffecc1SBen Gras
48951ffecc1SBen Gras /*
49051ffecc1SBen Gras * If we've already called start_color(), make sure all instances
49151ffecc1SBen Gras * of the curses default colour pair are dirty.
49251ffecc1SBen Gras */
49351ffecc1SBen Gras if (__using_color)
49451ffecc1SBen Gras __change_pair(PAIR_NUMBER(__default_color));
49551ffecc1SBen Gras
49651ffecc1SBen Gras return(OK);
49751ffecc1SBen Gras }
49851ffecc1SBen Gras
49951ffecc1SBen Gras /* no_color_video is a terminfo macro, but we need to retain binary compat */
50051ffecc1SBen Gras #ifdef __strong_alias
50151ffecc1SBen Gras #undef no_color_video
__strong_alias(no_color_video,no_color_attributes)50251ffecc1SBen Gras __strong_alias(no_color_video, no_color_attributes)
50351ffecc1SBen Gras #endif
50451ffecc1SBen Gras /*
50551ffecc1SBen Gras * no_color_attributes --
50651ffecc1SBen Gras * Return attributes that cannot be combined with color.
50751ffecc1SBen Gras */
50851ffecc1SBen Gras attr_t
50951ffecc1SBen Gras no_color_attributes(void)
51051ffecc1SBen Gras {
51151ffecc1SBen Gras return(_cursesi_screen->nca);
51251ffecc1SBen Gras }
51351ffecc1SBen Gras
51451ffecc1SBen Gras /*
51551ffecc1SBen Gras * __set_color --
51651ffecc1SBen Gras * Set terminal foreground and background colours.
51751ffecc1SBen Gras */
51851ffecc1SBen Gras void
__set_color(WINDOW * win,attr_t attr)51951ffecc1SBen Gras __set_color( /*ARGSUSED*/ WINDOW *win, attr_t attr)
52051ffecc1SBen Gras {
52151ffecc1SBen Gras short pair;
52251ffecc1SBen Gras
52351ffecc1SBen Gras if ((curscr->wattr & __COLOR) == (attr & __COLOR))
52451ffecc1SBen Gras return;
52551ffecc1SBen Gras
52651ffecc1SBen Gras pair = PAIR_NUMBER((u_int32_t)attr);
52751ffecc1SBen Gras #ifdef DEBUG
52851ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "__set_color: %d, %d, %d\n", pair,
52951ffecc1SBen Gras _cursesi_screen->colour_pairs[pair].fore,
53051ffecc1SBen Gras _cursesi_screen->colour_pairs[pair].back);
53151ffecc1SBen Gras #endif
53251ffecc1SBen Gras switch (_cursesi_screen->color_type) {
53351ffecc1SBen Gras /* Set ANSI forground and background colours */
53451ffecc1SBen Gras case COLOR_ANSI:
53551ffecc1SBen Gras if (_cursesi_screen->colour_pairs[pair].fore < 0 ||
53651ffecc1SBen Gras _cursesi_screen->colour_pairs[pair].back < 0)
53751ffecc1SBen Gras __unset_color(curscr);
53851ffecc1SBen Gras if (_cursesi_screen->colour_pairs[pair].fore >= 0)
539*0c3ae37fSLionel Sambuc tputs(tiparm(t_set_a_foreground(_cursesi_screen->term),
540*0c3ae37fSLionel Sambuc (int)_cursesi_screen->colour_pairs[pair].fore),
54151ffecc1SBen Gras 0, __cputchar);
54251ffecc1SBen Gras if (_cursesi_screen->colour_pairs[pair].back >= 0)
543*0c3ae37fSLionel Sambuc tputs(tiparm(t_set_a_background(_cursesi_screen->term),
544*0c3ae37fSLionel Sambuc (int)_cursesi_screen->colour_pairs[pair].back),
54551ffecc1SBen Gras 0, __cputchar);
54651ffecc1SBen Gras break;
54751ffecc1SBen Gras case COLOR_HP:
54851ffecc1SBen Gras /* XXX: need to support HP style */
54951ffecc1SBen Gras break;
55051ffecc1SBen Gras case COLOR_TEK:
55151ffecc1SBen Gras /* XXX: need to support Tek style */
55251ffecc1SBen Gras break;
55351ffecc1SBen Gras case COLOR_OTHER:
55451ffecc1SBen Gras if (_cursesi_screen->colour_pairs[pair].fore < 0 ||
55551ffecc1SBen Gras _cursesi_screen->colour_pairs[pair].back < 0)
55651ffecc1SBen Gras __unset_color(curscr);
55751ffecc1SBen Gras if (_cursesi_screen->colour_pairs[pair].fore >= 0)
558*0c3ae37fSLionel Sambuc tputs(tiparm(t_set_foreground(_cursesi_screen->term),
559*0c3ae37fSLionel Sambuc (int)_cursesi_screen->colour_pairs[pair].fore),
56051ffecc1SBen Gras 0, __cputchar);
56151ffecc1SBen Gras if (_cursesi_screen->colour_pairs[pair].back >= 0)
562*0c3ae37fSLionel Sambuc tputs(tiparm(t_set_background(_cursesi_screen->term),
563*0c3ae37fSLionel Sambuc (int)_cursesi_screen->colour_pairs[pair].back),
56451ffecc1SBen Gras 0, __cputchar);
56551ffecc1SBen Gras break;
56651ffecc1SBen Gras }
56751ffecc1SBen Gras curscr->wattr &= ~__COLOR;
56851ffecc1SBen Gras curscr->wattr |= attr & __COLOR;
56951ffecc1SBen Gras }
57051ffecc1SBen Gras
57151ffecc1SBen Gras /*
57251ffecc1SBen Gras * __unset_color --
57351ffecc1SBen Gras * Clear terminal foreground and background colours.
57451ffecc1SBen Gras */
57551ffecc1SBen Gras void
__unset_color(WINDOW * win)57651ffecc1SBen Gras __unset_color(WINDOW *win)
57751ffecc1SBen Gras {
57851ffecc1SBen Gras #ifdef DEBUG
57951ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "__unset_color\n");
58051ffecc1SBen Gras #endif
58151ffecc1SBen Gras switch (_cursesi_screen->color_type) {
58251ffecc1SBen Gras /* Clear ANSI forground and background colours */
58351ffecc1SBen Gras case COLOR_ANSI:
58451ffecc1SBen Gras if (orig_pair != NULL) {
58551ffecc1SBen Gras tputs(orig_pair, 0, __cputchar);
58651ffecc1SBen Gras win->wattr &= __mask_op;
58751ffecc1SBen Gras }
58851ffecc1SBen Gras break;
58951ffecc1SBen Gras case COLOR_HP:
59051ffecc1SBen Gras /* XXX: need to support HP style */
59151ffecc1SBen Gras break;
59251ffecc1SBen Gras case COLOR_TEK:
59351ffecc1SBen Gras /* XXX: need to support Tek style */
59451ffecc1SBen Gras break;
59551ffecc1SBen Gras case COLOR_OTHER:
59651ffecc1SBen Gras if (orig_pair != NULL) {
59751ffecc1SBen Gras tputs(orig_pair, 0, __cputchar);
59851ffecc1SBen Gras win->wattr &= __mask_op;
59951ffecc1SBen Gras }
60051ffecc1SBen Gras break;
60151ffecc1SBen Gras }
60251ffecc1SBen Gras }
60351ffecc1SBen Gras
60451ffecc1SBen Gras /*
60551ffecc1SBen Gras * __restore_colors --
60651ffecc1SBen Gras * Redo color definitions after restarting 'curses' mode.
60751ffecc1SBen Gras */
60851ffecc1SBen Gras void
__restore_colors(void)60951ffecc1SBen Gras __restore_colors(void)
61051ffecc1SBen Gras {
61151ffecc1SBen Gras if (can_change != 0)
61251ffecc1SBen Gras switch (_cursesi_screen->color_type) {
61351ffecc1SBen Gras case COLOR_HP:
61451ffecc1SBen Gras /* XXX: need to re-initialise HP style (Ip) */
61551ffecc1SBen Gras break;
61651ffecc1SBen Gras case COLOR_TEK:
61751ffecc1SBen Gras /* XXX: need to re-initialise Tek style (Ic) */
61851ffecc1SBen Gras break;
61951ffecc1SBen Gras }
62051ffecc1SBen Gras }
62151ffecc1SBen Gras
62251ffecc1SBen Gras /*
62351ffecc1SBen Gras * __change_pair --
62451ffecc1SBen Gras * Mark dirty all positions using pair.
62551ffecc1SBen Gras */
62651ffecc1SBen Gras void
__change_pair(short pair)62751ffecc1SBen Gras __change_pair(short pair)
62851ffecc1SBen Gras {
62951ffecc1SBen Gras struct __winlist *wlp;
63051ffecc1SBen Gras WINDOW *win;
63151ffecc1SBen Gras int y, x;
63251ffecc1SBen Gras __LINE *lp;
63351ffecc1SBen Gras uint32_t cl = COLOR_PAIR(pair);
63451ffecc1SBen Gras
63551ffecc1SBen Gras
63651ffecc1SBen Gras for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) {
63751ffecc1SBen Gras #ifdef DEBUG
63851ffecc1SBen Gras __CTRACE(__CTRACE_COLOR, "__change_pair: win = %p\n",
63951ffecc1SBen Gras wlp->winp);
64051ffecc1SBen Gras #endif
64151ffecc1SBen Gras win = wlp->winp;
64251ffecc1SBen Gras if (win == __virtscr)
64351ffecc1SBen Gras continue;
64451ffecc1SBen Gras else if (win == curscr) {
64551ffecc1SBen Gras /* Reset colour attribute on curscr */
64651ffecc1SBen Gras #ifdef DEBUG
64751ffecc1SBen Gras __CTRACE(__CTRACE_COLOR,
64851ffecc1SBen Gras "__change_pair: win == curscr\n");
64951ffecc1SBen Gras #endif
65051ffecc1SBen Gras for (y = 0; y < curscr->maxy; y++) {
65151ffecc1SBen Gras lp = curscr->alines[y];
65251ffecc1SBen Gras for (x = 0; x < curscr->maxx; x++) {
65351ffecc1SBen Gras if ((lp->line[x].attr & __COLOR) == cl)
65451ffecc1SBen Gras lp->line[x].attr &= ~__COLOR;
65551ffecc1SBen Gras }
65651ffecc1SBen Gras }
65751ffecc1SBen Gras } else {
65851ffecc1SBen Gras /* Mark dirty those positions with colour pair "pair" */
65951ffecc1SBen Gras for (y = 0; y < win->maxy; y++) {
66051ffecc1SBen Gras lp = win->alines[y];
66151ffecc1SBen Gras for (x = 0; x < win->maxx; x++)
66251ffecc1SBen Gras if ((lp->line[x].attr &
66351ffecc1SBen Gras __COLOR) == cl) {
66451ffecc1SBen Gras if (!(lp->flags & __ISDIRTY))
66551ffecc1SBen Gras lp->flags |= __ISDIRTY;
66651ffecc1SBen Gras /*
66751ffecc1SBen Gras * firstchp/lastchp are shared
66851ffecc1SBen Gras * between parent window and
66951ffecc1SBen Gras * sub-window.
67051ffecc1SBen Gras */
67151ffecc1SBen Gras if (*lp->firstchp > x)
67251ffecc1SBen Gras *lp->firstchp = x;
67351ffecc1SBen Gras if (*lp->lastchp < x)
67451ffecc1SBen Gras *lp->lastchp = x;
67551ffecc1SBen Gras }
67651ffecc1SBen Gras #ifdef DEBUG
67751ffecc1SBen Gras if ((win->alines[y]->flags & __ISDIRTY))
67851ffecc1SBen Gras __CTRACE(__CTRACE_COLOR,
67951ffecc1SBen Gras "__change_pair: first = %d, "
68051ffecc1SBen Gras "last = %d\n",
68151ffecc1SBen Gras *win->alines[y]->firstchp,
68251ffecc1SBen Gras *win->alines[y]->lastchp);
68351ffecc1SBen Gras #endif
68451ffecc1SBen Gras }
68551ffecc1SBen Gras }
68651ffecc1SBen Gras }
68751ffecc1SBen Gras }
688