7 static gboolean xdg_start;
8 static gchar *xdg_config_home_path;
9 static gchar *xdg_data_home_path;
10 static GSList *xdg_config_dir_paths;
11 static GSList *xdg_data_dir_paths;
20 GHashTable *callbacks;
23 static void destfunc(struct Callback *c)
29 ObParseInst* parse_startup()
31 ObParseInst *i = g_new(ObParseInst, 1);
32 i->callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
33 (GDestroyNotify)destfunc);
37 void parse_shutdown(ObParseInst *i)
40 g_hash_table_destroy(i->callbacks);
45 void parse_register(ObParseInst *i, const char *tag,
46 ParseCallback func, void *data)
50 if ((c = g_hash_table_lookup(i->callbacks, tag))) {
51 g_warning("tag '%s' already registered", tag);
55 c = g_new(struct Callback, 1);
56 c->tag = g_strdup(tag);
59 g_hash_table_insert(i->callbacks, c->tag, c);
62 gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root)
68 for (it = xdg_config_dir_paths; !r && it; it = g_slist_next(it)) {
69 path = g_build_filename(it->data, "openbox", "rc.xml", NULL);
70 r = parse_load(path, "openbox_config", doc, root);
74 g_warning("unable to find a valid config file, using defaults");
78 gboolean parse_load_menu(const gchar *file, xmlDocPtr *doc, xmlNodePtr *root)
85 r = parse_load(file, "openbox_menu", doc, root);
87 for (it = xdg_config_dir_paths; !r && it; it = g_slist_next(it)) {
88 path = g_build_filename(it->data, "openbox", file, NULL);
89 r = parse_load(path, "openbox_menu", doc, root);
94 g_warning("unable to find a valid menu file '%s'", file);
98 gboolean parse_load(const char *path, const char *rootname,
99 xmlDocPtr *doc, xmlNodePtr *root)
101 if ((*doc = xmlParseFile(path))) {
102 *root = xmlDocGetRootElement(*doc);
106 g_warning("%s is an empty document", path);
108 if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
111 g_warning("document %s is of wrong type. root node is "
112 "not '%s'", path, rootname);
121 gboolean parse_load_mem(gpointer data, guint len, const char *rootname,
122 xmlDocPtr *doc, xmlNodePtr *root)
124 if ((*doc = xmlParseMemory(data, len))) {
125 *root = xmlDocGetRootElement(*doc);
129 g_warning("Given memory is an empty document");
131 if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
134 g_warning("document in given memory is of wrong type. root "
135 "node is not '%s'", rootname);
144 void parse_close(xmlDocPtr doc)
149 void parse_tree(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
152 struct Callback *c = g_hash_table_lookup(i->callbacks, node->name);
155 c->func(i, doc, node, c->data);
161 char *parse_string(xmlDocPtr doc, xmlNodePtr node)
163 xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
164 char *s = g_strdup(c ? (char*)c : "");
169 int parse_int(xmlDocPtr doc, xmlNodePtr node)
171 xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
172 int i = atoi((char*)c);
177 gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
179 xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
181 if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
183 else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
185 else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
191 gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
193 xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
195 r = !xmlStrcasecmp(c, (const xmlChar*) val);
200 xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
203 if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
210 gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
212 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
215 *value = atoi((char*)c);
222 gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
224 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
227 *value = g_strdup((char*)c);
234 gboolean parse_attr_contains(const char *val, xmlNodePtr node,
237 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
239 r = !xmlStrcasecmp(c, (const xmlChar*) val);
244 static GSList* split_paths(const gchar *paths)
252 g_message("paths %s", paths);
253 while ((e = strchr(e + 1, ':'))) {
255 g_message("s %s", s);
257 list = g_slist_append(list, g_strdup(s));
261 list = g_slist_append(list, g_strdup(s));
266 void parse_paths_startup()
274 path = getenv("XDG_CONFIG_HOME");
275 if (path && path[0] != '\0') /* not unset or empty */
276 xdg_config_home_path = g_build_filename(path, NULL);
278 xdg_config_home_path = g_build_filename(g_get_home_dir(), ".config",
281 path = getenv("XDG_DATA_HOME");
282 if (path && path[0] != '\0') /* not unset or empty */
283 xdg_data_home_path = g_build_filename(path, NULL);
285 xdg_data_home_path = g_build_filename(g_get_home_dir(), ".local",
288 path = getenv("XDG_CONFIG_DIRS");
289 if (path && path[0] != '\0') /* not unset or empty */
290 xdg_config_dir_paths = split_paths(path);
292 xdg_config_dir_paths = g_slist_append(xdg_config_dir_paths,
295 "etc", "xdg", NULL));
296 xdg_config_dir_paths = g_slist_append(xdg_config_dir_paths,
297 g_strdup(CONFIGDIR));
299 xdg_config_dir_paths = g_slist_prepend(xdg_config_dir_paths,
300 xdg_config_home_path);
302 path = getenv("XDG_DATA_DIRS");
303 if (path && path[0] != '\0') /* not unset or empty */
304 xdg_data_dir_paths = split_paths(path);
306 xdg_data_dir_paths = g_slist_append(xdg_data_dir_paths,
309 "usr", "local", "share", NULL));
310 xdg_data_dir_paths = g_slist_append(xdg_data_dir_paths,
313 "usr", "share", NULL));
314 xdg_config_dir_paths = g_slist_append(xdg_config_dir_paths,
317 xdg_data_dir_paths = g_slist_prepend(xdg_data_dir_paths,
321 void parse_paths_shutdown()
329 for (it = xdg_config_dir_paths; it; it = g_slist_next(it))
331 g_slist_free(xdg_config_dir_paths);
332 xdg_config_dir_paths = NULL;
335 gchar *parse_expand_tilde(const gchar *f)
342 spl = g_strsplit(f, "~", 0);
343 ret = g_strjoinv(g_get_home_dir(), spl);
348 void parse_mkdir_path(const gchar *path, gint mode)
352 g_assert(path[0] == '/');
356 while ((e = strchr(e + 1, '/'))) {
365 const gchar* parse_xdg_config_home_path()
367 return xdg_config_home_path;
370 const gchar* parse_xdg_data_home_path()
372 return xdg_data_home_path;
375 GSList* parse_xdg_config_dir_paths()
377 return xdg_config_dir_paths;
380 GSList* parse_xdg_data_dir_paths()
382 return xdg_data_dir_paths;