From 9aaf990960c5182602de01fe046379af7bd9627a Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Fri, 15 Nov 2013 14:40:37 -0500 Subject: [PATCH] Add g_desktop_app_info_get_implementations() This provides support for the draft addition of 'Implements=' to the Desktop Entry specification. https://bugzilla.gnome.org/show_bug.cgi?id=712391 --- gio/gdesktopappinfo.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ gio/gdesktopappinfo.h | 3 ++ 2 files changed, 86 insertions(+) diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index 0b72803..913c872 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -146,6 +146,7 @@ typedef struct GHashTable *app_names; GHashTable *mime_tweaks; GHashTable *memory_index; + GHashTable *memory_implementations; } DesktopFileDir; static DesktopFileDir *desktop_file_dirs; @@ -954,6 +955,7 @@ desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir) gpointer app, path; dir->memory_index = memory_index_new (); + dir->memory_implementations = memory_index_new (); /* Nothing to search? */ if (dir->app_names == NULL) @@ -973,6 +975,7 @@ desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir) !g_key_file_get_boolean (key_file, "Desktop Entry", "Hidden", NULL)) { /* Index the interesting keys... */ + gchar **implements; gint i; for (i = 0; i < G_N_ELEMENTS (desktop_key_match_category); i++) @@ -1006,6 +1009,12 @@ desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir) g_free (raw); } + + /* Make note of the Implements= line */ + implements = g_key_file_get_string_list (key_file, "Desktop Entry", "Implements", NULL, NULL); + for (i = 0; implements && implements[i]; i++) + memory_index_add_token (dir->memory_implementations, implements[i], 0, app); + g_strfreev (implements); } g_key_file_free (key_file); @@ -1112,6 +1121,20 @@ desktop_file_dir_unindexed_default_lookup (DesktopFileDir *dir, } } +static void +desktop_file_dir_unindexed_get_implementations (DesktopFileDir *dir, + GList **results, + const gchar *interface) +{ + MemoryIndexEntry *mie; + + if (!dir->memory_index) + desktop_file_dir_unindexed_setup_search (dir); + + for (mie = g_hash_table_lookup (dir->memory_implementations, interface); mie; mie = mie->next) + *results = g_list_prepend (*results, g_strdup (mie->app_name)); +} + /* DesktopFileDir "API" {{{2 */ /*< internal > @@ -1189,6 +1212,12 @@ desktop_file_dir_reset (DesktopFileDir *dir) dir->mime_tweaks = NULL; } + if (dir->memory_implementations) + { + g_hash_table_unref (dir->memory_implementations); + dir->memory_implementations = NULL; + } + dir->is_setup = FALSE; } @@ -1311,6 +1340,14 @@ desktop_file_dir_search (DesktopFileDir *dir, desktop_file_dir_unindexed_search (dir, search_token); } +static void +desktop_file_dir_get_implementations (DesktopFileDir *dir, + GList **results, + const gchar *interface) +{ + desktop_file_dir_unindexed_get_implementations (dir, results, interface); +} + /* Lock/unlock and global setup API {{{2 */ static void @@ -4012,6 +4049,52 @@ g_app_info_get_default_for_uri_scheme (const char *uri_scheme) /* "Get all" API {{{2 */ /** + * g_desktop_app_info_get_implementations: + * @interface: the name of the interface + * + * Gets all applications that implement @interface. + * + * An application implements an interface if that interface is listed in + * the Implements= line of the desktop file of the application. + * + * Since: 2.42 + **/ +GList * +g_desktop_app_info_get_implementations (const gchar *interface) +{ + GList *result = NULL; + GList **ptr; + gint i; + + desktop_file_dirs_lock (); + + for (i = 0; i < n_desktop_file_dirs; i++) + desktop_file_dir_get_implementations (&desktop_file_dirs[i], &result, interface); + + desktop_file_dirs_unlock (); + + ptr = &result; + while (*ptr) + { + gchar *name = (*ptr)->data; + GDesktopAppInfo *app; + + app = g_desktop_app_info_new (name); + g_free (name); + + if (app) + { + (*ptr)->data = app; + ptr = &(*ptr)->next; + } + else + *ptr = g_list_delete_link (*ptr, *ptr); + } + + return result; +} + +/** * g_desktop_app_info_search: * @search_string: the search string to use * diff --git a/gio/gdesktopappinfo.h b/gio/gdesktopappinfo.h index b9bb699..877ce5d 100644 --- a/gio/gdesktopappinfo.h +++ b/gio/gdesktopappinfo.h @@ -165,6 +165,9 @@ gboolean g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo GLIB_AVAILABLE_IN_2_40 gchar *** g_desktop_app_info_search (const gchar *search_string); +GLIB_AVAILABLE_IN_2_42 +GList *g_desktop_app_info_get_implementations (const gchar *interface); + G_END_DECLS #endif /* __G_DESKTOP_APP_INFO_H__ */ -- 2.7.4