Draw the hilite texture with the icon appearance instead of the background.
[openbox.git] / obt / paths.c
blob6100499893e306a3dce92cd1fd041f49c20c85c2
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 obt/paths.c for the Openbox window manager
4 Copyright (c) 2003-2007 Dana Jansens
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.
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.
16 See the COPYING file for a copy of the GNU General Public License.
19 #include "obt/paths.h"
20 #include "obt/util.h"
22 #ifdef HAVE_SYS_STAT_H
23 # include <sys/stat.h>
24 #endif
25 #ifdef HAVE_SYS_TYPES_H
26 # include <sys/types.h>
27 #endif
28 #ifdef HAVE_STRING_H
29 # include <string.h>
30 #endif
32 struct _ObtPaths
34 gint ref;
35 gchar *config_home;
36 gchar *data_home;
37 gchar *cache_home;
38 GSList *config_dirs;
39 GSList *data_dirs;
42 static gint slist_path_cmp(const gchar *a, const gchar *b)
44 return strcmp(a, b);
47 typedef GSList* (*GSListFunc) (gpointer list, gconstpointer data);
49 static GSList* slist_path_add(GSList *list, gpointer data, GSListFunc func)
51 g_assert(func);
53 if (!data)
54 return list;
56 if (!g_slist_find_custom(list, data, (GCompareFunc) slist_path_cmp))
57 list = func(list, data);
58 else
59 g_free(data);
61 return list;
64 static GSList* split_paths(const gchar *paths)
66 GSList *list = NULL;
67 gchar **spl, **it;
69 if (!paths)
70 return NULL;
71 spl = g_strsplit(paths, ":", -1);
72 for (it = spl; *it; ++it)
73 list = slist_path_add(list, *it, (GSListFunc) g_slist_append);
74 g_free(spl);
75 return list;
78 ObtPaths* obt_paths_new(void)
80 ObtPaths *p;
81 const gchar *path;
83 p = g_new0(ObtPaths, 1);
84 p->ref = 1;
86 path = g_getenv("XDG_CONFIG_HOME");
87 if (path && path[0] != '\0') /* not unset or empty */
88 p->config_home = g_build_filename(path, NULL);
89 else
90 p->config_home = g_build_filename(g_get_home_dir(), ".config", NULL);
92 path = g_getenv("XDG_DATA_HOME");
93 if (path && path[0] != '\0') /* not unset or empty */
94 p->data_home = g_build_filename(path, NULL);
95 else
96 p->data_home = g_build_filename(g_get_home_dir(), ".local",
97 "share", NULL);
99 path = g_getenv("XDG_CACHE_HOME");
100 if (path && path[0] != '\0') /* not unset or empty */
101 p->cache_home = g_build_filename(path, NULL);
102 else
103 p->cache_home = g_build_filename(g_get_home_dir(), ".cache", NULL);
105 path = g_getenv("XDG_CONFIG_DIRS");
106 if (path && path[0] != '\0') /* not unset or empty */
107 p->config_dirs = split_paths(path);
108 else {
109 p->config_dirs = slist_path_add(p->config_dirs,
110 g_strdup(CONFIGDIR),
111 (GSListFunc) g_slist_append);
112 p->config_dirs = slist_path_add(p->config_dirs,
113 g_build_filename
114 (G_DIR_SEPARATOR_S,
115 "etc", "xdg", NULL),
116 (GSListFunc) g_slist_append);
118 p->config_dirs = slist_path_add(p->config_dirs,
119 g_strdup(p->config_home),
120 (GSListFunc) g_slist_prepend);
122 path = g_getenv("XDG_DATA_DIRS");
123 if (path && path[0] != '\0') /* not unset or empty */
124 p->data_dirs = split_paths(path);
125 else {
126 p->data_dirs = slist_path_add(p->data_dirs,
127 g_strdup(DATADIR),
128 (GSListFunc) g_slist_append);
129 p->data_dirs = slist_path_add(p->data_dirs,
130 g_build_filename
131 (G_DIR_SEPARATOR_S,
132 "usr", "local", "share", NULL),
133 (GSListFunc) g_slist_append);
134 p->data_dirs = slist_path_add(p->data_dirs,
135 g_build_filename
136 (G_DIR_SEPARATOR_S,
137 "usr", "share", NULL),
138 (GSListFunc) g_slist_append);
140 p->data_dirs = slist_path_add(p->data_dirs,
141 g_strdup(p->data_home),
142 (GSListFunc) g_slist_prepend);
143 return p;
146 void obt_paths_ref(ObtPaths *p)
148 ++p->ref;
151 void obt_paths_unref(ObtPaths *p)
153 if (p && --p->ref == 0) {
154 GSList *it;
156 for (it = p->config_dirs; it; it = g_slist_next(it))
157 g_free(it->data);
158 g_slist_free(p->config_dirs);
159 for (it = p->data_dirs; it; it = g_slist_next(it))
160 g_free(it->data);
161 g_slist_free(p->data_dirs);
162 g_free(p->config_home);
163 g_free(p->data_home);
164 g_free(p->cache_home);
166 obt_free0(p, ObtPaths, 1);
170 gchar *obt_paths_expand_tilde(const gchar *f)
172 gchar **spl;
173 gchar *ret;
175 if (!f)
176 return NULL;
177 spl = g_strsplit(f, "~", 0);
178 ret = g_strjoinv(g_get_home_dir(), spl);
179 g_strfreev(spl);
180 return ret;
183 gboolean obt_paths_mkdir(const gchar *path, gint mode)
185 gboolean ret = TRUE;
187 g_return_val_if_fail(path != NULL, FALSE);
188 g_return_val_if_fail(path[0] != '\0', FALSE);
190 if (!g_file_test(path, G_FILE_TEST_IS_DIR))
191 if (mkdir(path, mode) == -1)
192 ret = FALSE;
194 return ret;
197 gboolean obt_paths_mkdir_path(const gchar *path, gint mode)
199 gboolean ret = TRUE;
201 g_return_val_if_fail(path != NULL, FALSE);
202 g_return_val_if_fail(path[0] == '/', FALSE);
204 if (!g_file_test(path, G_FILE_TEST_IS_DIR)) {
205 gchar *c, *e;
207 c = g_strdup(path);
208 e = c;
209 while ((e = strchr(e + 1, '/'))) {
210 *e = '\0';
211 if (!(ret = obt_paths_mkdir(c, mode)))
212 goto parse_mkdir_path_end;
213 *e = '/';
215 ret = obt_paths_mkdir(c, mode);
217 parse_mkdir_path_end:
218 g_free(c);
221 return ret;
224 const gchar* obt_paths_config_home(ObtPaths *p)
226 return p->config_home;
229 const gchar* obt_paths_data_home(ObtPaths *p)
231 return p->data_home;
234 const gchar* obt_paths_cache_home(ObtPaths *p)
236 return p->cache_home;
239 GSList* obt_paths_config_dirs(ObtPaths *p)
241 return p->config_dirs;
244 GSList* obt_paths_data_dirs(ObtPaths *p)
246 return p->data_dirs;