1 /*
2 * GNT - The GLib Ncurses Toolkit
3 *
4 * GNT is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
7 *
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 */
22
23 #include "gntconfig.h"
24
25 #include <ncurses.h>
26
27 #include "gntinternal.h"
28 #undef GNT_LOG_DOMAIN
29 #define GNT_LOG_DOMAIN "Colors"
30
31 #include "gntcolors.h"
32 #include "gntstyle.h"
33
34 #include <glib.h>
35
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 static gboolean hascolors;
41 static int custom_type = GNT_COLORS;
42 static struct
43 {
44 short r, g, b;
45 } colors[GNT_TOTAL_COLORS];
46
47 static void
backup_colors(void)48 backup_colors(void)
49 {
50 short i;
51 for (i = 0; i < GNT_TOTAL_COLORS; i++)
52 {
53 color_content(i, &colors[i].r,
54 &colors[i].g, &colors[i].b);
55 }
56 }
57
58 static gboolean
can_use_custom_color(void)59 can_use_custom_color(void)
60 {
61 return (gnt_style_get_bool(GNT_STYLE_COLOR, FALSE) && can_change_color());
62 }
63
64 static void
restore_colors(void)65 restore_colors(void)
66 {
67 short i;
68 for (i = 0; i < GNT_TOTAL_COLORS; i++)
69 {
70 init_color(i, colors[i].r,
71 colors[i].g, colors[i].b);
72 }
73 }
74
gnt_init_colors()75 void gnt_init_colors()
76 {
77 static gboolean init = FALSE;
78 int defaults;
79
80 if (init)
81 return;
82 init = TRUE;
83
84 start_color();
85 if (!(hascolors = has_colors()))
86 return;
87 defaults = use_default_colors();
88
89 if (can_use_custom_color())
90 {
91 backup_colors();
92
93 /* Do some init_color()s */
94 init_color(GNT_COLOR_BLACK, 0, 0, 0);
95 init_color(GNT_COLOR_RED, 1000, 0, 0);
96 init_color(GNT_COLOR_GREEN, 0, 1000, 0);
97 init_color(GNT_COLOR_BLUE, 250, 250, 700);
98 init_color(GNT_COLOR_WHITE, 1000, 1000, 1000);
99 init_color(GNT_COLOR_GRAY, 699, 699, 699);
100 init_color(GNT_COLOR_DARK_GRAY, 256, 256, 256);
101
102 /* Now some init_pair()s */
103 init_pair(GNT_COLOR_NORMAL, GNT_COLOR_BLACK, GNT_COLOR_WHITE);
104 init_pair(GNT_COLOR_HIGHLIGHT, GNT_COLOR_WHITE, GNT_COLOR_BLUE);
105 init_pair(GNT_COLOR_SHADOW, GNT_COLOR_BLACK, GNT_COLOR_DARK_GRAY);
106
107 init_pair(GNT_COLOR_TITLE, GNT_COLOR_WHITE, GNT_COLOR_BLUE);
108 init_pair(GNT_COLOR_TITLE_D, GNT_COLOR_WHITE, GNT_COLOR_GRAY);
109
110 init_pair(GNT_COLOR_TEXT_NORMAL, GNT_COLOR_WHITE, GNT_COLOR_BLUE);
111 init_pair(GNT_COLOR_HIGHLIGHT_D, GNT_COLOR_BLACK, GNT_COLOR_GRAY);
112 init_pair(GNT_COLOR_DISABLED, GNT_COLOR_GRAY, GNT_COLOR_WHITE);
113 init_pair(GNT_COLOR_URGENT, GNT_COLOR_WHITE, GNT_COLOR_RED);
114 }
115 else
116 {
117 int bg;
118
119 if (defaults == OK) {
120 init_pair(GNT_COLOR_NORMAL, -1, -1);
121 bg = -1;
122 } else {
123 init_pair(GNT_COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE);
124 bg = COLOR_WHITE;
125 }
126 init_pair(GNT_COLOR_DISABLED, COLOR_YELLOW, bg);
127 init_pair(GNT_COLOR_URGENT, COLOR_GREEN, bg);
128
129 init_pair(GNT_COLOR_HIGHLIGHT, COLOR_WHITE, COLOR_BLUE);
130 init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK);
131 init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLUE);
132 init_pair(GNT_COLOR_TITLE_D, COLOR_WHITE, COLOR_BLACK);
133 init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_WHITE, COLOR_BLUE);
134 init_pair(GNT_COLOR_HIGHLIGHT_D, COLOR_CYAN, COLOR_BLACK);
135 }
136 }
137
138 void
gnt_uninit_colors()139 gnt_uninit_colors()
140 {
141 if (can_use_custom_color())
142 restore_colors();
143 }
144
145 int
gnt_colors_get_color(char * key)146 gnt_colors_get_color(char *key)
147 {
148 int color;
149 gboolean custom = can_use_custom_color();
150
151 key = g_strstrip(key);
152
153 if (strcmp(key, "black") == 0)
154 color = custom ? GNT_COLOR_BLACK : COLOR_BLACK;
155 else if (strcmp(key, "red") == 0)
156 color = custom ? GNT_COLOR_RED : COLOR_RED;
157 else if (strcmp(key, "green") == 0)
158 color = custom ? GNT_COLOR_GREEN : COLOR_GREEN;
159 else if (strcmp(key, "blue") == 0)
160 color = custom ? GNT_COLOR_BLUE : COLOR_BLUE;
161 else if (strcmp(key, "white") == 0)
162 color = custom ? GNT_COLOR_WHITE : COLOR_WHITE;
163 else if (strcmp(key, "gray") == 0 || strcmp(key, "grey") == 0)
164 color = custom ? GNT_COLOR_GRAY : COLOR_YELLOW; /* eh? */
165 else if (strcmp(key, "darkgray") == 0 || strcmp(key, "darkgrey") == 0)
166 color = custom ? GNT_COLOR_DARK_GRAY : COLOR_BLACK;
167 else if (strcmp(key, "magenta") == 0)
168 color = COLOR_MAGENTA;
169 else if (strcmp(key, "cyan") == 0)
170 color = COLOR_CYAN;
171 else if (strcmp(key, "default") == 0)
172 color = -1;
173 else {
174 g_warning("Invalid color name: %s\n", key);
175 color = -EINVAL;
176 }
177 return color;
178 }
179
gnt_colors_parse(GKeyFile * kfile)180 void gnt_colors_parse(GKeyFile *kfile)
181 {
182 GError *error = NULL;
183 gsize nkeys;
184 char **keys = g_key_file_get_keys(kfile, "colors", &nkeys, &error);
185
186 if (error)
187 {
188 gnt_warning("%s", error->message);
189 g_error_free(error);
190 error = NULL;
191 }
192 else if (nkeys)
193 {
194 gnt_init_colors();
195 while (nkeys--)
196 {
197 gsize len;
198 gchar *key = keys[nkeys];
199 char **list = g_key_file_get_string_list(kfile, "colors", key, &len, NULL);
200 if (len == 3)
201 {
202 int r = atoi(list[0]);
203 int g = atoi(list[1]);
204 int b = atoi(list[2]);
205 int color = -1;
206
207 key = g_ascii_strdown(key, -1);
208 color = gnt_colors_get_color(key);
209 g_free(key);
210 if (color == -EINVAL) {
211 g_strfreev(list);
212 continue;
213 }
214
215 init_color(color, r, g, b);
216 }
217 g_strfreev(list);
218 }
219
220 g_strfreev(keys);
221 }
222
223 gnt_color_pairs_parse(kfile);
224 }
225
gnt_color_pairs_parse(GKeyFile * kfile)226 void gnt_color_pairs_parse(GKeyFile *kfile)
227 {
228 GError *error = NULL;
229 gsize nkeys;
230 char **keys = g_key_file_get_keys(kfile, "colorpairs", &nkeys, &error);
231
232 if (error)
233 {
234 gnt_warning("%s", error->message);
235 g_error_free(error);
236 return;
237 }
238 else if (nkeys)
239 gnt_init_colors();
240
241 while (nkeys--)
242 {
243 gsize len;
244 gchar *key = keys[nkeys];
245 char **list = g_key_file_get_string_list(kfile, "colorpairs", key, &len, NULL);
246 if (len == 2)
247 {
248 GntColorType type = 0;
249 gchar *fgc = g_ascii_strdown(list[0], -1);
250 gchar *bgc = g_ascii_strdown(list[1], -1);
251 int fg = gnt_colors_get_color(fgc);
252 int bg = gnt_colors_get_color(bgc);
253 g_free(fgc);
254 g_free(bgc);
255 if (fg == -EINVAL || bg == -EINVAL) {
256 g_strfreev(list);
257 continue;
258 }
259
260 key = g_ascii_strdown(key, -1);
261
262 if (strcmp(key, "normal") == 0)
263 type = GNT_COLOR_NORMAL;
264 else if (strcmp(key, "highlight") == 0)
265 type = GNT_COLOR_HIGHLIGHT;
266 else if (strcmp(key, "highlightd") == 0)
267 type = GNT_COLOR_HIGHLIGHT_D;
268 else if (strcmp(key, "shadow") == 0)
269 type = GNT_COLOR_SHADOW;
270 else if (strcmp(key, "title") == 0)
271 type = GNT_COLOR_TITLE;
272 else if (strcmp(key, "titled") == 0)
273 type = GNT_COLOR_TITLE_D;
274 else if (strcmp(key, "text") == 0)
275 type = GNT_COLOR_TEXT_NORMAL;
276 else if (strcmp(key, "disabled") == 0)
277 type = GNT_COLOR_DISABLED;
278 else if (strcmp(key, "urgent") == 0)
279 type = GNT_COLOR_URGENT;
280 else {
281 g_strfreev(list);
282 g_free(key);
283 continue;
284 }
285 g_free(key);
286
287 init_pair(type, fg, bg);
288 }
289 g_strfreev(list);
290 }
291
292 g_strfreev(keys);
293 }
294
gnt_color_pair(int pair)295 int gnt_color_pair(int pair)
296 {
297 return (hascolors ? COLOR_PAIR(pair) :
298 ((pair == GNT_COLOR_NORMAL || pair == GNT_COLOR_HIGHLIGHT_D ||
299 pair == GNT_COLOR_TITLE_D || pair == GNT_COLOR_DISABLED) ? 0 : (int)A_STANDOUT));
300 }
301
gnt_color_add_pair(int fg,int bg)302 int gnt_color_add_pair(int fg, int bg)
303 {
304 init_pair(custom_type, fg, bg);
305 return custom_type++;
306 }
307