* 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
This commit is contained in:
Cedric BAIL 2010-11-26 14:56:23 +00:00
parent fbfa54bc05
commit a90e2e4aff
6 changed files with 913 additions and 753 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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__)
{

View File

@ -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

View File

@ -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