From 8309f40d0fbda18bdc13e6eaad84827b8a026624 Mon Sep 17 00:00:00 2001 From: Sebastian Dransfeld Date: Mon, 31 Jan 2011 11:44:35 +0000 Subject: [PATCH] Check if theme has changed when building cache SVN revision: 56596 --- legacy/efreet/ChangeLog | 3 + .../efreet/src/bin/efreet_icon_cache_create.c | 172 ++++++++++++++---- legacy/efreet/src/lib/efreet_cache.c | 18 +- legacy/efreet/src/lib/efreet_cache_private.h | 4 +- legacy/efreet/src/lib/efreet_private.h | 1 - .../efreet/src/tests/efreet_icon_cache_dump.c | 2 +- 6 files changed, 145 insertions(+), 55 deletions(-) diff --git a/legacy/efreet/ChangeLog b/legacy/efreet/ChangeLog index 23aa1afd75..0c4349b5a8 100644 --- a/legacy/efreet/ChangeLog +++ b/legacy/efreet/ChangeLog @@ -46,3 +46,6 @@ * Create internal struct for theme cache +2011-01-XX Sebastian Dransfeld + + * Check if theme has changed when building cache diff --git a/legacy/efreet/src/bin/efreet_icon_cache_create.c b/legacy/efreet/src/bin/efreet_icon_cache_create.c index 75075c0fb4..c44e025c2f 100644 --- a/legacy/efreet/src/bin/efreet_icon_cache_create.c +++ b/legacy/efreet/src/bin/efreet_icon_cache_create.c @@ -302,6 +302,35 @@ cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eina_Hash *icons, Eina_H return EINA_TRUE; } +static Eina_Bool +check_changed(Efreet_Cache_Icon_Theme *theme) +{ + Eina_List *l; + const char *name; + + if (!theme) return EINA_FALSE; + + if (theme->changed) return EINA_TRUE; + if (theme->theme.inherits) + { + EINA_LIST_FOREACH(theme->theme.inherits, l, name) + { + Efreet_Cache_Icon_Theme *inherit; + + inherit = eina_hash_find(icon_themes, name); + if (!inherit) fprintf(stderr, "Theme `%s` not found for `%s`.\n", + name, theme->theme.name.internal); + if (check_changed(inherit)) return EINA_TRUE; + } + } + else if (strcmp(theme->theme.name.internal, "hicolor")) + { + theme = eina_hash_find(icon_themes, "hicolor"); + if (check_changed(theme)) return EINA_TRUE; + } + return EINA_FALSE; +} + static Efreet_Icon_Theme_Directory * icon_theme_directory_new(Efreet_Ini *ini, const char *name) { @@ -314,6 +343,7 @@ icon_theme_directory_new(Efreet_Ini *ini, const char *name) dir = NEW(Efreet_Icon_Theme_Directory, 1); if (!dir) return NULL; dir->name = eina_stringshare_add(name); + eina_array_push(strs, dir->name); efreet_ini_section_set(ini, name); @@ -369,33 +399,64 @@ icon_theme_directory_new(Efreet_Ini *ini, const char *name) return dir; } -static void +static Eina_Bool icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path) { - /* TODO: return error value */ Efreet_Ini *ini; Efreet_Icon_Theme_Directory *dir; const char *tmp; + struct stat st; + char rp[PATH_MAX]; - if (!theme || !path) return; + if (!theme || !path) return EINA_FALSE; + + if (!realpath(path, rp)) return EINA_FALSE; + + if (stat(rp, &st) < 0) return EINA_FALSE; + if (theme->path && !strcmp(theme->path, rp) && theme->last_cache_check >= (long long) st.st_mtime) + { + /* no change */ + theme->valid = 1; + return EINA_TRUE; + } + if (!theme->path || strcmp(theme->path, rp)) + { + theme->path = eina_stringshare_add(rp); + eina_array_push(strs, theme->path); + } + if ((long long) st.st_mtime > theme->last_cache_check) + theme->last_cache_check = (long long) st.st_mtime; + theme->changed = 1; ini = efreet_ini_new(path); - if (!ini) return; + if (!ini) return EINA_FALSE; if (!ini->data) { efreet_ini_free(ini); - return; + return EINA_FALSE; } efreet_ini_section_set(ini, "Icon Theme"); tmp = efreet_ini_localestring_get(ini, "Name"); - if (tmp) theme->theme.name.name = eina_stringshare_add(tmp); + if (tmp) + { + theme->theme.name.name = eina_stringshare_add(tmp); + eina_array_push(strs, theme->theme.name.name); + } tmp = efreet_ini_localestring_get(ini, "Comment"); - if (tmp) theme->theme.comment = eina_stringshare_add(tmp); + if (tmp) + { + theme->theme.comment = eina_stringshare_add(tmp); + eina_array_push(strs, theme->theme.comment); + } tmp = efreet_ini_string_get(ini, "Example"); - if (tmp) theme->theme.example_icon = eina_stringshare_add(tmp); + if (tmp) + { + theme->theme.example_icon = eina_stringshare_add(tmp); + eina_array_push(strs, theme->theme.example_icon); + } theme->hidden = efreet_ini_boolean_get(ini, "Hidden"); @@ -406,6 +467,7 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path) if (tmp) { char *t, *s, *p; + const char *i; size_t len; len = strlen(tmp) + 1; @@ -418,11 +480,15 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path) { *p = '\0'; - theme->theme.inherits = eina_list_append(theme->theme.inherits, eina_stringshare_add(s)); + i = eina_stringshare_add(s); + theme->theme.inherits = eina_list_append(theme->theme.inherits, i); + eina_array_push(strs, i); s = ++p; p = strchr(s, ','); } - theme->theme.inherits = eina_list_append(theme->theme.inherits, eina_stringshare_add(s)); + i = eina_stringshare_add(s); + theme->theme.inherits = eina_list_append(theme->theme.inherits, i); + eina_array_push(strs, i); } /* make sure this one is done last as setting the directory will change @@ -455,6 +521,8 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path) error: efreet_ini_free(ini); + + return EINA_TRUE; } static Eina_Bool @@ -472,6 +540,9 @@ cache_theme_scan(const char *dir) const char *name; const char *path; char buf[PATH_MAX]; + struct stat st; + + if (stat(entry->path, &st) < 0) continue; if ((entry->type != EINA_FILE_DIR) && (entry->type != EINA_FILE_LNK)) @@ -484,17 +555,26 @@ cache_theme_scan(const char *dir) { theme = NEW(Efreet_Cache_Icon_Theme, 1); theme->theme.name.internal = eina_stringshare_add(name); + eina_array_push(strs, theme->theme.name.internal); eina_hash_direct_add(icon_themes, (void *)theme->theme.name.internal, theme); + theme->changed = 1; + } + if ((long long) st.st_mtime > theme->last_cache_check) + { + theme->last_cache_check = (long long) st.st_mtime; + theme->changed = 1; } - path = eina_stringshare_add(entry->path); - if (!eina_list_data_find(theme->theme.paths, path)) + /* TODO: We need to handle change in order of included paths */ + if (!eina_list_search_unsorted(theme->theme.paths, EINA_COMPARE_CB(strcmp), entry->path)) + { + path = eina_stringshare_add(entry->path); theme->theme.paths = eina_list_append(theme->theme.paths, path); - else - eina_stringshare_del(path); + eina_array_push(strs, path); + theme->changed = 1; + } - theme->last_cache_check = ecore_time_unix_get(); /* we're already valid so no reason to check for an index.theme file */ if (theme->valid) continue; @@ -502,7 +582,10 @@ cache_theme_scan(const char *dir) memcpy(buf, entry->path, entry->path_length); memcpy(buf + entry->path_length, "/index.theme", sizeof("/index.theme")); if (ecore_file_exists(buf)) - icon_theme_index_read(theme, buf); + { + if (!icon_theme_index_read(theme, buf)) + theme->valid = 0; + } } eina_iterator_free(it); return EINA_TRUE; @@ -536,17 +619,12 @@ static void icon_theme_free(Efreet_Cache_Icon_Theme *theme) { void *data; - Efreet_Icon_Theme_Directory *dir; - EINA_LIST_FREE(theme->theme.paths, data) - eina_stringshare_del(data); - EINA_LIST_FREE(theme->theme.inherits, data) - eina_stringshare_del(data); - EINA_LIST_FREE(theme->theme.directories, dir) - { - eina_stringshare_del(dir->name); - free(dir); - } + eina_list_free(theme->theme.paths); + eina_list_free(theme->theme.inherits); + EINA_LIST_FREE(theme->theme.directories, data) + free(data); + if (theme->dirs) efreet_hash_free(theme->dirs, free); free(theme); } @@ -577,7 +655,8 @@ main(int argc, char **argv) Eina_Bool changed = EINA_FALSE; int lockfd = -1; int tmpfd = -1; - int i; + char **keys; + int num, i; for (i = 1; i < argc; i++) { @@ -668,6 +747,18 @@ main(int argc, char **argv) theme_version->major = EFREET_ICON_CACHE_MAJOR; theme_version->minor = EFREET_ICON_CACHE_MINOR; + keys = eet_list(theme_ef, "*", &num); + if (keys) + { + for (i = 0; i < num; i++) + { + if (!strncmp(keys[i], "efreet", 6)) continue; + theme = eet_data_read(theme_ef, theme_edd, keys[i]); + if (theme) eina_hash_direct_add(icon_themes, theme->theme.name.internal, theme); + } + free(keys); + } + /* scan themes */ cache_theme_scan(efreet_icon_deprecated_user_dir_get()); cache_theme_scan(efreet_icon_user_dir_get()); @@ -690,7 +781,7 @@ main(int argc, char **argv) cache_theme_scan("/usr/share/pixmaps"); /* scan icons */ - edd = efreet_icons_edd(EINA_TRUE); + edd = efreet_icons_edd(); it = eina_hash_iterator_data_new(icon_themes); EINA_ITERATOR_FOREACH(it, theme) { @@ -718,10 +809,16 @@ main(int argc, char **argv) if (!cache->icons) cache->icons = eina_hash_string_superfast_new(NULL); - if (!cache->dirs) - cache->dirs = eina_hash_string_superfast_new(NULL); + changed = theme->changed = check_changed(theme); + if (theme->changed && theme->dirs) + { + efreet_hash_free(theme->dirs, free); + theme->dirs = NULL; + } + if (!theme->dirs) + theme->dirs = eina_hash_string_superfast_new(NULL); - if (cache_scan(&(theme->theme), themes, cache->icons, cache->dirs, &changed)) + if (cache_scan(&(theme->theme), themes, cache->icons, theme->dirs, &changed)) { fprintf(stderr, "generated: '%s' %i (%i)\n", theme->theme.name.internal, @@ -734,7 +831,6 @@ main(int argc, char **argv) eina_hash_free(themes); efreet_hash_free(cache->icons, EINA_FREE_CB(efreet_cache_icon_free)); - efreet_hash_free(cache->dirs, free); free(cache); /* TODO: Only write if changed */ @@ -742,7 +838,7 @@ main(int argc, char **argv) } eina_iterator_free(it); - edd = efreet_icons_fallback_edd(EINA_TRUE); + edd = efreet_icons_fallback_edd(); /* read fallback icons from the eet file */ cache = eet_data_read(icon_ef, edd, EFREET_CACHE_ICON_FALLBACK); @@ -759,11 +855,14 @@ main(int argc, char **argv) if (!cache->icons) cache->icons = eina_hash_string_superfast_new(NULL); - if (!cache->dirs) - cache->dirs = eina_hash_string_superfast_new(NULL); + theme = eet_data_read(theme_ef, theme_edd, EFREET_CACHE_ICON_FALLBACK); + if (!theme) + theme = NEW(Efreet_Cache_Icon_Theme, 1); + if (!theme->dirs) + theme->dirs = eina_hash_string_superfast_new(NULL); /* Save fallback in the right part */ - if (cache_fallback_scan(cache->icons, cache->dirs, &changed)) + if (cache_fallback_scan(cache->icons, theme->dirs, &changed)) { fprintf(stderr, "generated: fallback %i (%i)\n", changed, eina_hash_population(cache->icons)); if (changed) @@ -771,7 +870,6 @@ main(int argc, char **argv) } efreet_hash_free(cache->icons, EINA_FREE_CB(efreet_cache_icon_fallback_free)); - efreet_hash_free(cache->dirs, free); free(cache); eina_hash_free(icon_themes); diff --git a/legacy/efreet/src/lib/efreet_cache.c b/legacy/efreet/src/lib/efreet_cache.c index 5dbe4ea8a1..55de4df1bc 100644 --- a/legacy/efreet/src/lib/efreet_cache.c +++ b/legacy/efreet/src/lib/efreet_cache.c @@ -384,7 +384,6 @@ _efreet_cache_free(Efreet_Cache_Icons *c) if (!c) return NULL; if (c->icons) efreet_hash_free(c->icons, EINA_FREE_CB(efreet_cache_icon_free)); - if (c->dirs) efreet_hash_free(c->dirs, free); free(c); return NULL; @@ -396,7 +395,6 @@ _efreet_cache_fallback_free(Efreet_Cache_Icons *c) if (!c) return NULL; if (c->icons) efreet_hash_free(c->icons, EINA_FREE_CB(efreet_cache_icon_fallback_free)); - if (c->dirs) efreet_hash_free(c->dirs, free); free(c); return NULL; @@ -423,7 +421,7 @@ efreet_icon_directory_edd(void) * Needs EAPI because of helper binaries */ EAPI Eet_Data_Descriptor * -efreet_icons_edd(Eina_Bool include_dirs) +efreet_icons_edd(void) { Eet_Data_Descriptor_Class eddc; @@ -464,10 +462,6 @@ efreet_icons_edd(Eina_Bool include_dirs) EET_DATA_DESCRIPTOR_ADD_HASH(icons_edd, Efreet_Cache_Icons, "icons", icons, icon_edd); - if (include_dirs) - EET_DATA_DESCRIPTOR_ADD_HASH(icons_edd, Efreet_Cache_Icons, - "dirs", dirs, efreet_icon_directory_edd()); - return icons_edd; } @@ -539,7 +533,7 @@ efreet_icon_theme_edd(Eina_Bool cache) * Needs EAPI because of helper binaries */ EAPI Eet_Data_Descriptor * -efreet_icons_fallback_edd(Eina_Bool include_dirs) +efreet_icons_fallback_edd(void) { Eet_Data_Descriptor_Class eddc; @@ -559,10 +553,6 @@ efreet_icons_fallback_edd(Eina_Bool include_dirs) EET_DATA_DESCRIPTOR_ADD_HASH(fallback_edd, Efreet_Cache_Icons, "icons", icons, icon_fallback_edd); - if (include_dirs) - EET_DATA_DESCRIPTOR_ADD_HASH(fallback_edd, Efreet_Cache_Icons, - "dirs", dirs, efreet_icon_directory_edd()); - return fallback_edd; } @@ -651,7 +641,7 @@ efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon) if (!theme_name) { INFO("loading theme %s", theme->name.internal); - theme_cache = eet_data_read(icon_cache, efreet_icons_edd(EINA_FALSE), theme->name.internal); + theme_cache = eet_data_read(icon_cache, efreet_icons_edd(), theme->name.internal); if (theme_cache && !theme_cache->icons) theme_cache->icons = eina_hash_string_superfast_new(NULL); if (theme_cache) @@ -671,7 +661,7 @@ efreet_cache_icon_fallback_find(const char *icon) if (!fallback_cache) { INFO("loading fallback cache"); - fallback_cache = eet_data_read(icon_cache, efreet_icons_fallback_edd(EINA_FALSE), EFREET_CACHE_ICON_FALLBACK); + fallback_cache = eet_data_read(icon_cache, efreet_icons_fallback_edd(), EFREET_CACHE_ICON_FALLBACK); if (fallback_cache && !fallback_cache->icons) fallback_cache->icons = eina_hash_string_superfast_new(NULL); } diff --git a/legacy/efreet/src/lib/efreet_cache_private.h b/legacy/efreet/src/lib/efreet_cache_private.h index 1add8f83ba..8db044fe41 100644 --- a/legacy/efreet/src/lib/efreet_cache_private.h +++ b/legacy/efreet/src/lib/efreet_cache_private.h @@ -13,8 +13,8 @@ EAPI Eet_Data_Descriptor *efreet_hash_array_string_edd(void); EAPI Eet_Data_Descriptor *efreet_hash_string_edd(void); EAPI Eet_Data_Descriptor *efreet_array_string_edd(void); EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(Eina_Bool cache); -EAPI Eet_Data_Descriptor *efreet_icons_edd(Eina_Bool include_dirs); -EAPI Eet_Data_Descriptor *efreet_icons_fallback_edd(Eina_Bool include_dirs); +EAPI Eet_Data_Descriptor *efreet_icons_edd(void); +EAPI Eet_Data_Descriptor *efreet_icons_fallback_edd(void); typedef struct Efreet_Cache_Icon_Theme Efreet_Cache_Icon_Theme; diff --git a/legacy/efreet/src/lib/efreet_private.h b/legacy/efreet/src/lib/efreet_private.h index 9743834f2f..e1b212b881 100644 --- a/legacy/efreet/src/lib/efreet_private.h +++ b/legacy/efreet/src/lib/efreet_private.h @@ -133,7 +133,6 @@ typedef struct _Efreet_Cache_Fallback_Icon Efreet_Cache_Fallback_Icon; struct _Efreet_Cache_Icons { Eina_Hash *icons; - Eina_Hash *dirs; }; struct _Efreet_Cache_Directory diff --git a/legacy/efreet/src/tests/efreet_icon_cache_dump.c b/legacy/efreet/src/tests/efreet_icon_cache_dump.c index da6291c3ba..8f22468c4b 100644 --- a/legacy/efreet/src/tests/efreet_icon_cache_dump.c +++ b/legacy/efreet/src/tests/efreet_icon_cache_dump.c @@ -82,7 +82,7 @@ main(int argc, char **argv) theme_ef = eet_open(efreet_icon_theme_cache_file(), EET_FILE_MODE_READ); if (!theme_ef) return -1; - edd = efreet_icons_edd(EINA_FALSE); + edd = efreet_icons_edd(); if (!edd) return -1; if (argc > 1)