]> icculus.org git repositories - dana/openbox.git/blob - openbox/config_value.c
Rename obt_xml_find_node() to obt_xml_find_sibling(). Add obt_xml_tree_get_node(...
[dana/openbox.git] / openbox / config_value.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    config_value.c for the Openbox window manager
4    Copyright (c) 2011        Dana Jansens
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    See the COPYING file for a copy of the GNU General Public License.
17 */
18
19 #include "config_value.h"
20 #include "action_list.h"
21 #include "geom.h"
22
23 #include "stdlib.h"
24
25 struct _ObConfigValue {
26     gint ref;
27     enum {
28         OB_CV_STRING,
29         OB_CV_LIST,
30         OB_CV_ACTION_LIST
31     } type;
32     union {
33         gchar *string;
34         GList *list;
35         ObActionList *actions;
36     } v;
37 };
38
39 void config_value_ref(ObConfigValue *v)
40 {
41     ++v->ref;
42 }
43
44 void config_value_unref(ObConfigValue *v)
45 {
46     if (v && --v->ref < 1) {
47         switch (v->type) {
48         case OB_CV_STRING:
49             g_free(v->v.string);
50             break;
51         case OB_CV_LIST: {
52             GList *it;
53             for (it = v->v.list; it; it = g_list_next(it))
54                 config_value_unref(it->data);
55             g_list_free(v->v.list);
56             break;
57         }
58         case OB_CV_ACTION_LIST:
59             action_list_unref(v->v.actions);
60             break;
61         }
62         g_slice_free(ObConfigValue, v);
63     }
64 }
65
66 /*************************** describer functions ***************************/
67
68 gboolean config_value_is_string(const ObConfigValue *v)
69 {
70     g_return_val_if_fail(v != NULL, FALSE);
71     return v->type == OB_CV_STRING;
72 }
73
74 gboolean config_value_is_list(const ObConfigValue *v)
75 {
76     g_return_val_if_fail(v != NULL, FALSE);
77     return v->type == OB_CV_LIST;
78 }
79
80 gboolean config_value_is_action_list(const ObConfigValue *v)
81 {
82     g_return_val_if_fail(v != NULL, FALSE);
83     return v->type == OB_CV_ACTION_LIST;
84 }
85
86 /**************************** pointer functions ****************************/
87
88 void config_value_copy_ptr(ObConfigValue *v,
89                            ObConfigValueDataType type,
90                            ObConfigValueDataPtr p,
91                            const ObConfigValueEnum e[])
92 {
93     switch (type) {
94     case OB_CONFIG_VALUE_STRING:
95         *p.string = config_value_string(v);
96         break;
97     case OB_CONFIG_VALUE_BOOLEAN:
98         *p.boolean = config_value_bool(v);
99         break;
100     case OB_CONFIG_VALUE_INTEGER:
101         *p.integer = config_value_int(v);
102         break;
103     case OB_CONFIG_VALUE_ENUM:
104         *p.enumeration = config_value_enum(v, e);
105         break;
106     case OB_CONFIG_VALUE_FRACTION: {
107         gint n, d;
108         config_value_fraction(v, &n, &d);
109         p.fraction->numer = n;
110         p.fraction->denom = d;
111         break;
112     }
113     case OB_CONFIG_VALUE_GRAVITY_COORD: {
114         GravityCoord c;
115         config_value_gravity_coord(v, &c);
116         *p.coord = c;
117         break;
118     }
119     case OB_CONFIG_VALUE_LIST:
120         *p.list = config_value_list(v);
121         break;
122     case OB_CONFIG_VALUE_ACTIONLIST:
123         *p.actions = config_value_action_list(v);
124         break;
125     case NUM_OB_CONFIG_VALUE_TYPES:
126     default:
127         g_assert_not_reached();
128     }
129 }
130
131
132 /***************************** getter functions ****************************/
133
134 const gchar* config_value_string(ObConfigValue *v)
135 {
136     g_return_val_if_fail(v != NULL, NULL);
137     g_return_val_if_fail(config_value_is_string(v), NULL);
138     return v->v.string;
139 }
140 gboolean config_value_bool(ObConfigValue *v)
141 {
142     g_return_val_if_fail(v != NULL, FALSE);
143     g_return_val_if_fail(config_value_is_string(v), FALSE);
144     return (g_strcasecmp(v->v.string, "true") == 0 ||
145             g_strcasecmp(v->v.string, "yes") == 0);
146 }
147 guint config_value_int(ObConfigValue *v)
148 {
149     gchar *s;
150     g_return_val_if_fail(v != NULL, FALSE);
151     g_return_val_if_fail(config_value_is_string(v), FALSE);
152     s = v->v.string;
153     return strtol(s, &s, 10);
154 }
155 guint config_value_enum(ObConfigValue *v, const ObConfigValueEnum choices[])
156 {
157     const ObConfigValueEnum *e;
158
159     g_return_val_if_fail(v != NULL, (guint)-1);
160     g_return_val_if_fail(config_value_is_string(v), (guint)-1);
161     g_return_val_if_fail(choices != NULL, (guint)-1);
162
163     for (e = choices; e->name; ++e)
164         if (g_strcasecmp(v->v.string, e->name) == 0)
165             return e->value;
166     return (guint)-1;
167 }
168 void config_value_fraction(ObConfigValue *v, gint *numer, gint *denom)
169 {
170     gchar *s;
171
172     *numer = *denom = 0;
173
174     g_return_if_fail(v != NULL);
175     g_return_if_fail(config_value_is_string(v));
176
177     s = v->v.string;
178     *numer = strtol(s, &s, 10);
179     if (*s == '%')
180         *denom = 100;
181     else if (*s == '/')
182         *denom = atoi(s+1);
183     else
184         *denom = 0;
185 }
186 void config_value_gravity_coord(ObConfigValue *v, GravityCoord *c)
187 {
188     gchar *s;
189
190     c->center = FALSE;
191     c->pos = 0;
192     c->denom = 0;
193
194     g_return_if_fail(v != NULL);
195     g_return_if_fail(config_value_is_string(v));
196
197     s = v->v.string;
198     if (!g_ascii_strcasecmp(s, "center"))
199         c->center = TRUE;
200     else {
201         if (s[0] == '-')
202             c->opposite = TRUE;
203         if (s[0] == '-' || s[0] == '+')
204             ++s;
205
206         c->pos = strtol(s, &s, 10);
207
208         if (*s == '%')
209             c->denom = 100;
210         else if (*s == '/')
211             c->denom = atoi(s+1);
212     }
213 }
214 GList* config_value_list(ObConfigValue *v)
215 {
216     g_return_val_if_fail(v != NULL, NULL);
217     g_return_val_if_fail(config_value_is_list(v), NULL);
218     return v->v.list;
219 }
220 ObActionList* config_value_action_list(ObConfigValue *v)
221 {
222     g_return_val_if_fail(v != NULL, NULL);
223     g_return_val_if_fail(config_value_is_action_list(v), NULL);
224     return v->v.actions;
225 }
226
227 /****************************** constructors ******************************/
228
229 ObConfigValue* config_value_new_string(const gchar *s)
230 {
231     g_return_val_if_fail(s != NULL, NULL);
232     return config_value_new_string_steal(g_strdup(s));
233 }
234
235 ObConfigValue* config_value_new_string_steal(gchar *s)
236 {
237     ObConfigValue *v;
238     g_return_val_if_fail(s != NULL, NULL);
239     v = g_slice_new(ObConfigValue);
240     v->ref = 1;
241     v->type = OB_CV_STRING;
242     v->v.string = s;
243     return v;
244 }
245
246 ObConfigValue* config_value_new_list(GList *list)
247 {
248     GList *c = g_list_copy(list);
249     GList *it;
250
251     for (it = c; it; it = g_list_next(it))
252         config_value_ref(it->data);
253     return config_value_new_list_steal(c);
254 }
255
256 ObConfigValue* config_value_new_list_steal(GList *list)
257 {
258     ObConfigValue *v = g_slice_new(ObConfigValue);
259     v->ref = 1;
260     v->type = OB_CV_LIST;
261     v->v.list = list;
262     return v;
263 }
264
265 ObConfigValue* config_value_new_action_list(ObActionList *al)
266 {
267     ObConfigValue *v = g_slice_new(ObConfigValue);
268     v->ref = 1;
269     v->type = OB_CV_ACTION_LIST;
270     v->v.actions = al;
271     action_list_ref(al);
272     return v;
273 }