load the engine out of the config shit. tho the ordering is fucked atm
[dana/openbox.git] / openbox / config.c
1 #include "config.h"
2
3 #ifdef HAVE_STDIO_H
4 #  include <stdio.h>
5 #endif
6
7 static void config_free_entry(ConfigEntry *entry);
8 static void config_set_entry(char *name, ConfigValueType type,
9                              ConfigValue value);
10 static void config_def_free(ConfigDefEntry *entry);
11 static void print_config(GQuark q, gpointer data, gpointer fonk){
12     ConfigDefEntry *e = (ConfigDefEntry *)data;
13     g_message("config: %s %d", e->name, e->hasList);
14 }
15
16 static GData *config = NULL;
17 static GData *config_def = NULL;
18
19 /* provided by cparse.l */
20 void cparse_go(char *filename, FILE *);
21
22
23 void config_startup()
24 {
25     /* set up built in variables! and their default values! */
26
27     config_def_set(config_def_new("engine", Config_String));
28     config_def_set(config_def_new("theme", Config_String));
29     config_def_set(config_def_new("font", Config_String));
30     config_def_set(config_def_new("font.shadow.offset", Config_Integer));
31     config_def_set(config_def_new("font.shadow.tint", Config_Integer));
32     config_def_set(config_def_new("titlebar.layout", Config_String));
33
34     /*g_datalist_foreach(&config_def, print_config, NULL);*/
35 }
36
37 void config_shutdown()
38 {
39     g_datalist_clear(&config);
40     g_datalist_clear(&config_def);
41 }
42
43 void config_parse()
44 {
45     FILE *file;
46     char *path;
47
48     /* load the system wide rc file first */
49     path = g_build_filename(RCDIR, "rc3", NULL);
50     if ((file = fopen(path, "r")) != NULL) {
51         cparse_go(path, file);
52         fclose(file);
53     }
54     g_free(path);
55
56     /* then load the user one which can override it */
57     path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
58     if ((file = fopen(path, "r")) != NULL) {
59         cparse_go(path, file);
60         fclose(file);
61     }
62     g_free(path);
63 }
64
65 gboolean config_set(char *name, ConfigValueType type, ConfigValue value)
66 {
67     ConfigDefEntry *def;
68     gboolean ret = FALSE;
69
70     name = g_ascii_strdown(name, -1);
71     g_message("Setting %s", name);
72
73     /*g_datalist_foreach(&config_def, print_config, NULL);*/
74     def = g_datalist_get_data(&config_def, name);
75
76     if (def == NULL) {
77         g_message("Invalid config option '%s'", name);
78     } else {
79         if (def->hasList) {
80             gboolean found = FALSE;
81             GSList *it;
82
83             it = def->values;
84             g_assert(it != NULL);
85             do {
86                 if (g_ascii_strcasecmp(it->data, value.string) == 0) {
87                     found = TRUE;
88                     break;
89                 }
90             } while ((it = it->next));
91
92             if (!found)
93                 g_message("Invalid value '%s' for config option '%s'",
94                           value.string, name);
95             else
96                 ret = TRUE;
97         } else
98             ret = TRUE;
99
100     }
101
102     if (ret)
103         config_set_entry(name, type, value);
104     else
105         g_free(name);
106
107     return ret;
108 }
109
110 gboolean config_get(char *name, ConfigValueType type, ConfigValue *value)
111 {
112     ConfigEntry *entry;
113     gboolean ret = FALSE;
114
115     name = g_ascii_strdown(name, -1);
116     entry = g_datalist_get_data(&config, name);
117     if (entry != NULL && entry->type == type) {
118         *value = entry->value;
119         ret = TRUE;
120     }
121     g_free(name);
122     return ret;
123 }
124
125 static void config_set_entry(char *name, ConfigValueType type,
126                              ConfigValue value)
127 {
128     ConfigEntry *entry = NULL;
129
130     entry = g_new(ConfigEntry, 1);
131     entry->name = name;
132     entry->type = type;
133     if (type == Config_String)
134         entry->value.string = g_strdup(value.string);
135     else
136         entry->value = value;
137
138     g_datalist_set_data_full(&config, name, entry,
139                              (GDestroyNotify)config_free_entry);
140 }
141
142 static void config_free_entry(ConfigEntry *entry)
143 {
144     g_free(entry->name);
145     entry->name = NULL;
146     if(entry->type == Config_String) {
147         g_free(entry->value.string);
148         entry->value.string = NULL;
149     }
150     g_free(entry);
151 }
152
153 ConfigDefEntry *config_def_new(char *name, ConfigValueType type)
154 {
155     ConfigDefEntry *entry;
156
157     entry = g_new(ConfigDefEntry, 1);
158     entry->name = g_ascii_strdown(name, -1);
159     entry->hasList = FALSE;
160     entry->type = type;
161     entry->values = NULL;
162     return entry;
163 }
164
165 static void config_def_free(ConfigDefEntry *entry)
166 {
167     GSList *it;
168
169     g_free(entry->name);
170     if (entry->hasList) {
171         for (it = entry->values; it != NULL; it = it->next)
172             g_free(it->data);
173         g_slist_free(entry->values);
174     }
175     g_free(entry);
176 }
177
178 gboolean config_def_add_value(ConfigDefEntry *entry, char *value)
179 {
180     if (entry->type != Config_String) {
181         g_warning("Tried adding value to non-string config definition");
182         return FALSE;
183     }
184
185     entry->hasList = TRUE;
186     entry->values = g_slist_append(entry->values, g_ascii_strdown(value, -1));
187     return TRUE;
188 }
189
190 gboolean config_def_set(ConfigDefEntry *entry)
191 {
192     gboolean ret = FALSE;
193     ConfigDefEntry *def;
194
195     if ((def = g_datalist_get_data(&config_def, entry->name))) {
196         g_assert(def != entry); /* adding it twice!? */
197         g_warning("Definition already set for config option '%s'. ",
198                   entry->name);
199         config_def_free(entry);
200     } else {
201         g_datalist_set_data_full(&config_def, entry->name, entry,
202                                  (GDestroyNotify)config_def_free);
203         ret = TRUE;
204     }
205
206     return ret;
207 }