From a90e2e4aff365fee7ccad5188b1fe056ba34536f Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 26 Nov 2010 14:56:23 +0000 Subject: [PATCH] * efreet: improve icon cache, increase speed and consume a little more memory than previous version. TODO: efreet_icon_cache_create could be speeded up if we did reuse already generated theme instead when doing inherit work. NOTE: Let me add a rant against Freedesktop standard. Walking around 22731 paths for 3051 icons is insane and that's just for one theme ! Maybe they could give me one SSD... SVN revision: 55018 --- .../src/bin/efreet_desktop_cache_create.c | 25 +- .../efreet/src/bin/efreet_icon_cache_create.c | 663 +++++++++--------- .../efreet/src/bin/efreet_icon_cache_dump.c | 123 ++-- legacy/efreet/src/lib/efreet_cache.c | 513 ++++++++------ legacy/efreet/src/lib/efreet_icon.c | 267 +++---- legacy/efreet/src/lib/efreet_private.h | 75 +- 6 files changed, 913 insertions(+), 753 deletions(-) diff --git a/legacy/efreet/src/bin/efreet_desktop_cache_create.c b/legacy/efreet/src/bin/efreet_desktop_cache_create.c index 0778da2de5..7c9328b4fd 100644 --- a/legacy/efreet/src/bin/efreet_desktop_cache_create.c +++ b/legacy/efreet/src/bin/efreet_desktop_cache_create.c @@ -31,7 +31,7 @@ static char file[PATH_MAX] = { '\0' }; static char util_file[PATH_MAX] = { '\0' }; static void -term_handler (int sig, siginfo_t * info, void *data) +term_handler(int sig __UNUSED__, siginfo_t * info __UNUSED__, void *data __UNUSED__) { if (util_file[0]) unlink(util_file); if (file[0]) unlink(file); @@ -39,6 +39,19 @@ term_handler (int sig, siginfo_t * info, void *data) exit(1); } +static void +catch_sigterm(void) +{ + struct sigaction act; + + act.sa_sigaction = term_handler; + act.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset(&act.sa_mask); + + if (sigaction(SIGTERM, &act, NULL) < 0) + perror("sigaction"); /* It's bad if we can't deal with SIGTERM, but not dramatic */ +} + static int strcmplen(const void *data1, const void *data2) { @@ -248,15 +261,7 @@ main(int argc, char **argv) if (!ecore_init()) goto ecore_error; // Trap SIGTERM for clean shutdown - act.sa_sigaction = term_handler; - act.sa_flags = SA_RESTART | SA_SIGINFO; - sigemptyset(&act.sa_mask); - - if (sigaction(SIGTERM, &act, NULL) < 0) - { - perror("sigaction"); - goto efreet_error; - } + catch_sigterm(); efreet_cache_update = 0; diff --git a/legacy/efreet/src/bin/efreet_icon_cache_create.c b/legacy/efreet/src/bin/efreet_icon_cache_create.c index 4fe4f90358..bd603704de 100644 --- a/legacy/efreet/src/bin/efreet_icon_cache_create.c +++ b/legacy/efreet/src/bin/efreet_icon_cache_create.c @@ -18,75 +18,83 @@ #include "Efreet.h" #include "efreet_private.h" -static Eet_Data_Descriptor *edd = NULL; -static Eet_Data_Descriptor *fallback_edd = NULL; - -static Eina_List *extensions; +static const char *exts[] = { ".png", ".xpm", ".svg", NULL }; static int verbose = 0; -static char file[PATH_MAX] = { '\0' }; - -static void -term_handler (int sig, siginfo_t * info, void *data) +static Eina_Bool +_cache_extention_lookup(const char *ext) { - if (file[0]) unlink(file); - if (verbose) printf("EXIT\n"); - exit(1); + unsigned int i; + + for (i = 0; exts[i]; ++i) + if (!strcmp(exts[i], ext)) + return EINA_TRUE; + return EINA_FALSE; } -static int -cache_fallback_scan_dir(Eet_File *ef, Eina_Hash *dirs, const char *dir, int *changed) +static Eina_Bool +cache_fallback_scan_dir(Eina_Hash *icons, Eina_Hash *dirs, const char *dir, Eina_Bool *changed) { Eina_Iterator *it; - const char *ext, *ent; + Eina_File_Direct_Info *entry; if (eina_hash_find(dirs, dir)) return 1; eina_hash_add(dirs, dir, (void *)-1); - it = eina_file_ls(dir); + it = eina_file_stat_ls(dir); if (!it) return 1; - EINA_ITERATOR_FOREACH(it, ent) - { - Efreet_Cache_Icon *icon; - char *name, *tmp; - ext = strrchr(ent, '.'); - if (!ext) continue; - ext = eina_stringshare_add(ext); - if (!eina_list_data_find(extensions, ext)) - { - eina_stringshare_del(ext); - continue; - } - /* icon with known extension */ - name = strdup(ecore_file_file_get(ent)); - tmp = strrchr(name, '.'); - if (tmp) *tmp = '\0'; - icon = eet_data_read(ef, fallback_edd, name); - if (!icon) - { - icon = NEW(Efreet_Cache_Icon, 1); - icon->free = 1; - icon->fallback = 1; - icon->theme = NULL; - } + EINA_ITERATOR_FOREACH(it, entry) + { + Efreet_Cache_Fallback_Icon *icon; + char *name; + char *ext; + unsigned int i; + + if (entry->type == EINA_FILE_DIR) + continue; + + ext = strrchr(entry->path + entry->name_start, '.'); + if (!ext || !_cache_extention_lookup(ext)) + continue; + + /* icon with known extension */ + name = entry->path + entry->name_start; + *ext = '\0'; + + icon = eina_hash_find(icons, name); + if (!icon) + { + icon = NEW(Efreet_Cache_Fallback_Icon, 1); + icon->free = 1; + icon->theme = NULL; + eina_hash_add(icons, name, icon); + } + + *ext = '.'; + + for (i = 0; i < icon->icons_count; ++i) + if (!strcmp(icon->icons[i], entry->path)) + break; + + if (i != icon->icons_count) + continue ; + + /* we don't really track path deat here, so we will leak... */ + icon->icons = realloc(icon->icons, sizeof (char *) * (icon->icons_count + 1)); + icon->icons[icon->icons_count++] = eina_stringshare_add(entry->path); + + *changed = EINA_TRUE; + } - icon->icons = eina_list_append(icon->icons, eina_stringshare_ref(ent)); - if (!eet_data_write(ef, fallback_edd, name, icon, 1)) - { - free(name); - break; - } - efreet_cache_icon_free(icon); - free(name); - } eina_iterator_free(it); + return 1; } -static int -cache_fallback_scan(Eet_File *ef, int *changed) +static Eina_Bool +cache_fallback_scan(Eina_Hash *icons, Eina_Bool *changed) { Eina_List *xdg_dirs, *l; const char *dir; @@ -94,123 +102,144 @@ cache_fallback_scan(Eet_File *ef, int *changed) Eina_Hash *dirs; dirs = eina_hash_string_superfast_new(NULL); - cache_fallback_scan_dir(ef, dirs, efreet_icon_deprecated_user_dir_get(), changed); - cache_fallback_scan_dir(ef, dirs, efreet_icon_user_dir_get(), changed); + + cache_fallback_scan_dir(icons, dirs, efreet_icon_deprecated_user_dir_get(), changed); + cache_fallback_scan_dir(icons, dirs, efreet_icon_user_dir_get(), changed); xdg_dirs = efreet_data_dirs_get(); EINA_LIST_FOREACH(xdg_dirs, l, dir) { snprintf(path, sizeof(path), "%s/icons", dir); - cache_fallback_scan_dir(ef, dirs, path, changed); + cache_fallback_scan_dir(icons, dirs, path, changed); } #ifndef STRICT_SPEC EINA_LIST_FOREACH(xdg_dirs, l, dir) { snprintf(path, sizeof(path), "%s/pixmaps", dir); - cache_fallback_scan_dir(ef, dirs, path, changed); + cache_fallback_scan_dir(icons, dirs, path, changed); } #endif - cache_fallback_scan_dir(ef, dirs, "/usr/share/pixmaps", changed); + cache_fallback_scan_dir(icons, dirs, "/usr/share/pixmaps", changed); + eina_hash_free(dirs); return 1; } -static int -cache_scan_path_dir(Efreet_Icon_Theme *theme, const char *path, Efreet_Icon_Theme_Directory *dir, Eet_File *ef, int *changed) +static Eina_Bool +cache_scan_path_dir(Efreet_Icon_Theme *theme, + const char *path, + Efreet_Icon_Theme_Directory *dir, + Eina_Hash *icons, + Eina_Bool *changed) { Eina_Iterator *it; char buf[PATH_MAX]; - const char *ext, *ent; + Eina_File_Direct_Info *entry; snprintf(buf, sizeof(buf), "%s/%s", path, dir->name); - it = eina_file_ls(buf); + + it = eina_file_stat_ls(buf); if (!it) return 1; - EINA_ITERATOR_FOREACH(it, ent) - { - Eina_List *l; - Efreet_Cache_Icon *icon; - Efreet_Cache_Icon_Element *elem = NULL, *oelem = NULL; - char *name, *tmp; - ext = strrchr(ent, '.'); - if (!ext) continue; - ext = eina_stringshare_add(ext); - if (!eina_list_data_find(extensions, ext)) - { - eina_stringshare_del(ext); - continue; - } - /* icon with known extension */ - name = strdup(ecore_file_file_get(ent)); - tmp = strrchr(name, '.'); - if (tmp) *tmp = '\0'; - icon = eet_data_read(ef, edd, name); - if (!icon) - { - icon = NEW(Efreet_Cache_Icon, 1); - icon->free = 1; - icon->theme = eina_stringshare_add(theme->name.internal); - } - else if (strcmp(icon->theme, theme->name.internal)) - { - /* We got this icon from a parent theme */ - free(name); - continue; - } + EINA_ITERATOR_FOREACH(it, entry) + { + Efreet_Cache_Icon *icon; + char *name; + char *ext; + unsigned int i; - /* find if we have the same icon in another type */ - EINA_LIST_FOREACH(icon->icons, l, oelem) - { - if ((oelem->type == dir->type) && - (oelem->size.normal == dir->size.normal) && - (oelem->size.max == dir->size.max) && - (oelem->size.min == dir->size.min)) - { - elem = oelem; + if (entry->type == EINA_FILE_DIR) + continue; + + ext = strrchr(entry->path + entry->name_start, '.'); + if (!ext || !_cache_extention_lookup(ext)) + continue; + + /* icon with known extension */ + name = entry->path + entry->name_start; + *ext = '\0'; + + icon = eina_hash_find(icons, name); + if (!icon) + { + icon = NEW(Efreet_Cache_Icon, 1); + icon->free = 1; + icon->theme = eina_stringshare_add(theme->name.internal); + eina_hash_add(icons, name, icon); + } + else if (icon->theme && strcmp(icon->theme, theme->name.internal)) + { + /* We got this icon from a parent theme */ + continue; + } + + /* find if we have the same icon in another type */ + for (i = 0; i < icon->icons_count; ++i) + { + if ((icon->icons[i]->type == dir->type) && + (icon->icons[i]->normal == dir->size.normal) && + (icon->icons[i]->max == dir->size.max) && + (icon->icons[i]->min == dir->size.min)) break; - } - } - if (elem) - { - elem->paths = eina_list_append(elem->paths, eina_stringshare_ref(ent)); - } - else - { - elem = NEW(Efreet_Cache_Icon_Element, 1); - elem->paths = eina_list_append(elem->paths, eina_stringshare_ref(ent)); - elem->type = dir->type; - elem->size.normal = dir->size.normal; - elem->size.min = dir->size.min; - elem->size.max = dir->size.max; - icon->icons = eina_list_append(icon->icons, elem); - } - if (!eet_data_write(ef, edd, name, icon, 1)) - { - free(name); - break; - } - efreet_cache_icon_free(icon); - free(name); - } + } + + *ext = '.'; + + if (i != icon->icons_count) + { + unsigned int j; + + /* check if the path already exist */ + for (j = 0; j < icon->icons[i]->paths_count; ++j) + if (!strcmp(icon->icons[i]->paths[j], entry->path)) + break ; + + if (j != icon->icons[i]->paths_count) + continue ; + } + /* no icon match so add a new one */ + else + { + icon->icons = realloc(icon->icons, + sizeof (Efreet_Cache_Icon_Element*) * (++icon->icons_count)); + icon->icons[i] = NEW(Efreet_Cache_Icon_Element, 1); + icon->icons[i]->type = dir->type; + icon->icons[i]->normal = dir->size.normal; + icon->icons[i]->min = dir->size.min; + icon->icons[i]->max = dir->size.max; + icon->icons[i]->paths = NULL; + icon->icons[i]->paths_count = 0; + } + + /* and finally store the path */ + icon->icons[i]->paths = realloc(icon->icons[i]->paths, + sizeof (char*) * (icon->icons[i]->paths_count + 1)); + icon->icons[i]->paths[icon->icons[i]->paths_count++] = eina_stringshare_add(entry->path); + + *changed = EINA_TRUE; + } + eina_iterator_free(it); + return 1; } static int -cache_scan_path(Efreet_Icon_Theme *theme, const char *path, Eet_File *ef, int *changed) +cache_scan_path(Efreet_Icon_Theme *theme, Eina_Hash *icons, const char *path, Eina_Bool *changed) { Eina_List *l; Efreet_Icon_Theme_Directory *dir; EINA_LIST_FOREACH(theme->directories, l, dir) - if (!cache_scan_path_dir(theme, path, dir, ef, changed)) return 0; + if (!cache_scan_path_dir(theme, path, dir, icons, changed)) return 0; + return 1; } -static int -cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eet_File *ef, int *changed) +static Eina_Bool +cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eina_Hash *icons, Eina_Bool *changed) { Eina_List *l; const char *path; @@ -219,29 +248,76 @@ cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eet_File *ef, int *chang if (!theme) return 1; if (eina_hash_find(themes, theme->name.internal)) return 1; eina_hash_direct_add(themes, theme->name.internal, theme); - /* TODO: Maybe always read entry from eet, so when can check changed */ /* scan theme */ EINA_LIST_FOREACH(theme->paths, l, path) - if (!cache_scan_path(theme, path, ef, changed)) return 0; + if (!cache_scan_path(theme, icons, path, changed)) return 0; /* scan inherits */ if (theme->inherits) - { - EINA_LIST_FOREACH(theme->inherits, l, name) - { - theme = efreet_icon_theme_find(name); - if (!cache_scan(theme, themes, ef, changed)) return 0; - } - } + { + EINA_LIST_FOREACH(theme->inherits, l, name) + { + Efreet_Icon_Theme *inherit; + + inherit = efreet_icon_theme_find(name); + if (!inherit) fprintf(stderr, "Theme `%s` not found for `%s`.\n", + name, theme->name.internal); + if (!cache_scan(inherit, themes, icons, changed)) return 0; + } + } else if (strcmp(theme->name.internal, "hicolor")) - { - theme = efreet_icon_theme_find("hicolor"); - if (!cache_scan(theme, themes, ef, changed)) return 0; - } + { + theme = efreet_icon_theme_find("hicolor"); + if (!cache_scan(theme, themes, icons, changed)) return 0; + } + return 1; } +static int +cache_lock_file(void) +{ + char file[PATH_MAX]; + struct flock fl; + int lockfd; + + snprintf(file, sizeof(file), "%s/.efreet/icon_data.lock", efreet_home_dir_get()); + lockfd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (lockfd < 0) return -1; + + memset(&fl, 0, sizeof(struct flock)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + if (fcntl(lockfd, F_SETLK, &fl) < 0) + { + if (verbose) printf("LOCKED! You may want to delete %s if this persists\n", file); + close(lockfd); + return -1; + } + + return lockfd; +} + +static void +term_handler(int sig __UNUSED__, siginfo_t * info __UNUSED__, void *data __UNUSED__) +{ +} + +/* prevent early death */ +static void +catch_sigterm(void) +{ + struct sigaction act; + + act.sa_sigaction = term_handler; + act.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset(&act.sa_mask); + + if (sigaction(SIGTERM, &act, NULL) < 0) + perror("sigaction"); /* It's bad if we can't deal with SIGTERM, but not dramatic */ +} + int main(int argc, char **argv) { @@ -252,233 +328,170 @@ main(int argc, char **argv) * - pass extra dirs to binary, and read them * - make sure programs with different extra dirs all work together */ - Eet_File *ef; - Eina_List *l = NULL; - Efreet_Icon_Theme *theme; - char *dir = NULL; - int lockfd = -1, tmpfd; - int changed = 0; - int i; - struct flock fl; - const char *exts[] = { ".png", ".xpm", ".svg", NULL }; - struct sigaction act; + Efreet_Cache_Theme *cache; + Efreet_Icon_Theme *theme; + Eet_Data_Descriptor *edd; + Eet_File *ef; + Eina_List *l = NULL; + char file[PATH_MAX]; + char *dir = NULL; + Eina_Bool changed = EINA_FALSE; + int lockfd = -1; + int i; - for (i = 1; i < argc; i++) - { + for (i = 1; i < argc; i++) + { if (!strcmp(argv[i], "-v")) verbose = 1; else if ((!strcmp(argv[i], "-h")) || (!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "--h")) || (!strcmp(argv[i], "--help"))) - { - printf("Options:\n"); - printf(" -v Verbose mode\n"); - exit(0); - } - } - /* init external subsystems */ - if (!eina_init()) goto eina_error; - if (!eet_init()) goto eet_error; - if (!ecore_init()) goto ecore_error; + { + printf("Options:\n"); + printf(" -v Verbose mode\n"); + exit(0); + } + } - // Trap SIGTERM for clean shutdown - act.sa_sigaction = term_handler; - act.sa_flags = SA_RESTART | SA_SIGINFO; - sigemptyset(&act.sa_mask); - - if (sigaction(SIGTERM, &act, NULL) < 0) - { - perror("sigaction"); - goto efreet_error; - } - - for (i = 0; exts[i]; i++) - extensions = eina_list_append(extensions, eina_stringshare_add(exts[i])); + /* init external subsystems */ + if (!eina_init()) return -1; + if (!eet_init()) return -1; + if (!ecore_init()) return -1; efreet_cache_update = 0; + /* FIXME: should be in cache dir maybe */ /* create homedir */ snprintf(file, sizeof(file), "%s/.efreet", efreet_home_dir_get()); - if (!ecore_file_mkpath(file)) goto efreet_error; + if (!ecore_file_mkpath(file)) return -1; + + catch_sigterm(); /* lock process, so that we only run one copy of this program */ - snprintf(file, sizeof(file), "%s/.efreet/icon_data.lock", efreet_home_dir_get()); - lockfd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - if (lockfd < 0) goto efreet_error; - memset(&fl, 0, sizeof(struct flock)); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - if (fcntl(lockfd, F_SETLK, &fl) < 0) - { - if (verbose) - { - printf("LOCKED! You may want to delete %s if this persists\n", file); - } - goto efreet_error; - } + lockfd = cache_lock_file(); + if (lockfd == -1) return -1; /* create dir for icon cache */ - dir = ecore_file_dir_get(efreet_icon_cache_file("")); - if (!ecore_file_mkpath(dir)) goto efreet_error; + dir = ecore_file_dir_get(efreet_icon_cache_file()); + if (!ecore_file_mkpath(dir)) goto on_error; free(dir); /* finish efreet init */ - if (!efreet_init()) goto efreet_error; - edd = efreet_icon_edd_init(); - if (!edd) goto edd_error; - fallback_edd = efreet_icon_fallback_edd_init(); - if (!edd) goto edd_error; + if (!efreet_init()) goto on_error; if (argc > 1) - { - for (i = 1; i < argc; i++) - { - theme = efreet_icon_theme_find(argv[i]); - if (theme) l = eina_list_append(l, theme); - } - } - if (!l) - l = efreet_icon_theme_list_get(); + { + for (i = 1; i < argc; i++) + { + theme = efreet_icon_theme_find(argv[i]); + if (theme) l = eina_list_append(l, theme); + } + } + + if (!l) l = efreet_icon_theme_list_get(); + + ef = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ_WRITE); + if (!ef) goto on_error_efreet; + + edd = efreet_icon_theme_edd(); + EINA_LIST_FREE(l, theme) - { - Eina_Hash *themes; + { + Eina_Hash *themes; - changed = 0; - /* create cache */ - /* TODO: Copy old cache to temp file, so we can check whether something has changed */ - snprintf(file, sizeof(file), "%s.XXXXXX", efreet_icon_cache_file(theme->name.internal)); - tmpfd = mkstemp(file); - if (tmpfd < 0) goto error; - close(tmpfd); - ef = eet_open(file, EET_FILE_MODE_READ_WRITE); - if (!ef) goto error; + themes = eina_hash_string_superfast_new(NULL); - themes = eina_hash_string_superfast_new(NULL); - if (!cache_scan(theme, themes, ef, &changed)) - { - eet_close(ef); - eina_hash_free(themes); - goto error; - } + /* read icons from the eet file */ + cache = eet_data_read(ef, edd, theme->name.internal); - changed = 1; - /* check if old and new caches contain the same number of entries */ -#if 0 - if (!changed) - { - Eet_File *old; + /* Wype out in case of version change */ + if (cache + && cache->version.major != EFREET_CACHE_MAJOR + && cache->version.minor != EFREET_CACHE_MINOR) + { + eina_hash_free(cache->icons); + free(cache); + cache = NULL; + } - old = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ); - if (!old || eet_num_entries(old) != eet_num_entries(ef)) changed = 1; - if (old) eet_close(old); + /* No existing cache before, so create it */ + if (!cache) + { + cache = malloc(sizeof (Efreet_Cache_Theme)); + if (!cache) goto on_error_efreet; - } -#endif + cache->version.major = EFREET_CACHE_MAJOR; + cache->version.minor = EFREET_CACHE_MINOR; - /* cleanup */ - eet_close(ef); - eina_hash_free(themes); + cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_free); - /* unlink old cache files */ - if (changed) - { - if (unlink(efreet_icon_cache_file(theme->name.internal)) < 0) - { - if (errno != ENOENT) goto error; - } - /* rename tmp files to real files */ - if (rename(file, efreet_icon_cache_file(theme->name.internal)) < 0) goto error; - } - else - { - unlink(file); - } + changed = EINA_TRUE; + } - eet_clearcache(); + if (cache_scan(theme, themes, cache->icons, &changed)) + { + fprintf(stderr, "generated: '%s' %i (%i)\n", + theme->name.internal, + changed, + eina_hash_population(cache->icons)); + if (changed) + eet_data_write(ef, edd, theme->name.internal, cache, 1); + changed = EINA_FALSE; + } + + eina_hash_free(themes); + eina_hash_free(cache->icons); + free(cache); } - /* fallback */ - changed = 0; - /* TODO: Copy old cache to temp file, so we can check whether something has changed */ - snprintf(file, sizeof(file), "%s.XXXXXX", efreet_icon_cache_file("_fallback")); - tmpfd = mkstemp(file); - if (tmpfd < 0) goto error; - close(tmpfd); - ef = eet_open(file, EET_FILE_MODE_READ_WRITE); - if (!ef) goto error; + edd = efreet_icon_fallback_edd(); - if (!cache_fallback_scan(ef, &changed)) - { - eet_close(ef); - goto error; - } + /* read fallback icons from the eet file */ + cache = eet_data_read(ef, edd, "efreet/fallback"); + if (cache && cache->version.major != EFREET_CACHE_MAJOR) + { + eina_hash_free(cache->icons); + free(cache); + cache = NULL; + } - changed = 1; - /* check if old and new caches contain the same number of entries */ -#if 0 - if (!changed) - { - Eet_File *old; + /* No existing fallback, create it */ + if (!cache) + { + cache = malloc(sizeof (Efreet_Cache_Theme)); + if (!cache) goto on_error_efreet; - old = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ); - if (!old || eet_num_entries(old) != eet_num_entries(ef)) changed = 1; - if (old) eet_close(old); + cache->version.major = EFREET_CACHE_MAJOR; + cache->version.minor = EFREET_CACHE_MINOR; - } -#endif + cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_fallback_free); - /* cleanup */ + changed = EINA_TRUE; + } + + /* Save fallback in the right part */ + if (cache_fallback_scan(cache->icons, &changed)) + { + fprintf(stderr, "generated: fallback %i (%i)\n", changed, eina_hash_population(cache->icons)); + if (changed) + eet_data_write(ef, edd, "efreet/fallback", cache, 1); + } + + eina_hash_free(cache->icons); + free(cache); + + /* save data */ eet_close(ef); - /* unlink old cache files */ - if (changed) - { - if (unlink(efreet_icon_cache_file("_fallback")) < 0) - { - if (errno != ENOENT) goto error; - } - /* rename tmp files to real files */ - if (rename(file, efreet_icon_cache_file("_fallback")) < 0) goto error; - } - else - { - unlink(file); - } - - /* Remove signal handler, no need to exit now */ - act.sa_sigaction = SIG_IGN; - act.sa_flags = SA_RESTART | SA_SIGINFO; - sigemptyset(&act.sa_mask); - sigaction(SIGTERM, &act, NULL); - - eina_list_free(extensions); - - /* touch update file */ - snprintf(file, sizeof(file), "%s/.efreet/icon_data.update", efreet_home_dir_get()); - tmpfd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); - if (tmpfd >= 0) - { - write(tmpfd, "a", 1); - close(tmpfd); - } + on_error_efreet: efreet_shutdown(); - ecore_shutdown(); - eet_shutdown(); - eina_shutdown(); + + on_error: close(lockfd); - return 0; -error: - printf("error\n"); - IF_FREE(dir); -edd_error: - efreet_shutdown(); -efreet_error: + ecore_shutdown(); -ecore_error: eet_shutdown(); -eet_error: eina_shutdown(); -eina_error: - if (lockfd >= 0) close(lockfd); - return 1; + + return 0; } diff --git a/legacy/efreet/src/bin/efreet_icon_cache_dump.c b/legacy/efreet/src/bin/efreet_icon_cache_dump.c index 30b33e24d8..b71f97786b 100644 --- a/legacy/efreet/src/bin/efreet_icon_cache_dump.c +++ b/legacy/efreet/src/bin/efreet_icon_cache_dump.c @@ -23,78 +23,79 @@ static Eet_Data_Descriptor *edd = NULL; int verbose = 0; static void -dump(Efreet_Icon_Theme *theme) +dump(Efreet_Icon_Theme *theme, Eet_File *ef) { - Eet_File *ef; - char **keys; - int i, num; - double start, max, avg; + Efreet_Cache_Theme *cache; + Eina_Iterator *it; + const char *key; + unsigned int count; + double start, avg; - start = ecore_time_get(); - ef = eet_open(efreet_icon_cache_file(theme->name.internal), EET_FILE_MODE_READ); - printf("open: %s %f\n", theme->name.internal, ecore_time_get() - start); - if (!ef) return; - start = ecore_time_get(); - keys = eet_list(ef, "*", &num); - printf("list: %s %d, %f\n", theme->name.internal, num, ecore_time_get() - start); - if (!keys) - { - eet_close(ef); - return; - } - start = ecore_time_get(); - for (i = 0; i < num; i++) - { + start = ecore_time_get(); + + printf("open: %s\n", theme->name.internal); + + cache = eet_data_read(ef, edd, theme->name.internal); + + printf("read: %s %f\n", theme->name.internal, ecore_time_get() - start); + + if (!cache || !cache->icons) return ; + + it = eina_hash_iterator_key_new(cache->icons); + + EINA_ITERATOR_FOREACH(it, key) + { Efreet_Cache_Icon *icon; - double dt; + unsigned int i; - dt = ecore_time_get(); - icon = eet_data_read(ef, edd, keys[i]); - if (!icon) continue; - dt = ecore_time_get() - dt; - if (dt > max) - max = dt; - efreet_cache_icon_free(icon); - } - start = ecore_time_get() - start; - avg = start / num; - printf("read: %s %f %f %f\n", theme->name.internal, start, avg, max); - free(keys); - eet_close(ef); + icon = eina_hash_find(cache->icons, key); + + for (i = 0; i < icon->icons_count; ++i) + count += icon->icons[i]->paths_count; + } + + eina_iterator_free(it); + + eina_hash_free(cache->icons); + free(cache); + + start = ecore_time_get() - start; + avg = start / count; + printf("read: %s - %i paths (time: %f) (avg %f)\n", theme->name.internal, count, start, avg); } int main(int argc, char **argv) { - Eina_List *l = NULL; - Efreet_Icon_Theme *theme; - int i; + Eet_File *ef; + Eina_List *l = NULL; + Efreet_Icon_Theme *theme; + int i; - efreet_cache_update = 0; + efreet_cache_update = 0; - if (!efreet_init()) goto efreet_error; - edd = efreet_icon_edd_init(); - if (!edd) goto edd_error; + if (!efreet_init()) return -1; - if (argc > 1) - { - for (i = 1; i < argc; i++) - { - theme = efreet_icon_theme_find(argv[i]); - if (theme) l = eina_list_append(l, theme); - } - } - if (!l) - l = efreet_icon_theme_list_get(); - EINA_LIST_FREE(l, theme) - { - dump(theme); - } + edd = efreet_icon_theme_edd(); + if (!edd) return -1; - efreet_shutdown(); - return 0; -edd_error: - efreet_shutdown(); -efreet_error: - return 1; + if (argc > 1) + for (i = 1; i < argc; i++) + { + theme = efreet_icon_theme_find(argv[i]); + if (theme) l = eina_list_append(l, theme); + } + + if (!l) l = efreet_icon_theme_list_get(); + + ef = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ); + if (!ef) return -1; + + EINA_LIST_FREE(l, theme) + dump(theme, ef); + + eet_close(ef); + + efreet_shutdown(); + return 0; } diff --git a/legacy/efreet/src/lib/efreet_cache.c b/legacy/efreet/src/lib/efreet_cache.c index c9effd42a3..98edcd734c 100644 --- a/legacy/efreet/src/lib/efreet_cache.c +++ b/legacy/efreet/src/lib/efreet_cache.c @@ -19,18 +19,29 @@ struct _Efreet_Old_Cache Eet_File *ef; }; +#ifdef EFREET_MODULE_LOG_DOM +#undef EFREET_MODULE_LOG_DOM +#endif +#define EFREET_MODULE_LOG_DOM _efreet_cache_log_dom + +static int _efreet_cache_log_dom = -1; /** * Data for cache files */ #ifdef ICON_CACHE -static Eet_Data_Descriptor *cache_icon_edd = NULL; -static Eet_Data_Descriptor *cache_icon_element_edd = NULL; -static Eet_Data_Descriptor *cache_icon_fallback_edd = NULL; +static Eet_Data_Descriptor *cache_theme_edd = NULL; +static Eet_Data_Descriptor *cache_fallback_edd = NULL; -static Eet_File *icon_cache = NULL; -static const char *icon_cache_name = NULL; -static Eet_File *icon_fallback_cache = NULL; +static Eet_Data_Descriptor *icon_element_pointer_edd; +static Eet_Data_Descriptor *icon_element_edd; +static Eet_Data_Descriptor *icon_edd; + +static Eet_File *cache = NULL; + +static const char *theme_name = NULL; +static Efreet_Cache_Theme *theme_cache = NULL; +static Efreet_Cache_Theme *fallback_cache = NULL; #endif static Eet_Data_Descriptor *desktop_edd = NULL; @@ -41,10 +52,6 @@ static const char *desktop_cache_file = NULL; static Ecore_File_Monitor *cache_monitor = NULL; -#ifdef ICON_CACHE -static Ecore_Timer *cache_timer = NULL; -#endif - static Ecore_Event_Handler *cache_exe_handler = NULL; #ifdef ICON_CACHE static Ecore_Job *icon_cache_job = NULL; @@ -66,15 +73,6 @@ static Eina_Bool cache_exe_cb(void *data, int type, void *event); static void cache_update_cb(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path); -#ifdef ICON_CACHE -static void cache_timer_update(void); -static Eina_Bool cache_timer_cb(void *data); -#endif - -#ifdef ICON_CACHE -static void icon_cache_close(void); -#endif - static void desktop_cache_update_cache_job(void *data); #ifdef ICON_CACHE static void icon_cache_update_cache_job(void *data); @@ -91,12 +89,9 @@ efreet_cache_init(void) { char buf[PATH_MAX]; -#ifdef ICON_CACHE - if (!efreet_icon_edd_init()) - goto error; - if (!efreet_icon_fallback_edd_init()) - goto error; -#endif + _efreet_cache_log_dom = eina_log_domain_register("efreet_cache", EFREET_DEFAULT_LOG_COLOR); + if (_efreet_cache_log_dom < 0) + return 0; if (!efreet_desktop_edd_init()) goto error; @@ -144,10 +139,27 @@ efreet_cache_shutdown(void) Efreet_Old_Cache *d; #ifdef ICON_CACHE - if (cache_timer) ecore_timer_del(cache_timer); - cache_timer = NULL; - icon_cache_close(); + if (theme_cache) + { + eina_hash_free(theme_cache->icons); + free(theme_cache); + theme_cache = NULL; + } + + if (theme_name) eina_stringshare_del(theme_name); + theme_name = NULL; + + if (fallback_cache) + { + eina_hash_free(fallback_cache->icons); + free(fallback_cache); + fallback_cache = NULL; + } + + if (cache) eet_close(cache); + cache = NULL; #endif + if (desktop_cache) eet_close(desktop_cache); desktop_cache = NULL; IF_RELEASE(desktop_cache_file); @@ -157,9 +169,11 @@ efreet_cache_shutdown(void) cache_exe_handler = NULL; if (cache_monitor) ecore_file_monitor_del(cache_monitor); cache_monitor = NULL; + #ifdef ICON_CACHE efreet_icon_edd_shutdown(); #endif + efreet_desktop_edd_shutdown(); if (desktop_cache_job) { @@ -174,6 +188,7 @@ efreet_cache_shutdown(void) icon_cache_exe_lock = -1; } #endif + if (desktop_cache_exe) ecore_exe_terminate(desktop_cache_exe); if (desktop_cache_exe_lock > 0) { @@ -186,6 +201,8 @@ efreet_cache_shutdown(void) eina_hash_free(d->hash); free(d); } + + eina_log_domain_unregister(_efreet_cache_log_dom); } #ifdef ICON_CACHE @@ -193,14 +210,14 @@ efreet_cache_shutdown(void) * Needs EAPI because of helper binaries */ EAPI const char * -efreet_icon_cache_file(const char *theme) +efreet_icon_cache_file(void) { static char cache_file[PATH_MAX] = { '\0' }; const char *home; home = efreet_home_dir_get(); - snprintf(cache_file, sizeof(cache_file), "%s/.efreet/icon_%s.cache", home, theme); + snprintf(cache_file, sizeof(cache_file), "%s/.efreet/icons.eet", home); return cache_file; } @@ -252,72 +269,145 @@ efreet_desktop_cache_dirs(void) } #ifdef ICON_CACHE -/* - * Needs EAPI because of helper binaries - */ -EAPI Eet_Data_Descriptor * -efreet_icon_edd_init(void) + +#define EFREET_POINTER_TYPE(Edd_Dest, Edd_Source, Type) \ + { \ + typedef struct _Efreet_##Type##_Pointer Efreet_##Type##_Pointer; \ + struct _Efreet_##Type##_Pointer \ + { \ + Efreet_##Type *pointer; \ + }; \ + \ + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_##Type##_Pointer); \ + Edd_Dest = eet_data_descriptor_file_new(&eddc); \ + EET_DATA_DESCRIPTOR_ADD_SUB(Edd_Dest, Efreet_##Type##_Pointer, \ + "pointer", pointer, Edd_Source); \ + } + +static void * +_efreet_icon_hash_add(void *h, const char *key, void *d) { - Eet_Data_Descriptor_Class iconeddc; - Eet_Data_Descriptor_Class elemeddc; + Eina_Hash *hash = h; - if (!cache_icon_edd) - { - EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&iconeddc, Efreet_Cache_Icon); - EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&elemeddc, Efreet_Cache_Icon_Element); - cache_icon_edd = eet_data_descriptor_file_new(&iconeddc); - if (!cache_icon_edd) - goto error; - cache_icon_element_edd = eet_data_descriptor_file_new(&elemeddc); - if (!cache_icon_element_edd) - goto error; + if (!hash) hash = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_free); + if (!hash) return NULL; - EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_edd, Efreet_Cache_Icon, "theme", theme, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_LIST(cache_icon_edd, Efreet_Cache_Icon, "icons", icons, cache_icon_element_edd); - eet_data_descriptor_element_add(cache_icon_element_edd, "paths", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Icon_Element, paths), 0, NULL, NULL); - EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_element_edd, Efreet_Cache_Icon_Element, "size.normal", size.normal, EET_T_USHORT); - EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_element_edd, Efreet_Cache_Icon_Element, "size.min", size.min, EET_T_USHORT); - EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_element_edd, Efreet_Cache_Icon_Element, "size.max", size.max, EET_T_USHORT); - } - return cache_icon_edd; -error: - efreet_icon_edd_shutdown(); - return NULL; + eina_hash_direct_add(hash, key, d); + + return hash; } /* * Needs EAPI because of helper binaries */ EAPI Eet_Data_Descriptor * -efreet_icon_fallback_edd_init(void) +efreet_icon_theme_edd(void) { - Eet_Data_Descriptor_Class eddc; + Eet_Data_Descriptor_Class eddc; - if (!cache_icon_fallback_edd) - { - EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon); - cache_icon_fallback_edd = eet_data_descriptor_file_new(&eddc); - if (!cache_icon_fallback_edd) - goto error; + if (cache_theme_edd) return cache_theme_edd; - EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_fallback_edd, Efreet_Cache_Icon, "fallback", fallback, EET_T_UCHAR); - eet_data_descriptor_element_add(cache_icon_fallback_edd, "icons", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Icon, icons), 0, NULL, NULL); - } - return cache_icon_fallback_edd; -error: - efreet_icon_edd_shutdown(); - return NULL; + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon_Element); + icon_element_edd = eet_data_descriptor_file_new(&eddc); + if (!icon_element_edd) return NULL; + + EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element, + "type", type, EET_T_USHORT); + EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element, + "normal", normal, EET_T_USHORT); + EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element, + "normal", normal, EET_T_USHORT); + EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element, + "min", min, EET_T_USHORT); + EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element, + "max", max, EET_T_USHORT); + EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(icon_element_edd, Efreet_Cache_Icon_Element, + "paths", paths); + + EFREET_POINTER_TYPE(icon_element_pointer_edd, icon_element_edd, Cache_Icon_Element); + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon); + icon_edd = eet_data_descriptor_file_new(&eddc); + if (!icon_edd) return NULL; + + EET_DATA_DESCRIPTOR_ADD_BASIC(icon_edd, Efreet_Cache_Icon, + "theme", theme, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(icon_edd, Efreet_Cache_Icon, + "icons", icons, icon_element_pointer_edd); + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon); + eddc.func.hash_add = _efreet_icon_hash_add; + cache_theme_edd = eet_data_descriptor_file_new(&eddc); + if (!cache_theme_edd) return NULL; + + EET_DATA_DESCRIPTOR_ADD_BASIC(cache_theme_edd, Efreet_Cache_Theme, + "version.minor", version.minor, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(cache_theme_edd, Efreet_Cache_Theme, + "version.major", version.major, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_HASH(cache_theme_edd, Efreet_Cache_Theme, + "icons", icons, icon_edd); + + return cache_theme_edd; } +static void * +_efreet_icon_fallback_hash_add(void *h, const char *key, void *d) +{ + Eina_Hash *hash = h; + + if (!hash) hash = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_fallback_free); + if (!hash) return NULL; + + eina_hash_direct_add(hash, key, d); + + return hash; +} + +/* + * Needs EAPI because of helper binaries + */ +EAPI Eet_Data_Descriptor * +efreet_icon_fallback_edd(void) +{ + Eet_Data_Descriptor_Class eddc; + Eet_Data_Descriptor *icon_fallback_edd; + + if (cache_fallback_edd) return cache_fallback_edd; + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Fallback_Icon); + icon_fallback_edd = eet_data_descriptor_file_new(&eddc); + if (!icon_fallback_edd) return NULL; + + EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(icon_fallback_edd, + Efreet_Cache_Fallback_Icon, "icons", icons); + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon); + eddc.func.hash_add = _efreet_icon_fallback_hash_add; + cache_fallback_edd = eet_data_descriptor_file_new(&eddc); + if (!cache_fallback_edd) return NULL; + + EET_DATA_DESCRIPTOR_ADD_BASIC(cache_fallback_edd, Efreet_Cache_Theme, + "version.minor", version.minor, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(cache_fallback_edd, Efreet_Cache_Theme, + "version.major", version.major, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_HASH(cache_fallback_edd, Efreet_Cache_Theme, + "icons", icons, icon_fallback_edd); + + return cache_fallback_edd; +} + +#define EDD_SHUTDOWN(Edd) \ + if (Edd) eet_data_descriptor_free(Edd); \ + Edd = NULL; + static void efreet_icon_edd_shutdown(void) { - if (cache_icon_edd) eet_data_descriptor_free(cache_icon_edd); - cache_icon_edd = NULL; - if (cache_icon_element_edd) eet_data_descriptor_free(cache_icon_element_edd); - cache_icon_element_edd = NULL; - if (cache_icon_fallback_edd) eet_data_descriptor_free(cache_icon_fallback_edd); - cache_icon_fallback_edd = NULL; + EDD_SHUTDOWN(cache_fallback_edd); + EDD_SHUTDOWN(cache_theme_edd); + EDD_SHUTDOWN(icon_element_pointer_edd); + EDD_SHUTDOWN(icon_element_edd); + EDD_SHUTDOWN(icon_edd); } #endif @@ -327,44 +417,45 @@ efreet_icon_edd_shutdown(void) EAPI Eet_Data_Descriptor * efreet_desktop_edd_init(void) { - if (!desktop_edd) - { - Eet_Data_Descriptor_Class eddc; + Eet_Data_Descriptor_Class eddc; - EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop); - desktop_edd = eet_data_descriptor_file_new(&eddc); - if (!desktop_edd) return NULL; - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "type", type, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "version", version, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "orig_path", orig_path, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "load_time", load_time, EET_T_LONG_LONG); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "name", name, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "generic_name", generic_name, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "comment", comment, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "icon", icon, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "try_exec", try_exec, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "exec", exec, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "path", path, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_wm_class", startup_wm_class, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "url", url, EET_T_STRING); - eet_data_descriptor_element_add(desktop_edd, "only_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, only_show_in), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "not_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, not_show_in), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "categories", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, categories), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "mime_types", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, mime_types), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "x", EET_T_STRING, EET_G_HASH, offsetof(Efreet_Desktop, x), 0, NULL, NULL); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "no_display", no_display, EET_T_UCHAR); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "hidden", hidden, EET_T_UCHAR); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "terminal", terminal, EET_T_UCHAR); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_notify", startup_notify, EET_T_UCHAR); - } - return desktop_edd; + if (desktop_edd) return desktop_edd; + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop); + desktop_edd = eet_data_descriptor_file_new(&eddc); + if (!desktop_edd) return NULL; + + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "type", type, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "version", version, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "orig_path", orig_path, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "load_time", load_time, EET_T_LONG_LONG); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "name", name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "generic_name", generic_name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "comment", comment, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "icon", icon, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "try_exec", try_exec, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "exec", exec, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "path", path, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_wm_class", startup_wm_class, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "url", url, EET_T_STRING); + eet_data_descriptor_element_add(desktop_edd, "only_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, only_show_in), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "not_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, not_show_in), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "categories", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, categories), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "mime_types", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, mime_types), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "x", EET_T_STRING, EET_G_HASH, offsetof(Efreet_Desktop, x), 0, NULL, NULL); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "no_display", no_display, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "hidden", hidden, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "terminal", terminal, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_notify", startup_notify, EET_T_UCHAR); + + return desktop_edd; } static void efreet_desktop_edd_shutdown(void) { - if (desktop_edd) eet_data_descriptor_free(desktop_edd); - desktop_edd = NULL; + if (desktop_edd) eet_data_descriptor_free(desktop_edd); + desktop_edd = NULL; } #ifdef ICON_CACHE @@ -374,85 +465,97 @@ efreet_desktop_edd_shutdown(void) EAPI void efreet_cache_icon_free(Efreet_Cache_Icon *icon) { - void *data; + unsigned int i; - if (!icon) return; + if (!icon) return; + + if (icon->free) + { + unsigned int j; - if (icon->free) eina_stringshare_del(icon->theme); - EINA_LIST_FREE(icon->icons, data) - { - const char *path; + for (i = 0; i < icon->icons_count; ++i) + { + for (j = 0; j < icon->icons[i]->paths_count; ++j) + eina_stringshare_del(icon->icons[i]->paths[j]); + } + } - if (icon->fallback) - { - if (icon->free) - eina_stringshare_del(data); - } - else - { - Efreet_Cache_Icon_Element *elem; + for (i = 0; i < icon->icons_count; ++i) + { + free(icon->icons[i]->paths); + free(icon->icons[i]); + } - elem = data; - if (icon->free) - { - EINA_LIST_FREE(elem->paths, path) - eina_stringshare_del(path); - } - else - eina_list_free(elem->paths); - free(elem); - } - } - free(icon); + free(icon->icons); + free(icon); +} + +EAPI void +efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon) +{ + unsigned int i; + + if (!icon) return ; + + if (icon->free) + for (i = 0; i < icon->icons_count; ++i) + eina_stringshare_del(icon->icons[i]); + + free(icon->icons); + free(icon); } Efreet_Cache_Icon * efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon) { - if (icon_cache) - { - if (!strcmp(icon_cache_name, theme->name.internal)) - { - eet_close(icon_cache); - eina_stringshare_del(icon_cache_name); - icon_cache = NULL; - icon_cache_name = NULL; - } - } - if (!icon_cache) - { - const char *path; + if (!cache) cache = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ); + if (!cache) return NULL; - path = efreet_icon_cache_file(theme->name.internal); - icon_cache = eet_open(path, EET_FILE_MODE_READ); - if (icon_cache) - { - icon_cache_name = eina_stringshare_add(theme->name.internal); - cache_timer_update(); - } - } - if (icon_cache) - return eet_data_read(icon_cache, cache_icon_edd, icon); - return NULL; + if (theme_name && strcmp(theme_name, theme->name.internal)) + { + /* FIXME: this is bad if people have pointer to this cache, things will go wrong */ + INFO("theme_name change from `%s` to `%s`", theme_name, theme->name.internal); + eina_hash_free(theme_cache->icons); + free(theme_cache); + eina_stringshare_del(theme_name); + theme_cache = NULL; + theme_name = NULL; + } + + if (!theme_name) + { + INFO("loading theme %s", theme->name.internal); + theme_cache = eet_data_read(cache, efreet_icon_theme_edd(), theme->name.internal); + if (theme_cache && !theme_cache->icons) + theme_cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_free); + if (theme_cache) + theme_name = eina_stringshare_add(theme->name.internal); + } + + if (!theme_cache || theme_cache->version.major != EFREET_CACHE_MAJOR) return NULL; + + return eina_hash_find(theme_cache->icons, icon); } -Efreet_Cache_Icon * +Efreet_Cache_Fallback_Icon * efreet_cache_icon_fallback_find(const char *icon) { - if (!icon_fallback_cache) - { - const char *path; + if (!cache) cache = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ); + if (!cache) return NULL; - path = efreet_icon_cache_file("_fallback"); - icon_fallback_cache = eet_open(path, EET_FILE_MODE_READ); - if (icon_fallback_cache) - cache_timer_update(); - } - if (icon_fallback_cache) - return eet_data_read(icon_fallback_cache, cache_icon_fallback_edd, icon); - return NULL; + if (!fallback_cache) + { + INFO("loading fallback cache"); + fallback_cache = eet_data_read(cache, efreet_icon_fallback_edd(), "efreet/fallback"); + if (fallback_cache && !fallback_cache->icons) + fallback_cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_fallback_free); + } + + if (!fallback_cache || fallback_cache->version.major != EFREET_CACHE_MAJOR) return NULL; + + return eina_hash_find(fallback_cache->icons, icon); } #endif @@ -586,14 +689,34 @@ cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__, ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, ev, desktop_cache_update_free, d); } #ifdef ICON_CACHE - else if (!strcmp(file, "icon_data.update")) - { - icon_cache_close(); + else if (!strcmp(file, efreet_icon_cache_file())) + { + if (theme_cache) + { + INFO("Destorying theme cache due to cache change."); + eina_hash_free(theme_cache->icons); + free(theme_cache); + theme_cache = NULL; + } - ev = NEW(Efreet_Event_Cache_Update, 1); - if (!ev) return; - ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, NULL, NULL); - } + if (theme_name) eina_stringshare_del(theme_name); + theme_name = NULL; + + if (fallback_cache) + { + INFO("Destroying fallback cache due to cache change."); + eina_hash_free(fallback_cache->icons); + free(fallback_cache); + fallback_cache = NULL; + } + + if (cache) eet_close(cache); + cache = NULL; + + ev = NEW(Efreet_Event_Cache_Update, 1); + if (!ev) return; + ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, NULL, NULL); + } #endif return; error: @@ -602,36 +725,6 @@ error: if (tmp) eet_close(tmp); } -#ifdef ICON_CACHE -static void -cache_timer_update(void) -{ - if (cache_timer) - ecore_timer_interval_set(cache_timer, 60.0); - else - cache_timer = ecore_timer_add(60.0, cache_timer_cb, NULL); -} - -static Eina_Bool -cache_timer_cb(void *data __UNUSED__) -{ - cache_timer = NULL; - - icon_cache_close(); - return ECORE_CALLBACK_DONE; -} - -static void -icon_cache_close(void) -{ - if (icon_cache) eet_close(icon_cache); - icon_cache = NULL; - if (icon_fallback_cache) eet_close(icon_fallback_cache); - icon_fallback_cache = NULL; - IF_RELEASE(icon_cache_name); -} -#endif - static void desktop_cache_update_cache_job(void *data __UNUSED__) { diff --git a/legacy/efreet/src/lib/efreet_icon.c b/legacy/efreet/src/lib/efreet_icon.c index 1080f11160..dc90c4091d 100644 --- a/legacy/efreet/src/lib/efreet_icon.c +++ b/legacy/efreet/src/lib/efreet_icon.c @@ -122,13 +122,14 @@ static int efreet_cache_icon_size_match(Efreet_Cache_Icon_Element *elem, unsigne static double efreet_cache_icon_size_distance(Efreet_Cache_Icon_Element *elem, unsigned int size); static const char *efreet_cache_icon_lookup_path(Efreet_Cache_Icon_Element *elem); static const char *efreet_cache_icon_lookup_path_path(Efreet_Cache_Icon_Element *elem, const char *path); -static const char *efreet_cache_icon_fallback_lookup_path(Efreet_Cache_Icon *icon); -static const char *efreet_cache_icon_fallback_lookup_path_path(Efreet_Cache_Icon *icon, const char *path); +static const char *efreet_cache_icon_fallback_lookup_path(Efreet_Cache_Fallback_Icon *icon); +static const char *efreet_cache_icon_fallback_lookup_path_path(Efreet_Cache_Fallback_Icon *icon, + const char *path); static void efreet_icon_changes_listen(void); static void efreet_icon_changes_monitor_add(const char *path); static void efreet_icon_changes_cb(void *data, Ecore_File_Monitor *em, - Ecore_File_Event event, const char *path); + Ecore_File_Event event, const char *path); #endif @@ -400,14 +401,15 @@ efreet_icon_path_find(const char *theme_name, const char *icon, unsigned int siz { const char *value = NULL; Efreet_Icon_Theme *theme; -#ifdef ICON_CACHE - Efreet_Cache_Icon *cache; -#endif theme = efreet_icon_find_theme_check(theme_name); if (theme) { +#ifdef ICON_CACHE + Efreet_Cache_Icon *cache; +#endif + #ifdef SLOPPY_SPEC { char *tmp; @@ -417,7 +419,7 @@ efreet_icon_path_find(const char *theme_name, const char *icon, unsigned int siz #ifdef ICON_CACHE cache = efreet_cache_icon_find(theme, tmp); value = efreet_cache_icon_lookup_icon(cache, size); - efreet_cache_icon_free(cache); + if (!value) INFO("lookup for `%s` failed in theme `%s` with %p.", icon, theme_name, cache); #else value = efreet_icon_find_helper(theme, tmp, size); #endif @@ -427,7 +429,7 @@ efreet_icon_path_find(const char *theme_name, const char *icon, unsigned int siz #ifdef ICON_CACHE cache = efreet_cache_icon_find(theme, icon); value = efreet_cache_icon_lookup_icon(cache, size); - efreet_cache_icon_free(cache); + if (!value) INFO("lookup for `%s` failed in theme `%s` with %p.", icon, theme_name, cache); #else value = efreet_icon_find_helper(theme, icon, size); #endif @@ -439,13 +441,15 @@ efreet_icon_path_find(const char *theme_name, const char *icon, unsigned int siz */ if (!value || (value == NON_EXISTING)) #ifdef ICON_CACHE - { - cache = efreet_cache_icon_fallback_find(icon); - value = efreet_cache_icon_fallback_lookup_path(cache); - efreet_cache_icon_free(cache); - } + { + Efreet_Cache_Fallback_Icon *cache; + + cache = efreet_cache_icon_fallback_find(icon); + value = efreet_cache_icon_fallback_lookup_path(cache); + if (!value) INFO("lookup for `%s` failed in fallback too with %p.", icon, cache); + } #else - value = efreet_icon_fallback_icon(icon); + value = efreet_icon_fallback_icon(icon); #endif if (value == NON_EXISTING) value = NULL; @@ -1668,77 +1672,76 @@ efreet_icon_cache_add(Efreet_Icon_Theme *theme, const char *icon, unsigned int s static const char * efreet_cache_icon_lookup_icon(Efreet_Cache_Icon *icon, unsigned int size) { - Eina_List *l; - Efreet_Cache_Icon_Element *elem; - const char *path = NULL; - const char *tmp = NULL; - double minimal_distance = INT_MAX; - unsigned int ret_size = 0; + const char *path = NULL; + double minimal_distance = INT_MAX; + unsigned int ret_size = 0; + unsigned int i; - if (!icon) return NULL; + if (!icon) return NULL; - /* search for allowed size == requested size */ - EINA_LIST_FOREACH(icon->icons, l, elem) - { - if (!efreet_cache_icon_size_match(elem, size)) continue; - path = efreet_cache_icon_lookup_path(elem); + /* search for allowed size == requested size */ + for (i = 0; i < icon->icons_count; ++i) + { + if (!efreet_cache_icon_size_match(icon->icons[i], size)) continue; + path = efreet_cache_icon_lookup_path(icon->icons[i]); if (path) return path; - } + } - /* search for any icon that matches */ - EINA_LIST_FOREACH(icon->icons, l, elem) - { + /* search for any icon that matches */ + for (i = 0; i < icon->icons_count; ++i) + { + const char *tmp = NULL; double distance; - distance = efreet_cache_icon_size_distance(elem, size); + distance = efreet_cache_icon_size_distance(icon->icons[i], size); if (distance > minimal_distance) continue; // prefer downsizing if ((distance == minimal_distance) && (size < ret_size)) continue; - tmp = efreet_cache_icon_lookup_path(elem); + tmp = efreet_cache_icon_lookup_path(icon->icons[i]); if (tmp) - { - path = tmp; - minimal_distance = distance; - ret_size = size; - } - } + { + path = tmp; + minimal_distance = distance; + ret_size = size; + } + } - return path; + return path; } static int efreet_cache_icon_size_match(Efreet_Cache_Icon_Element *elem, unsigned int size) { - if (elem->type == EFREET_ICON_SIZE_TYPE_FIXED) - return (elem->size.normal == size); + if (elem->type == EFREET_ICON_SIZE_TYPE_FIXED) + return (elem->normal == size); - if ((elem->type == EFREET_ICON_SIZE_TYPE_SCALABLE) || - (elem->type == EFREET_ICON_SIZE_TYPE_THRESHOLD)) - return ((elem->size.min < size) && (size < elem->size.max)); + if ((elem->type == EFREET_ICON_SIZE_TYPE_SCALABLE) || + (elem->type == EFREET_ICON_SIZE_TYPE_THRESHOLD)) + return ((elem->min < size) && (size < elem->max)); - return 0; + return 0; } static double efreet_cache_icon_size_distance(Efreet_Cache_Icon_Element *elem, unsigned int size) { if (elem->type == EFREET_ICON_SIZE_TYPE_FIXED) - return (abs(elem->size.normal - size)); + return (abs(elem->normal - size)); if ((elem->type == EFREET_ICON_SIZE_TYPE_SCALABLE) || (elem->type == EFREET_ICON_SIZE_TYPE_THRESHOLD)) { #ifdef STRICT_SPEC - if (size < elem->size.min) - return (elem->size.min - size); - if (elem->size.max < size) - return (size - elem->size.max); + if (size < elem->min) + return (elem->min - size); + if (elem->max < size) + return (size - elem->max); #else - if (size < elem->size.min) - return (elem->size.min / (double)size); - if (elem->size.max < size) - return (size / (double)elem->size.max); + if (size < elem->min) + return (elem->min / (double)size); + if (elem->max < size) + return (size / (double)elem->max); #endif return 0; } @@ -1749,28 +1752,30 @@ efreet_cache_icon_size_distance(Efreet_Cache_Icon_Element *elem, unsigned int si static const char * efreet_cache_icon_lookup_path(Efreet_Cache_Icon_Element *elem) { - const char *path; - Eina_List *xdg_dirs, *l; - const char *dir; - char buf[PATH_MAX]; + Eina_List *xdg_dirs, *l; + const char *path; + const char *dir; + char buf[PATH_MAX]; - if (eina_list_count(elem->paths) == 1) - { + if (elem->paths_count == 1) + { const char *pp, *ext; - path = eina_list_data_get(elem->paths); - pp = strrchr(path, '.'); + pp = strrchr(elem->paths[0], '.'); + if (!pp) return NULL; EINA_LIST_FOREACH(efreet_icon_extensions, l, ext) - if (!strcmp(pp, ext)) - return path; + if (!strcmp(pp, ext)) + return elem->paths[0]; return NULL; - } + } + + path = efreet_cache_icon_lookup_path_path(elem, efreet_icon_deprecated_user_dir_get()); + if (path) return path; + + path = efreet_cache_icon_lookup_path_path(elem, efreet_icon_user_dir_get()); + if (path) return path; - path = efreet_cache_icon_lookup_path_path(elem, efreet_icon_deprecated_user_dir_get()); - if (path) return path; - path = efreet_cache_icon_lookup_path_path(elem, efreet_icon_user_dir_get()); - if (path) return path; #if 0 EINA_LIST_FOREACH(efreet_extra_icon_dirs, l, dir) { @@ -1782,11 +1787,12 @@ efreet_cache_icon_lookup_path(Efreet_Cache_Icon_Element *elem) xdg_dirs = efreet_data_dirs_get(); EINA_LIST_FOREACH(xdg_dirs, l, dir) - { - snprintf(buf, sizeof(buf), "%s/icons", dir); - path = efreet_cache_icon_lookup_path_path(elem, buf); - if (path) return path; - } + { + snprintf(buf, sizeof(buf), "%s/icons", dir); + + path = efreet_cache_icon_lookup_path_path(elem, buf); + if (path) return path; + } return NULL; } @@ -1794,53 +1800,56 @@ efreet_cache_icon_lookup_path(Efreet_Cache_Icon_Element *elem) static const char * efreet_cache_icon_lookup_path_path(Efreet_Cache_Icon_Element *elem, const char *path) { - Eina_List *l, *ll; - const char *ext, *p, *pp; - int len; + Eina_List *ll; + const char *ext, *pp; + unsigned int i; + int len; - len = strlen(path); + len = strlen(path); - EINA_LIST_FOREACH(elem->paths, l, p) - { - - if (strncmp(path, p, len)) continue; - pp = strrchr(p, '.'); + for (i = 0; i < elem->paths_count; ++i) + { + if (strncmp(path, elem->paths[i], len)) continue; + pp = strrchr(elem->paths[i], '.'); if (!pp) continue; EINA_LIST_FOREACH(efreet_icon_extensions, ll, ext) - if (!strcmp(pp, ext)) - return p; - } - return NULL; + if (!strcmp(pp, ext)) + return elem->paths[i]; + } + + return NULL; } static const char * -efreet_cache_icon_fallback_lookup_path(Efreet_Cache_Icon *icon) +efreet_cache_icon_fallback_lookup_path(Efreet_Cache_Fallback_Icon *icon) { - const char *path; - Eina_List *xdg_dirs, *l; - const char *dir; - char buf[PATH_MAX]; + const char *path; + Eina_List *xdg_dirs, *l; + const char *dir; + char buf[PATH_MAX]; - if (!icon) return NULL; + if (!icon) return NULL; - if (eina_list_count(icon->icons) == 1) - { + if (icon->icons_count == 1) + { const char *pp, *ext; - path = eina_list_data_get(icon->icons); - pp = strrchr(path, '.'); + pp = strrchr(icon->icons[0], '.'); + if (!pp) return NULL; EINA_LIST_FOREACH(efreet_icon_extensions, l, ext) - if (!strcmp(pp, ext)) - return path; + if (!strcmp(pp, ext)) + return icon->icons[0]; return NULL; - } + } + + path = efreet_cache_icon_fallback_lookup_path_path(icon, efreet_icon_deprecated_user_dir_get()); + if (path) return path; + + path = efreet_cache_icon_fallback_lookup_path_path(icon, efreet_icon_user_dir_get()); + if (path) return path; - path = efreet_cache_icon_fallback_lookup_path_path(icon, efreet_icon_deprecated_user_dir_get()); - if (path) return path; - path = efreet_cache_icon_fallback_lookup_path_path(icon, efreet_icon_user_dir_get()); - if (path) return path; #if 0 EINA_LIST_FOREACH(efreet_extra_icon_dirs, l, dir) { @@ -1852,19 +1861,21 @@ efreet_cache_icon_fallback_lookup_path(Efreet_Cache_Icon *icon) xdg_dirs = efreet_data_dirs_get(); EINA_LIST_FOREACH(xdg_dirs, l, dir) - { - snprintf(buf, sizeof(buf), "%s/icons", dir); - path = efreet_cache_icon_fallback_lookup_path_path(icon, buf); - if (path) return path; - } + { + snprintf(buf, sizeof(buf), "%s/icons", dir); + + path = efreet_cache_icon_fallback_lookup_path_path(icon, buf); + if (path) return path; + } #ifndef STRICT_SPEC EINA_LIST_FOREACH(xdg_dirs, l, dir) - { - snprintf(buf, sizeof(buf), "%s/pixmaps", dir); - path = efreet_cache_icon_fallback_lookup_path_path(icon, buf); - if (path) return path; - } + { + snprintf(buf, sizeof(buf), "%s/pixmaps", dir); + + path = efreet_cache_icon_fallback_lookup_path_path(icon, buf); + if (path) return path; + } #endif path = efreet_cache_icon_fallback_lookup_path_path(icon, "/usr/share/pixmaps"); @@ -1874,26 +1885,28 @@ efreet_cache_icon_fallback_lookup_path(Efreet_Cache_Icon *icon) } static const char * -efreet_cache_icon_fallback_lookup_path_path(Efreet_Cache_Icon *icon, const char *path) +efreet_cache_icon_fallback_lookup_path_path(Efreet_Cache_Fallback_Icon *icon, const char *path) { - Eina_List *l, *ll; - const char *ext, *p, *pp; - int len; + Eina_List *ll; + const char *ext, *pp; + unsigned int i; + int len; - len = strlen(path); + len = strlen(path); - EINA_LIST_FOREACH(icon->icons, l, p) - { + for (i = 0; i < icon->icons_count; ++i) + { + if (strncmp(path, icon->icons[i], len)) continue; - if (strncmp(path, p, len)) continue; - pp = strrchr(p, '.'); + pp = strrchr(icon->icons[i], '.'); if (!pp) continue; EINA_LIST_FOREACH(efreet_icon_extensions, ll, ext) - if (!strcmp(pp, ext)) - return p; - } - return NULL; + if (!strcmp(pp, ext)) + return icon->icons[i]; + } + + return NULL; } static void diff --git a/legacy/efreet/src/lib/efreet_private.h b/legacy/efreet/src/lib/efreet_private.h index 60e14ca92c..2ba8a25500 100644 --- a/legacy/efreet/src/lib/efreet_private.h +++ b/legacy/efreet/src/lib/efreet_private.h @@ -120,26 +120,60 @@ extern int _efreet_log_dom_global; extern Eina_Hash *efreet_desktop_cache; #ifdef ICON_CACHE -typedef struct Efreet_Cache_Icon Efreet_Cache_Icon; -struct Efreet_Cache_Icon +#define EFREET_CACHE_MAJOR 0 +#define EFREET_CACHE_MINOR 2 + +typedef struct _Efreet_Cache_Icon_Element Efreet_Cache_Icon_Element; +typedef struct _Efreet_Cache_Fallback_Icon Efreet_Cache_Fallback_Icon; +typedef struct _Efreet_Cache_Icon Efreet_Cache_Icon; +typedef struct _Efreet_Cache_Theme Efreet_Cache_Theme; + +struct _Efreet_Cache_Theme { - const char *theme; - Eina_List *icons; - unsigned char fallback; - unsigned char free:1; + struct { + unsigned char major; + unsigned char minor; + } version; + + Eina_Hash *icons; }; -typedef struct Efreet_Cache_Icon_Element Efreet_Cache_Icon_Element; -struct Efreet_Cache_Icon_Element +struct _Efreet_Cache_Icon { - int type; /* size type of icon */ - Eina_List *paths; /* possible paths for icon */ - struct - { - unsigned short normal; /* The size for this icon */ - unsigned short min; /* The minimum size for this icon */ - unsigned short max; /* The maximum size for this icon */ - } size; + const char *theme; + + Efreet_Cache_Icon_Element **icons; + unsigned int icons_count; + + unsigned char free:1; +}; + +struct _Efreet_Cache_Icon_Element +{ + const char **paths; /* possible paths for icon */ + unsigned int paths_count; + + unsigned short type; /* size type of icon */ + + unsigned short normal; /* The size for this icon */ + unsigned short min; /* The minimum size for this icon */ + unsigned short max; /* The maximum size for this icon */ +}; + +struct _Efreet_Cache_Fallback_Icon +{ +#if 0 + const char *name; +#endif + const char *theme; +#if 0 + int context; /* the type of icon */ +#endif + + const char **icons; + unsigned int icons_count; + + unsigned char free:1; }; #endif @@ -193,13 +227,14 @@ void efreet_cache_desktop_free(Efreet_Desktop *desktop); Efreet_Desktop *efreet_cache_desktop_find(const char *file); #ifdef ICON_CACHE -EAPI const char *efreet_icon_cache_file(const char *theme); +EAPI const char *efreet_icon_cache_file(void); -EAPI Eet_Data_Descriptor *efreet_icon_edd_init(void); -EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd_init(void); +EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(void); +EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd(void); EAPI void efreet_cache_icon_free(Efreet_Cache_Icon *icon); +EAPI void efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon); Efreet_Cache_Icon *efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon); -Efreet_Cache_Icon *efreet_cache_icon_fallback_find(const char *icon); +Efreet_Cache_Fallback_Icon *efreet_cache_icon_fallback_find(const char *icon); #endif #define NON_EXISTING (void *)-1