diff options
Diffstat (limited to 'src/eggdesktopfile.c')
-rw-r--r-- | src/eggdesktopfile.c | 1839 |
1 files changed, 921 insertions, 918 deletions
diff --git a/src/eggdesktopfile.c b/src/eggdesktopfile.c index e38d867..cde7b75 100644 --- a/src/eggdesktopfile.c +++ b/src/eggdesktopfile.c @@ -34,13 +34,14 @@ #include <gdk/gdkx.h> #include <gtk/gtk.h> -struct EggDesktopFile { - GKeyFile *key_file; - char *source; +struct EggDesktopFile +{ + GKeyFile *key_file; + char *source; - char *name, *icon; - EggDesktopFileType type; - char document_code; + char *name, *icon; + EggDesktopFileType type; + char document_code; }; /** @@ -55,17 +56,17 @@ struct EggDesktopFile { EggDesktopFile * egg_desktop_file_new (const char *desktop_file_path, GError **error) { - GKeyFile *key_file; + GKeyFile *key_file; - key_file = g_key_file_new (); - if (!g_key_file_load_from_file (key_file, desktop_file_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, desktop_file_path, 0, error)) + { + g_key_file_free (key_file); + return NULL; + } - return egg_desktop_file_new_from_key_file (key_file, desktop_file_path, - error); + return egg_desktop_file_new_from_key_file (key_file, desktop_file_path, + error); } /** @@ -81,25 +82,25 @@ egg_desktop_file_new (const char *desktop_file_path, GError **error) **/ EggDesktopFile * egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, - GError **error) + GError **error) { - EggDesktopFile *desktop_file; - GKeyFile *key_file; - char *full_path; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_data_dirs (key_file, desktop_file_path, - &full_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - desktop_file = egg_desktop_file_new_from_key_file (key_file, - full_path, - error); - g_free (full_path); - return desktop_file; + EggDesktopFile *desktop_file; + GKeyFile *key_file; + char *full_path; + + key_file = g_key_file_new (); + if (!g_key_file_load_from_data_dirs (key_file, desktop_file_path, + &full_path, 0, error)) + { + g_key_file_free (key_file); + return NULL; + } + + desktop_file = egg_desktop_file_new_from_key_file (key_file, + full_path, + error); + g_free (full_path); + return desktop_file; } /** @@ -116,26 +117,26 @@ egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, **/ EggDesktopFile * egg_desktop_file_new_from_dirs (const char *desktop_file_path, - const char **search_dirs, - GError **error) + const char **search_dirs, + GError **error) { - EggDesktopFile *desktop_file; - GKeyFile *key_file; - char *full_path; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs, - &full_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - desktop_file = egg_desktop_file_new_from_key_file (key_file, - full_path, - error); - g_free (full_path); - return desktop_file; + EggDesktopFile *desktop_file; + GKeyFile *key_file; + char *full_path; + + key_file = g_key_file_new (); + if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs, + &full_path, 0, error)) + { + g_key_file_free (key_file); + return NULL; + } + + desktop_file = egg_desktop_file_new_from_key_file (key_file, + full_path, + error); + g_free (full_path); + return desktop_file; } /** @@ -152,153 +153,153 @@ egg_desktop_file_new_from_dirs (const char *desktop_file_path, **/ EggDesktopFile * egg_desktop_file_new_from_key_file (GKeyFile *key_file, - const char *source, - GError **error) + const char *source, + GError **error) { - EggDesktopFile *desktop_file; - char *version, *type; - - if (!g_key_file_has_group (key_file, EGG_DESKTOP_FILE_GROUP)) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_INVALID, - _("File is not a valid .desktop file")); - g_key_file_free (key_file); - return NULL; - } - - version = g_key_file_get_value (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_VERSION, - NULL); - if (version) - { - double version_num; - char *end; - - version_num = g_ascii_strtod (version, &end); - if (*end) + EggDesktopFile *desktop_file; + char *version, *type; + + if (!g_key_file_has_group (key_file, EGG_DESKTOP_FILE_GROUP)) { - g_warning ("Invalid Version string '%s' in %s", - version, source ? source : "(unknown)"); + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_INVALID, + _("File is not a valid .desktop file")); + g_key_file_free (key_file); + return NULL; } - else if (version_num > 1.0) + + version = g_key_file_get_value (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_VERSION, + NULL); + if (version) { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_INVALID, - _("Unrecognized desktop file Version '%s'"), version); - g_free (version); - g_key_file_free (key_file); - return NULL; + double version_num; + char *end; + + version_num = g_ascii_strtod (version, &end); + if (*end) + { + g_warning ("Invalid Version string '%s' in %s", + version, source ? source : "(unknown)"); + } + else if (version_num > 1.0) + { + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_INVALID, + _("Unrecognized desktop file Version '%s'"), version); + g_free (version); + g_key_file_free (key_file); + return NULL; + } + g_free (version); } - g_free (version); - } - - desktop_file = g_new0 (EggDesktopFile, 1); - desktop_file->key_file = key_file; - - if (g_path_is_absolute (source)) - desktop_file->source = g_filename_to_uri (source, NULL, NULL); - else - desktop_file->source = g_strdup (source); - - desktop_file->name = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NAME, error); - if (!desktop_file->name) - { - egg_desktop_file_free (desktop_file); - return NULL; - } - - type = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TYPE, error); - if (!type) - { - egg_desktop_file_free (desktop_file); - return NULL; - } - - if (!strcmp (type, "Application")) - { - char *exec, *p; - - desktop_file->type = EGG_DESKTOP_FILE_TYPE_APPLICATION; - - exec = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - error); - if (!exec) + + desktop_file = g_new0 (EggDesktopFile, 1); + desktop_file->key_file = key_file; + + if (g_path_is_absolute (source)) + desktop_file->source = g_filename_to_uri (source, NULL, NULL); + else + desktop_file->source = g_strdup (source); + + desktop_file->name = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_NAME, error); + if (!desktop_file->name) { - egg_desktop_file_free (desktop_file); - g_free (type); - return NULL; + egg_desktop_file_free (desktop_file); + return NULL; } - /* See if it takes paths or URIs or neither */ - for (p = exec; *p; p++) + type = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TYPE, error); + if (!type) { - if (*p == '%') - { - if (p[1] == '\0' || strchr ("FfUu", p[1])) - { - desktop_file->document_code = p[1]; - break; - } - p++; - } + egg_desktop_file_free (desktop_file); + return NULL; } - g_free (exec); - } - else if (!strcmp (type, "Link")) - { - char *url; + if (!strcmp (type, "Application")) + { + char *exec, *p; + + desktop_file->type = EGG_DESKTOP_FILE_TYPE_APPLICATION; - desktop_file->type = EGG_DESKTOP_FILE_TYPE_LINK; + exec = g_key_file_get_string (key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_EXEC, + error); + if (!exec) + { + egg_desktop_file_free (desktop_file); + g_free (type); + return NULL; + } - url = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_URL, - error); - if (!url) + /* See if it takes paths or URIs or neither */ + for (p = exec; *p; p++) + { + if (*p == '%') + { + if (p[1] == '\0' || strchr ("FfUu", p[1])) + { + desktop_file->document_code = p[1]; + break; + } + p++; + } + } + + g_free (exec); + } + else if (!strcmp (type, "Link")) { - egg_desktop_file_free (desktop_file); - g_free (type); - return NULL; + char *url; + + desktop_file->type = EGG_DESKTOP_FILE_TYPE_LINK; + + url = g_key_file_get_string (key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_URL, + error); + if (!url) + { + egg_desktop_file_free (desktop_file); + g_free (type); + return NULL; + } + g_free (url); } - g_free (url); - } - else if (!strcmp (type, "Directory")) - desktop_file->type = EGG_DESKTOP_FILE_TYPE_DIRECTORY; - else - desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED; - - g_free (type); - - /* Check the Icon key */ - desktop_file->icon = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_ICON, - NULL); - if (desktop_file->icon && !g_path_is_absolute (desktop_file->icon)) - { - char *ext; - - /* Lots of .desktop files still get this wrong */ - ext = strrchr (desktop_file->icon, '.'); - if (ext && (!strcmp (ext, ".png") || - !strcmp (ext, ".xpm") || - !strcmp (ext, ".svg"))) + else if (!strcmp (type, "Directory")) + desktop_file->type = EGG_DESKTOP_FILE_TYPE_DIRECTORY; + else + desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED; + + g_free (type); + + /* Check the Icon key */ + desktop_file->icon = g_key_file_get_string (key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_ICON, + NULL); + if (desktop_file->icon && !g_path_is_absolute (desktop_file->icon)) { - g_warning ("Desktop file '%s' has malformed Icon key '%s'" - "(should not include extension)", - source ? source : "(unknown)", - desktop_file->icon); - *ext = '\0'; + char *ext; + + /* Lots of .desktop files still get this wrong */ + ext = strrchr (desktop_file->icon, '.'); + if (ext && (!strcmp (ext, ".png") || + !strcmp (ext, ".xpm") || + !strcmp (ext, ".svg"))) + { + g_warning ("Desktop file '%s' has malformed Icon key '%s'" + "(should not include extension)", + source ? source : "(unknown)", + desktop_file->icon); + *ext = '\0'; + } } - } - return desktop_file; + return desktop_file; } /** @@ -310,11 +311,11 @@ egg_desktop_file_new_from_key_file (GKeyFile *key_file, void egg_desktop_file_free (EggDesktopFile *desktop_file) { - g_key_file_free (desktop_file->key_file); - g_free (desktop_file->source); - g_free (desktop_file->name); - g_free (desktop_file->icon); - g_free (desktop_file); + g_key_file_free (desktop_file->key_file); + g_free (desktop_file->source); + g_free (desktop_file->name); + g_free (desktop_file->icon); + g_free (desktop_file); } /** @@ -328,7 +329,7 @@ egg_desktop_file_free (EggDesktopFile *desktop_file) const char * egg_desktop_file_get_source (EggDesktopFile *desktop_file) { - return desktop_file->source; + return desktop_file->source; } /** @@ -342,7 +343,7 @@ egg_desktop_file_get_source (EggDesktopFile *desktop_file) EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file) { - return desktop_file->type; + return desktop_file->type; } /** @@ -356,7 +357,7 @@ egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file) const char * egg_desktop_file_get_name (EggDesktopFile *desktop_file) { - return desktop_file->name; + return desktop_file->name; } /** @@ -377,82 +378,82 @@ egg_desktop_file_get_name (EggDesktopFile *desktop_file) const char * egg_desktop_file_get_icon (EggDesktopFile *desktop_file) { - return desktop_file->icon; + return desktop_file->icon; } gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file, - const char *key, - GError **error) + const char *key, + GError **error) { - return g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); + return g_key_file_has_key (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); } char * egg_desktop_file_get_string (EggDesktopFile *desktop_file, - const char *key, - GError **error) + const char *key, + GError **error) { - return g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); + return g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); } char * egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - GError **error) + const char *key, + const char *locale, + GError **error) { - return g_key_file_get_locale_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, locale, - error); + return g_key_file_get_locale_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, locale, + error); } gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, - const char *key, - GError **error) + const char *key, + GError **error) { - return g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); + return g_key_file_get_boolean (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); } double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, - const char *key, - GError **error) + const char *key, + GError **error) { - return g_key_file_get_double (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); + return g_key_file_get_double (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); } char ** egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, - const char *key, - gsize *length, - GError **error) + const char *key, + gsize *length, + GError **error) { - return g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, length, - error); + return g_key_file_get_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, length, + error); } char ** egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - gsize *length, - GError **error) + const char *key, + const char *locale, + gsize *length, + GError **error) { - return g_key_file_get_locale_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - locale, length, - error); + return g_key_file_get_locale_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + locale, length, + error); } /** @@ -477,74 +478,74 @@ egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, **/ gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file, - const char *desktop_environment) + const char *desktop_environment) { - char *try_exec, *found_program; - char **only_show_in, **not_show_in; - gboolean found; - int i; - - if (desktop_file->type != EGG_DESKTOP_FILE_TYPE_APPLICATION && - desktop_file->type != EGG_DESKTOP_FILE_TYPE_LINK) - return FALSE; - - if (desktop_environment) - { - only_show_in = g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN, - NULL, NULL); - if (only_show_in) + char *try_exec, *found_program; + char **only_show_in, **not_show_in; + gboolean found; + int i; + + if (desktop_file->type != EGG_DESKTOP_FILE_TYPE_APPLICATION && + desktop_file->type != EGG_DESKTOP_FILE_TYPE_LINK) + return FALSE; + + if (desktop_environment) { - for (i = 0, found = FALSE; only_show_in[i] && !found; i++) - { - if (!strcmp (only_show_in[i], desktop_environment)) - found = TRUE; - } + only_show_in = g_key_file_get_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN, + NULL, NULL); + if (only_show_in) + { + for (i = 0, found = FALSE; only_show_in[i] && !found; i++) + { + if (!strcmp (only_show_in[i], desktop_environment)) + found = TRUE; + } - g_strfreev (only_show_in); + g_strfreev (only_show_in); - if (!found) - return FALSE; - } + if (!found) + return FALSE; + } - not_show_in = g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN, - NULL, NULL); - if (not_show_in) - { - for (i = 0, found = FALSE; not_show_in[i] && !found; i++) - { - if (!strcmp (not_show_in[i], desktop_environment)) - found = TRUE; - } + not_show_in = g_key_file_get_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN, + NULL, NULL); + if (not_show_in) + { + for (i = 0, found = FALSE; not_show_in[i] && !found; i++) + { + if (!strcmp (not_show_in[i], desktop_environment)) + found = TRUE; + } - g_strfreev (not_show_in); + g_strfreev (not_show_in); - if (found) - return FALSE; + if (found) + return FALSE; + } } - } - - if (desktop_file->type == EGG_DESKTOP_FILE_TYPE_APPLICATION) - { - try_exec = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TRY_EXEC, - NULL); - if (try_exec) + + if (desktop_file->type == EGG_DESKTOP_FILE_TYPE_APPLICATION) { - found_program = g_find_program_in_path (try_exec); - g_free (try_exec); + try_exec = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TRY_EXEC, + NULL); + if (try_exec) + { + found_program = g_find_program_in_path (try_exec); + g_free (try_exec); - if (!found_program) - return FALSE; - g_free (found_program); + if (!found_program) + return FALSE; + g_free (found_program); + } } - } - return TRUE; + return TRUE; } /** @@ -559,7 +560,7 @@ egg_desktop_file_can_launch (EggDesktopFile *desktop_file, gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file) { - return desktop_file->document_code != 0; + return desktop_file->document_code != 0; } /** @@ -578,8 +579,8 @@ egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file) gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file) { - return (desktop_file->document_code == 'F' || - desktop_file->document_code == 'U'); + return (desktop_file->document_code == 'F' || + desktop_file->document_code == 'U'); } /** @@ -594,256 +595,256 @@ egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file) gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file) { - return (desktop_file->document_code == 'U' || - desktop_file->document_code == 'u'); + return (desktop_file->document_code == 'U' || + desktop_file->document_code == 'u'); } static void append_quoted_word (GString *str, - const char *s, - gboolean in_single_quotes, - gboolean in_double_quotes) + const char *s, + gboolean in_single_quotes, + gboolean in_double_quotes) { - const char *p; - - if (!in_single_quotes && !in_double_quotes) - g_string_append_c (str, '\''); - else if (!in_single_quotes && in_double_quotes) - g_string_append (str, "\"'"); - - if (!strchr (s, '\'')) - g_string_append (str, s); - else - { - for (p = s; *p != '\0'; p++) + const char *p; + + if (!in_single_quotes && !in_double_quotes) + g_string_append_c (str, '\''); + else if (!in_single_quotes && in_double_quotes) + g_string_append (str, "\"'"); + + if (!strchr (s, '\'')) + g_string_append (str, s); + else { - if (*p == '\'') - g_string_append (str, "'\\''"); - else - g_string_append_c (str, *p); + for (p = s; *p != '\0'; p++) + { + if (*p == '\'') + g_string_append (str, "'\\''"); + else + g_string_append_c (str, *p); + } } - } - if (!in_single_quotes && !in_double_quotes) - g_string_append_c (str, '\''); - else if (!in_single_quotes && in_double_quotes) - g_string_append (str, "'\""); + if (!in_single_quotes && !in_double_quotes) + g_string_append_c (str, '\''); + else if (!in_single_quotes && in_double_quotes) + g_string_append (str, "'\""); } static void do_percent_subst (EggDesktopFile *desktop_file, - char code, - GString *str, - GSList **documents, - gboolean in_single_quotes, - gboolean in_double_quotes) + char code, + GString *str, + GSList **documents, + gboolean in_single_quotes, + gboolean in_double_quotes) { - GSList *d; - char *doc; - - switch (code) - { - case '%': - g_string_append_c (str, '%'); - break; - - case 'F': - case 'U': - for (d = *documents; d; d = d->next) - { - doc = d->data; - g_string_append (str, " "); - append_quoted_word (str, doc, in_single_quotes, in_double_quotes); - } - *documents = NULL; - break; + GSList *d; + char *doc; - case 'f': - case 'u': - if (*documents) + switch (code) { - doc = (*documents)->data; - g_string_append (str, " "); - append_quoted_word (str, doc, in_single_quotes, in_double_quotes); - *documents = (*documents)->next; - } - break; + case '%': + g_string_append_c (str, '%'); + break; - case 'i': - if (desktop_file->icon) - { - g_string_append (str, "--icon "); - append_quoted_word (str, desktop_file->icon, - in_single_quotes, in_double_quotes); - } - break; + case 'F': + case 'U': + for (d = *documents; d; d = d->next) + { + doc = d->data; + g_string_append (str, " "); + append_quoted_word (str, doc, in_single_quotes, in_double_quotes); + } + *documents = NULL; + break; - case 'c': - if (desktop_file->name) - { - append_quoted_word (str, desktop_file->name, - in_single_quotes, in_double_quotes); - } - break; + case 'f': + case 'u': + if (*documents) + { + doc = (*documents)->data; + g_string_append (str, " "); + append_quoted_word (str, doc, in_single_quotes, in_double_quotes); + *documents = (*documents)->next; + } + break; - case 'k': - if (desktop_file->source) - { - append_quoted_word (str, desktop_file->source, - in_single_quotes, in_double_quotes); + case 'i': + if (desktop_file->icon) + { + g_string_append (str, "--icon "); + append_quoted_word (str, desktop_file->icon, + in_single_quotes, in_double_quotes); + } + break; + + case 'c': + if (desktop_file->name) + { + append_quoted_word (str, desktop_file->name, + in_single_quotes, in_double_quotes); + } + break; + + case 'k': + if (desktop_file->source) + { + append_quoted_word (str, desktop_file->source, + in_single_quotes, in_double_quotes); + } + break; + + case 'D': + case 'N': + case 'd': + case 'n': + case 'v': + case 'm': + /* Deprecated; skip */ + break; + + default: + g_warning ("Unrecognized %%-code '%%%c' in Exec", code); + break; } - break; - - case 'D': - case 'N': - case 'd': - case 'n': - case 'v': - case 'm': - /* Deprecated; skip */ - break; - - default: - g_warning ("Unrecognized %%-code '%%%c' in Exec", code); - break; - } } static char * parse_exec (EggDesktopFile *desktop_file, - GSList **documents, - GError **error) + GSList **documents, + GError **error) { - char *exec, *p, *command; - gboolean escape, single_quot, double_quot; - GString *gs; - - exec = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - error); - if (!exec) - return NULL; - - /* Build the command */ - gs = g_string_new (NULL); - escape = single_quot = double_quot = FALSE; - - for (p = exec; *p != '\0'; p++) - { - if (escape) - { - escape = FALSE; - g_string_append_c (gs, *p); - } - else if (*p == '\\') - { - if (!single_quot) - escape = TRUE; - g_string_append_c (gs, *p); - } - else if (*p == '\'') + char *exec, *p, *command; + gboolean escape, single_quot, double_quot; + GString *gs; + + exec = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_EXEC, + error); + if (!exec) + return NULL; + + /* Build the command */ + gs = g_string_new (NULL); + escape = single_quot = double_quot = FALSE; + + for (p = exec; *p != '\0'; p++) { - g_string_append_c (gs, *p); - if (!single_quot && !double_quot) - single_quot = TRUE; - else if (single_quot) - single_quot = FALSE; - } - else if (*p == '"') - { - g_string_append_c (gs, *p); - if (!single_quot && !double_quot) - double_quot = TRUE; - else if (double_quot) - double_quot = FALSE; - } - else if (*p == '%' && p[1]) - { - do_percent_subst (desktop_file, p[1], gs, documents, - single_quot, double_quot); - p++; - } - else - g_string_append_c (gs, *p); - } - - g_free (exec); - command = g_string_free (gs, FALSE); - - /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */ - if (g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TERMINAL, - NULL)) - { - GError *terminal_error = NULL; - gboolean use_terminal = - g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TERMINAL, - &terminal_error); - if (terminal_error) - { - g_free (command); - g_propagate_error (error, terminal_error); - return NULL; + if (escape) + { + escape = FALSE; + g_string_append_c (gs, *p); + } + else if (*p == '\\') + { + if (!single_quot) + escape = TRUE; + g_string_append_c (gs, *p); + } + else if (*p == '\'') + { + g_string_append_c (gs, *p); + if (!single_quot && !double_quot) + single_quot = TRUE; + else if (single_quot) + single_quot = FALSE; + } + else if (*p == '"') + { + g_string_append_c (gs, *p); + if (!single_quot && !double_quot) + double_quot = TRUE; + else if (double_quot) + double_quot = FALSE; + } + else if (*p == '%' && p[1]) + { + do_percent_subst (desktop_file, p[1], gs, documents, + single_quot, double_quot); + p++; + } + else + g_string_append_c (gs, *p); } - if (use_terminal) + g_free (exec); + command = g_string_free (gs, FALSE); + + /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */ + if (g_key_file_has_key (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TERMINAL, + NULL)) { - gs = g_string_new ("xdg-terminal "); - append_quoted_word (gs, command, FALSE, FALSE); - g_free (command); - command = g_string_free (gs, FALSE); + GError *terminal_error = NULL; + gboolean use_terminal = + g_key_file_get_boolean (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TERMINAL, + &terminal_error); + if (terminal_error) + { + g_free (command); + g_propagate_error (error, terminal_error); + return NULL; + } + + if (use_terminal) + { + gs = g_string_new ("xdg-terminal "); + append_quoted_word (gs, command, FALSE, FALSE); + g_free (command); + command = g_string_free (gs, FALSE); + } } - } - return command; + return command; } static GSList * translate_document_list (EggDesktopFile *desktop_file, GSList *documents) { - gboolean accepts_uris = egg_desktop_file_accepts_uris (desktop_file); - GSList *ret, *d; + gboolean accepts_uris = egg_desktop_file_accepts_uris (desktop_file); + GSList *ret, *d; - for (d = documents, ret = NULL; d; d = d->next) - { - const char *document = d->data; - gboolean is_uri = !g_path_is_absolute (document); - char *translated; - - if (accepts_uris) - { - if (is_uri) - translated = g_strdup (document); - else - translated = g_filename_to_uri (document, NULL, NULL); - } - else + for (d = documents, ret = NULL; d; d = d->next) { - if (is_uri) - translated = g_filename_from_uri (document, NULL, NULL); - else - translated = g_strdup (document); - } + const char *document = d->data; + gboolean is_uri = !g_path_is_absolute (document); + char *translated; + + if (accepts_uris) + { + if (is_uri) + translated = g_strdup (document); + else + translated = g_filename_to_uri (document, NULL, NULL); + } + else + { + if (is_uri) + translated = g_filename_from_uri (document, NULL, NULL); + else + translated = g_strdup (document); + } - if (translated) - ret = g_slist_prepend (ret, translated); - } + if (translated) + ret = g_slist_prepend (ret, translated); + } - return g_slist_reverse (ret); + return g_slist_reverse (ret); } static void free_document_list (GSList *documents) { - GSList *d; + GSList *d; - for (d = documents; d; d = d->next) - g_free (d->data); - g_slist_free (documents); + for (d = documents; d; d = d->next) + g_free (d->data); + g_slist_free (documents); } /** @@ -864,422 +865,423 @@ free_document_list (GSList *documents) **/ char * egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, - GSList *documents, - GError **error) + GSList *documents, + GError **error) { - GSList *translated, *docs; - char *command; + GSList *translated, *docs; + char *command; - docs = translated = translate_document_list (desktop_file, documents); - command = parse_exec (desktop_file, &docs, error); - free_document_list (translated); + docs = translated = translate_document_list (desktop_file, documents); + command = parse_exec (desktop_file, &docs, error); + free_document_list (translated); - return command; + return command; } static gboolean parse_link (EggDesktopFile *desktop_file, - EggDesktopFile **app_desktop_file, - GSList **documents, - GError **error) + EggDesktopFile **app_desktop_file, + GSList **documents, + GError **error) { - char *url; - GKeyFile *key_file; - - url = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_URL, - error); - if (!url) - return FALSE; - *documents = g_slist_prepend (NULL, url); - - /* FIXME: use gvfs */ - key_file = g_key_file_new (); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NAME, - "xdg-open"); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TYPE, - "Application"); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - "xdg-open %u"); - *app_desktop_file = egg_desktop_file_new_from_key_file (key_file, NULL, NULL); - return TRUE; + char *url; + GKeyFile *key_file; + + url = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_URL, + error); + if (!url) + return FALSE; + *documents = g_slist_prepend (NULL, url); + + /* FIXME: use gvfs */ + key_file = g_key_file_new (); + g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_NAME, + "xdg-open"); + g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TYPE, + "Application"); + g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_EXEC, + "xdg-open %u"); + *app_desktop_file = egg_desktop_file_new_from_key_file (key_file, NULL, NULL); + return TRUE; } #if GTK_CHECK_VERSION (2, 12, 0) static char * start_startup_notification (GdkDisplay *display, - EggDesktopFile *desktop_file, - const char *argv0, - int screen, - int workspace, - guint32 launch_time) + EggDesktopFile *desktop_file, + const char *argv0, + int screen, + int workspace, + guint32 launch_time) { - static int sequence = 0; - char *startup_id; - char *description, *wmclass; - char *screen_str, *workspace_str; - - if (g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, - NULL)) - { - if (!g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, - NULL)) - return NULL; - wmclass = NULL; - } - else - { - wmclass = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS, - NULL); - if (!wmclass) - return NULL; - } - - if (launch_time == (guint32)-1) - launch_time = gdk_x11_display_get_user_time (display); - startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu", - g_get_prgname (), - (unsigned long)getpid (), - g_get_host_name (), - argv0, - sequence++, - (unsigned long)launch_time); - - description = g_strdup_printf (_("Starting %s"), desktop_file->name); - screen_str = g_strdup_printf ("%d", screen); - workspace_str = workspace == -1 ? NULL : g_strdup_printf ("%d", workspace); - - gdk_x11_display_broadcast_startup_message (display, "new", - "ID", startup_id, - "NAME", desktop_file->name, - "SCREEN", screen_str, - "BIN", argv0, - "ICON", desktop_file->icon, - "DESKTOP", workspace_str, - "DESCRIPTION", description, - "WMCLASS", wmclass, - NULL); - - g_free (description); - g_free (wmclass); - g_free (screen_str); - g_free (workspace_str); - - return startup_id; + static int sequence = 0; + char *startup_id; + char *description, *wmclass; + char *screen_str, *workspace_str; + + if (g_key_file_has_key (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, + NULL)) + { + if (!g_key_file_get_boolean (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, + NULL)) + return NULL; + wmclass = NULL; + } + else + { + wmclass = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS, + NULL); + if (!wmclass) + return NULL; + } + + if (launch_time == (guint32)-1) + launch_time = gdk_x11_display_get_user_time (display); + startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu", + g_get_prgname (), + (unsigned long)getpid (), + g_get_host_name (), + argv0, + sequence++, + (unsigned long)launch_time); + + description = g_strdup_printf (_("Starting %s"), desktop_file->name); + screen_str = g_strdup_printf ("%d", screen); + workspace_str = workspace == -1 ? NULL : g_strdup_printf ("%d", workspace); + + gdk_x11_display_broadcast_startup_message (display, "new", + "ID", startup_id, + "NAME", desktop_file->name, + "SCREEN", screen_str, + "BIN", argv0, + "ICON", desktop_file->icon, + "DESKTOP", workspace_str, + "DESCRIPTION", description, + "WMCLASS", wmclass, + NULL); + + g_free (description); + g_free (wmclass); + g_free (screen_str); + g_free (workspace_str); + + return startup_id; } static void end_startup_notification (GdkDisplay *display, - const char *startup_id) + const char *startup_id) { - gdk_x11_display_broadcast_startup_message (display, "remove", - "ID", startup_id, - NULL); + gdk_x11_display_broadcast_startup_message (display, "remove", + "ID", startup_id, + NULL); } #define EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH (30 /* seconds */) -typedef struct { - GdkDisplay *display; - char *startup_id; +typedef struct +{ + GdkDisplay *display; + char *startup_id; } StartupNotificationData; static gboolean startup_notification_timeout (gpointer data) { - StartupNotificationData *sn_data = data; + StartupNotificationData *sn_data = data; - end_startup_notification (sn_data->display, sn_data->startup_id); - g_object_unref (sn_data->display); - g_free (sn_data->startup_id); - g_free (sn_data); + end_startup_notification (sn_data->display, sn_data->startup_id); + g_object_unref (sn_data->display); + g_free (sn_data->startup_id); + g_free (sn_data); - return FALSE; + return FALSE; } static void set_startup_notification_timeout (GdkDisplay *display, - const char *startup_id) + const char *startup_id) { - StartupNotificationData *sn_data; + StartupNotificationData *sn_data; - sn_data = g_new (StartupNotificationData, 1); - sn_data->display = g_object_ref (display); - sn_data->startup_id = g_strdup (startup_id); + sn_data = g_new (StartupNotificationData, 1); + sn_data->display = g_object_ref (display); + sn_data->startup_id = g_strdup (startup_id); - g_timeout_add_seconds (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH, - startup_notification_timeout, sn_data); + g_timeout_add_seconds (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH, + startup_notification_timeout, sn_data); } #endif /* GTK 2.12 */ static GPtrArray * array_putenv (GPtrArray *env, char *variable) { - guint i, keylen; + guint i, keylen; - if (!env) - { - char **envp; - - env = g_ptr_array_new (); + if (!env) + { + char **envp; - envp = g_listenv (); - for (i = 0; envp[i]; i++) - { - const char *value; + env = g_ptr_array_new (); - value = g_getenv (envp[i]); - g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i], - value ? value : "")); - } - g_strfreev (envp); - } + envp = g_listenv (); + for (i = 0; envp[i]; i++) + { + const char *value; - keylen = strcspn (variable, "="); + value = g_getenv (envp[i]); + g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i], + value ? value : "")); + } + g_strfreev (envp); + } - /* Remove old value of key */ - for (i = 0; i < env->len; i++) - { - char *envvar = env->pdata[i]; + keylen = strcspn (variable, "="); - if (!strncmp (envvar, variable, keylen) && envvar[keylen] == '=') + /* Remove old value of key */ + for (i = 0; i < env->len; i++) { - g_free (envvar); - g_ptr_array_remove_index_fast (env, i); - break; + char *envvar = env->pdata[i]; + + if (!strncmp (envvar, variable, keylen) && envvar[keylen] == '=') + { + g_free (envvar); + g_ptr_array_remove_index_fast (env, i); + break; + } } - } - /* Add new value */ - g_ptr_array_add (env, g_strdup (variable)); + /* Add new value */ + g_ptr_array_add (env, g_strdup (variable)); - return env; + return env; } static gboolean egg_desktop_file_launchv (EggDesktopFile *desktop_file, - GSList *documents, va_list args, - GError **error) + GSList *documents, va_list args, + GError **error) { - EggDesktopFileLaunchOption option; - GSList *translated_documents = NULL, *docs = NULL; - char *command, **argv; - int argc, i, screen_num; - gboolean success, current_success; - GdkDisplay *display; - char *startup_id; - - GPtrArray *env = NULL; - char **variables = NULL; - GdkScreen *screen = NULL; - int workspace = -1; - const char *directory = NULL; - guint32 launch_time = (guint32)-1; - GSpawnFlags flags = G_SPAWN_SEARCH_PATH; - GSpawnChildSetupFunc setup_func = NULL; - gpointer setup_data = NULL; - - GPid *ret_pid = NULL; - int *ret_stdin = NULL, *ret_stdout = NULL, *ret_stderr = NULL; - char **ret_startup_id = NULL; - - if (documents && desktop_file->document_code == 0) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Application does not accept documents on command line")); - return FALSE; - } - - /* Read the options: technically it's incorrect for the caller to - * NULL-terminate the list of options (rather than 0-terminating - * it), but NULL-terminating lets us use G_GNUC_NULL_TERMINATED, - * it's more consistent with other glib/gtk methods, and it will - * work as long as sizeof (int) <= sizeof (NULL), and NULL is - * represented as 0. (Which is true everywhere we care about.) - */ - while ((option = va_arg (args, EggDesktopFileLaunchOption))) - { - switch (option) + EggDesktopFileLaunchOption option; + GSList *translated_documents = NULL, *docs = NULL; + char *command, **argv; + int argc, i, screen_num; + gboolean success, current_success; + GdkDisplay *display; + char *startup_id; + + GPtrArray *env = NULL; + char **variables = NULL; + GdkScreen *screen = NULL; + int workspace = -1; + const char *directory = NULL; + guint32 launch_time = (guint32)-1; + GSpawnFlags flags = G_SPAWN_SEARCH_PATH; + GSpawnChildSetupFunc setup_func = NULL; + gpointer setup_data = NULL; + + GPid *ret_pid = NULL; + int *ret_stdin = NULL, *ret_stdout = NULL, *ret_stderr = NULL; + char **ret_startup_id = NULL; + + if (documents && desktop_file->document_code == 0) { - case EGG_DESKTOP_FILE_LAUNCH_CLEARENV: - if (env) - g_ptr_array_free (env, TRUE); - env = g_ptr_array_new (); - break; - case EGG_DESKTOP_FILE_LAUNCH_PUTENV: - variables = va_arg (args, char **); - for (i = 0; variables[i]; i++) - env = array_putenv (env, variables[i]); - break; - - case EGG_DESKTOP_FILE_LAUNCH_SCREEN: - screen = va_arg (args, GdkScreen *); - break; - case EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: - workspace = va_arg (args, int); - break; - - case EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: - directory = va_arg (args, const char *); - break; - case EGG_DESKTOP_FILE_LAUNCH_TIME: - launch_time = va_arg (args, guint32); - break; - case EGG_DESKTOP_FILE_LAUNCH_FLAGS: - flags |= va_arg (args, GSpawnFlags); - /* Make sure they didn't set any flags that don't make sense. */ - flags &= ~G_SPAWN_FILE_AND_ARGV_ZERO; - break; - case EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC: - setup_func = va_arg (args, GSpawnChildSetupFunc); - setup_data = va_arg (args, gpointer); - break; - - case EGG_DESKTOP_FILE_LAUNCH_RETURN_PID: - ret_pid = va_arg (args, GPid *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE: - ret_stdin = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE: - ret_stdout = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE: - ret_stderr = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID: - ret_startup_id = va_arg (args, char **); - break; - - default: - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION, - _("Unrecognized launch option: %d"), - GPOINTER_TO_INT (option)); - success = FALSE; - goto out; + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, + _("Application does not accept documents on command line")); + return FALSE; } - } - - if (screen) - { - char *display_name = gdk_screen_make_display_name (screen); - char *display_env = g_strdup_printf ("DISPLAY=%s", display_name); - env = array_putenv (env, display_env); - g_free (display_name); - g_free (display_env); - - display = gdk_screen_get_display (screen); - } - else - { - display = gdk_display_get_default (); - screen = gdk_display_get_default_screen (display); - } - screen_num = gdk_screen_get_number (screen); - - translated_documents = translate_document_list (desktop_file, documents); - docs = translated_documents; - - success = FALSE; - - do - { - command = parse_exec (desktop_file, &docs, error); - if (!command) - goto out; - - if (!g_shell_parse_argv (command, &argc, &argv, error)) + + /* Read the options: technically it's incorrect for the caller to + * NULL-terminate the list of options (rather than 0-terminating + * it), but NULL-terminating lets us use G_GNUC_NULL_TERMINATED, + * it's more consistent with other glib/gtk methods, and it will + * work as long as sizeof (int) <= sizeof (NULL), and NULL is + * represented as 0. (Which is true everywhere we care about.) + */ + while ((option = va_arg (args, EggDesktopFileLaunchOption))) { - g_free (command); - goto out; + switch (option) + { + case EGG_DESKTOP_FILE_LAUNCH_CLEARENV: + if (env) + g_ptr_array_free (env, TRUE); + env = g_ptr_array_new (); + break; + case EGG_DESKTOP_FILE_LAUNCH_PUTENV: + variables = va_arg (args, char **); + for (i = 0; variables[i]; i++) + env = array_putenv (env, variables[i]); + break; + + case EGG_DESKTOP_FILE_LAUNCH_SCREEN: + screen = va_arg (args, GdkScreen *); + break; + case EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: + workspace = va_arg (args, int); + break; + + case EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: + directory = va_arg (args, const char *); + break; + case EGG_DESKTOP_FILE_LAUNCH_TIME: + launch_time = va_arg (args, guint32); + break; + case EGG_DESKTOP_FILE_LAUNCH_FLAGS: + flags |= va_arg (args, GSpawnFlags); + /* Make sure they didn't set any flags that don't make sense. */ + flags &= ~G_SPAWN_FILE_AND_ARGV_ZERO; + break; + case EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC: + setup_func = va_arg (args, GSpawnChildSetupFunc); + setup_data = va_arg (args, gpointer); + break; + + case EGG_DESKTOP_FILE_LAUNCH_RETURN_PID: + ret_pid = va_arg (args, GPid *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE: + ret_stdin = va_arg (args, int *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE: + ret_stdout = va_arg (args, int *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE: + ret_stderr = va_arg (args, int *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID: + ret_startup_id = va_arg (args, char **); + break; + + default: + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION, + _("Unrecognized launch option: %d"), + GPOINTER_TO_INT (option)); + success = FALSE; + goto out; + } } - g_free (command); -#if GTK_CHECK_VERSION (2, 12, 0) - startup_id = start_startup_notification (display, desktop_file, - argv[0], screen_num, - workspace, launch_time); - if (startup_id) + if (screen) + { + char *display_name = gdk_screen_make_display_name (screen); + char *display_env = g_strdup_printf ("DISPLAY=%s", display_name); + env = array_putenv (env, display_env); + g_free (display_name); + g_free (display_env); + + display = gdk_screen_get_display (screen); + } + else { - char *startup_id_env = g_strdup_printf ("DESKTOP_STARTUP_ID=%s", - startup_id); - env = array_putenv (env, startup_id_env); - g_free (startup_id_env); + display = gdk_display_get_default (); + screen = gdk_display_get_default_screen (display); } + screen_num = gdk_screen_get_number (screen); + + translated_documents = translate_document_list (desktop_file, documents); + docs = translated_documents; + + success = FALSE; + + do + { + command = parse_exec (desktop_file, &docs, error); + if (!command) + goto out; + + if (!g_shell_parse_argv (command, &argc, &argv, error)) + { + g_free (command); + goto out; + } + g_free (command); + +#if GTK_CHECK_VERSION (2, 12, 0) + startup_id = start_startup_notification (display, desktop_file, + argv[0], screen_num, + workspace, launch_time); + if (startup_id) + { + char *startup_id_env = g_strdup_printf ("DESKTOP_STARTUP_ID=%s", + startup_id); + env = array_putenv (env, startup_id_env); + g_free (startup_id_env); + } #else - startup_id = NULL; + startup_id = NULL; #endif /* GTK 2.12 */ - if (env != NULL) - g_ptr_array_add (env, NULL); - - current_success = - g_spawn_async_with_pipes (directory, - argv, - env ? (char **)(env->pdata) : NULL, - flags, - setup_func, setup_data, - ret_pid, - ret_stdin, ret_stdout, ret_stderr, - error); - g_strfreev (argv); - - if (startup_id) - { + if (env != NULL) + g_ptr_array_add (env, NULL); + + current_success = + g_spawn_async_with_pipes (directory, + argv, + env ? (char **)(env->pdata) : NULL, + flags, + setup_func, setup_data, + ret_pid, + ret_stdin, ret_stdout, ret_stderr, + error); + g_strfreev (argv); + + if (startup_id) + { #if GTK_CHECK_VERSION (2, 12, 0) - if (current_success) - { - set_startup_notification_timeout (display, startup_id); - - if (ret_startup_id) - *ret_startup_id = startup_id; - else - g_free (startup_id); - } - else + if (current_success) + { + set_startup_notification_timeout (display, startup_id); + + if (ret_startup_id) + *ret_startup_id = startup_id; + else + g_free (startup_id); + } + else #endif /* GTK 2.12 */ - g_free (startup_id); + g_free (startup_id); + } + else if (ret_startup_id) + *ret_startup_id = NULL; + + if (current_success) + { + /* If we successfully launch any instances of the app, make + * sure we return TRUE and don't set @error. + */ + success = TRUE; + error = NULL; + + /* Also, only set the output params on the first one */ + ret_pid = NULL; + ret_stdin = ret_stdout = ret_stderr = NULL; + ret_startup_id = NULL; + } } - else if (ret_startup_id) - *ret_startup_id = NULL; + while (docs && current_success); - if (current_success) +out: + if (env) { - /* If we successfully launch any instances of the app, make - * sure we return TRUE and don't set @error. - */ - success = TRUE; - error = NULL; - - /* Also, only set the output params on the first one */ - ret_pid = NULL; - ret_stdin = ret_stdout = ret_stderr = NULL; - ret_startup_id = NULL; + g_ptr_array_foreach (env, (GFunc)g_free, NULL); + g_ptr_array_free (env, TRUE); } - } - while (docs && current_success); - - out: - if (env) - { - g_ptr_array_foreach (env, (GFunc)g_free, NULL); - g_ptr_array_free (env, TRUE); - } - free_document_list (translated_documents); - - return success; + free_document_list (translated_documents); + + return success; } /** @@ -1349,61 +1351,61 @@ egg_desktop_file_launchv (EggDesktopFile *desktop_file, **/ gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file, - GSList *documents, GError **error, - ...) + GSList *documents, GError **error, + ...) { - va_list args; - gboolean success; - EggDesktopFile *app_desktop_file; - - switch (desktop_file->type) - { - case EGG_DESKTOP_FILE_TYPE_APPLICATION: - va_start (args, error); - success = egg_desktop_file_launchv (desktop_file, documents, - args, error); - va_end (args); - break; - - case EGG_DESKTOP_FILE_TYPE_LINK: - if (documents) + va_list args; + gboolean success; + EggDesktopFile *app_desktop_file; + + switch (desktop_file->type) { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Can't pass document URIs to a 'Type=Link' desktop entry")); - return FALSE; - } + case EGG_DESKTOP_FILE_TYPE_APPLICATION: + va_start (args, error); + success = egg_desktop_file_launchv (desktop_file, documents, + args, error); + va_end (args); + break; + + case EGG_DESKTOP_FILE_TYPE_LINK: + if (documents) + { + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, + _("Can't pass document URIs to a 'Type=Link' desktop entry")); + return FALSE; + } - if (!parse_link (desktop_file, &app_desktop_file, &documents, error)) - return FALSE; + if (!parse_link (desktop_file, &app_desktop_file, &documents, error)) + return FALSE; + + va_start (args, error); + success = egg_desktop_file_launchv (app_desktop_file, documents, + args, error); + va_end (args); + + egg_desktop_file_free (app_desktop_file); + free_document_list (documents); + break; - va_start (args, error); - success = egg_desktop_file_launchv (app_desktop_file, documents, - args, error); - va_end (args); - - egg_desktop_file_free (app_desktop_file); - free_document_list (documents); - break; - - case EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED: - case EGG_DESKTOP_FILE_TYPE_DIRECTORY: - default: - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Not a launchable item")); - success = FALSE; - break; - } - - return success; + case EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED: + case EGG_DESKTOP_FILE_TYPE_DIRECTORY: + default: + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, + _("Not a launchable item")); + success = FALSE; + break; + } + + return success; } GQuark egg_desktop_file_error_quark (void) { - return g_quark_from_static_string ("egg-desktop_file-error-quark"); + return g_quark_from_static_string ("egg-desktop_file-error-quark"); } @@ -1414,34 +1416,35 @@ static void egg_set_desktop_file_internal (const char *desktop_file_path, gboolean set_defaults) { - GError *error = NULL; - - G_LOCK (egg_desktop_file); - if (egg_desktop_file) - egg_desktop_file_free (egg_desktop_file); - - egg_desktop_file = egg_desktop_file_new (desktop_file_path, &error); - if (error) - { - g_warning ("Could not load desktop file '%s': %s", - desktop_file_path, error->message); - g_error_free (error); - } - - if (set_defaults && egg_desktop_file != NULL) { - /* Set localized application name and default window icon */ - if (egg_desktop_file->name) - g_set_application_name (egg_desktop_file->name); - if (egg_desktop_file->icon) - { - if (g_path_is_absolute (egg_desktop_file->icon)) - gtk_window_set_default_icon_from_file (egg_desktop_file->icon, NULL); - else - gtk_window_set_default_icon_name (egg_desktop_file->icon); - } - } - - G_UNLOCK (egg_desktop_file); + GError *error = NULL; + + G_LOCK (egg_desktop_file); + if (egg_desktop_file) + egg_desktop_file_free (egg_desktop_file); + + egg_desktop_file = egg_desktop_file_new (desktop_file_path, &error); + if (error) + { + g_warning ("Could not load desktop file '%s': %s", + desktop_file_path, error->message); + g_error_free (error); + } + + if (set_defaults && egg_desktop_file != NULL) + { + /* Set localized application name and default window icon */ + if (egg_desktop_file->name) + g_set_application_name (egg_desktop_file->name); + if (egg_desktop_file->icon) + { + if (g_path_is_absolute (egg_desktop_file->icon)) + gtk_window_set_default_icon_from_file (egg_desktop_file->icon, NULL); + else + gtk_window_set_default_icon_name (egg_desktop_file->icon); + } + } + + G_UNLOCK (egg_desktop_file); } /** @@ -1466,7 +1469,7 @@ egg_set_desktop_file_internal (const char *desktop_file_path, void egg_set_desktop_file (const char *desktop_file_path) { - egg_set_desktop_file_internal (desktop_file_path, TRUE); + egg_set_desktop_file_internal (desktop_file_path, TRUE); } /** @@ -1486,25 +1489,25 @@ egg_set_desktop_file (const char *desktop_file_path) void egg_set_desktop_file_without_defaults (const char *desktop_file_path) { - egg_set_desktop_file_internal (desktop_file_path, FALSE); + egg_set_desktop_file_internal (desktop_file_path, FALSE); } /** * egg_get_desktop_file: - * + * * Gets the application's #EggDesktopFile, as set by * egg_set_desktop_file(). - * + * * Return value: the #EggDesktopFile, or %NULL if it hasn't been set. **/ EggDesktopFile * egg_get_desktop_file (void) { - EggDesktopFile *retval; + EggDesktopFile *retval; - G_LOCK (egg_desktop_file); - retval = egg_desktop_file; - G_UNLOCK (egg_desktop_file); + G_LOCK (egg_desktop_file); + retval = egg_desktop_file; + G_UNLOCK (egg_desktop_file); - return retval; + return retval; } |