diff --git a/ChangeLog b/ChangeLog index 00a191de9f..1313293b74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2004-10-21 Matthias Clasen + + * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for + cached themes. + + * gtk/gtkiconcache.h: + * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function. + + * gtk/updateiconcache.c (scan_directory): Don't skip .icon + files which are listed before their images. + (foreach_remove_func): Instead filter lonely .icon files out + here. + + * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out + the HAS_ICON_FILE flag. + 2004-10-21 Matthias Clasen * gtk/gtkiconcache.c: Make it compile without mmap() and diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 00a191de9f..1313293b74 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,19 @@ +2004-10-21 Matthias Clasen + + * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for + cached themes. + + * gtk/gtkiconcache.h: + * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function. + + * gtk/updateiconcache.c (scan_directory): Don't skip .icon + files which are listed before their images. + (foreach_remove_func): Instead filter lonely .icon files out + here. + + * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out + the HAS_ICON_FILE flag. + 2004-10-21 Matthias Clasen * gtk/gtkiconcache.c: Make it compile without mmap() and diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 00a191de9f..1313293b74 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,19 @@ +2004-10-21 Matthias Clasen + + * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for + cached themes. + + * gtk/gtkiconcache.h: + * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function. + + * gtk/updateiconcache.c (scan_directory): Don't skip .icon + files which are listed before their images. + (foreach_remove_func): Instead filter lonely .icon files out + here. + + * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out + the HAS_ICON_FILE flag. + 2004-10-21 Matthias Clasen * gtk/gtkiconcache.c: Make it compile without mmap() and diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 00a191de9f..1313293b74 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,19 @@ +2004-10-21 Matthias Clasen + + * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for + cached themes. + + * gtk/gtkiconcache.h: + * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function. + + * gtk/updateiconcache.c (scan_directory): Don't skip .icon + files which are listed before their images. + (foreach_remove_func): Instead filter lonely .icon files out + here. + + * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out + the HAS_ICON_FILE flag. + 2004-10-21 Matthias Clasen * gtk/gtkiconcache.c: Make it compile without mmap() and diff --git a/gtk/gtkiconcache.c b/gtk/gtkiconcache.c index 7aca03eac0..5175787c7c 100644 --- a/gtk/gtkiconcache.c +++ b/gtk/gtkiconcache.c @@ -50,7 +50,6 @@ GtkIconCache * _gtk_icon_cache_ref (GtkIconCache *cache) { cache->ref_count ++; - return cache; } @@ -141,7 +140,6 @@ _gtk_icon_cache_new_for_path (const gchar *path) cache->ref_count = 1; cache->buffer = buffer; cache->size = st.st_size; - done: g_free (cache_filename); close (fd); @@ -282,6 +280,36 @@ _gtk_icon_cache_add_icons (GtkIconCache *cache, chain_offset = GET_UINT32 (cache->buffer, chain_offset); } - } - + } } + +gboolean +_gtk_icon_cache_has_icon (GtkIconCache *cache, + const gchar *icon_name) +{ + guint32 hash_offset; + guint32 n_buckets; + guint32 chain_offset; + gint hash; + + hash_offset = GET_UINT32 (cache->buffer, 4); + n_buckets = GET_UINT32 (cache->buffer, hash_offset); + + hash = icon_name_hash (icon_name) % n_buckets; + + chain_offset = GET_UINT32 (cache->buffer, hash_offset + 4 + 4 * hash); + while (chain_offset != 0xffffffff) + { + guint32 name_offset = GET_UINT32 (cache->buffer, chain_offset + 4); + gchar *name = cache->buffer + name_offset; + + if (strcmp (name, icon_name) == 0) + return TRUE; + + chain_offset = GET_UINT32 (cache->buffer, chain_offset); + } + + return FALSE; +} + + diff --git a/gtk/gtkiconcache.h b/gtk/gtkiconcache.h index ee9d48aeb3..010ebfe939 100644 --- a/gtk/gtkiconcache.h +++ b/gtk/gtkiconcache.h @@ -26,6 +26,8 @@ typedef struct _GtkIconCache GtkIconCache; GtkIconCache *_gtk_icon_cache_new_for_path (const gchar *path); gboolean _gtk_icon_cache_has_directory (GtkIconCache *cache, const gchar *directory); +gboolean _gtk_icon_cache_has_icon (GtkIconCache *cache, + const gchar *icon_name); void _gtk_icon_cache_add_icons (GtkIconCache *cache, const gchar *directory, GHashTable *hash_table); diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index 7b428bcf9f..1b9e9a6998 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -1322,6 +1322,27 @@ gtk_icon_theme_load_icon (GtkIconTheme *icon_theme, return pixbuf; } +typedef struct +{ + const gchar *icon_name; + gboolean found; +} CacheSearch; + +static void +cache_has_icon (gpointer key, + gpointer value, + gpointer user_data) +{ + GtkIconCache *cache = (GtkIconCache *)value; + CacheSearch *search = (CacheSearch *)user_data; + + if (!cache || search->found) + return; + + if (_gtk_icon_cache_has_icon (cache, search->icon_name)) + search->found = TRUE; +} + /** * gtk_icon_theme_has_icon: * @icon_theme: a #GtkIconTheme @@ -1340,6 +1361,8 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme, const char *icon_name) { GtkIconThemePrivate *priv; + GList *l; + CacheSearch search; g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), FALSE); @@ -1347,6 +1370,27 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme, ensure_valid_themes (icon_theme); + search.icon_name = icon_name; + search.found = FALSE; + + for (l = priv->themes; l; l = l->next) + { + IconTheme *theme = (IconTheme *)l->data; + + g_hash_table_foreach (theme->icon_caches, cache_has_icon, &search); + + if (search.found) + return TRUE; + } + + for (l = priv->unthemed_icons_caches; l; l = l->next) + { + GtkIconCache *cache = (GtkIconCache *)l->data; + + if (_gtk_icon_cache_has_icon (cache, icon_name)) + return TRUE; + } + if (g_hash_table_lookup_extended (priv->all_icons, icon_name, NULL, NULL)) return TRUE; @@ -1741,9 +1785,9 @@ theme_dir_get_icon_suffix (IconThemeDir *dir, dir->subdir); if (has_icon_file) - { - *has_icon_file = suffix & HAS_ICON_FILE; - } + *has_icon_file = suffix & HAS_ICON_FILE; + + suffix = suffix & ~HAS_ICON_FILE; } else suffix = GPOINTER_TO_UINT (g_hash_table_lookup (dir->icons, icon_name)); diff --git a/gtk/updateiconcache.c b/gtk/updateiconcache.c index e6957cff68..4bf31ec656 100644 --- a/gtk/updateiconcache.c +++ b/gtk/updateiconcache.c @@ -81,10 +81,19 @@ typedef struct static gboolean foreach_remove_func (gpointer key, gpointer value, gpointer user_data) { + Image *image = (Image *)value; GHashTable *files = user_data; GList *list; - gboolean free_key = FALSE;; - + gboolean free_key = FALSE; + + if (image->flags == HAS_ICON_FILE) + { + g_free (key); + g_free (image); + + return TRUE; + } + list = g_hash_table_lookup (files, key); if (list) free_key = TRUE; @@ -171,7 +180,7 @@ scan_directory (const gchar *base_path, image = g_hash_table_lookup (dir_hash, basename); if (image) image->flags |= flags; - else if ((flags & HAS_ICON_FILE) != HAS_ICON_FILE) + else { if (!dir_added) {