2 * By Tony Houghton, <h@realh.co.uk>.
12 #include <sys/types.h>
17 #include "xxdgautostart.h"
19 extern char *locale_name
;
20 extern char *short_locale_name
;
22 void xdesktop_entry_read_name_from_keyfile(DesktopEntry
*xde
)
27 xde
->name
= g_key_file_get_locale_string(xde
->kf
, _DE
, "Name",
30 if (!xde
->name
&& short_locale_name
)
32 xde
->name
= g_key_file_get_locale_string(xde
->kf
, _DE
, "Name",
33 short_locale_name
, NULL
);
36 xde
->name
= g_key_file_get_string(xde
->kf
, _DE
, "Name", NULL
);
38 xde
->name
= g_strdup(_("No name"));
41 DesktopEntry
*xdesktop_entry_new(const char *pathname
, const char *basename
,
44 DesktopEntry
*xde
= g_new0(DesktopEntry
, 1);
46 if (!desktop_entry_load(xde
, pathname
, basename
, TRUE
, savable
))
48 desktop_entry_delete(xde
);
52 xdesktop_entry_read_name_from_keyfile(xde
);
56 gboolean
xdesktop_entry_get_only_in_rox(DesktopEntry
*xde
)
58 return (xde
->only_show_in
&& xde
->only_show_in
[0] &&
59 !strcmp(xde
->only_show_in
[0], "ROX") &&
60 (!xde
->only_show_in
[1] || !xde
->only_show_in
[1][0]));
63 gboolean
xdesktop_entry_can_set_only_in_rox(DesktopEntry
*xde
)
65 return xdesktop_entry_get_only_in_rox(xde
) ||
66 (desktop_entry_get_show_in_rox(xde
) &&
67 str_v_is_empty(xde
->only_show_in
));
70 static int str_v_len(char const **str_v
)
74 for (n
= 0; str_v
&& str_v
[n
]; ++n
);
78 static void update_kf_from_show_ins(DesktopEntry
*xde
)
80 if (!xde
->only_show_in
)
82 g_key_file_remove_key(xde
->kf
, _DE
, "OnlyShowIn", NULL
);
86 g_key_file_set_string_list(xde
->kf
, _DE
, "OnlyShowIn",
87 (char const **) xde
->only_show_in
,
88 str_v_len((char const **) xde
->only_show_in
));
90 if (!xde
->not_show_in
)
92 g_key_file_remove_key(xde
->kf
, _DE
, "NotShowIn", NULL
);
96 g_key_file_set_string_list(xde
->kf
, _DE
, "NotShowIn",
97 (char const **) xde
->not_show_in
,
98 str_v_len((char const **) xde
->not_show_in
));
102 void xdesktop_entry_set_only_in_rox(DesktopEntry
*xde
, gboolean state
)
104 g_strfreev(xde
->only_show_in
);
105 xde
->only_show_in
= NULL
;
106 g_strfreev(xde
->not_show_in
);
107 xde
->not_show_in
= NULL
;
110 xde
->only_show_in
= g_new0(char *, 2);
111 xde
->only_show_in
[0] = g_strdup("ROX");
113 update_kf_from_show_ins(xde
);
116 static void remove_rox_from_strv(char ***p_str_v
)
118 if (!str_v_is_empty(*p_str_v
))
121 gboolean moving
= FALSE
;
123 for (ps
= *p_str_v
; *ps
; ++ps
)
130 else if (!strcmp(*ps
, "ROX"))
137 if (str_v_is_empty(*p_str_v
))
139 g_strfreev(*p_str_v
);
145 static void add_rox_to_strv(char ***p_str_v
, gboolean force
)
149 if (!str_v_is_empty(*p_str_v
))
151 gboolean contains_rox
= FALSE
;
153 for (ps
= *p_str_v
; *ps
; ++ps
)
155 if (!strcmp(*ps
, "ROX"))
163 int l
= str_v_len((char const **) *p_str_v
);
165 *p_str_v
= g_renew(char *, *p_str_v
, l
+ 2);
166 (*p_str_v
)[l
] = g_strdup("ROX");
167 (*p_str_v
)[l
+ 1] = NULL
;
172 g_strfreev(*p_str_v
);
173 *p_str_v
= g_new0(char *, 2);
174 (*p_str_v
)[0] = g_strdup("ROX");
179 static void show_strv(char **strv)
183 for (ps = strv; ps && *ps; ++ps)
185 g_print("%s ; ", *ps);
191 void xdesktop_entry_set_start_in_rox(DesktopEntry
*xde
, gboolean state
)
195 add_rox_to_strv(&xde
->only_show_in
, FALSE
);
196 remove_rox_from_strv(&xde
->not_show_in
);
200 remove_rox_from_strv(&xde
->only_show_in
);
201 add_rox_to_strv(&xde
->not_show_in
, TRUE
);
203 update_kf_from_show_ins(xde
);
206 void xdesktop_entry_save(DesktopEntry
*xde
)
214 g_free(xde
->pathname
);
215 xde
->pathname
= g_build_filename(g_get_user_config_dir(),
216 xde
->basename
, NULL
);
219 buffer
= g_key_file_to_data(xde
->kf
, &buflen
, &err
);
222 message_dialog(NULL
, GTK_MESSAGE_ERROR
,
223 _("Unable to prepare Desktop Entry for saving to '%s': %s"),
224 xde
->pathname
, err
? err
->message
: _("unknown reason"));
229 if (!g_file_set_contents(xde
->pathname
, buffer
, buflen
, &err
))
231 message_dialog(NULL
, GTK_MESSAGE_ERROR
,
232 _("Unable to save '%s': %s"),
233 xde
->pathname
, err
? err
->message
: _("unknown reason"));
240 inline static char *add_desktop_extension(const char *basename
)
242 return g_strjoin(".", basename
, "desktop", NULL
);
245 /* basename doesn't include .desktop extension */
246 static char *xdg_autostart_pathname(const char *basename
)
248 char *leafname
= add_desktop_extension(basename
);
249 char *pathname
= g_build_filename(g_get_user_config_dir(), "autostart",
256 /* This has side-effect of creating file if it doesn't clash,
257 * so it must be overwritten or deleted */
258 static int filename_clash(const char *basename
)
260 static char *dir
= NULL
;
262 const char * const *dirs
;
263 const char * const *d
;
266 dirs
= g_get_system_config_dirs();
267 for (d
= dirs
; *d
; ++d
)
269 char *leafname
= add_desktop_extension(basename
);
271 pathname
= g_build_filename(*d
, "autostart", leafname
, NULL
);
273 if (g_file_test(pathname
, G_FILE_TEST_EXISTS
))
281 dir
= g_build_filename(g_get_user_config_dir(), "autostart", NULL
);
282 if (g_mkdir_with_parents(dir
, 0755) == -1)
284 message_dialog(NULL
, GTK_MESSAGE_ERROR
,
285 _("Unable to create '%s' directory"), dir
);
288 if (!g_file_test(dir
, G_FILE_TEST_IS_DIR
))
290 pathname
= xdg_autostart_pathname(basename
);
291 result
= open(pathname
, O_WRONLY
| O_EXCL
|O_CREAT
, 0644);
298 static char *add_number_ext(const char *basename
)
300 int l
= strlen(basename
);
304 for (n
= l
- 1; n
>= 0 && isdigit(basename
[n
]); --n
);
305 /* This will also accept a trailing - with no subsequent digits,
307 if (basename
[n
] == '-')
311 number
= atoi(basename
+ n
+ 1) + 1;
315 return g_strdup_printf("%.*s-%d", l
, basename
, number
);
318 void xdesktop_entry_filenames_from_name(DesktopEntry
*de
, const char *leafname
)
321 char *basename
= NULL
;
328 basename
= g_strdup(leafname
);
329 sep
= strrchr(basename
, '.');
330 if (sep
&& sep
[1] && !strcmp(sep
+ 1, "desktop"))
335 basename
= g_filename_from_utf8(de
->name
, -1, NULL
, NULL
, NULL
);
337 if (!basename
|| !basename
[0])
341 basename
= g_strdup(_("rox-session-autostart"));
345 for (n
= 0; basename
[n
]; ++n
)
347 if (isspace(basename
[n
]))
350 basename
[n
] = tolower(basename
[n
]);
353 while ((fd
= filename_clash(basename
)) == -1)
355 char *old
= basename
;
358 basename
= add_number_ext(basename
);
361 g_free(de
->basename
);
362 de
->basename
= add_desktop_extension(basename
);
363 g_free(de
->pathname
);
364 de
->pathname
= xdg_autostart_pathname(basename
);