2 * By Tony Houghton, <h@realh.co.uk>.
9 #include "xdgautostart.h"
11 static void desktop_entry_free_keyfile_mirrors(DesktopEntry
*de
)
21 g_strfreev(de
->only_show_in
);
22 de
->only_show_in
= NULL
;
23 g_strfreev(de
->not_show_in
);
24 de
->not_show_in
= NULL
;
27 void desktop_entry_read_keyfile(DesktopEntry
*de
)
29 GKeyFile
*kf
= de
->kf
;
31 desktop_entry_free_keyfile_mirrors(de
);
32 de
->exec
= g_key_file_get_string(kf
, _DE
, "Exec", NULL
);
33 de
->path
= g_key_file_get_string(kf
, _DE
, "Path", NULL
);
34 de
->terminal
= g_key_file_get_boolean(kf
, _DE
, "Terminal", NULL
);
35 de
->try_exec
= g_key_file_get_string(kf
, _DE
, "TryExec", NULL
);
36 de
->only_show_in
= g_key_file_get_string_list(kf
, _DE
, "OnlyShowIn",
38 de
->not_show_in
= g_key_file_get_string_list(kf
, _DE
, "NotShowIn",
42 gboolean
desktop_entry_load(DesktopEntry
*de
, const char *pathname
,
43 const char *basename
, gboolean keep_keyfile
, gboolean savable
)
45 GKeyFile
*kf
= g_key_file_new();
49 if (!g_key_file_load_from_file(kf
, pathname
,
51 G_KEY_FILE_KEEP_COMMENTS
| G_KEY_FILE_KEEP_TRANSLATIONS
:
55 g_warning(_("Can't load key-file '%s': %s"), pathname
,
56 err
? err
->message
: _("unknown reason"));
60 if (!g_key_file_has_group(kf
, _DE
))
62 g_warning(_("'%s' is not a .desktop file"), pathname
);
66 de
->pathname
= g_strdup(pathname
);
67 de
->basename
= g_strdup(basename
);
68 de
->savable
= savable
;
69 de
->deletable
= savable
;
71 desktop_entry_read_keyfile(de
);
81 void desktop_entry_free(DesktopEntry
*de
)
83 desktop_entry_free_keyfile_mirrors(de
);
90 g_key_file_free(de
->kf
);
95 void desktop_entry_delete(DesktopEntry
*de
)
97 desktop_entry_free(de
);
101 DesktopEntry
*desktop_entry_new(const char *pathname
, const char *basename
,
104 DesktopEntry
*de
= g_new0(DesktopEntry
, 1);
106 if (!desktop_entry_load(de
, pathname
, basename
, FALSE
, savable
))
108 desktop_entry_delete(de
);
114 gboolean
desktop_entry_str_in_strv(char **v
, const char *s
)
116 for ( ; v
&& *v
; ++v
)
124 gboolean
desktop_entry_get_show_in_environ(const DesktopEntry
*de
,
127 if (de
->only_show_in
)
129 if (desktop_entry_str_in_strv(de
->only_show_in
, environ
))
134 if (desktop_entry_str_in_strv(de
->not_show_in
, environ
))
140 /* Also checks Exec and TryExec */
141 gboolean
desktop_entry_can_start_in_rox(const DesktopEntry
*de
)
143 if (!desktop_entry_get_show_in_rox(de
))
149 if (!g_file_test(de
->try_exec
, G_FILE_TEST_EXISTS
))
152 if (de
->exec
[0] == '/')
154 return g_file_test(de
->exec
, G_FILE_TEST_IS_EXECUTABLE
);
158 char *ef
= g_find_program_in_path(de
->exec
);
159 gboolean result
= ef
!= NULL
;
167 static GList
*scan_dir(const char *dir
, GList
*desl
,
168 DesktopEntryConstructor ctor
, gboolean savable
)
170 char *dir2
= g_build_filename(dir
, "autostart", NULL
);
172 const char *basename
;
174 if (!g_file_test(dir2
, G_FILE_TEST_IS_DIR
))
176 dir0
= g_dir_open(dir2
, 0, NULL
);
179 while ((basename
= g_dir_read_name(dir0
)) != NULL
)
182 gboolean dupl
= FALSE
;
184 /* Don't add if there's already one with the same basename */
185 for (node
= desl
; node
; node
= g_list_next(node
))
187 DesktopEntry
*de
= node
->data
;
189 if (!strcmp(basename
, de
->basename
))
197 char *pathname
= g_build_filename(dir2
, basename
, NULL
);
198 DesktopEntry
*de
= ctor(pathname
, basename
, savable
);
201 desl
= g_list_append(desl
, de
);
212 GList
*get_desktop_entries(DesktopEntryConstructor ctor
)
215 const char *udir
= g_get_user_config_dir();
216 const char * const * sdirs
;
218 desl
= scan_dir(udir
, desl
, ctor
, TRUE
);
219 for (sdirs
= g_get_system_config_dirs(); sdirs
&& *sdirs
; ++sdirs
)
221 desl
= scan_dir(*sdirs
, desl
, ctor
, FALSE
);
226 gboolean
str_v_is_empty(char **sv
)