Update to 24f58c58bb8d22c0e8e6c5ce43c536c47b719bc6
[gnt.git] / gntstyle.c
blobd911bd7e60d86551464342ce53a5af9daedf6feb
1 /**
2 * GNT - The GLib Ncurses Toolkit
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.
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.
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.
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
23 #include "gntstyle.h"
24 #include "gntcolors.h"
25 #include "gntws.h"
27 #include <glib.h>
28 #include <ctype.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #define MAX_WORKSPACES 99
34 #if GLIB_CHECK_VERSION(2,6,0)
35 static GKeyFile *gkfile;
36 #endif
38 static char * str_styles[GNT_STYLES];
39 static int int_styles[GNT_STYLES];
40 static int bool_styles[GNT_STYLES];
42 const char *gnt_style_get(GntStyle style)
44 return str_styles[style];
47 char *gnt_style_get_from_name(const char *group, const char *key)
49 #if GLIB_CHECK_VERSION(2,6,0)
50 const char *prg = g_get_prgname();
51 if ((group == NULL || *group == '\0') && prg &&
52 g_key_file_has_group(gkfile, prg))
53 group = prg;
54 if (!group)
55 group = "general";
56 return g_key_file_get_value(gkfile, group, key, NULL);
57 #else
58 return NULL;
59 #endif
62 int
63 gnt_style_get_color(char *group, char *key)
65 #if GLIB_CHECK_VERSION(2,6,0)
66 int fg = 0, bg = 0;
67 gsize n;
68 char **vals;
69 int ret = 0;
70 vals = gnt_style_get_string_list(group, key, &n);
71 if (vals && n == 2) {
72 fg = gnt_colors_get_color(vals[0]);
73 bg = gnt_colors_get_color(vals[1]);
74 ret = gnt_color_add_pair(fg, bg);
76 g_strfreev(vals);
77 return ret;
78 #else
79 return 0;
80 #endif
83 char **gnt_style_get_string_list(const char *group, const char *key, gsize *length)
85 #if GLIB_CHECK_VERSION(2,6,0)
86 const char *prg = g_get_prgname();
87 if ((group == NULL || *group == '\0') && prg &&
88 g_key_file_has_group(gkfile, prg))
89 group = prg;
90 if (!group)
91 group = "general";
92 return g_key_file_get_string_list(gkfile, group, key, length, NULL);
93 #else
94 return NULL;
95 #endif
98 gboolean gnt_style_get_bool(GntStyle style, gboolean def)
100 const char * str;
102 if (bool_styles[style] != -1)
103 return bool_styles[style];
105 str = gnt_style_get(style);
107 bool_styles[style] = str ? gnt_style_parse_bool(str) : def;
108 return bool_styles[style];
111 gboolean gnt_style_parse_bool(const char *str)
113 gboolean def = FALSE;
114 int i;
116 if (str)
118 if (g_ascii_strcasecmp(str, "false") == 0)
119 def = FALSE;
120 else if (g_ascii_strcasecmp(str, "true") == 0)
121 def = TRUE;
122 else if (sscanf(str, "%d", &i) == 1)
124 if (i)
125 def = TRUE;
126 else
127 def = FALSE;
130 return def;
133 #if GLIB_CHECK_VERSION(2,6,0)
134 static void
135 refine(char *text)
137 char *s = text, *t = text;
139 while (*s)
141 if (*s == '^' && *(s + 1) == '[')
143 *t = '\033'; /* escape */
144 s++;
146 else if (*s == '\\')
148 if (*(s + 1) == '\0')
149 *t = ' ';
150 else
152 s++;
153 if (*s == 'r' || *s == 'n')
154 *t = '\r';
155 else if (*s == 't')
156 *t = '\t';
157 else
158 *t = *s;
161 else
162 *t = *s;
163 t++;
164 s++;
166 *t = '\0';
169 static char *
170 parse_key(const char *key)
172 return (char *)gnt_key_translate(key);
174 #endif
176 void gnt_style_read_workspaces(GntWM *wm)
178 #if GLIB_CHECK_VERSION(2,6,0)
179 int i;
180 gchar *name;
181 gsize c;
183 for (i = 1; i < MAX_WORKSPACES; ++i) {
184 int j;
185 GntWS *ws;
186 gchar **titles;
187 char group[32];
188 g_snprintf(group, sizeof(group), "Workspace-%d", i);
189 name = g_key_file_get_value(gkfile, group, "name", NULL);
190 if (!name)
191 return;
193 ws = gnt_ws_new(name);
194 gnt_wm_add_workspace(wm, ws);
195 g_free(name);
197 titles = g_key_file_get_string_list(gkfile, group, "window-names", &c, NULL);
198 if (titles) {
199 for (j = 0; j < c; ++j)
200 g_hash_table_replace(wm->name_places, g_strdup(titles[j]), ws);
201 g_strfreev(titles);
204 titles = g_key_file_get_string_list(gkfile, group, "window-titles", &c, NULL);
205 if (titles) {
206 for (j = 0; j < c; ++j)
207 g_hash_table_replace(wm->title_places, g_strdup(titles[j]), ws);
208 g_strfreev(titles);
211 #endif
213 void gnt_style_read_actions(GType type, GntBindableClass *klass)
215 #if GLIB_CHECK_VERSION(2,6,0)
216 char *name;
217 GError *error = NULL;
219 name = g_strdup_printf("%s::binding", g_type_name(type));
221 if (g_key_file_has_group(gkfile, name))
223 gsize len = 0;
224 char **keys;
226 keys = g_key_file_get_keys(gkfile, name, &len, &error);
227 if (error)
229 g_printerr("GntStyle: %s\n", error->message);
230 g_error_free(error);
231 g_free(name);
232 return;
235 while (len--)
237 char *key, *action;
239 key = g_strdup(keys[len]);
240 action = g_key_file_get_string(gkfile, name, keys[len], &error);
242 if (error)
244 g_printerr("GntStyle: %s\n", error->message);
245 g_error_free(error);
246 error = NULL;
248 else
250 const char *keycode = parse_key(key);
251 if (keycode == NULL) {
252 g_printerr("GntStyle: Invalid key-binding %s\n", key);
253 } else {
254 gnt_bindable_register_binding(klass, action, keycode, NULL);
257 g_free(key);
258 g_free(action);
260 g_strfreev(keys);
262 g_free(name);
263 #endif
266 gboolean gnt_style_read_menu_accels(const char *name, GHashTable *table)
268 #if GLIB_CHECK_VERSION(2,6,0)
269 char *kname;
270 GError *error = NULL;
271 gboolean ret = FALSE;
273 kname = g_strdup_printf("%s::menu", name);
275 if (g_key_file_has_group(gkfile, kname))
277 gsize len = 0;
278 char **keys;
280 keys = g_key_file_get_keys(gkfile, kname, &len, &error);
281 if (error)
283 g_printerr("GntStyle: %s\n", error->message);
284 g_error_free(error);
285 g_free(kname);
286 return ret;
289 while (len--)
291 char *key, *menuid;
293 key = g_strdup(keys[len]);
294 menuid = g_key_file_get_string(gkfile, kname, keys[len], &error);
296 if (error)
298 g_printerr("GntStyle: %s\n", error->message);
299 g_error_free(error);
300 error = NULL;
302 else
304 const char *keycode = parse_key(key);
305 if (keycode == NULL) {
306 g_printerr("GntStyle: Invalid key-binding %s\n", key);
307 } else {
308 ret = TRUE;
309 g_hash_table_replace(table, g_strdup(keycode), menuid);
310 menuid = NULL;
313 g_free(key);
314 g_free(menuid);
316 g_strfreev(keys);
319 g_free(kname);
320 return ret;
321 #endif
322 return FALSE;
325 void gnt_styles_get_keyremaps(GType type, GHashTable *hash)
327 #if GLIB_CHECK_VERSION(2,6,0)
328 char *name;
329 GError *error = NULL;
331 name = g_strdup_printf("%s::remap", g_type_name(type));
333 if (g_key_file_has_group(gkfile, name))
335 gsize len = 0;
336 char **keys;
338 keys = g_key_file_get_keys(gkfile, name, &len, &error);
339 if (error)
341 g_printerr("GntStyle: %s\n", error->message);
342 g_error_free(error);
343 g_free(name);
344 return;
347 while (len--)
349 char *key, *replace;
351 key = g_strdup(keys[len]);
352 replace = g_key_file_get_string(gkfile, name, keys[len], &error);
354 if (error)
356 g_printerr("GntStyle: %s\n", error->message);
357 g_error_free(error);
358 error = NULL;
359 g_free(key);
361 else
363 refine(key);
364 refine(replace);
365 g_hash_table_insert(hash, key, replace);
368 g_strfreev(keys);
371 g_free(name);
372 #endif
375 #if GLIB_CHECK_VERSION(2,6,0)
376 static void
377 read_general_style(GKeyFile *kfile)
379 GError *error = NULL;
380 gsize nkeys;
381 const char *prgname = g_get_prgname();
382 char **keys = NULL;
383 int i;
384 struct
386 const char *style;
387 GntStyle en;
388 } styles[] = {{"shadow", GNT_STYLE_SHADOW},
389 {"customcolor", GNT_STYLE_COLOR},
390 {"mouse", GNT_STYLE_MOUSE},
391 {"wm", GNT_STYLE_WM},
392 {"remember_position", GNT_STYLE_REMPOS},
393 {NULL, 0}};
395 if (prgname && *prgname)
396 keys = g_key_file_get_keys(kfile, prgname, &nkeys, NULL);
398 if (keys == NULL) {
399 prgname = "general";
400 keys = g_key_file_get_keys(kfile, prgname, &nkeys, &error);
403 if (error)
405 g_printerr("GntStyle: %s\n", error->message);
406 g_error_free(error);
408 else
410 for (i = 0; styles[i].style; i++)
412 str_styles[styles[i].en] =
413 g_key_file_get_string(kfile, prgname, styles[i].style, NULL);
416 g_strfreev(keys);
418 #endif
420 void gnt_style_read_configure_file(const char *filename)
422 #if GLIB_CHECK_VERSION(2,6,0)
423 GError *error = NULL;
424 gkfile = g_key_file_new();
426 if (!g_key_file_load_from_file(gkfile, filename,
427 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error))
429 g_printerr("GntStyle: %s\n", error->message);
430 g_error_free(error);
431 return;
433 gnt_colors_parse(gkfile);
434 read_general_style(gkfile);
435 #endif
438 void gnt_init_styles()
440 int i;
441 for (i = 0; i < GNT_STYLES; i++)
443 str_styles[i] = NULL;
444 int_styles[i] = -1;
445 bool_styles[i] = -1;
449 void gnt_uninit_styles()
451 int i;
452 for (i = 0; i < GNT_STYLES; i++) {
453 g_free(str_styles[i]);
454 str_styles[i] = NULL;
457 #if GLIB_CHECK_VERSION(2,6,0)
458 g_key_file_free(gkfile);
459 gkfile = NULL;
460 #endif