xref: /aosp_15_r20/external/coreboot/payloads/libpayload/curses/PDCurses/pdcurses/color.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* Public Domain Curses */
2 
3 #include <curspriv.h>
4 
5 RCSID("$Id: color.c,v 1.83 2008/07/13 16:08:18 wmcbrine Exp $")
6 
7 /*man-start**************************************************************
8 
9   Name:                                                         color
10 
11   Synopsis:
12         int start_color(void);
13         int init_pair(short pair, short fg, short bg);
14         int init_color(short color, short red, short green, short blue);
15         bool has_colors(void);
16         bool can_change_color(void);
17         int color_content(short color, short *red, short *green, short *blue);
18         int pair_content(short pair, short *fg, short *bg);
19 
20         int assume_default_colors(int f, int b);
21         int use_default_colors(void);
22 
23         int PDC_set_line_color(short color);
24 
25   Description:
26         To use these routines, start_color() must be called, usually
27         immediately after initscr(). Colors are always used in pairs,
28         referred to as color-pairs. A color-pair consists of a
29         foreground color and a background color. A color-pair is
30         initialized via init_pair(). After initialization, COLOR_PAIR(n)
31         can be used like any other video attribute.
32 
33         start_color() initializes eight basic colors (black, red, green,
34         yellow, blue, magenta, cyan, and white), and two global
35         variables; COLORS and COLOR_PAIRS (respectively defining the
36         maximum number of colors and color-pairs the terminal is capable
37         of displaying).
38 
39         init_pair() changes the definition of a color-pair. It takes
40         three arguments: the number of the color-pair to be redefined,
41         and the new values of the foreground and background colors. The
42         pair number must be between 0 and COLOR_PAIRS - 1, inclusive.
43         The foreground and background must be between 0 and COLORS - 1,
44         inclusive. If the color pair was previously initialized, the
45         screen is refreshed, and all occurrences of that color-pair are
46         changed to the new definition.
47 
48         has_colors() indicates if the terminal supports, and can
49         maniplulate color. It returns TRUE or FALSE.
50 
51         can_change_color() indicates if the terminal has the capability
52         to change the definition of its colors.
53 
54         pair_content() is used to determine what the colors of a given
55         color-pair consist of.
56 
57         assume_default_colors() and use_default_colors() emulate the
58         ncurses extensions of the same names. assume_default_colors(f,
59         b) is essentially the same as init_pair(0, f, b) (which isn't
60         allowed); it redefines the default colors. use_default_colors()
61         allows the use of -1 as a foreground or background color with
62         init_pair(), and calls assume_default_colors(-1, -1); -1
63         represents the foreground or background color that the terminal
64         had at startup. If the environment variable PDC_ORIGINAL_COLORS
65         is set at the time start_color() is called, that's equivalent to
66         calling use_default_colors().
67 
68         PDC_set_line_color() is used to set the color, globally, for
69         the color of the lines drawn for the attributes: A_UNDERLINE,
70         A_OVERLINE, A_LEFTLINE and A_RIGHTLINE. A value of -1 (the
71         default) indicates that the current foreground color should be
72         used.
73 
74         NOTE: COLOR_PAIR() and PAIR_NUMBER() are implemented as macros.
75 
76   Return Value:
77         All functions return OK on success and ERR on error, except for
78         has_colors() and can_change_colors(), which return TRUE or FALSE.
79 
80   Portability                                X/Open    BSD    SYS V
81         start_color                             Y       -      3.2
82         init_pair                               Y       -      3.2
83         init_color                              Y       -      3.2
84         has_colors                              Y       -      3.2
85         can_change_color                        Y       -      3.2
86         color_content                           Y       -      3.2
87         pair_content                            Y       -      3.2
88         assume_default_colors                   -       -       -
89         use_default_colors                      -       -       -
90         PDC_set_line_color                      -       -       -
91 
92 **man-end****************************************************************/
93 
94 #include <stdlib.h>
95 #include <string.h>
96 
97 int COLORS = 0;
98 int COLOR_PAIRS = PDC_COLOR_PAIRS;
99 
100 bool pdc_color_started = FALSE;
101 
102 /* pair_set[] tracks whether a pair has been set via init_pair() */
103 
104 static bool pair_set[PDC_COLOR_PAIRS];
105 static bool default_colors = FALSE;
106 static short first_col = 0;
107 
start_color(void)108 int start_color(void)
109 {
110     PDC_LOG(("start_color() - called\n"));
111 
112     if (SP->mono)
113         return ERR;
114 
115     pdc_color_started = TRUE;
116 
117     PDC_set_blink(FALSE);   /* Also sets COLORS, to 8 or 16 */
118 
119     if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS"))
120         default_colors = TRUE;
121 
122     PDC_init_atrtab();
123 
124     memset(pair_set, 0, PDC_COLOR_PAIRS);
125 
126     return OK;
127 }
128 
_normalize(short * fg,short * bg)129 static void _normalize(short *fg, short *bg)
130 {
131     if (*fg == -1)
132         *fg = SP->orig_attr ? SP->orig_fore : COLOR_WHITE;
133 
134     if (*bg == -1)
135         *bg = SP->orig_attr ? SP->orig_back : COLOR_BLACK;
136 }
137 
init_pair(short pair,short fg,short bg)138 int init_pair(short pair, short fg, short bg)
139 {
140     PDC_LOG(("init_pair() - called: pair %d fg %d bg %d\n", pair, fg, bg));
141 
142     if (!pdc_color_started || pair < 1 || pair >= COLOR_PAIRS ||
143         fg < first_col || fg >= COLORS || bg < first_col || bg >= COLORS)
144         return ERR;
145 
146     _normalize(&fg, &bg);
147 
148     /* To allow the PDC_PRESERVE_SCREEN option to work, we only reset
149        curscr if this call to init_pair() alters a color pair created by
150        the user. */
151 
152     if (pair_set[pair])
153     {
154         short oldfg, oldbg;
155 
156         PDC_pair_content(pair, &oldfg, &oldbg);
157 
158         if (oldfg != fg || oldbg != bg)
159             curscr->_clear = TRUE;
160     }
161 
162     PDC_init_pair(pair, fg, bg);
163 
164     pair_set[pair] = TRUE;
165 
166     return OK;
167 }
168 
has_colors(void)169 bool has_colors(void)
170 {
171     PDC_LOG(("has_colors() - called\n"));
172 
173     return !(SP->mono);
174 }
175 
init_color(short color,short red,short green,short blue)176 int init_color(short color, short red, short green, short blue)
177 {
178     PDC_LOG(("init_color() - called\n"));
179 
180     if (color < 0 || color >= COLORS || !PDC_can_change_color() ||
181         red < 0 || red > 1000 || green < 0 || green > 1000 ||
182         blue < 0 || blue > 1000)
183         return ERR;
184 
185     return PDC_init_color(color, red, green, blue);
186 }
187 
color_content(short color,short * red,short * green,short * blue)188 int color_content(short color, short *red, short *green, short *blue)
189 {
190     PDC_LOG(("color_content() - called\n"));
191 
192     if (color < 0 || color >= COLORS || !red || !green || !blue)
193         return ERR;
194 
195     if (PDC_can_change_color())
196         return PDC_color_content(color, red, green, blue);
197     else
198     {
199         /* Simulated values for platforms that don't support palette
200            changing */
201 
202         short maxval = (color & 8) ? 1000 : 680;
203 
204         *red = (color & COLOR_RED) ? maxval : 0;
205         *green = (color & COLOR_GREEN) ? maxval : 0;
206         *blue = (color & COLOR_BLUE) ? maxval : 0;
207 
208         return OK;
209     }
210 }
211 
can_change_color(void)212 bool can_change_color(void)
213 {
214     PDC_LOG(("can_change_color() - called\n"));
215 
216     return PDC_can_change_color();
217 }
218 
pair_content(short pair,short * fg,short * bg)219 int pair_content(short pair, short *fg, short *bg)
220 {
221     PDC_LOG(("pair_content() - called\n"));
222 
223     if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg)
224         return ERR;
225 
226     return PDC_pair_content(pair, fg, bg);
227 }
228 
assume_default_colors(int f,int b)229 int assume_default_colors(int f, int b)
230 {
231     PDC_LOG(("assume_default_colors() - called: f %d b %d\n", f, b));
232 
233     if (f < -1 || f >= COLORS || b < -1 || b >= COLORS)
234         return ERR;
235 
236     if (pdc_color_started)
237     {
238         short fg, bg, oldfg, oldbg;
239 
240         fg = f;
241         bg = b;
242 
243         _normalize(&fg, &bg);
244 
245         PDC_pair_content(0, &oldfg, &oldbg);
246 
247         if (oldfg != fg || oldbg != bg)
248             curscr->_clear = TRUE;
249 
250         PDC_init_pair(0, fg, bg);
251     }
252 
253     return OK;
254 }
255 
use_default_colors(void)256 int use_default_colors(void)
257 {
258     PDC_LOG(("use_default_colors() - called\n"));
259 
260     default_colors = TRUE;
261     first_col = -1;
262 
263     return assume_default_colors(-1, -1);
264 }
265 
PDC_set_line_color(short color)266 int PDC_set_line_color(short color)
267 {
268     PDC_LOG(("PDC_set_line_color() - called: %d\n", color));
269 
270     if (color < -1 || color >= COLORS)
271         return ERR;
272 
273     SP->line_color = color;
274 
275     return OK;
276 }
277 
PDC_init_atrtab(void)278 void PDC_init_atrtab(void)
279 {
280     int i;
281     short fg, bg;
282 
283     if (pdc_color_started && !default_colors)
284     {
285         fg = COLOR_WHITE;
286         bg = COLOR_BLACK;
287     }
288     else
289         fg = bg = -1;
290 
291     _normalize(&fg, &bg);
292 
293     for (i = 0; i < PDC_COLOR_PAIRS; i++)
294         PDC_init_pair(i, fg, bg);
295 }
296