* clear out some warnings by gcc 9.3.1.
[alpine.git] / web / src / alpined.d / color.c
blobe8d0af86999aedca9cc2c5fb75ee12b6af5e4e8f
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: color.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
3 #endif
5 /* ========================================================================
6 * Copyright 2006-2007 University of Washington
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * ========================================================================
17 #include <system.h>
18 #include <general.h>
20 #include "../../../pith/osdep/color.h"
21 #include "../../../pith/osdep/collate.h"
24 static COLOR_PAIR *the_rev_color;
25 static char *_nfcolor, *_nbcolor, *_rfcolor, *_rbcolor;
26 static char *_last_fg_color, *_last_bg_color;
27 static int _force_fg_color_change, _force_bg_color_change;
30 /* * * * * * * PITH-REQUIRED COLOR ROUTINES * * * * * * */
32 /* internal prototypes */
33 char *alpine_color_name(char *);
34 int alpine_valid_rgb(char *s);
36 int
37 pico_usingcolor(void)
39 return(TRUE);
43 int
44 pico_hascolor(void)
46 return(TRUE);
51 * Web Alpine Color Table
53 static struct color_table {
54 int number;
55 char *rgb;
56 struct {
57 char *s,
59 } name;
60 } webcoltab[] = {
61 {COL_BLACK, " 0, 0, 0", {"black", 5}},
62 {COL_RED, "255, 0, 0", {"red", 3}},
63 {COL_GREEN, " 0,255, 0", {"green", 5}},
64 {COL_YELLOW, "255,255, 0", {"yellow", 6}},
65 {COL_BLUE, " 0, 0,255", {"blue", 4}},
66 {COL_MAGENTA, "255, 0,255", {"magenta", 7}},
67 {COL_CYAN, " 0,255,255", {"cyan", 4}},
68 {COL_WHITE, "255,255,255", {"white", 5}},
69 {8, "192,192,192", {"color008", 8}}, /* light gray */
70 {9, "128,128,128", {"color009", 8}}, /* gray */
71 {10, " 64, 64, 64", {"color010", 8}}, /* dark gray */
72 {COL_YELLOW, "255,255, 0", {"color011", 8}},
73 {COL_BLUE, " 0, 0,255", {"color012", 8}},
74 {COL_MAGENTA, "255, 0,255", {"color013", 8}},
75 {COL_CYAN, " 0,255,255", {"color014", 8}},
76 {COL_WHITE, "255,255,255", {"color015", 8}},
77 {8, "192,192,192", {"colorlgr", 8}}, /* light gray */
78 {9, "128,128,128", {"colormgr", 8}}, /* gray */
79 {10, " 64, 64, 64", {"colordgr", 8}}, /* dark gray */
80 {16, "000,000,000", {"color016", 8}},
81 {17, "000,000,095", {"color017", 8}},
82 {18, "000,000,135", {"color018", 8}},
83 {19, "000,000,175", {"color019", 8}},
84 {20, "000,000,215", {"color020", 8}},
85 {21, "000,000,255", {"color021", 8}},
86 {22, "000,095,000", {"color022", 8}},
87 {23, "000,095,095", {"color023", 8}},
88 {24, "000,095,135", {"color024", 8}},
89 {25, "000,095,175", {"color025", 8}},
90 {26, "000,095,215", {"color026", 8}},
91 {27, "000,095,255", {"color027", 8}},
92 {28, "000,135,000", {"color028", 8}},
93 {29, "000,135,095", {"color029", 8}},
94 {30, "000,135,135", {"color030", 8}},
95 {31, "000,135,175", {"color031", 8}},
96 {32, "000,135,215", {"color032", 8}},
97 {33, "000,135,255", {"color033", 8}},
98 {34, "000,175,000", {"color034", 8}},
99 {35, "000,175,095", {"color035", 8}},
100 {36, "000,175,135", {"color036", 8}},
101 {37, "000,175,175", {"color037", 8}},
102 {38, "000,175,215", {"color038", 8}},
103 {39, "000,175,255", {"color039", 8}},
104 {40, "000,215,000", {"color040", 8}},
105 {41, "000,215,095", {"color041", 8}},
106 {42, "000,215,135", {"color042", 8}},
107 {43, "000,215,175", {"color043", 8}},
108 {44, "000,215,215", {"color044", 8}},
109 {45, "000,215,255", {"color045", 8}},
110 {46, "000,255,000", {"color046", 8}},
111 {47, "000,255,095", {"color047", 8}},
112 {48, "000,255,135", {"color048", 8}},
113 {49, "000,255,175", {"color049", 8}},
114 {50, "000,255,215", {"color050", 8}},
115 {51, "000,255,255", {"color051", 8}},
116 {52, "095,000,000", {"color052", 8}},
117 {53, "095,000,095", {"color053", 8}},
118 {54, "095,000,135", {"color054", 8}},
119 {55, "095,000,175", {"color055", 8}},
120 {56, "095,000,215", {"color056", 8}},
121 {57, "095,000,255", {"color057", 8}},
122 {58, "095,095,000", {"color058", 8}},
123 {59, "095,095,095", {"color059", 8}},
124 {60, "095,095,135", {"color060", 8}},
125 {61, "095,095,175", {"color061", 8}},
126 {62, "095,095,215", {"color062", 8}},
127 {63, "095,095,255", {"color063", 8}},
128 {64, "095,135,000", {"color064", 8}},
129 {65, "095,135,095", {"color065", 8}},
130 {66, "095,135,135", {"color066", 8}},
131 {67, "095,135,175", {"color067", 8}},
132 {68, "095,135,215", {"color068", 8}},
133 {69, "095,135,255", {"color069", 8}},
134 {70, "095,175,000", {"color070", 8}},
135 {71, "095,175,095", {"color071", 8}},
136 {72, "095,175,135", {"color072", 8}},
137 {73, "095,175,175", {"color073", 8}},
138 {74, "095,175,215", {"color074", 8}},
139 {75, "095,175,255", {"color075", 8}},
140 {76, "095,215,000", {"color076", 8}},
141 {77, "095,215,095", {"color077", 8}},
142 {78, "095,215,135", {"color078", 8}},
143 {79, "095,215,175", {"color079", 8}},
144 {80, "095,215,215", {"color080", 8}},
145 {81, "095,215,255", {"color081", 8}},
146 {82, "095,255,000", {"color082", 8}},
147 {83, "095,255,095", {"color083", 8}},
148 {84, "095,255,135", {"color084", 8}},
149 {85, "095,255,175", {"color085", 8}},
150 {86, "095,255,215", {"color086", 8}},
151 {87, "095,255,255", {"color087", 8}},
152 {88, "135,000,000", {"color088", 8}},
153 {89, "135,000,095", {"color089", 8}},
154 {90, "135,000,135", {"color090", 8}},
155 {91, "135,000,175", {"color091", 8}},
156 {92, "135,000,215", {"color092", 8}},
157 {93, "135,000,255", {"color093", 8}},
158 {94, "135,095,000", {"color094", 8}},
159 {95, "135,095,095", {"color095", 8}},
160 {96, "135,095,135", {"color096", 8}},
161 {97, "135,095,175", {"color097", 8}},
162 {98, "135,095,215", {"color098", 8}},
163 {99, "135,095,255", {"color099", 8}},
164 {100, "135,135,000", {"color100", 8}},
165 {101, "135,135,095", {"color101", 8}},
166 {102, "135,135,135", {"color102", 8}},
167 {103, "135,135,175", {"color103", 8}},
168 {104, "135,135,215", {"color104", 8}},
169 {105, "135,135,255", {"color105", 8}},
170 {106, "135,175,000", {"color106", 8}},
171 {107, "135,175,095", {"color107", 8}},
172 {108, "135,175,135", {"color108", 8}},
173 {109, "135,175,175", {"color109", 8}},
174 {110, "135,175,215", {"color110", 8}},
175 {111, "135,175,255", {"color111", 8}},
176 {112, "135,215,000", {"color112", 8}},
177 {113, "135,215,095", {"color113", 8}},
178 {114, "135,215,135", {"color114", 8}},
179 {115, "135,215,175", {"color115", 8}},
180 {116, "135,215,215", {"color116", 8}},
181 {117, "135,215,255", {"color117", 8}},
182 {118, "135,255,000", {"color118", 8}},
183 {119, "135,255,095", {"color119", 8}},
184 {120, "135,255,135", {"color120", 8}},
185 {121, "135,255,175", {"color121", 8}},
186 {122, "135,255,215", {"color122", 8}},
187 {123, "135,255,255", {"color123", 8}},
188 {124, "175,000,000", {"color124", 8}},
189 {125, "175,000,095", {"color125", 8}},
190 {126, "175,000,135", {"color126", 8}},
191 {127, "175,000,175", {"color127", 8}},
192 {128, "175,000,215", {"color128", 8}},
193 {129, "175,000,255", {"color129", 8}},
194 {130, "175,095,000", {"color130", 8}},
195 {131, "175,095,095", {"color131", 8}},
196 {132, "175,095,135", {"color132", 8}},
197 {133, "175,095,175", {"color133", 8}},
198 {134, "175,095,215", {"color134", 8}},
199 {135, "175,095,255", {"color135", 8}},
200 {136, "175,135,000", {"color136", 8}},
201 {137, "175,135,095", {"color137", 8}},
202 {138, "175,135,135", {"color138", 8}},
203 {139, "175,135,175", {"color139", 8}},
204 {140, "175,135,215", {"color140", 8}},
205 {141, "175,135,255", {"color141", 8}},
206 {142, "175,175,000", {"color142", 8}},
207 {143, "175,175,095", {"color143", 8}},
208 {144, "175,175,135", {"color144", 8}},
209 {145, "175,175,175", {"color145", 8}},
210 {146, "175,175,215", {"color146", 8}},
211 {147, "175,175,255", {"color147", 8}},
212 {148, "175,215,000", {"color148", 8}},
213 {149, "175,215,095", {"color149", 8}},
214 {150, "175,215,135", {"color150", 8}},
215 {151, "175,215,175", {"color151", 8}},
216 {152, "175,215,215", {"color152", 8}},
217 {153, "175,215,255", {"color153", 8}},
218 {154, "175,255,000", {"color154", 8}},
219 {155, "175,255,095", {"color155", 8}},
220 {156, "175,255,135", {"color156", 8}},
221 {157, "175,255,175", {"color157", 8}},
222 {158, "175,255,215", {"color158", 8}},
223 {159, "175,255,255", {"color159", 8}},
224 {160, "215,000,000", {"color160", 8}},
225 {161, "215,000,095", {"color161", 8}},
226 {162, "215,000,135", {"color162", 8}},
227 {163, "215,000,175", {"color163", 8}},
228 {164, "215,000,215", {"color164", 8}},
229 {165, "215,000,255", {"color165", 8}},
230 {166, "215,095,000", {"color166", 8}},
231 {167, "215,095,095", {"color167", 8}},
232 {168, "215,095,135", {"color168", 8}},
233 {169, "215,095,175", {"color169", 8}},
234 {170, "215,095,215", {"color170", 8}},
235 {171, "215,095,255", {"color171", 8}},
236 {172, "215,135,000", {"color172", 8}},
237 {173, "215,135,095", {"color173", 8}},
238 {174, "215,135,135", {"color174", 8}},
239 {175, "215,135,175", {"color175", 8}},
240 {176, "215,135,215", {"color176", 8}},
241 {177, "215,135,255", {"color177", 8}},
242 {178, "215,175,000", {"color178", 8}},
243 {179, "215,175,095", {"color179", 8}},
244 {180, "215,175,135", {"color180", 8}},
245 {181, "215,175,175", {"color181", 8}},
246 {182, "215,175,215", {"color182", 8}},
247 {183, "215,175,255", {"color183", 8}},
248 {184, "215,215,000", {"color184", 8}},
249 {185, "215,215,095", {"color185", 8}},
250 {186, "215,215,135", {"color186", 8}},
251 {187, "215,215,175", {"color187", 8}},
252 {188, "215,215,215", {"color188", 8}},
253 {189, "215,215,255", {"color189", 8}},
254 {190, "215,255,000", {"color190", 8}},
255 {191, "215,255,095", {"color191", 8}},
256 {192, "215,255,135", {"color192", 8}},
257 {193, "215,255,175", {"color193", 8}},
258 {194, "215,255,215", {"color194", 8}},
259 {195, "215,255,255", {"color195", 8}},
260 {196, "255,000,000", {"color196", 8}},
261 {197, "255,000,095", {"color197", 8}},
262 {198, "255,000,135", {"color198", 8}},
263 {199, "255,000,175", {"color199", 8}},
264 {200, "255,000,215", {"color200", 8}},
265 {201, "255,000,255", {"color201", 8}},
266 {202, "255,095,000", {"color202", 8}},
267 {203, "255,095,095", {"color203", 8}},
268 {204, "255,095,135", {"color204", 8}},
269 {205, "255,095,175", {"color205", 8}},
270 {206, "255,095,215", {"color206", 8}},
271 {207, "255,095,255", {"color207", 8}},
272 {208, "255,135,000", {"color208", 8}},
273 {209, "255,135,095", {"color209", 8}},
274 {210, "255,135,135", {"color210", 8}},
275 {211, "255,135,175", {"color211", 8}},
276 {212, "255,135,215", {"color212", 8}},
277 {213, "255,135,255", {"color213", 8}},
278 {214, "255,175,000", {"color214", 8}},
279 {215, "255,175,095", {"color215", 8}},
280 {216, "255,175,135", {"color216", 8}},
281 {217, "255,175,175", {"color217", 8}},
282 {218, "255,175,215", {"color218", 8}},
283 {219, "255,175,255", {"color219", 8}},
284 {220, "255,215,000", {"color220", 8}},
285 {221, "255,215,095", {"color221", 8}},
286 {222, "255,215,135", {"color222", 8}},
287 {223, "255,215,175", {"color223", 8}},
288 {224, "255,215,215", {"color224", 8}},
289 {225, "255,215,255", {"color225", 8}},
290 {226, "255,255,000", {"color226", 8}},
291 {227, "255,255,095", {"color227", 8}},
292 {228, "255,255,135", {"color228", 8}},
293 {229, "255,255,175", {"color229", 8}},
294 {230, "255,255,215", {"color230", 8}},
295 {231, "255,255,255", {"color231", 8}}
299 char *
300 colorx(int color)
302 int i;
303 static char cbuf[12];
305 for(i = 0; i < sizeof(webcoltab) / sizeof(struct color_table); i++)
306 if(color == webcoltab[i].number)
307 return(webcoltab[i].rgb);
309 sprintf(cbuf, "color%3.3d", color);
310 return(cbuf);
315 * Return a pointer to an rgb string for the input color. The output is 11
316 * characters long and looks like rrr,ggg,bbb.
318 * Args colorName -- The color to convert to ascii rgb.
320 * Returns Pointer to a static buffer containing the rgb string.
322 char *
323 color_to_asciirgb(char *colorName)
325 int i;
326 static char c_to_a_buf[3][RGBLEN+1];
327 static int whichbuf = 0;
329 whichbuf = (whichbuf + 1) % 3;
331 for(i = 0; i < sizeof(webcoltab) / sizeof(struct color_table); i++)
332 if(!strucmp(webcoltab[i].name.s, colorName))
333 return(webcoltab[i].rgb);
336 * If we didn't find the color it could be that it is the
337 * normal color (MATCH_NORM_COLOR) or the none color
338 * (MATCH_NONE_COLOR). If that is the case, this strncpy thing
339 * will work out correctly because those two strings are
340 * RGBLEN long. Otherwise we're in a bit of trouble. This
341 * most likely means that the user is using the same pinerc on
342 * two terminals, one with more colors than the other. We didn't
343 * find a match because this color isn't present on this terminal.
344 * Since the return value of this function is assumed to be
345 * RGBLEN long, we'd better make it that long.
346 * It still won't work correctly because colors will be screwed up,
347 * but at least the embedded colors in filter.c will get properly
348 * sucked up when they're encountered.
350 strncpy(c_to_a_buf[whichbuf], "xxxxxxxxxxx", RGBLEN); /* RGBLEN is 11 */
351 i = strlen(colorName);
352 strncpy(c_to_a_buf[whichbuf], colorName, (i < RGBLEN) ? i : RGBLEN);
353 c_to_a_buf[whichbuf][RGBLEN] = '\0';
354 return(c_to_a_buf[whichbuf]);
360 pico_is_good_color(char *s)
362 return(alpine_color_name(s) != NULL || alpine_valid_rgb(s));
367 alpine_valid_rgb(char *s)
369 int i, j;
371 /* has to be three spaces or decimal digits followed by a dot.*/
373 for(i = 0; i < 3; i++){
374 int n = 0;
376 for(j = 0; j < 3; j++, s++) {
377 if(*s == ' '){
378 if(n)
379 return(FALSE);
381 else if(isdigit((unsigned char) *s)){
382 n = (n * 10) + (*s - '0');
384 else
385 return(FALSE);
388 if (i < 2 && *s++ != ',')
389 return(FALSE);
392 return (TRUE);
397 char *
398 alpine_color_name(char *s)
400 if(s){
401 int i;
403 if(!struncmp(s, MATCH_NORM_COLOR, RGBLEN) || !struncmp(s, MATCH_NONE_COLOR, RGBLEN))
404 return(s);
405 else if(*s == ' ' || isdigit(*s)){
406 /* check for rgb string instead of name */
407 for(i = 0; i < sizeof(webcoltab) / sizeof(struct color_table); i++)
408 if(!strncmp(webcoltab[i].rgb, s, RGBLEN))
409 return(webcoltab[i].name.s);
411 else{
412 for(i = 0; i < sizeof(webcoltab) / sizeof(struct color_table); i++)
413 if(!struncmp(webcoltab[i].name.s, s, webcoltab[i].name.l))
414 return(webcoltab[i].name.s);
418 return(NULL);
423 * Sets color to (fg,bg).
424 * Flags == PSC_NONE No alternate default if fg,bg fails.
425 * == PSC_NORM Set it to Normal color on failure.
426 * == PSC_REV Set it to Reverse color on failure.
428 * If flag PSC_RET is set, returns an allocated copy of the previous
429 * color pair, otherwise returns NULL.
431 COLOR_PAIR *
432 pico_set_colors(char *fg, char *bg, int flags)
434 int uc;
435 COLOR_PAIR *cp = NULL, *rev = NULL;
437 if(flags & PSC_RET)
438 cp = pico_get_cur_color();
440 if(!((uc = pico_usingcolor())
441 && fg && bg
442 && pico_set_fg_color(fg) && pico_set_bg_color(bg))){
444 if(uc && flags & PSC_NORM){
445 pico_set_normal_color();
447 else if(flags & PSC_REV){
448 if((rev = pico_get_rev_color()) != NULL){
449 pico_set_fg_color(rev->fg); /* these will succeed */
450 pico_set_bg_color(rev->bg);
455 return(cp);
460 void
461 pico_nfcolor(char *s)
463 if(_nfcolor){
464 free(_nfcolor);
465 _nfcolor = NULL;
468 if(s){
469 _nfcolor = (char *)malloc(strlen(s)+1);
470 if(_nfcolor)
471 strcpy(_nfcolor, s);
476 void
477 pico_nbcolor(char *s)
479 if(_nbcolor){
480 free(_nbcolor);
481 _nbcolor = NULL;
484 if(s){
485 _nbcolor = (char *)malloc(strlen(s)+1);
486 if(_nbcolor)
487 strcpy(_nbcolor, s);
491 void
492 pico_rfcolor(char *s)
494 if(_rfcolor){
495 free(_rfcolor);
496 _rfcolor = NULL;
499 if(s){
500 _rfcolor = (char *)malloc(strlen(s)+1);
501 if(_rfcolor)
502 strcpy(_rfcolor, s);
504 if(the_rev_color)
505 strcpy(the_rev_color->fg, _rfcolor);
507 else if(the_rev_color)
508 free_color_pair(&the_rev_color);
511 void
512 pico_rbcolor(char *s)
514 if(_rbcolor){
515 free(_rbcolor);
516 _rbcolor = NULL;
519 if(s){
520 _rbcolor = (char *)malloc(strlen(s)+1);
521 if(_rbcolor)
522 strcpy(_rbcolor, s);
524 if(the_rev_color)
525 strcpy(the_rev_color->bg, _rbcolor);
527 else if(the_rev_color)
528 free_color_pair(&the_rev_color);
532 void
533 pico_endcolor(void)
535 if(_nfcolor){
536 free(_nfcolor);
537 _nfcolor = NULL;
540 if(_nbcolor){
541 free(_nbcolor);
542 _nbcolor = NULL;
545 if(_rfcolor){
546 free(_rfcolor);
547 _rfcolor = NULL;
550 if(_rbcolor){
551 free(_rbcolor);
552 _rbcolor = NULL;
555 if(the_rev_color)
556 free_color_pair(&the_rev_color);
560 COLOR_PAIR *
561 pico_get_cur_color(void)
563 return(new_color_pair(_last_fg_color, _last_bg_color));
567 * If inverse is a color, returns a pointer to that color.
568 * If not, returns NULL.
570 * NOTE: Don't free this!
572 COLOR_PAIR *
573 pico_get_rev_color(void)
575 if(pico_usingcolor() && _rfcolor && _rbcolor &&
576 pico_is_good_color(_rfcolor) && pico_is_good_color(_rbcolor)){
577 if(!the_rev_color)
578 the_rev_color = new_color_pair(_rfcolor, _rbcolor);
580 return(the_rev_color);
582 else
583 return(NULL);
588 pico_set_fg_color(char *s)
590 if(pico_is_good_color(s)){
591 if(!struncmp(s, MATCH_NORM_COLOR, RGBLEN))
592 s = _nfcolor;
593 else if(!struncmp(s, MATCH_NONE_COLOR, RGBLEN))
594 return(TRUE);
596 /* already set correctly */
597 if(!_force_fg_color_change
598 && _last_fg_color
599 && !strcmp(_last_fg_color, s))
600 return(TRUE);
602 _force_fg_color_change = 0;
603 if(_last_fg_color)
604 free(_last_fg_color);
606 if((_last_fg_color = (char *) malloc(strlen(s) + 1)) != NULL)
607 strcpy(_last_fg_color, s);
609 return(TRUE);
612 return(FALSE);
617 pico_set_bg_color(char *s)
619 if(pico_is_good_color(s)){
620 if(!struncmp(s, MATCH_NORM_COLOR, RGBLEN))
621 s = _nbcolor;
622 else if(!struncmp(s, MATCH_NONE_COLOR, RGBLEN))
623 return(TRUE);
625 /* already set correctly */
626 if(!_force_bg_color_change
627 && _last_bg_color
628 && !strcmp(_last_bg_color, s))
629 return(TRUE);
631 _force_bg_color_change = 0;
632 if(_last_bg_color)
633 free(_last_bg_color);
635 if((_last_bg_color = (char *) malloc(strlen(s) + 1)) != NULL)
636 strcpy(_last_bg_color, s);
638 return(TRUE);
641 return(FALSE);
645 void
646 pico_set_normal_color(void)
648 if(!_nfcolor || !_nbcolor ||
649 !pico_set_fg_color(_nfcolor) || !pico_set_bg_color(_nbcolor)){
650 (void)pico_set_fg_color(DEFAULT_NORM_FORE_RGB);
651 (void)pico_set_bg_color(DEFAULT_NORM_BACK_RGB);
656 char *
657 pico_get_last_fg_color(void)
659 char *ret = NULL;
661 if(_last_fg_color)
662 if((ret = (char *)malloc(strlen(_last_fg_color)+1)) != NULL)
663 strcpy(ret, _last_fg_color);
665 return(ret);
668 char *
669 pico_get_last_bg_color(void)
671 char *ret = NULL;
673 if(_last_bg_color)
674 if((ret = (char *)malloc(strlen(_last_bg_color)+1)) != NULL)
675 strcpy(ret, _last_bg_color);
677 return(ret);