|
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 |
|
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 |
|
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 |
|
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 |
|
169 bool has_colors(void) |
|
170 { |
|
171 PDC_LOG(("has_colors() - called\n")); |
|
172 |
|
173 return !(SP->mono); |
|
174 } |
|
175 |
|
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 |
|
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 |
|
212 bool can_change_color(void) |
|
213 { |
|
214 PDC_LOG(("can_change_color() - called\n")); |
|
215 |
|
216 return PDC_can_change_color(); |
|
217 } |
|
218 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 } |