From: Alexander Larsson Date: Mon, 3 Feb 2020 09:00:17 +0000 (+0100) Subject: icon-cache: Add new function to list all the icons in a directory X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~20^2~113^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0a8d7603ea7448d80e5d1c39bdeb050d7ca926d8;p=gtk4.git icon-cache: Add new function to list all the icons in a directory This lists the icons in a particular director, with their flags in a hashtable. We also convert from "icon.symbolic" + SUFFIX_PNG to "icon" + SUFFIX_SYMBOLIC_PNG. --- diff --git a/gtk/gtkiconcache.c b/gtk/gtkiconcache.c index bcbfe83071..bc238e0028 100644 --- a/gtk/gtkiconcache.c +++ b/gtk/gtkiconcache.c @@ -43,6 +43,18 @@ #define GET_UINT16(cache, offset) (GUINT16_FROM_BE (*(guint16 *)((cache) + (offset)))) #define GET_UINT32(cache, offset) (GUINT32_FROM_BE (*(guint32 *)((cache) + (offset)))) +/* Keep in sync with gtkicontheme.c */ +typedef enum +{ + /* These are used in the file format: */ + ICON_SUFFIX_NONE = 0, + ICON_SUFFIX_XPM = 1 << 0, + ICON_SUFFIX_SVG = 1 << 1, + ICON_SUFFIX_PNG = 1 << 2, + HAS_ICON_FILE = 1 << 3, + /* This is just used by Gtk, so we convert internally to this: */ + ICON_SUFFIX_SYMBOLIC_PNG = 1 << 4 +} IconSuffix; struct _GtkIconCache { gint ref_count; @@ -334,6 +346,78 @@ gtk_icon_cache_has_icons (GtkIconCache *cache, return FALSE; } +GHashTable * +gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache, + const gchar *directory) +{ + gint directory_index; + guint32 hash_offset, n_buckets; + guint32 chain_offset; + guint32 image_list_offset, n_images; + int i, j; + GHashTable *icons = NULL; + + directory_index = get_directory_index (cache, directory); + + if (directory_index == -1) + return NULL; + + hash_offset = GET_UINT32 (cache->buffer, 4); + n_buckets = GET_UINT32 (cache->buffer, hash_offset); + + for (i = 0; i < n_buckets; i++) + { + chain_offset = GET_UINT32 (cache->buffer, hash_offset + 4 + 4 * i); + while (chain_offset != 0xffffffff) + { + guint32 flags = 0; + + image_list_offset = GET_UINT32 (cache->buffer, chain_offset + 8); + n_images = GET_UINT32 (cache->buffer, image_list_offset); + + for (j = 0; j < n_images; j++) + { + if (GET_UINT16 (cache->buffer, image_list_offset + 4 + 8 * j) == + directory_index) + { + flags = GET_UINT16 (cache->buffer, image_list_offset + 4 + 8 * j + 2); + break; + } + } + + if (flags != 0) + { + guint32 name_offset = GET_UINT32 (cache->buffer, chain_offset + 4); + const char *name = cache->buffer + name_offset; + char *converted_name; + guint32 hash_flags = 0; + + /* Icons named foo.symbolic.png are stored in the cache as "foo.symbolic" with ICON_SUFFIX_PNG, + * but we convert it internally to ICON_SUFFIX_SYMBOLIC_PNG. + * Otherwise we use the same enum values and names as on disk. */ + if (g_str_has_suffix (name, ".symbolic") && (flags & ICON_SUFFIX_PNG) != 0) + { + flags |= ICON_SUFFIX_SYMBOLIC_PNG; + flags &= ~ICON_SUFFIX_PNG; + converted_name = g_strndup (name, strlen(name) - 9); + } + else + converted_name = g_strdup (name); + + if (!icons) + icons = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + hash_flags = GPOINTER_TO_INT (g_hash_table_lookup (icons, converted_name)); + g_hash_table_replace (icons, converted_name, GUINT_TO_POINTER (hash_flags|flags)); + } + + chain_offset = GET_UINT32 (cache->buffer, chain_offset); + } + } + + return icons; +} + void gtk_icon_cache_add_icons (GtkIconCache *cache, const gchar *directory, diff --git a/gtk/gtkiconcacheprivate.h b/gtk/gtkiconcacheprivate.h index 08e581fe9a..2f73891e6b 100644 --- a/gtk/gtkiconcacheprivate.h +++ b/gtk/gtkiconcacheprivate.h @@ -32,6 +32,8 @@ gboolean gtk_icon_cache_has_icon (GtkIconCache *cache, gboolean gtk_icon_cache_has_icon_in_directory (GtkIconCache *cache, const gchar *icon_name, const gchar *directory); +GHashTable *gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache, + const gchar *directory); gboolean gtk_icon_cache_has_icons (GtkIconCache *cache, const gchar *directory); void gtk_icon_cache_add_icons (GtkIconCache *cache, diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index d437094063..ae33375bce 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -167,6 +167,7 @@ typedef enum } IconThemeDirType; /* In reverse search order: */ +/* Keep in sync with gtkiconcache.c */ typedef enum { ICON_SUFFIX_NONE = 0,