]> icculus.org git repositories - dana/obconf.git/blob - src/tree.c
Use new RrButton structure
[dana/obconf.git] / src / tree.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    tree.c for ObConf, the configuration tool for Openbox
4    Copyright (c) 2003-2007   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 "tree.h"
20 #include "main.h"
21
22 #include <obt/xml.h>
23 #include <gdk/gdkx.h>
24
25 xmlNodePtr tree_get_node(const gchar *path, const gchar *def)
26 {
27     xmlNodePtr n, c;
28     gchar **nodes;
29     gchar **it, **next;
30
31     n = obt_xml_root(parse_i);
32
33     nodes = g_strsplit(path, "/", 0);
34     for (it = nodes; *it; it = next) {
35         gchar **attrs;
36         gboolean ok = FALSE;
37
38         attrs = g_strsplit(*it, ":", 0);
39         next = it + 1;
40
41         /* match attributes */
42         c = obt_xml_find_node(n->children, attrs[0]);
43         while (c && !ok) {
44             gint i;
45
46             ok = TRUE;
47             for (i = 1; attrs[i]; ++i) {
48                 gchar **eq = g_strsplit(attrs[i], "=", 2);
49                 if (eq[1] && !obt_xml_attr_contains(c, eq[0], eq[1]))
50                     ok = FALSE;
51                 g_strfreev(eq);
52             }
53             if (!ok)
54                 c = obt_xml_find_node(c->next, attrs[0]);
55         }
56
57         if (!c) {
58             gint i;
59
60             c = xmlNewTextChild(n, NULL, attrs[0], *next ? NULL : def);
61
62             for (i = 1; attrs[i]; ++i) {
63                 gchar **eq = g_strsplit(attrs[i], "=", 2);
64                 if (eq[1])
65                     xmlNewProp(c, eq[0], eq[1]);
66                 g_strfreev(eq);
67             }
68         }
69         n = c;
70
71         g_strfreev(attrs);
72     }
73
74     g_strfreev(nodes);
75
76     return n;
77 }
78
79 void tree_delete_node(const gchar *path)
80 {
81     xmlNodePtr n;
82
83     n = tree_get_node(path, NULL);
84     xmlUnlinkNode(n);
85     xmlFreeNode(n);
86 }
87
88 void tree_apply()
89 {
90     gchar *p, *d;
91     gboolean err;
92
93     if (obc_config_file)
94         p = g_strdup(obc_config_file);
95     else
96         p = g_build_filename(obt_paths_config_home(paths), "openbox",
97                              "rc.xml", NULL);
98
99     d = g_path_get_dirname(p);
100     obt_paths_mkdir_path(d, 0700);
101     g_free(d);
102
103     if (!obt_xml_save_file(parse_i, p, TRUE)) {
104         gchar *s;
105         s = g_strdup_printf("An error occured while saving the "
106                             "config file '%s'", p);
107         obconf_error(s, FALSE);
108         g_free(s);
109     }
110     g_free(p);
111
112     if (!err) {
113         XEvent ce;
114
115         ce.xclient.type = ClientMessage;
116         ce.xclient.message_type = gdk_x11_get_xatom_by_name("_OB_CONTROL");
117         ce.xclient.display = GDK_DISPLAY();
118         ce.xclient.window = GDK_ROOT_WINDOW();
119         ce.xclient.format = 32;
120         ce.xclient.data.l[0] = 1; /* reconfigure */
121         ce.xclient.data.l[1] = 0;
122         ce.xclient.data.l[2] = 0;
123         ce.xclient.data.l[3] = 0;
124         ce.xclient.data.l[4] = 0;
125         XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), FALSE,
126                    SubstructureNotifyMask | SubstructureRedirectMask,
127                    &ce);
128     }
129 }
130
131 void tree_set_string(const gchar *node, const gchar *value)
132 {
133     xmlNodePtr n;
134
135     n = tree_get_node(node, NULL);
136     xmlNodeSetContent(n, (const xmlChar*) value);
137
138     tree_apply();
139 }
140
141 void tree_set_int(const gchar *node, const gint value)
142 {
143     xmlNodePtr n;
144     gchar *s;
145
146     n = tree_get_node(node, NULL);
147     s = g_strdup_printf("%d", value);
148     xmlNodeSetContent(n, (const xmlChar*) s);
149     g_free(s);
150
151     tree_apply();
152 }
153
154 void tree_set_bool(const gchar *node, const gboolean value)
155 {
156     xmlNodePtr n;
157
158     n = tree_get_node(node, NULL);
159     xmlNodeSetContent(n, (const xmlChar*) (value ? "yes" : "no"));
160
161     tree_apply();
162 }
163
164 gchar* tree_get_string(const gchar *node, const gchar *def)
165 {
166     xmlNodePtr n;
167
168     n = tree_get_node(node, def);
169     return obt_xml_node_string(n);
170 }
171
172 gint tree_get_int(const gchar *node, gint def)
173 {
174     xmlNodePtr n;
175     gchar *d;
176
177     d = g_strdup_printf("%d", def);
178     n = tree_get_node(node, d);
179     g_free(d);
180     return obt_xml_node_int(n);
181 }
182
183 gboolean tree_get_bool(const gchar *node, gboolean def)
184 {
185     xmlNodePtr n;
186
187     n = tree_get_node(node, (def ? "yes" : "no"));
188     return obt_xml_node_bool(n);
189 }