Clean menu -- made to use standart GNOME menu entries
[midnight-commander.git] / src / color.c
blobd96b6cd40233af72cf32e1705c9798ae01b88514
1 /* Color setup
2 Copyright (C) 1994 Miguel de Icaza.
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.
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.
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. */
18 #include <config.h>
19 #include "tty.h"
20 #include <stdio.h>
21 #include <string.h>
22 #include "global.h"
23 #include "setup.h" /* For the externs */
24 #include "color.h"
25 #include "x.h"
27 /* "$Id$" */
29 /* To avoid excessive calls to ncurses' has_colors () */
30 int hascolors = 0;
32 /* Set to force black and white display at program startup */
33 int disable_colors = 0;
35 /* Set if we are actually using colors */
36 int use_colors = 0;
38 int dialog_colors [4];
40 #define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) )
44 #ifdef HAVE_GNOME
45 # define CTYPE GdkColor *
46 void init_pair (int, CTYPE, CTYPE);
47 #else
48 # ifdef HAVE_SLANG
49 # define CTYPE char *
50 # else
51 # define CTYPE int
52 # define color_map_fg(n) (color_map[n].fg % COLORS)
53 # define color_map_bg(n) (color_map[n].bg % COLORS)
54 # endif
55 #endif
57 struct colorpair {
58 char *name; /* Name of the entry */
59 CTYPE fg; /* foreground color */
60 CTYPE bg; /* background color */
63 #ifndef color_map_fg
64 # define color_map_fg(n) color_map[n].fg
65 # define color_map_bg(n) color_map[n].bg
66 #endif
68 struct colorpair color_map [] = {
69 { "normal=", 0, 0 }, /* normal */ /* 1 */
70 { "selected=", 0, 0 }, /* selected */
71 { "marked=", 0, 0 }, /* marked */
72 { "markselect=", 0, 0 }, /* marked/selected */
73 { "errors=", 0, 0 }, /* errors */
74 { "menu=", 0, 0 }, /* menu entry */
75 { "reverse=", 0, 0 }, /* reverse */
77 /* Dialog colors */
78 { "dnormal=", 0, 0 }, /* Dialog normal */ /* 8 */
79 { "dfocus=", 0, 0 }, /* Dialog focused */
80 { "dhotnormal=", 0, 0 }, /* Dialog normal/hot */
81 { "dhotfocus=", 0, 0 }, /* Dialog focused/hot */
83 { "viewunderline=", 0, 0 }, /* _\b? sequence in view, underline in editor */
84 { "menusel=", 0, 0 }, /* Menu selected color */ /* 13 */
85 { "menuhot=", 0, 0 }, /* Color for menu hotkeys */
86 { "menuhotsel=", 0, 0 }, /* Menu hotkeys/selected entry */
88 { "helpnormal=", 0, 0 }, /* Help normal */ /* 16 */
89 { "helpitalic=", 0, 0 }, /* Italic in help */
90 { "helpbold=", 0, 0 }, /* Bold in help */
91 { "helplink=", 0, 0 }, /* Not selected hyperlink */
92 { "helpslink=", 0, 0 }, /* Selected hyperlink */
94 { "gauge=", 0, 0 }, /* Color of the progress bar (percentage) *//* 21 */
95 { "input=", 0, 0 },
97 /* Per file types colors */
98 { "directory=", 0, 0 }, /* 23 */
99 { "executable=", 0, 0 },
100 { "link=", 0, 0 }, /* symbolic link (neither stalled nor link to directory) */
101 { "stalledlink=",0, 0 }, /* stalled symbolic link */
102 { "device=", 0, 0 },
103 { "special=", 0, 0 }, /* sockets, fifo */
104 { "core=", 0, 0 }, /* core files */ /* 29 */
106 { 0, 0, 0 }, /* not usable (DEFAULT_COLOR_INDEX) *//* 30 */
107 { 0, 0, 0 }, /* unused */
108 { 0, 0, 0 }, /* not usable (A_REVERSE) */
109 { 0, 0, 0 }, /* not usable (A_REVERSE_BOLD) */
111 /* editor colors start at 34 */
112 { "editnormal=", 0, 0 }, /* normal */ /* 34 */
113 { "editbold=", 0, 0 }, /* search->found */
114 { "editmarked=", 0, 0 }, /* marked/selected */
117 struct color_table_s {
118 char *name;
119 int value;
123 struct color_table_s color_table [] = {
124 { "black", COLOR_BLACK },
125 { "gray", COLOR_BLACK | A_BOLD },
126 { "red", COLOR_RED },
127 { "brightred", COLOR_RED | A_BOLD },
128 { "green", COLOR_GREEN },
129 { "brightgreen", COLOR_GREEN | A_BOLD },
130 { "brown", COLOR_YELLOW },
131 { "yellow", COLOR_YELLOW | A_BOLD },
132 { "blue", COLOR_BLUE },
133 { "brightblue", COLOR_BLUE | A_BOLD },
134 { "magenta", COLOR_MAGENTA },
135 { "brightmagenta", COLOR_MAGENTA | A_BOLD },
136 { "cyan", COLOR_CYAN },
137 { "brightcyan", COLOR_CYAN | A_BOLD },
138 { "lightgray", COLOR_WHITE },
139 { "white", COLOR_WHITE | A_BOLD },
140 { "default", 0 } /* hack for transparent background */
143 #ifdef HAVE_GNOME
144 void get_color (char *cpp, CTYPE *colp);
145 #else
146 # ifdef HAVE_SLANG
147 # define color_value(i) color_table [i].name
148 # define color_name(i) color_table [i].name
149 # else
150 # define color_value(i) color_table [i].value
151 # define color_name(i) color_table [i].name
152 # endif
154 static void get_color (char *cpp, CTYPE *colp)
156 int i;
158 for (i = 0; i < ELEMENTS(color_table); i++){
159 if (strcmp (cpp, color_name (i)) == 0){
160 *colp = color_value (i);
161 return;
165 #endif /* HAVE_GNOME */
167 static void get_two_colors (char **cpp, struct colorpair *colorpairp)
169 char *p = *cpp;
170 int state;
172 state = 0;
174 for (; *p; p++){
175 if (*p == ':'){
176 *p = 0;
177 get_color (*cpp, state ? &colorpairp->bg : &colorpairp->fg);
178 *p = ':';
179 *cpp = p + 1;
180 return;
183 if (*p == ','){
184 state = 1;
185 *p = 0;
186 get_color (*cpp, &colorpairp->fg);
187 *p = ',';
188 *cpp = p + 1;
191 get_color (*cpp, state ? &colorpairp->bg : &colorpairp->fg);
194 void configure_colors_string (char *the_color_string)
196 char *color_string, *p;
197 int i, found;
199 if (!the_color_string)
200 return;
202 p = color_string = g_strdup (the_color_string);
203 while (color_string && *color_string){
204 while (*color_string == ' ' || *color_string == '\t')
205 color_string++;
207 found = 0;
208 for (i = 0; i < ELEMENTS(color_map); i++){
209 int klen;
211 if (!color_map [i].name)
212 continue;
213 klen = strlen (color_map [i].name);
215 if (strncmp (color_string, color_map [i].name, klen) == 0){
216 color_string += klen;
217 get_two_colors (&color_string, &color_map [i]);
218 found = 1;
221 if (!found){
222 while (*color_string && *color_string != ':')
223 color_string++;
224 if (*color_string)
225 color_string++;
228 g_free (p);
231 static void configure_colors (void)
233 extern char *command_line_colors;
234 extern char *default_edition_colors;
236 configure_colors_string (default_edition_colors);
237 configure_colors_string (setup_color_string);
238 configure_colors_string (term_color_string);
239 configure_colors_string (getenv ("MC_COLOR_TABLE"));
240 configure_colors_string (command_line_colors);
243 #ifndef HAVE_SLANG
244 #define MAX_PAIRS 34
245 int attr_pairs [MAX_PAIRS];
246 #endif
248 static void
249 load_dialog_colors (void)
251 dialog_colors [0] = COLOR_NORMAL;
252 dialog_colors [1] = COLOR_FOCUS;
253 dialog_colors [2] = COLOR_HOT_NORMAL;
254 dialog_colors [3] = COLOR_HOT_FOCUS;
257 #ifdef HAVE_X
258 void
259 init_colors (void)
261 int i;
263 use_colors = 1;
264 configure_colors ();
265 for (i = 0; i < ELEMENTS (color_map); i++)
266 if (color_map [i].name)
267 init_pair (i+1, color_map_fg(i), color_map_bg(i));
268 load_dialog_colors ();
270 #else
271 void init_colors (void)
273 int i;
275 hascolors = has_colors ();
277 if (!disable_colors && hascolors){
278 use_colors = 1;
281 if (use_colors){
282 #ifndef HAVE_X
283 start_color ();
284 #endif
285 configure_colors ();
287 #ifndef HAVE_SLANG
288 if (ELEMENTS (color_map) > MAX_PAIRS){
289 /* This message should only be seen by the developers */
290 fprintf (stderr,
291 "Too many defined colors, resize MAX_PAIRS on color.c");
292 exit (1);
294 #endif
296 #if defined HAVE_SLANG && !defined(HAS_DIRECT_COLOR_ACCESS)
297 if (use_colors) { /* Hack to make COLOR_PAIR(DEFAULT_COLOR_INDEX)
298 be the default fg/bg of the terminal */
299 char *Norm_Vid = SLtt_tgetstr ("me");
301 if (Norm_Vid == NULL)
302 Norm_Vid = SLtt_tgetstr ("se");
303 if (Norm_Vid == NULL)
304 Norm_Vid = "\033[0m";
305 SLtt_set_color_esc (DEFAULT_COLOR_INDEX, Norm_Vid);
307 #endif
309 for (i = 0; i < ELEMENTS (color_map); i++){
310 if (!color_map [i].name)
311 continue;
313 init_pair (i+1, color_map_fg(i), color_map_bg(i));
315 #ifndef HAVE_SLANG
317 * As a convenience, for the SVr4 curses configuration, we have
318 * OR'd the A_BOLD attribute to the color number. We'll need that
319 * later, to set the attribute with the colors.
321 attr_pairs [i+1] = color_map [i].fg & A_BOLD;
322 #endif
325 load_dialog_colors ();
327 #endif
329 void toggle_color_mode (void)
331 if (hascolors)
332 use_colors = !use_colors;