10 static GHashTable *callbacks;
11 static xmlDocPtr doc_config = NULL;
13 static void destfunc(struct Callback *c)
21 callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
22 (GDestroyNotify)destfunc);
30 g_hash_table_destroy(callbacks);
33 void parse_register(const char *tag, ParseCallback func, void *data)
37 if ((c = g_hash_table_lookup(callbacks, tag))) {
38 g_warning("tag '%s' already registered", tag);
42 c = g_new(struct Callback, 1);
43 c->tag = g_strdup(tag);
46 g_hash_table_insert(callbacks, c->tag, c);
52 xmlNodePtr node = NULL;
54 xmlLineNumbersDefault(1);
56 path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
57 if ((doc_config = xmlParseFile(path))) {
58 node = xmlDocGetRootElement(doc_config);
60 xmlFreeDoc(doc_config);
62 g_warning("%s is an empty document", path);
64 if (xmlStrcasecmp(node->name, (const xmlChar*)"openbox_config")) {
65 xmlFreeDoc(doc_config);
67 g_warning("document %s is of wrong type. root node is "
68 "not 'openbox_config'", path);
74 path = g_build_filename(RCDIR, "rc3", NULL);
75 if ((doc_config = xmlParseFile(path))) {
76 node = xmlDocGetRootElement(doc_config);
78 xmlFreeDoc(doc_config);
80 g_warning("%s is an empty document", path);
82 if (xmlStrcasecmp(node->name,
83 (const xmlChar*)"openbox_config")) {
84 xmlFreeDoc(doc_config);
86 g_warning("document %s is of wrong type. root node is "
87 "not 'openbox_config'", path);
94 g_message("unable to find a valid config file, using defaults");
96 parse_tree(doc_config, node->xmlChildrenNode, NULL);
100 void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing)
103 struct Callback *c = g_hash_table_lookup(callbacks, node->name);
106 c->func(doc, node->xmlChildrenNode, c->data);
112 char *parse_string(xmlDocPtr doc, xmlNodePtr node)
114 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
115 char *s = g_strdup((char*)c);
120 int parse_int(xmlDocPtr doc, xmlNodePtr node)
122 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
123 int i = atoi((char*)c);
128 gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
130 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
132 if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
134 else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
136 else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
142 gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
144 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
146 r = !xmlStrcasecmp(c, (const xmlChar*) val);
151 xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
154 if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
161 gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
163 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
166 *value = atoi((char*)c);
173 gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
175 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
178 *value = g_strdup((char*)c);
185 Action *parse_action(xmlDocPtr doc, xmlNodePtr node)
191 if (parse_attr_string("name", node, &actname)) {
192 if ((act = action_from_string(actname))) {
193 if (act->func == action_execute || act->func == action_restart) {
194 if ((n = parse_find_node("execute", node->xmlChildrenNode)))
195 act->data.execute.path = parse_string(doc, n);
196 } else if (act->func == action_showmenu) {
197 if ((n = parse_find_node("menu", node->xmlChildrenNode)))
198 act->data.showmenu.name = parse_string(doc, n);
199 } else if (act->func == action_desktop) {
200 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
201 act->data.desktop.desk = parse_int(doc, n);
202 if (act->data.desktop.desk > 0) act->data.desktop.desk--;
203 } else if (act->func == action_send_to_desktop) {
204 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
205 act->data.sendto.desk = parse_int(doc, n);
206 if (act->data.sendto.desk > 0) act->data.sendto.desk--;
207 } else if (act->func == action_move_relative_horz ||
208 act->func == action_move_relative_vert ||
209 act->func == action_resize_relative_horz ||
210 act->func == action_resize_relative_vert) {
211 if ((n = parse_find_node("delta", node->xmlChildrenNode)))
212 act->data.relative.delta = parse_int(doc, n);
213 } else if (act->func == action_desktop_right ||
214 act->func == action_desktop_left ||
215 act->func == action_desktop_up ||
216 act->func == action_desktop_down) {
217 if ((n = parse_find_node("wrap", node->xmlChildrenNode))) {
218 g_message("WRAP %d", parse_bool(doc, n));
219 act->data.desktopdir.wrap = parse_bool(doc, n);
221 } else if (act->func == action_send_to_desktop_right ||
222 act->func == action_send_to_desktop_left ||
223 act->func == action_send_to_desktop_up ||
224 act->func == action_send_to_desktop_down) {
225 if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
226 act->data.sendtodir.wrap = parse_bool(doc, n);
227 if ((n = parse_find_node("follow", node->xmlChildrenNode)))
228 act->data.sendtodir.follow = parse_bool(doc, n);
235 gboolean parse_attr_contains(const char *val, xmlNodePtr node,
238 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
240 r = !xmlStrcasecmp(c, (const xmlChar*) val);