added PCI interrupt link device
[reactos.git] / rosapps / mc / src / color.c
1 /* Color setup
2 Copyright (C) 1994 Miguel de Icaza.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #include <config.h>
19 #include "tty.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "mad.h"
24 #include "setup.h" /* For the externs */
25 #include "color.h"
26 #include "x.h"
27
28 /* "$Id$" */
29
30 /* To avoid excessive calls to ncurses' has_colors () */
31 int hascolors = 0;
32
33 /* Set to force black and white display at program startup */
34 int disable_colors = 0;
35
36 /* Set if we are actually using colors */
37 int use_colors = 0;
38
39 int dialog_colors [4];
40
41 #define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) )
42
43
44
45 #ifdef HAVE_GNOME
46 # define CTYPE GdkColor *
47 void init_pair (int, CTYPE, CTYPE);
48 #else
49 # ifdef HAVE_SLANG
50 # define CTYPE char *
51 # else
52 # define CTYPE int
53 # define color_map_fg(n) (color_map[n].fg % COLORS)
54 # define color_map_bg(n) (color_map[n].bg % COLORS)
55 # endif
56 #endif
57
58 struct colorpair {
59 char *name; /* Name of the entry */
60 CTYPE fg; /* foreground color */
61 CTYPE bg; /* background color */
62 };
63
64 #ifndef color_map_fg
65 # define color_map_fg(n) color_map[n].fg
66 # define color_map_bg(n) color_map[n].bg
67 #endif
68
69 struct colorpair color_map [] = {
70 { "normal=", 0, 0 }, /* normal */
71 { "selected=", 0, 0 }, /* selected */
72 { "marked=", 0, 0 }, /* marked */
73 { "markselect=", 0, 0 }, /* marked/selected */
74 { "errors=", 0, 0 }, /* errors */
75 { "menu=", 0, 0 }, /* menu entry */
76 { "reverse=", 0, 0 }, /* reverse */
77
78 /* Dialog colors */
79 { "dnormal=", 0, 0 }, /* Dialog normal */
80 { "dfocus=", 0, 0 }, /* Dialog focused */
81 { "dhotnormal=", 0, 0 }, /* Dialog normal/hot */
82 { "dhotfocus=", 0, 0 }, /* Dialog focused/hot */
83
84 { "viewunderline=", 0, 0 }, /* _\b? sequence in view */
85 { "menusel=", 0, 0 }, /* Menu selected color */
86 { "menuhot=", 0, 0 }, /* Color for menu hotkeys */
87 { "menuhotsel=", 0, 0 }, /* Menu hotkeys/selected entry */
88
89 { "helpnormal=", 0, 0 }, /* Help normal */
90 { "helpitalic=", 0, 0 }, /* Italic in help */
91 { "helpbold=", 0, 0 }, /* Bold in help */
92 { "helplink=", 0, 0 }, /* Not selected hyperlink */
93 { "helpslink=", 0, 0 }, /* Selected hyperlink */
94
95 { "gauge=", 0, 0 }, /* Color of the progress bar (percentage) */
96 { "input=", 0, 0 },
97
98 /* Per file types colors */
99 { "directory=", 0, 0 },
100 { "execute=", 0, 0 },
101 { "link=", 0, 0 },
102 { "device=", 0, 0 },
103 { "special=", 0, 0 },
104 { "core=", 0, 0 },
105 };
106
107 struct color_table_s {
108 char *name;
109 int value;
110 };
111
112
113 struct color_table_s color_table [] = {
114 { "black", COLOR_BLACK },
115 { "gray", COLOR_BLACK | A_BOLD },
116 { "red", COLOR_RED },
117 { "brightred", COLOR_RED | A_BOLD },
118 { "green", COLOR_GREEN },
119 { "brightgreen", COLOR_GREEN | A_BOLD },
120 { "brown", COLOR_YELLOW },
121 { "yellow", COLOR_YELLOW | A_BOLD },
122 { "blue", COLOR_BLUE },
123 { "brightblue", COLOR_BLUE | A_BOLD },
124 { "magenta", COLOR_MAGENTA },
125 { "brightmagenta", COLOR_MAGENTA | A_BOLD },
126 { "cyan", COLOR_CYAN },
127 { "brightcyan", COLOR_CYAN | A_BOLD },
128 { "lightgray", COLOR_WHITE },
129 { "white", COLOR_WHITE | A_BOLD }
130 };
131
132 #ifdef HAVE_GNOME
133 void get_color (char *cpp, CTYPE *colp);
134 #else
135 # ifdef HAVE_SLANG
136 # define color_value(i) color_table [i].name
137 # define color_name(i) color_table [i].name
138 # else
139 # define color_value(i) color_table [i].value
140 # define color_name(i) color_table [i].name
141 # endif
142
143 static void get_color (char *cpp, CTYPE *colp)
144 {
145 int i;
146
147 for (i = 0; i < ELEMENTS(color_table); i++){
148 if (strcmp (cpp, color_name (i)) == 0){
149 *colp = color_value (i);
150 return;
151 }
152 }
153 }
154 #endif /* HAVE_GNOME */
155
156 static void get_two_colors (char **cpp, struct colorpair *colorpairp)
157 {
158 char *p = *cpp;
159 int state;
160
161 state = 0;
162
163 for (; *p; p++){
164 if (*p == ':'){
165 *p = 0;
166 get_color (*cpp, state ? &colorpairp->bg : &colorpairp->fg);
167 *p = ':';
168 *cpp = p + 1;
169 return;
170 }
171
172 if (*p == ','){
173 state = 1;
174 *p = 0;
175 get_color (*cpp, &colorpairp->fg);
176 *p = ',';
177 *cpp = p + 1;
178 }
179 }
180 get_color (*cpp, state ? &colorpairp->bg : &colorpairp->fg);
181 }
182
183 void configure_colors_string (char *the_color_string)
184 {
185 char *color_string, *p;
186 int i, found;
187
188 if (!the_color_string)
189 return;
190
191 p = color_string = strdup (the_color_string);
192 while (color_string && *color_string){
193 while (*color_string == ' ' || *color_string == '\t')
194 color_string++;
195
196 found = 0;
197 for (i = 0; i < ELEMENTS(color_map); i++){
198 int klen = strlen (color_map [i].name);
199
200 if (strncmp (color_string, color_map [i].name, klen) == 0){
201 color_string += klen;
202 get_two_colors (&color_string, &color_map [i]);
203 found = 1;
204 }
205 }
206 if (!found){
207 while (*color_string && *color_string != ':')
208 color_string++;
209 if (*color_string)
210 color_string++;
211 }
212 }
213 free (p);
214 }
215
216 static void configure_colors (void)
217 {
218 extern char *command_line_colors;
219 #ifndef HAVE_TK
220 #ifndef HAVE_XVIEW
221 extern char *default_edition_colors;
222
223 configure_colors_string (default_edition_colors);
224 #endif
225 #endif
226 configure_colors_string (setup_color_string);
227 configure_colors_string (term_color_string);
228 configure_colors_string (getenv ("MC_COLOR_TABLE"));
229 configure_colors_string (command_line_colors);
230 }
231
232 #ifndef HAVE_SLANG
233 #define MAX_PAIRS 30
234 int attr_pairs [MAX_PAIRS];
235 #endif
236
237 static void
238 load_dialog_colors (void)
239 {
240 dialog_colors [0] = COLOR_NORMAL;
241 dialog_colors [1] = COLOR_FOCUS;
242 dialog_colors [2] = COLOR_HOT_NORMAL;
243 dialog_colors [3] = COLOR_HOT_FOCUS;
244 }
245
246 #ifdef HAVE_X
247 void
248 init_colors (void)
249 {
250 int i;
251
252 use_colors = 1;
253 start_color ();
254 configure_colors ();
255 for (i = 0; i < ELEMENTS (color_map); i++)
256 init_pair (i+1, color_map_fg(i), color_map_bg(i));
257 load_dialog_colors ();
258 }
259 #else
260 void init_colors (void)
261 {
262 int i;
263
264 hascolors = has_colors ();
265
266 if (!disable_colors && hascolors){
267 use_colors = 1;
268 }
269
270 if (use_colors){
271 start_color ();
272 configure_colors ();
273
274 #ifndef HAVE_SLANG
275 if (ELEMENTS (color_map) > MAX_PAIRS){
276 /* This message should only be seen by the developers */
277 fprintf (stderr,
278 "Too many defined colors, resize MAX_PAIRS on color.c");
279 exit (1);
280 }
281 #endif
282
283 #if defined HAVE_SLANG && !defined(OS2_NT)
284 if (use_colors) { /* Hack to make COLOR_PAIR(31) be the default fg/bg
285 of the terminal */
286 char *Norm_Vid = SLtt_tgetstr ("me");
287
288 if (Norm_Vid == NULL)
289 Norm_Vid = SLtt_tgetstr ("se");
290 if (Norm_Vid == NULL)
291 Norm_Vid = "\033[0m";
292 SLtt_set_color_esc (31, Norm_Vid);
293 }
294 #endif
295
296 for (i = 0; i < ELEMENTS (color_map); i++){
297 init_pair (i+1, color_map_fg(i), color_map_bg(i));
298
299 #ifndef HAVE_SLANG
300 /*
301 * As a convenience, for the SVr4 curses configuration, we have
302 * OR'd the A_BOLD attribute to the color number. We'll need that
303 * later, to set the attribute with the colors.
304 */
305 attr_pairs [i+1] = color_map [i].fg & A_BOLD;
306 #endif
307 }
308 }
309 load_dialog_colors ();
310 }
311 #endif
312
313 void toggle_color_mode (void)
314 {
315 if (hascolors)
316 use_colors = !use_colors;
317 }
318