Define _DE in xdgautostart.c too so it can be used unchanged in ROX-Session.
[AutoStart.git] / src / xdgautostart.c
blob4506bfa655125388ed544ebeb7789b00ae0ed4a9
1 /*
2 * By Tony Houghton, <h@realh.co.uk>.
3 */
5 #include "config.h"
7 #include <stdlib.h>
8 #include <string.h>
10 #include "xdgautostart.h"
12 #ifndef _DE
13 #define _DE "Desktop Entry"
14 #endif
16 static const char *locale_name = NULL;
17 static const char *short_locale_name = NULL;
19 static void desktop_entry_free_keyfile_mirrors(DesktopEntry *de)
21 g_free(de->name);
22 de->name = NULL;
23 g_free(de->exec);
24 de->exec = NULL;
25 g_free(de->path);
26 de->path = NULL;
27 g_free(de->try_exec);
28 de->try_exec = NULL;
29 g_strfreev(de->only_show_in);
30 de->only_show_in = NULL;
31 g_strfreev(de->not_show_in);
32 de->not_show_in = NULL;
35 static void desktop_entry_read_name_from_keyfile(DesktopEntry *xde)
37 g_free(xde->name);
38 if (locale_name)
40 xde->name = g_key_file_get_locale_string(xde->kf, _DE, "Name",
41 locale_name, NULL);
43 if (!xde->name && short_locale_name)
45 xde->name = g_key_file_get_locale_string(xde->kf, _DE, "Name",
46 short_locale_name, NULL);
48 if (!xde->name)
49 xde->name = g_key_file_get_string(xde->kf, _DE, "Name", NULL);
50 if (!xde->name)
51 xde->name = g_strdup(_("No name"));
54 void desktop_entry_read_keyfile(DesktopEntry *de)
56 GKeyFile *kf = de->kf;
58 desktop_entry_free_keyfile_mirrors(de);
59 desktop_entry_read_name_from_keyfile(de);
60 de->exec = g_key_file_get_string(kf, _DE, "Exec", NULL);
61 de->path = g_key_file_get_string(kf, _DE, "Path", NULL);
62 de->terminal = g_key_file_get_boolean(kf, _DE, "Terminal", NULL);
63 de->try_exec = g_key_file_get_string(kf, _DE, "TryExec", NULL);
64 de->only_show_in = g_key_file_get_string_list(kf, _DE, "OnlyShowIn",
65 NULL, NULL);
66 de->not_show_in = g_key_file_get_string_list(kf, _DE, "NotShowIn",
67 NULL, NULL);
70 gboolean desktop_entry_load(DesktopEntry *de, const char *pathname,
71 const char *basename, gboolean keep_keyfile, gboolean savable)
73 GKeyFile *kf = g_key_file_new();
74 GError *err = NULL;
76 de->kf = kf;
77 if (!g_key_file_load_from_file(kf, pathname,
78 keep_keyfile ?
79 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS :
80 G_KEY_FILE_NONE,
81 &err))
83 g_warning(_("Can't load key-file '%s': %s"), pathname,
84 err ? err->message : _("unknown reason"));
85 g_error_free(err);
86 return FALSE;
88 if (!g_key_file_has_group(kf, _DE))
90 g_warning(_("'%s' is not a .desktop file"), pathname);
91 return FALSE;
94 de->pathname = g_strdup(pathname);
95 de->basename = g_strdup(basename);
96 de->savable = savable;
97 de->deletable = savable;
99 desktop_entry_read_keyfile(de);
101 if (!keep_keyfile)
103 g_key_file_free(kf);
104 de->kf = NULL;
106 return TRUE;
109 void desktop_entry_free(DesktopEntry *de)
111 desktop_entry_free_keyfile_mirrors(de);
112 g_free(de->pathname);
113 de->pathname = NULL;
114 g_free(de->basename);
115 de->basename = NULL;
116 if (de->kf)
118 g_key_file_free(de->kf);
119 de->kf = NULL;
123 void desktop_entry_delete(DesktopEntry *de)
125 desktop_entry_free(de);
126 g_free(de);
129 DesktopEntry *desktop_entry_new(const char *pathname, const char *basename,
130 gboolean savable)
132 DesktopEntry *de = g_new0(DesktopEntry, 1);
134 if (!desktop_entry_load(de, pathname, basename, FALSE, savable))
136 desktop_entry_delete(de);
137 de = NULL;
139 return de;
142 gboolean desktop_entry_str_in_strv(char **v, const char *s)
144 for ( ; v && *v; ++v)
146 if (!strcmp(*v, s))
147 return TRUE;
149 return FALSE;
152 gboolean desktop_entry_get_show_in_environ(const DesktopEntry *de,
153 const char *environ)
155 if (de->only_show_in)
157 return desktop_entry_str_in_strv(de->only_show_in, environ);
159 if (de->not_show_in)
161 if (desktop_entry_str_in_strv(de->not_show_in, environ))
162 return FALSE;
164 return TRUE;
167 /* Also checks Exec and TryExec */
168 gboolean desktop_entry_can_start_in_rox(const DesktopEntry *de)
170 if (!desktop_entry_get_show_in_rox(de))
171 return FALSE;
172 if (!de->exec)
173 return FALSE;
174 if (de->try_exec)
176 if (!g_file_test(de->try_exec, G_FILE_TEST_EXISTS))
177 return FALSE;
179 if (de->exec[0] == '/')
181 return g_file_test(de->exec, G_FILE_TEST_IS_EXECUTABLE);
183 else
185 char *ef = g_find_program_in_path(de->exec);
186 gboolean result = ef != NULL;
188 g_free(ef);
189 return result;
191 return FALSE;
194 static GList *scan_dir(const char *dir, GList *desl,
195 DesktopEntryConstructor ctor, gboolean savable)
197 char *dir2 = g_build_filename(dir, "autostart", NULL);
198 GDir *dir0;
199 const char *basename;
201 if (!g_file_test(dir2, G_FILE_TEST_IS_DIR))
202 goto no_dir;
203 dir0 = g_dir_open(dir2, 0, NULL);
204 if (!dir0)
205 goto no_dir;
206 while ((basename = g_dir_read_name(dir0)) != NULL)
208 GList *node;
209 gboolean dupl = FALSE;
211 /* Don't add if there's already one with the same basename */
212 for (node = desl; node; node = g_list_next(node))
214 DesktopEntry *de = node->data;
216 if (!strcmp(basename, de->basename))
218 dupl = TRUE;
219 break;
222 if (!dupl)
224 char *pathname = g_build_filename(dir2, basename, NULL);
225 DesktopEntry *de = ctor(pathname, basename, savable);
227 if (de)
228 desl = g_list_append(desl, de);
229 g_free(pathname);
233 g_dir_close(dir0);
234 no_dir:
235 g_free(dir2);
236 return desl;
239 GList *get_desktop_entries(DesktopEntryConstructor ctor)
241 GList *desl = NULL;
242 const char *udir = g_get_user_config_dir();
243 const char * const * sdirs;
245 desl = scan_dir(udir, desl, ctor, TRUE);
246 for (sdirs = g_get_system_config_dirs(); sdirs && *sdirs; ++sdirs)
248 desl = scan_dir(*sdirs, desl, ctor, FALSE);
250 return desl;
253 gboolean str_v_is_empty(char **sv)
255 if (!sv)
256 return TRUE;
257 for ( ; *sv; ++sv)
259 if (*sv)
260 return FALSE;
262 return TRUE;
265 void desktop_entry_set_locale_names(const char *full_name,
266 const char *short_name)
268 locale_name = full_name;
269 short_locale_name = short_name;
272 void desktop_entry_init_locales(char const **long_name, char const **short_name)
274 char *lang = getenv("LANG");
276 if (lang)
278 char *sep = strchr(lang, '.');
279 int l = sep ? sep - lang : strlen(lang);
281 locale_name = g_strdup_printf("%.*s", l, lang);
282 sep = strchr(locale_name, '_');
283 if (sep)
285 short_locale_name = g_strdup_printf("%.*s",
286 (int) (sep - locale_name), locale_name);
289 else
291 locale_name = NULL;
293 if (long_name)
294 *long_name = locale_name;
295 if (short_name)
296 *short_name = short_locale_name;