create cache for fallback icons

SVN revision: 54583
This commit is contained in:
Sebastian Dransfeld 2010-11-16 10:32:21 +00:00
parent 8a1cde087d
commit e2a715ccc9
3 changed files with 212 additions and 13 deletions

View File

@ -19,10 +19,101 @@
#include "efreet_private.h"
static Eet_Data_Descriptor *edd = NULL;
static Eet_Data_Descriptor *fallback_edd = NULL;
static Eina_List *extensions;
int verbose = 0;
static int verbose = 0;
static int
cache_fallback_scan_dir(Eet_File *ef, Eina_Hash *dirs, const char *dir, int *changed)
{
Eina_Iterator *it;
char buf[PATH_MAX];
const char *ext, *file;
if (eina_hash_find(dirs, dir)) return 1;
eina_hash_add(dirs, dir, (void *)-1);
it = eina_file_ls(dir);
if (!it) return 1;
EINA_ITERATOR_FOREACH(it, file)
{
Eina_List *l;
Efreet_Cache_Icon *icon;
char *name, *tmp;
ext = strrchr(file, '.');
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(file));
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;
#if 0
icon->name = eina_stringshare_add(name);
#endif
icon->theme = NULL;
#if 0
icon->context = dir->context;
#endif
}
icon->icons = eina_list_append(icon->icons, eina_stringshare_ref(file));
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)
{
Eina_List *xdg_dirs, *l;
const char *dir;
char path[PATH_MAX];
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);
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);
}
#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);
}
#endif
cache_fallback_scan_dir(ef, 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)
@ -132,7 +223,6 @@ 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: flush icons after each theme */
/* TODO: Maybe always read entry from eet, so when can check changed */
/* scan theme */
@ -148,7 +238,7 @@ cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eet_File *ef, int *chang
if (!cache_scan(theme, themes, ef, changed)) return 0;
}
}
else
else if (strcmp(theme->name.internal, "hicolor"))
{
theme = efreet_icon_theme_find("hicolor");
if (!cache_scan(theme, themes, ef, changed)) return 0;
@ -163,7 +253,10 @@ main(int argc, char **argv)
* - Add file monitor on files, so that we catch changes on files
* during whilst this program runs.
* - Maybe linger for a while to reduce number of cache re-creates.
* - pass extra dirs to binary, and read them
* - make sure programs with different extra dirs all work together
*/
Eet_File *ef;
char file[PATH_MAX];
Eina_List *l = NULL;
Efreet_Icon_Theme *theme;
@ -226,6 +319,8 @@ main(int argc, char **argv)
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 (argc > 1)
{
@ -239,10 +334,9 @@ main(int argc, char **argv)
l = efreet_icon_theme_list_get();
EINA_LIST_FREE(l, theme)
{
Eet_File *ef;
Eina_Hash *themes;
changed = 0;
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));
@ -296,6 +390,54 @@ main(int argc, char **argv)
eet_clearcache();
}
/* 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;
if (!cache_fallback_scan(ef, &changed))
{
eet_close(ef);
goto error;
}
changed = 1;
/* check if old and new caches contain the same number of entries */
#if 0
if (!changed)
{
Eet_File *old;
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);
}
#endif
/* cleanup */
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);
}
eina_list_free(extensions);
efreet_shutdown();

View File

@ -10,13 +10,23 @@
*/
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 void efreet_icon_edd_shutdown(void);
int
efreet_cache_init(void)
{
if (!efreet_icon_edd_init()) return 0;
if (!efreet_icon_edd_init())
{
efreet_icon_edd_shutdown();
return 0;
}
if (!efreet_icon_fallback_edd_init())
{
efreet_icon_edd_shutdown();
return 0;
}
return 1;
}
@ -84,6 +94,35 @@ error:
return NULL;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_icon_fallback_edd_init(void)
{
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 0
EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_fallback_edd, Efreet_Cache_Icon, "name", name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_fallback_edd, Efreet_Cache_Icon, "theme", theme, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(cache_icon_fallback_edd, Efreet_Cache_Icon, "context", context, EET_T_INT);
#endif
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;
}
static void
efreet_icon_edd_shutdown(void)
{
@ -91,6 +130,8 @@ efreet_icon_edd_shutdown(void)
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;
}
/*
@ -99,7 +140,8 @@ efreet_icon_edd_shutdown(void)
EAPI void
efreet_cache_icon_free(Efreet_Cache_Icon *icon)
{
Efreet_Cache_Icon_Element *elem;
void *data;
if (icon->free)
{
#if 0
@ -108,16 +150,29 @@ efreet_cache_icon_free(Efreet_Cache_Icon *icon)
eina_stringshare_del(icon->theme);
}
EINA_LIST_FREE(icon->icons, elem)
EINA_LIST_FREE(icon->icons, data)
{
const char *path;
if (icon->free)
EINA_LIST_FREE(elem->paths, path)
eina_stringshare_del(path);
if (icon->fallback)
{
if (icon->free)
eina_stringshare_del(data);
}
else
eina_list_free(elem->paths);
free(elem);
{
Efreet_Cache_Icon_Element *elem;
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);
}

View File

@ -146,6 +146,7 @@ struct Efreet_Cache_Icon
int context; /* the type of icon */
#endif
Eina_List *icons;
unsigned char fallback;
unsigned char free:1;
};
@ -210,6 +211,7 @@ EAPI const char *efreet_desktop_cache_dirs(void);
EAPI const char *efreet_icon_cache_file(const char *theme);
EAPI Eet_Data_Descriptor *efreet_icon_edd_init(void);
EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd_init(void);
EAPI void efreet_cache_icon_free(Efreet_Cache_Icon *icon);
#endif