Add icon theme cache

Not used yet.

SVN revision: 55384
This commit is contained in:
Sebastian Dransfeld 2010-12-08 21:39:43 +00:00
parent 84fdf4e0ef
commit d104d2e745
7 changed files with 461 additions and 119 deletions

View File

@ -22,14 +22,9 @@
static const char *exts[] = { ".png", ".xpm", ".svg", ".edj", NULL };
static Eina_Array *strs = NULL;
static Eina_Hash *icon_themes = NULL;
static int verbose = 0;
static void
_cache_directory_free(void *dcache)
{
free(dcache);
}
static Eina_Bool
cache_directory_find(Eina_Hash *dirs, const char *dir)
{
@ -290,7 +285,7 @@ cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eina_Hash *icons, Eina_H
{
Efreet_Icon_Theme *inherit;
inherit = efreet_icon_theme_find(name);
inherit = eina_hash_find(icon_themes, name);
if (!inherit) fprintf(stderr, "Theme `%s` not found for `%s`.\n",
name, theme->name.internal);
if (!cache_scan(inherit, themes, icons, dirs, changed)) return 0;
@ -298,13 +293,152 @@ cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eina_Hash *icons, Eina_H
}
else if (strcmp(theme->name.internal, "hicolor"))
{
theme = efreet_icon_theme_find("hicolor");
theme = eina_hash_find(icon_themes, "hicolor");
if (!cache_scan(theme, themes, icons, dirs, changed)) return 0;
}
return 1;
}
static void
icon_theme_index_read(Efreet_Icon_Theme *theme, const char *path)
{
/* TODO: return error value */
Efreet_Ini *ini;
Efreet_Icon_Theme_Directory *dir;
const char *tmp;
if (!theme || !path) return;
ini = efreet_ini_new(path);
if (!ini) return;
if (!ini->data)
{
efreet_ini_free(ini);
return;
}
efreet_ini_section_set(ini, "Icon Theme");
tmp = efreet_ini_localestring_get(ini, "Name");
if (tmp) theme->name.name = eina_stringshare_add(tmp);
tmp = efreet_ini_localestring_get(ini, "Comment");
if (tmp) theme->comment = eina_stringshare_add(tmp);
tmp = efreet_ini_string_get(ini, "Example");
if (tmp) theme->example_icon = eina_stringshare_add(tmp);
theme->hidden = efreet_ini_boolean_get(ini, "Hidden");
theme->valid = 1;
/* Check the inheritance. If there is none we inherit from the hicolor theme */
tmp = efreet_ini_string_get(ini, "Inherits");
if (tmp)
{
char *t, *s, *p;
size_t len;
len = strlen(tmp) + 1;
t = alloca(len);
memcpy(t, tmp, len);
s = t;
p = strchr(s, ',');
while (p)
{
*p = '\0';
theme->inherits = eina_list_append(theme->inherits, eina_stringshare_add(s));
s = ++p;
p = strchr(s, ',');
}
theme->inherits = eina_list_append(theme->inherits, eina_stringshare_add(s));
}
/* make sure this one is done last as setting the directory will change
* the ini section ... */
tmp = efreet_ini_string_get(ini, "Directories");
if (tmp)
{
char *t, *s, *p;
size_t len;
len = strlen(tmp) + 1;
t = alloca(len);
memcpy(t, tmp, len);
s = t;
p = s;
while (p)
{
p = strchr(s, ',');
if (p) *p = '\0';
dir = efreet_icon_theme_directory_new(ini, s);
if (!dir) goto error;
theme->directories = eina_list_append(theme->directories, dir);
if (p) s = ++p;
}
}
error:
efreet_ini_free(ini);
}
static Eina_Bool
cache_theme_scan(const char *dir)
{
Eina_Iterator *it;
Eina_File_Direct_Info *entry;
it = eina_file_stat_ls(dir);
if (!it) return 1;
EINA_ITERATOR_FOREACH(it, entry)
{
Efreet_Icon_Theme *theme;
const char *name;
const char *path;
char buf[PATH_MAX];
if ((entry->type != EINA_FILE_DIR) &&
(entry->type != EINA_FILE_LNK))
continue;
name = entry->path + entry->name_start;
theme = eina_hash_find(icon_themes, name);
if (!theme)
{
theme = efreet_icon_theme_new();
theme->name.internal = eina_stringshare_add(name);
eina_hash_direct_add(icon_themes,
(void *)theme->name.internal, theme);
}
path = eina_stringshare_add(entry->path);
if (!eina_list_data_find(theme->paths, path))
theme->paths = eina_list_append(theme->paths, path);
else
eina_stringshare_del(path);
theme->last_cache_check = ecore_time_unix_get();
/* we're already valid so no reason to check for an index.theme file */
if (theme->valid) continue;
/* if the index.theme file exists we parse it into the theme */
memcpy(buf, entry->path, entry->path_length);
memcpy(buf + entry->path_length, "/index.theme", sizeof("/index.theme"));
if (ecore_file_exists(buf))
icon_theme_index_read(theme, buf);
}
eina_iterator_free(it);
return 1;
}
static int
cache_lock_file(void)
{
@ -329,6 +463,24 @@ cache_lock_file(void)
return lockfd;
}
static void
icon_theme_free(Efreet_Icon_Theme *theme)
{
void *data;
Efreet_Icon_Theme_Directory *dir;
EINA_LIST_FREE(theme->paths, data)
eina_stringshare_del(data);
EINA_LIST_FREE(theme->inherits, data)
eina_stringshare_del(data);
EINA_LIST_FREE(theme->directories, dir)
{
eina_stringshare_del(dir->name);
free(dir);
}
free(theme);
}
int
main(int argc, char **argv)
{
@ -339,11 +491,15 @@ main(int argc, char **argv)
* - pass extra dirs to binary, and read them
* - make sure programs with different extra dirs all work together
*/
Efreet_Cache_Version *version;
Eina_Iterator *it;
Efreet_Cache_Version *icon_version;
Efreet_Cache_Version *theme_version;
Efreet_Cache_Icons *cache;
Efreet_Icon_Theme *theme;
Eet_Data_Descriptor *edd;
Eet_File *ef;
Eet_File *icon_ef;
Eet_File *theme_ef;
Eina_List *xdg_dirs = NULL;
Eina_List *l = NULL;
char file[PATH_MAX];
const char *path;
@ -392,49 +548,91 @@ main(int argc, char **argv)
/* finish efreet init */
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);
}
}
icon_themes = eina_hash_string_superfast_new(EINA_FREE_CB(icon_theme_free));
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;
version = eet_data_read(ef, efreet_version_edd(), EFREET_CACHE_VERSION);
if (version &&
((version->major != EFREET_ICON_CACHE_MAJOR) ||
(version->minor != EFREET_ICON_CACHE_MINOR)))
/* open icon file */
icon_ef = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ_WRITE);
if (!icon_ef) goto on_error_efreet;
icon_version = eet_data_read(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION);
if (icon_version &&
((icon_version->major != EFREET_ICON_CACHE_MAJOR) ||
(icon_version->minor != EFREET_ICON_CACHE_MINOR)))
{
// delete old cache
eet_close(ef);
eet_close(icon_ef);
if (unlink(efreet_icon_cache_file()) < 0)
{
if (errno != ENOENT) goto on_error_efreet;
}
ef = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ_WRITE);
if (!ef) goto on_error_efreet;
icon_ef = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ_WRITE);
if (!icon_ef) goto on_error_efreet;
}
if (!version)
version = NEW(Efreet_Cache_Version, 1);
if (!icon_version)
icon_version = NEW(Efreet_Cache_Version, 1);
version->major = EFREET_ICON_CACHE_MAJOR;
version->minor = EFREET_ICON_CACHE_MINOR;
icon_version->major = EFREET_ICON_CACHE_MAJOR;
icon_version->minor = EFREET_ICON_CACHE_MINOR;
edd = efreet_icon_theme_edd(EINA_TRUE);
/* open theme file */
theme_ef = eet_open(efreet_icon_theme_cache_file(), EET_FILE_MODE_READ_WRITE);
if (!theme_ef) goto on_error_efreet;
theme_version = eet_data_read(theme_ef, efreet_version_edd(), EFREET_CACHE_VERSION);
if (theme_version &&
((theme_version->major != EFREET_ICON_CACHE_MAJOR) ||
(theme_version->minor != EFREET_ICON_CACHE_MINOR)))
{
// delete old cache
eet_close(theme_ef);
if (unlink(efreet_icon_theme_cache_file()) < 0)
{
if (errno != ENOENT) goto on_error_efreet;
}
theme_ef = eet_open(efreet_icon_theme_cache_file(), EET_FILE_MODE_READ_WRITE);
if (!theme_ef) goto on_error_efreet;
}
if (!theme_version)
theme_version = NEW(Efreet_Cache_Version, 1);
EINA_LIST_FREE(l, theme)
theme_version->major = EFREET_ICON_CACHE_MAJOR;
theme_version->minor = EFREET_ICON_CACHE_MINOR;
/* scan themes */
cache_theme_scan(efreet_icon_deprecated_user_dir_get());
cache_theme_scan(efreet_icon_user_dir_get());
xdg_dirs = efreet_data_dirs_get();
EINA_LIST_FOREACH(xdg_dirs, l, dir)
{
snprintf(file, sizeof(file), "%s/icons", dir);
cache_theme_scan(file);
}
#ifndef STRICT_SPEC
EINA_LIST_FOREACH(xdg_dirs, l, dir)
{
snprintf(file, sizeof(file), "%s/pixmaps", dir);
cache_theme_scan(file);
}
#endif
cache_theme_scan("/usr/share/pixmaps");
/* scan icons */
edd = efreet_icons_edd(EINA_TRUE);
it = eina_hash_iterator_data_new(icon_themes);
EINA_ITERATOR_FOREACH(it, theme)
{
Eina_Hash *themes;
if (!theme->valid || theme->hidden) continue;
#ifndef STRICT_SPEC
if (!theme->name.name) continue;
#endif
themes = eina_hash_string_superfast_new(NULL);
/* read icons from the eet file */
cache = eet_data_read(ef, edd, theme->name.internal);
cache = eet_data_read(icon_ef, edd, theme->name.internal);
/* No existing cache before, so create it */
if (!cache)
@ -446,10 +644,10 @@ main(int argc, char **argv)
}
if (!cache->icons)
cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_fallback_free);
cache->icons = eina_hash_string_superfast_new(NULL);
if (!cache->dirs)
cache->dirs = eina_hash_string_superfast_new(_cache_directory_free);
cache->dirs = eina_hash_string_superfast_new(NULL);
if (cache_scan(theme, themes, cache->icons, cache->dirs, &changed))
{
@ -458,20 +656,24 @@ main(int argc, char **argv)
changed,
eina_hash_population(cache->icons));
if (changed)
eet_data_write(ef, edd, theme->name.internal, cache, 1);
eet_data_write(icon_ef, edd, theme->name.internal, cache, 1);
changed = EINA_FALSE;
}
eina_hash_free(themes);
eina_hash_free(cache->icons);
eina_hash_free(cache->dirs);
efreet_hash_free(cache->icons, EINA_FREE_CB(efreet_cache_icon_free));
efreet_hash_free(cache->dirs, free);
free(cache);
}
edd = efreet_icon_fallback_edd(EINA_TRUE);
/* TODO: Only write if changed */
eet_data_write(theme_ef, efreet_icon_theme_edd(), theme->name.internal, theme, 1);
}
eina_iterator_free(it);
edd = efreet_icons_fallback_edd(EINA_TRUE);
/* read fallback icons from the eet file */
cache = eet_data_read(ef, edd, EFREET_CACHE_ICON_FALLBACK);
cache = eet_data_read(icon_ef, edd, EFREET_CACHE_ICON_FALLBACK);
/* No existing fallback, create it */
if (!cache)
@ -483,26 +685,32 @@ main(int argc, char **argv)
}
if (!cache->icons)
cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_fallback_free);
cache->icons = eina_hash_string_superfast_new(NULL);
if (!cache->dirs)
cache->dirs = eina_hash_string_superfast_new(_cache_directory_free);
cache->dirs = eina_hash_string_superfast_new(NULL);
/* Save fallback in the right part */
if (cache_fallback_scan(cache->icons, cache->dirs, &changed))
{
fprintf(stderr, "generated: fallback %i (%i)\n", changed, eina_hash_population(cache->icons));
if (changed)
eet_data_write(ef, edd, EFREET_CACHE_ICON_FALLBACK, cache, 1);
eet_data_write(icon_ef, edd, EFREET_CACHE_ICON_FALLBACK, cache, 1);
}
eina_hash_free(cache->icons);
eina_hash_free(cache->dirs);
efreet_hash_free(cache->icons, EINA_FREE_CB(efreet_cache_icon_fallback_free));
efreet_hash_free(cache->dirs, free);
free(cache);
eina_hash_free(icon_themes);
/* save data */
eet_data_write(ef, efreet_version_edd(), EFREET_CACHE_VERSION, version, 1);
eet_close(ef);
eet_data_write(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION, icon_version, 1);
eet_close(icon_ef);
free(icon_version);
eet_data_write(theme_ef, efreet_version_edd(), EFREET_CACHE_VERSION, theme_version, 1);
eet_close(theme_ef);
free(theme_version);
/* touch update file */
snprintf(file, sizeof(file), "%s/efreet/icon_data.update", efreet_cache_home_get());

View File

@ -34,15 +34,20 @@ static int _efreet_cache_log_dom = -1;
*/
#ifdef ICON_CACHE
static Eet_Data_Descriptor *directory_edd = NULL;
static Eet_Data_Descriptor *theme_edd = NULL;
static Eet_Data_Descriptor *icon_theme_edd = NULL;
static Eet_Data_Descriptor *icon_theme_directory_edd = NULL;
static Eet_Data_Descriptor *icons_edd = NULL;
static Eet_Data_Descriptor *fallback_edd = NULL;
static Eet_Data_Descriptor *icon_element_pointer_edd;
static Eet_Data_Descriptor *icon_element_edd;
static Eet_Data_Descriptor *icon_edd;
static Eet_Data_Descriptor *icon_fallback_edd = NULL;
static Eet_Data_Descriptor *icon_element_pointer_edd = NULL;
static Eet_Data_Descriptor *icon_element_edd = NULL;
static Eet_Data_Descriptor *icon_edd = NULL;
static Eet_File *icon_cache = NULL;
static const char *icon_theme_cache_file = NULL;
static const char *theme_name = NULL;
static Efreet_Cache_Icons *theme_cache = NULL;
static Efreet_Cache_Icons *fallback_cache = NULL;
@ -71,6 +76,7 @@ static Eina_List *old_desktop_caches = NULL;
#ifdef ICON_CACHE
static Efreet_Cache_Icons *_efreet_cache_free(Efreet_Cache_Icons *cache);
static Efreet_Cache_Icons *_efreet_cache_fallback_free(Efreet_Cache_Icons *cache);
#endif
static void efreet_cache_edd_shutdown(void);
@ -138,7 +144,7 @@ efreet_cache_shutdown(void)
#ifdef ICON_CACHE
theme_cache = _efreet_cache_free(theme_cache);
fallback_cache = _efreet_cache_free(fallback_cache);
fallback_cache = _efreet_cache_fallback_free(fallback_cache);
if (theme_name) eina_stringshare_del(theme_name);
theme_name = NULL;
@ -162,6 +168,7 @@ efreet_cache_shutdown(void)
desktop_cache_job = NULL;
}
#ifdef ICON_CACHE
IF_RELEASE(icon_theme_cache_file);
if (icon_cache_exe_lock > 0)
{
close(icon_cache_exe_lock);
@ -200,6 +207,23 @@ efreet_icon_cache_file(void)
return cache_file;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI const char *
efreet_icon_theme_cache_file(void)
{
char tmp[PATH_MAX] = { '\0' };
if (icon_theme_cache_file) return icon_theme_cache_file;
snprintf(tmp, sizeof(tmp), "%s/efreet/icon_themes_%s.eet",
efreet_cache_home_get(), efreet_hostname_get());
icon_theme_cache_file = eina_stringshare_add(tmp);
return icon_theme_cache_file;
}
#endif
/*
@ -280,8 +304,11 @@ efreet_cache_edd_shutdown(void)
EDD_SHUTDOWN(desktop_edd);
#ifdef ICON_CACHE
EDD_SHUTDOWN(fallback_edd);
EDD_SHUTDOWN(theme_edd);
EDD_SHUTDOWN(icon_theme_edd);
EDD_SHUTDOWN(icon_theme_directory_edd);
EDD_SHUTDOWN(icons_edd);
EDD_SHUTDOWN(directory_edd);
EDD_SHUTDOWN(icon_fallback_edd);
EDD_SHUTDOWN(icon_element_pointer_edd);
EDD_SHUTDOWN(icon_element_edd);
EDD_SHUTDOWN(icon_edd);
@ -307,54 +334,53 @@ efreet_cache_edd_shutdown(void)
static Efreet_Cache_Icons *
_efreet_cache_free(Efreet_Cache_Icons *c)
{
if (!c) return NULL;
if (!c) return NULL;
if (c->icons) eina_hash_free(c->icons);
if (c->dirs) eina_hash_free(c->dirs);
free(c);
if (c->icons) efreet_hash_free(c->icons, EINA_FREE_CB(efreet_cache_icon_free));
if (c->dirs) efreet_hash_free(c->dirs, free);
free(c);
return NULL;
return NULL;
}
static void *
_efreet_icon_hash_add(void *h, const char *key, void *d)
static Efreet_Cache_Icons *
_efreet_cache_fallback_free(Efreet_Cache_Icons *c)
{
Eina_Hash *hash = h;
if (!c) return NULL;
if (!hash) hash = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_free);
if (!hash) return NULL;
if (c->icons) efreet_hash_free(c->icons, EINA_FREE_CB(efreet_cache_icon_fallback_free));
if (c->dirs) efreet_hash_free(c->dirs, free);
free(c);
eina_hash_direct_add(hash, key, d);
return hash;
return NULL;
}
static Eet_Data_Descriptor *
efreet_icon_directory_edd(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor_Class eddc;
if (directory_edd) return directory_edd;
if (directory_edd) return directory_edd;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Directory);
directory_edd = eet_data_descriptor_file_new(&eddc);
if (!directory_edd) return NULL;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Directory);
directory_edd = eet_data_descriptor_file_new(&eddc);
if (!directory_edd) return NULL;
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
"modified_time", modified_time, EET_T_LONG_LONG);
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
"modified_time", modified_time, EET_T_LONG_LONG);
return directory_edd;
return directory_edd;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_icon_theme_edd(Eina_Bool include_dirs)
efreet_icons_edd(Eina_Bool include_dirs)
{
Eet_Data_Descriptor_Class eddc;
if (theme_edd) return theme_edd;
if (icons_edd) return icons_edd;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon_Element);
icon_element_edd = eet_data_descriptor_file_new(&eddc);
@ -385,41 +411,81 @@ efreet_icon_theme_edd(Eina_Bool include_dirs)
"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;
theme_edd = eet_data_descriptor_file_new(&eddc);
if (!theme_edd) return NULL;
icons_edd = eet_data_descriptor_file_new(&eddc);
if (!icons_edd) return NULL;
EET_DATA_DESCRIPTOR_ADD_HASH(theme_edd, Efreet_Cache_Icons,
EET_DATA_DESCRIPTOR_ADD_HASH(icons_edd, Efreet_Cache_Icons,
"icons", icons, icon_edd);
if (include_dirs)
EET_DATA_DESCRIPTOR_ADD_HASH(theme_edd, Efreet_Cache_Icons,
EET_DATA_DESCRIPTOR_ADD_HASH(icons_edd, Efreet_Cache_Icons,
"dirs", dirs, efreet_icon_directory_edd());
return 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;
return icons_edd;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_icon_fallback_edd(Eina_Bool include_dirs)
efreet_icon_theme_edd(void)
{
Eet_Data_Descriptor_Class eddc;
if (icon_theme_edd) return icon_theme_edd;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Icon_Theme_Directory);
icon_theme_directory_edd = eet_data_descriptor_file_new(&eddc);
if (!icon_theme_directory_edd) return NULL;
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
"name", name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
"context", context, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
"type", type, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
"size.normal", size.normal, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
"size.min", size.min, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
"size.max", size.max, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
"size.threshold", size.threshold, EET_T_UINT);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Icon_Theme);
icon_theme_edd = eet_data_descriptor_file_new(&eddc);
if (!icon_theme_edd) return NULL;
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Icon_Theme,
"name.internal", name.internal, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Icon_Theme,
"name.name", name.name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Icon_Theme,
"comment", comment, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Icon_Theme,
"example_icon", example_icon, EET_T_STRING);
eet_data_descriptor_element_add(icon_theme_edd, "paths", EET_T_STRING, EET_G_LIST,
offsetof(Efreet_Icon_Theme, paths), 0, NULL, NULL);
eet_data_descriptor_element_add(icon_theme_edd, "inherits", EET_T_STRING, EET_G_LIST,
offsetof(Efreet_Icon_Theme, inherits), 0, NULL, NULL);
EET_DATA_DESCRIPTOR_ADD_LIST(icon_theme_edd, Efreet_Icon_Theme,
"directories", directories, icon_theme_directory_edd);
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Icon_Theme,
"last_cache_check", last_cache_check, EET_T_DOUBLE);
return icon_theme_edd;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_icons_fallback_edd(Eina_Bool include_dirs)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *icon_fallback_edd;
if (fallback_edd) return fallback_edd;
@ -431,7 +497,6 @@ efreet_icon_fallback_edd(Eina_Bool include_dirs)
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;
fallback_edd = eet_data_descriptor_file_new(&eddc);
if (!fallback_edd) return NULL;
@ -510,7 +575,7 @@ efreet_cache_icon_free(Efreet_Cache_Icon *icon)
EAPI void
efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon)
{
if (!icon) return ;
if (!icon) return;
free(icon->icons);
free(icon);
@ -533,9 +598,9 @@ efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon)
if (!theme_name)
{
INFO("loading theme %s", theme->name.internal);
theme_cache = eet_data_read(icon_cache, efreet_icon_theme_edd(EINA_FALSE), theme->name.internal);
theme_cache = eet_data_read(icon_cache, efreet_icons_edd(EINA_FALSE), theme->name.internal);
if (theme_cache && !theme_cache->icons)
theme_cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_free);
theme_cache->icons = eina_hash_string_superfast_new(NULL);
if (theme_cache)
theme_name = eina_stringshare_add(theme->name.internal);
}
@ -553,9 +618,9 @@ efreet_cache_icon_fallback_find(const char *icon)
if (!fallback_cache)
{
INFO("loading fallback cache");
fallback_cache = eet_data_read(icon_cache, efreet_icon_fallback_edd(EINA_FALSE), EFREET_CACHE_ICON_FALLBACK);
fallback_cache = eet_data_read(icon_cache, efreet_icons_fallback_edd(EINA_FALSE), EFREET_CACHE_ICON_FALLBACK);
if (fallback_cache && !fallback_cache->icons)
fallback_cache->icons = eina_hash_string_superfast_new((Eina_Free_Cb) efreet_cache_icon_fallback_free);
fallback_cache->icons = eina_hash_string_superfast_new(NULL);
}
if (!fallback_cache) return NULL;
@ -736,7 +801,7 @@ cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__,
if (fallback_cache)
{
INFO("Destroying fallback cache due to cache change.");
fallback_cache = _efreet_cache_free(fallback_cache);
fallback_cache = _efreet_cache_fallback_free(fallback_cache);
}
icon_cache = efreet_cache_close(icon_cache);

View File

@ -12,8 +12,9 @@ void *efreet_cache_close(Eet_File *ef);
EAPI Eet_Data_Descriptor *efreet_version_edd(void);
EAPI Eet_Data_Descriptor *efreet_desktop_edd(void);
#ifdef ICON_CACHE
EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(Eina_Bool include_dirs);
EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd(Eina_Bool include_dirs);
EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(void);
EAPI Eet_Data_Descriptor *efreet_icons_edd(Eina_Bool include_dirs);
EAPI Eet_Data_Descriptor *efreet_icons_fallback_edd(Eina_Bool include_dirs);
#endif
#endif

View File

@ -100,7 +100,9 @@ static const char *efreet_icon_lookup_directory_helper(Efreet_Icon_Theme_Directo
static Efreet_Icon *efreet_icon_new(const char *path);
static void efreet_icon_populate(Efreet_Icon *icon, const char *file);
#ifndef ICON_CACHE
static Efreet_Icon_Theme *efreet_icon_theme_new(void);
#endif
static void efreet_icon_theme_free(Efreet_Icon_Theme *theme);
static void efreet_icon_theme_dir_scan_all(const char *theme_name);
static void efreet_icon_theme_dir_scan(const char *dir,
@ -110,8 +112,10 @@ static void efreet_icon_theme_path_add(Efreet_Icon_Theme *theme,
static void efreet_icon_theme_index_read(Efreet_Icon_Theme *theme,
const char *path);
#ifndef ICON_CACHE
static Efreet_Icon_Theme_Directory *efreet_icon_theme_directory_new(Efreet_Ini *ini,
const char *name);
#endif
static void efreet_icon_theme_directory_free(Efreet_Icon_Theme_Directory *dir);
#ifndef ICON_CACHE
@ -1244,8 +1248,14 @@ error:
* @internal
* @return Returns a new Efreet_Icon_Theme on success or NULL on failure
* @brief Creates a new Efreet_Icon_Theme structure
*
* Needs EAPI because of helper binaries
*/
#ifndef ICON_CACHE
static Efreet_Icon_Theme *
#else
EAPI Efreet_Icon_Theme *
#endif
efreet_icon_theme_new(void)
{
Efreet_Icon_Theme *theme;
@ -1577,8 +1587,14 @@ error:
* information in @a ini.
* @brief Creates and initialises an icon theme directory from the given ini
* information
*
* Needs EAPI because of helper binaries
*/
#ifndef ICON_CACHE
static Efreet_Icon_Theme_Directory *
#else
EAPI Efreet_Icon_Theme_Directory *
#endif
efreet_icon_theme_directory_new(Efreet_Ini *ini, const char *name)
{
Efreet_Icon_Theme_Directory *dir;

View File

@ -232,13 +232,20 @@ Efreet_Desktop *efreet_cache_desktop_find(const char *file);
#ifdef ICON_CACHE
EAPI const char *efreet_icon_cache_file(void);
EAPI const char *efreet_icon_theme_cache_file(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_Fallback_Icon *efreet_cache_icon_fallback_find(const char *icon);
EAPI Efreet_Icon_Theme *efreet_icon_theme_new(void);
EAPI Efreet_Icon_Theme_Directory *efreet_icon_theme_directory_new(Efreet_Ini *ini,
const char *name);
#endif
EAPI void efreet_hash_free(Eina_Hash *hash, Eina_Free_Cb free_cb);
#define NON_EXISTING (void *)-1
EAPI extern int efreet_cache_update;

View File

@ -609,3 +609,17 @@ efreet_util_desktop_cache_reload(void)
{
cache = efreet_cache_close(cache);
}
EAPI void
efreet_hash_free(Eina_Hash *hash, Eina_Free_Cb free_cb)
{
Eina_Iterator *it;
void *data;
it = eina_hash_iterator_data_new(hash);
EINA_ITERATOR_FOREACH(it, data)
(*free_cb)(data);
eina_iterator_free(it);
eina_hash_free(hash);
}

View File

@ -58,7 +58,7 @@ dump(Efreet_Icon_Theme *theme, Eet_File *ef)
eina_iterator_free(it);
eina_hash_free(cache->icons);
efreet_hash_free(cache->icons, EINA_FREE_CB(efreet_cache_icon_free));
free(cache);
start = ecore_time_get() - start;
@ -69,7 +69,8 @@ dump(Efreet_Icon_Theme *theme, Eet_File *ef)
int
main(int argc, char **argv)
{
Eet_File *ef;
Eet_File *icons_ef;
Eet_File *theme_ef;
Eina_List *l = NULL;
Efreet_Icon_Theme *theme;
int i;
@ -78,25 +79,55 @@ main(int argc, char **argv)
if (!efreet_init()) return -1;
edd = efreet_icon_theme_edd(EINA_FALSE);
theme_ef = eet_open(efreet_icon_theme_cache_file(), EET_FILE_MODE_READ);
if (!theme_ef) return -1;
edd = efreet_icons_edd(EINA_FALSE);
if (!edd) return -1;
if (argc > 1)
{
for (i = 1; i < argc; i++)
{
theme = efreet_icon_theme_find(argv[i]);
theme = eet_data_read(theme_ef, efreet_icon_theme_edd(), argv[i]);
if (theme) l = eina_list_append(l, theme);
}
}
else
{
char **keys;
int num;
if (!l) l = efreet_icon_theme_list_get();
keys = eet_list(theme_ef, "*", &num);
if (keys)
{
for (i = 0; i < num; i++)
{
theme = eet_data_read(theme_ef, efreet_icon_theme_edd(), keys[i]);
if (theme) l = eina_list_append(l, theme);
}
free(keys);
}
}
ef = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ);
if (!ef) return -1;
icons_ef = eet_open(efreet_icon_cache_file(), EET_FILE_MODE_READ);
if (!icons_ef) return -1;
EINA_LIST_FREE(l, theme)
dump(theme, ef);
{
void *data;
eet_close(ef);
dump(theme, icons_ef);
/* free theme */
eina_list_free(theme->paths);
eina_list_free(theme->inherits);
EINA_LIST_FREE(theme->directories, data)
free(data);
free(theme);
}
eet_close(icons_ef);
efreet_shutdown();
return 0;