Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmpdcurses/pdcurses/color.c
3153 views
1
/* PDCurses */
2
3
#include <curspriv.h>
4
5
/*man-start**************************************************************
6
7
color
8
-----
9
10
### Synopsis
11
12
bool has_colors(void);
13
int start_color(void);
14
int init_pair(short pair, short fg, short bg);
15
int pair_content(short pair, short *fg, short *bg);
16
bool can_change_color(void);
17
int init_color(short color, short red, short green, short blue);
18
int color_content(short color, short *red, short *green, short *blue);
19
20
int alloc_pair(int fg, int bg);
21
int assume_default_colors(int f, int b);
22
int find_pair(int fg, int bg);
23
int free_pair(int pair);
24
int use_default_colors(void);
25
26
int PDC_set_line_color(short color);
27
28
### Description
29
30
To use these routines, first, call start_color(). Colors are always
31
used in pairs, referred to as color-pairs. A color-pair is created by
32
init_pair(), and consists of a foreground color and a background
33
color. After initialization, COLOR_PAIR(n) can be used like any other
34
video attribute.
35
36
has_colors() reports whether the terminal supports color.
37
38
start_color() initializes eight basic colors (black, red, green,
39
yellow, blue, magenta, cyan, and white), and two global variables:
40
COLORS and COLOR_PAIRS (respectively defining the maximum number of
41
colors and color-pairs the terminal is capable of displaying).
42
43
init_pair() changes the definition of a color-pair. It takes three
44
arguments: the number of the color-pair to be redefined, and the new
45
values of the foreground and background colors. The pair number must
46
be between 0 and COLOR_PAIRS - 1, inclusive. The foreground and
47
background must be between 0 and COLORS - 1, inclusive. If the color
48
pair was previously initialized, the screen is refreshed, and all
49
occurrences of that color-pair are changed to the new definition.
50
51
pair_content() is used to determine what the colors of a given color-
52
pair consist of.
53
54
can_change_color() indicates if the terminal has the capability to
55
change the definition of its colors.
56
57
init_color() is used to redefine a color, if possible. Each of the
58
components -- red, green, and blue -- is specified in a range from 0
59
to 1000, inclusive.
60
61
color_content() reports the current definition of a color in the same
62
format as used by init_color().
63
64
assume_default_colors() and use_default_colors() emulate the ncurses
65
extensions of the same names. assume_default_colors(f, b) is
66
essentially the same as init_pair(0, f, b) (which isn't allowed); it
67
redefines the default colors. use_default_colors() allows the use of
68
-1 as a foreground or background color with init_pair(), and calls
69
assume_default_colors(-1, -1); -1 represents the foreground or
70
background color that the terminal had at startup. If the environment
71
variable PDC_ORIGINAL_COLORS is set at the time start_color() is
72
called, that's equivalent to calling use_default_colors().
73
74
alloc_pair(), find_pair() and free_pair() are also from ncurses.
75
free_pair() marks a pair as unused; find_pair() returns an existing
76
pair with the specified foreground and background colors, if one
77
exists. And alloc_pair() returns such a pair whether or not it was
78
previously set, overwriting the oldest initialized pair if there are
79
no free pairs.
80
81
PDC_set_line_color() is used to set the color, globally, for the
82
color of the lines drawn for the attributes: A_UNDERLINE, A_LEFT and
83
A_RIGHT. A value of -1 (the default) indicates that the current
84
foreground color should be used.
85
86
NOTE: COLOR_PAIR() and PAIR_NUMBER() are implemented as macros.
87
88
### Return Value
89
90
Most functions return OK on success and ERR on error. has_colors()
91
and can_change_colors() return TRUE or FALSE. alloc_pair() and
92
find_pair() return a pair number, or -1 on error.
93
94
### Portability
95
X/Open ncurses NetBSD
96
has_colors Y Y Y
97
start_color Y Y Y
98
init_pair Y Y Y
99
pair_content Y Y Y
100
can_change_color Y Y Y
101
init_color Y Y Y
102
color_content Y Y Y
103
alloc_pair - Y -
104
assume_default_colors - Y Y
105
find_pair - Y -
106
free_pair - Y -
107
use_default_colors - Y Y
108
PDC_set_line_color - - -
109
110
**man-end****************************************************************/
111
112
#include <stdlib.h>
113
#include <string.h>
114
115
int COLORS = 0;
116
int COLOR_PAIRS = PDC_COLOR_PAIRS;
117
118
static bool default_colors = FALSE;
119
static short first_col = 0;
120
static int allocnum = 0;
121
122
int start_color(void)
123
{
124
PDC_LOG(("start_color() - called\n"));
125
126
if (!SP || SP->mono)
127
return ERR;
128
129
SP->color_started = TRUE;
130
131
PDC_set_blink(FALSE); /* Also sets COLORS */
132
133
if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS"))
134
default_colors = TRUE;
135
136
PDC_init_atrtab();
137
138
return OK;
139
}
140
141
static void _normalize(short *fg, short *bg)
142
{
143
if (*fg == -1)
144
*fg = SP->orig_attr ? SP->orig_fore : COLOR_WHITE;
145
146
if (*bg == -1)
147
*bg = SP->orig_attr ? SP->orig_back : COLOR_BLACK;
148
}
149
150
static void _init_pair_core(short pair, short fg, short bg)
151
{
152
PDC_PAIR *p = SP->atrtab + pair;
153
154
_normalize(&fg, &bg);
155
156
/* To allow the PDC_PRESERVE_SCREEN option to work, we only reset
157
curscr if this call to init_pair() alters a color pair created by
158
the user. */
159
160
if (p->set)
161
{
162
if (p->f != fg || p->b != bg)
163
curscr->_clear = TRUE;
164
}
165
166
p->f = fg;
167
p->b = bg;
168
p->count = allocnum++;
169
p->set = TRUE;
170
}
171
172
int init_pair(short pair, short fg, short bg)
173
{
174
PDC_LOG(("init_pair() - called: pair %d fg %d bg %d\n", pair, fg, bg));
175
176
if (!SP || !SP->color_started || pair < 1 || pair >= COLOR_PAIRS ||
177
fg < first_col || fg >= COLORS || bg < first_col || bg >= COLORS)
178
return ERR;
179
180
_init_pair_core(pair, fg, bg);
181
182
return OK;
183
}
184
185
bool has_colors(void)
186
{
187
PDC_LOG(("has_colors() - called\n"));
188
189
return SP ? !(SP->mono) : FALSE;
190
}
191
192
int init_color(short color, short red, short green, short blue)
193
{
194
PDC_LOG(("init_color() - called\n"));
195
196
if (!SP || color < 0 || color >= COLORS || !PDC_can_change_color() ||
197
red < -1 || red > 1000 || green < -1 || green > 1000 ||
198
blue < -1 || blue > 1000)
199
return ERR;
200
201
SP->dirty = TRUE;
202
203
return PDC_init_color(color, red, green, blue);
204
}
205
206
int color_content(short color, short *red, short *green, short *blue)
207
{
208
PDC_LOG(("color_content() - called\n"));
209
210
if (color < 0 || color >= COLORS || !red || !green || !blue)
211
return ERR;
212
213
if (PDC_can_change_color())
214
return PDC_color_content(color, red, green, blue);
215
else
216
{
217
/* Simulated values for platforms that don't support palette
218
changing */
219
220
short maxval = (color & 8) ? 1000 : 680;
221
222
*red = (color & COLOR_RED) ? maxval : 0;
223
*green = (color & COLOR_GREEN) ? maxval : 0;
224
*blue = (color & COLOR_BLUE) ? maxval : 0;
225
226
return OK;
227
}
228
}
229
230
bool can_change_color(void)
231
{
232
PDC_LOG(("can_change_color() - called\n"));
233
234
return PDC_can_change_color();
235
}
236
237
int pair_content(short pair, short *fg, short *bg)
238
{
239
PDC_LOG(("pair_content() - called\n"));
240
241
if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg)
242
return ERR;
243
244
*fg = SP->atrtab[pair].f;
245
*bg = SP->atrtab[pair].b;
246
247
return OK;
248
}
249
250
int assume_default_colors(int f, int b)
251
{
252
PDC_LOG(("assume_default_colors() - called: f %d b %d\n", f, b));
253
254
if (f < -1 || f >= COLORS || b < -1 || b >= COLORS)
255
return ERR;
256
257
if (SP->color_started)
258
_init_pair_core(0, f, b);
259
260
return OK;
261
}
262
263
int use_default_colors(void)
264
{
265
PDC_LOG(("use_default_colors() - called\n"));
266
267
default_colors = TRUE;
268
first_col = -1;
269
270
return assume_default_colors(-1, -1);
271
}
272
273
int PDC_set_line_color(short color)
274
{
275
PDC_LOG(("PDC_set_line_color() - called: %d\n", color));
276
277
if (!SP || color < -1 || color >= COLORS)
278
return ERR;
279
280
SP->line_color = color;
281
282
return OK;
283
}
284
285
void PDC_init_atrtab(void)
286
{
287
PDC_PAIR *p = SP->atrtab;
288
short i, fg, bg;
289
290
if (SP->color_started && !default_colors)
291
{
292
fg = COLOR_WHITE;
293
bg = COLOR_BLACK;
294
}
295
else
296
fg = bg = -1;
297
298
_normalize(&fg, &bg);
299
300
for (i = 0; i < PDC_COLOR_PAIRS; i++)
301
{
302
p[i].f = fg;
303
p[i].b = bg;
304
p[i].set = FALSE;
305
}
306
}
307
308
int free_pair(int pair)
309
{
310
if (pair < 1 || pair >= PDC_COLOR_PAIRS || !(SP->atrtab[pair].set))
311
return ERR;
312
313
SP->atrtab[pair].set = FALSE;
314
return OK;
315
}
316
317
int find_pair(int fg, int bg)
318
{
319
int i;
320
PDC_PAIR *p = SP->atrtab;
321
322
for (i = 0; i < PDC_COLOR_PAIRS; i++)
323
if (p[i].set && p[i].f == fg && p[i].b == bg)
324
return i;
325
326
return -1;
327
}
328
329
static int _find_oldest()
330
{
331
int i, lowind = 0, lowval = 0;
332
PDC_PAIR *p = SP->atrtab;
333
334
for (i = 1; i < PDC_COLOR_PAIRS; i++)
335
{
336
if (!p[i].set)
337
return i;
338
339
if (!lowval || (p[i].count < lowval))
340
{
341
lowind = i;
342
lowval = p[i].count;
343
}
344
}
345
346
return lowind;
347
}
348
349
int alloc_pair(int fg, int bg)
350
{
351
int i = find_pair(fg, bg);
352
353
if (-1 == i)
354
{
355
i = _find_oldest();
356
357
if (ERR == init_pair(i, fg, bg))
358
return -1;
359
}
360
361
return i;
362
}
363
364