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