From 38c73581a5673bbdd3ad939278839f9430e7cec7 Mon Sep 17 00:00:00 2001 From: ningerso Date: Sat, 3 Feb 2007 13:51:02 +0000 Subject: [PATCH] Remove debugging file. SVN revision: 28220 --- legacy/efreet/src/lib/efreet_icon_new.c | 1464 ----------------------- 1 file changed, 1464 deletions(-) delete mode 100644 legacy/efreet/src/lib/efreet_icon_new.c diff --git a/legacy/efreet/src/lib/efreet_icon_new.c b/legacy/efreet/src/lib/efreet_icon_new.c deleted file mode 100644 index 65f51b3962..0000000000 --- a/legacy/efreet/src/lib/efreet_icon_new.c +++ /dev/null @@ -1,1464 +0,0 @@ -/* vim: set sw=4 ts=4 sts=4 et: */ -#include "Efreet.h" -#include "efreet_private.h" -#include -#include - -#define NO_MATCH_KEY ((char *)0xdeadbeef) - -static char *efreet_icon_user_dir = NULL; -static Ecore_Hash *efreet_icon_themes = NULL; /**< Maps theme name to data */ -Ecore_List *efreet_icon_extensions = NULL; /**< The list of file extensions - we'll check */ - -static Efreet_Icon *efreet_icon_new(const char *path); -static void efreet_icon_free(Efreet_Icon *icon); -static void efreet_icon_populate(Efreet_Icon *icon, const char *file); - -Efreet_Icon *efreet_icon_find_helper(Efreet_Icon_Theme *theme, - const char *cache_key, - const char *icon, - const char *size); -static Efreet_Icon *efreet_icon_lookup_icon(Efreet_Icon_Theme *theme, - const char *icon_name, - const char *size); -static Efreet_Icon *efreet_icon_fallback_icon(const char *icon_name); -static Efreet_Icon *efreet_icon_fallback_dir_scan(const char *dir, - const char *icon_name); - -static Efreet_Icon *efreet_icon_lookup_directory_size_distance( - Efreet_Icon_Theme *theme, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, - unsigned int size, - int *minimal_size); -static Efreet_Icon *efreet_icon_lookup_directory_size_match( - Efreet_Icon_Theme *theme, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, - unsigned int size); -static int efreet_icon_directory_size_distance(Efreet_Icon_Theme_Directory *dir, - unsigned int size); -static int efreet_icon_directory_size_match(Efreet_Icon_Theme_Directory *dir, - unsigned int size); -#if 0 -static Efreet_Icon *efreet_icon_lookup_directory_size_match_scan(const char *path, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, - unsigned int size); -static Efreet_Icon *efreet_icon_lookup_directory_size_distance_scan(const char *path, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, - unsigned int size, - unsigned int *minimal_size); -#endif - -static Efreet_Icon_Theme *efreet_icon_theme_new(void); -static void efreet_icon_theme_free(Efreet_Icon_Theme *theme); -static Efreet_Icon_Theme *efreet_icon_theme_find(const char *theme_name); -static void efreet_icon_theme_dir_scan_all(const char *theme_name); -static void efreet_icon_theme_dir_scan(const char *dir, - const char *theme_name); -static void efreet_icon_theme_dir_validity_check(void); -static void efreet_icon_theme_path_add(Efreet_Icon_Theme *theme, - const char *path); -static void efreet_icon_theme_index_read(Efreet_Icon_Theme *theme, - const char *path); - -static Efreet_Icon_Theme_Directory *efreet_icon_theme_directory_new(Efreet_Ini *ini, - const char *name); -static void efreet_icon_theme_directory_free(Efreet_Icon_Theme_Directory *dir); - -static void efreet_icon_theme_cache_check(Efreet_Icon_Theme *theme); -static int efreet_icon_theme_cache_check_dir(Efreet_Icon_Theme *theme, - const char *dir); - -static void efreet_icon_point_free(Efreet_Icon_Point *point); - -/** - * @internal - * @return Returns 1 on success or 0 on failure - * @brief Initializes the icon system - */ -int -efreet_icon_init(void) -{ - if (!efreet_icon_themes) - { - const char *default_exts[] = {".png", ".xpm", NULL}; - int i; - - if (!ecore_init()) return 0; - - /* setup the default extension list */ - efreet_icon_extensions = ecore_list_new(); - ecore_list_set_free_cb(efreet_icon_extensions, free); - - for (i = 0; default_exts[i] != NULL; i++) - ecore_list_append(efreet_icon_extensions, strdup(default_exts[i])); - - efreet_icon_themes = ecore_hash_new(NULL, NULL); - ecore_hash_set_free_key(efreet_icon_themes, - ECORE_FREE_CB(ecore_string_release)); - ecore_hash_set_free_value(efreet_icon_themes, - ECORE_FREE_CB(efreet_icon_theme_free)); - } - - return 1; -} - -/** - * @internal - * @return Returns no value - * @brief Shuts down the icon system - */ -void -efreet_icon_shutdown(void) -{ - IF_FREE(efreet_icon_user_dir); - - IF_FREE_LIST(efreet_icon_extensions); - IF_FREE_HASH(efreet_icon_themes); - - ecore_shutdown(); -} - -/** - * @return Returns the user icon directory - * @brief Returns the user icon directory - */ -const char * -efreet_icon_dir_get(void) -{ - const char *user; - int len; - - if (efreet_icon_user_dir) return efreet_icon_user_dir; - - user = efreet_home_dir_get(); - len = strlen(user) + strlen("/.icons") + 1; - efreet_icon_user_dir = malloc(sizeof(char) * len); - snprintf(efreet_icon_user_dir, len, "%s/.icons", user); - - return efreet_icon_user_dir; -} - -/** - * @param ext: The extension to add to the list of checked extensions - * @return Returns no value. - * @brief Adds the given extension to the list of possible icon extensions - */ -void -efreet_icon_extension_add(const char *ext) -{ - ecore_list_append(efreet_icon_extensions, strdup(ext)); -} - -/** - * @return Returns a list of Efreet_Icon structs for all the non-hidden icon - * themes - * @brief Retrieves all of the non-hidden icon themes available on the system. - * The returned list must be freed. Do not free the list data. - */ -Ecore_List * -efreet_icon_theme_list_get(void) -{ - Ecore_List *list, *theme_list; - char *dir; - - /* reset the theme hash */ - ecore_hash_destroy(efreet_icon_themes); - efreet_icon_themes = ecore_hash_new(ecore_str_hash, ecore_str_compare); - ecore_hash_set_free_value(efreet_icon_themes, - ECORE_FREE_CB(efreet_icon_theme_free)); - - efreet_icon_theme_dir_scan_all(NULL); - efreet_icon_theme_dir_validity_check(); - - /* create the list for the user */ - list = ecore_list_new(); - theme_list = ecore_hash_keys(efreet_icon_themes); - ecore_list_goto_first(theme_list); - while ((dir = ecore_list_next(theme_list))) - { - Efreet_Icon_Theme *theme; - - theme = ecore_hash_get(efreet_icon_themes, dir); - if (theme->hidden || theme->fake) continue; - - ecore_list_append(list, theme); - } - ecore_list_destroy(theme_list); - - return list; -} - -static size_t -efreet_array_cat(char *buffer, size_t size, const char *strs[]) -{ - int i; - size_t n; - - for (i = 0, n = 0; n < size && strs[i]; i++) - n += efreet_strlcpy(buffer + n, strs[i], size - n); - return n; -} - -static void * -efreet_icon_cache_get(Efreet_Icon_Theme *theme, const char *key) -{ - return ecore_hash_get(theme->icon_cache, key); -} - -static void -efreet_icon_cache_set(Efreet_Icon_Theme *theme, const char *key, void *value) -{ - /* add back to the cache */ - /* XXX this is a bit inefficient as I'll end up adding back to the cache - * even if I found the item in the cache. Not a big deal at the moment - * tho. */ - if (!value) - ecore_hash_set(theme->icon_cache, (void *)key, NO_MATCH_KEY); - else - ecore_hash_set(theme->icon_cache, (void *)key, value); -} - -/** - * @param theme_name: The icon theme to look for - * @param icon: The icon to look for - * @param size; The icon size to look for - * @return Returns the Efreet_Icon structure representing this icon or NULL - * if the icon is not found - * @brief Retrieves all of the information about the given icon. - */ -Efreet_Icon * -efreet_icon_find(const char *theme_name, const char *icon, const char *size) -{ - const char *share_key; - char cache_key[PATH_MAX]; - Efreet_Icon *value = NULL; - Efreet_Icon_Theme *theme; - const char *key_list[] = { icon, "@", size, NULL }; - - theme = efreet_icon_theme_find(theme_name); - if (!theme) - { - theme = efreet_icon_theme_new(); - theme->fake = 1; - theme->name.internal = ecore_string_instance(theme_name); - ecore_hash_set(efreet_icon_themes, (void *)theme->name.internal, theme); - } - - efreet_array_cat(cache_key, sizeof(cache_key), key_list); - - share_key = ecore_string_instance(cache_key); - value = efreet_icon_find_helper(theme, share_key, icon, size); - - /* we didn't find the icon in the theme or in the inherited directories - * then just look for a non theme icon */ - if (!value) value = efreet_icon_fallback_icon(icon); - - efreet_icon_cache_set(theme, share_key, value); - - if (value == (void *)NO_MATCH_KEY) - value = NULL; - - return value; -} - -/** - * @param theme_name: The theme to search in - * @param cache_key: The cache key to use - * @param icon: The icon to search for - * @param size: The size to search for - * @return Returns the icon matching the given information or NULL if no - * icon found - * @brief Scans the theme and any inheriting themes for the given icon - */ -Efreet_Icon * -efreet_icon_find_helper(Efreet_Icon_Theme *theme, const char *cache_key, - const char *icon, - const char *size) -{ - Efreet_Icon *value; - - efreet_icon_theme_cache_check(theme); - - /* see if this is in the cache already */ - value = efreet_icon_cache_get(theme, cache_key); - if (value) return value; - - /* go no further if this theme is fake */ - if (theme->fake || !theme->valid) return NULL; - - value = efreet_icon_lookup_icon(theme, icon, size); - - /* we didin't find the image check the inherited themes */ - if (!value) - { - char *parent; - - if (theme->inherits) - { - ecore_list_goto_first(theme->inherits); - while ((parent = ecore_list_next(theme->inherits))) - { - Efreet_Icon_Theme *parent_theme; - - parent_theme = efreet_icon_theme_find(parent); - if (!parent_theme) continue; - - value = efreet_icon_find_helper(parent_theme, cache_key, - icon, size); - if (value) break; - } - } - /* if this isn't the hicolor theme, and we have no other fallbacks - * check hicolor */ - else if (strcmp(theme->name.internal, "hicolor")) - { - Efreet_Icon_Theme *parent_theme; - - parent_theme = efreet_icon_theme_find("hicolor"); - if (parent_theme) - value = efreet_icon_find_helper(parent_theme, cache_key, - icon, size); - } - } - - return value; -} - -/** - * @param theme: The icon theme to look for - * @param icon: The icon to look for - * @param size: The icon size to look for - * @return Returns the path to the given icon or NULL if none found - * @brief Retrives the path to the given icon. - */ -const char * -efreet_icon_path_find(const char *theme, const char *icon, const char *size) -{ - Efreet_Icon *ico; - - ico = efreet_icon_find(theme, icon, size); - - return (ico ? ico->path : NULL); -} - -/** - * @internal - * @param theme: The icon theme to look in - * @param icon: The icon name to look for - * @param size: The icon size to look for - * @return Returns the Efreet_Icon for the theme/icon/size combo or NULL if - * none found - * @brief Looks for the @a icon in the @a theme for the @a size given. - */ -static Efreet_Icon * -efreet_icon_lookup_icon(Efreet_Icon_Theme *theme, const char *icon_name, - const char *size) -{ - Efreet_Icon *icon = NULL, *tmp = NULL; - Efreet_Icon_Theme_Directory *dir; - int minimal_size = INT_MAX; - unsigned int real_size; - - if (!theme || !icon_name || !size) return NULL; - - real_size = atoi(size); - - /* search for allowed size == requested size */ - ecore_list_goto_first(theme->directories); - while ((dir = ecore_list_next(theme->directories))) - { - icon = efreet_icon_lookup_directory_size_match(theme, dir, - icon_name, real_size); - if (icon) return icon; - } - - /* search for any icon that matches */ - ecore_list_goto_first(theme->directories); - while ((dir = ecore_list_next(theme->directories))) - { - tmp = efreet_icon_lookup_directory_size_distance(theme, dir, - icon_name, - real_size, - &minimal_size); - if (tmp) icon = tmp; - } - - return icon; -} - -/** - */ -static void -efreet_icon_directory_cache(Efreet_Icon_Theme *theme, - Efreet_Icon_Theme_Directory *dir, const char *path, - unsigned int size) -{ - char *icon_name; - char file_path[PATH_MAX]; - Ecore_List *icon_list; - const char *path_strs[] = { path, "/", dir->name, NULL }; - - efreet_array_cat(file_path, sizeof(file_path), path_strs); - - icon_list = ecore_file_ls(file_path); - if (icon_list) - { - while ((icon_name = ecore_list_remove_first(icon_list))) - { - char *ext; - const char *key; - Efreet_Icon *value; - - /* Drop the extension to cache icon name */ - ext = strrchr(icon_name, '.'); - if (ext) *ext = '\0'; - - snprintf(file_path, sizeof(file_path), "%s@%dx%d", icon_name, size, - size); - - /* Cache is direct compare, so get a string instance */ - key = ecore_string_instance(file_path); - - /* Restore extension for full path */ - if (ext) *ext = '.'; - - /* Check for an existing cached icon */ - value = ecore_hash_get(theme->icon_cache, key); - if (value == (void *)NO_MATCH_KEY) value = NULL; - if (!value) - { - const char *icon_path[] = { path, "/", dir->name, "/", icon_name }; - /* No icon present, build a full path and generate icon */ - efreet_array_cat(file_path, sizeof(file_path), icon_path); - value = efreet_icon_new(file_path); - } - - if (value) - { - const char *cur_ext, *check_ext; - - /* Find the currently cached path extension */ - cur_ext = strrchr(value->path, '.'); - if (!cur_ext) cur_ext = ""; - - ecore_list_goto_first(efreet_icon_extensions); - while ((check_ext = ecore_list_next(efreet_icon_extensions))) - { - /* Finished if the current extension matched first */ - if (!strcmp(cur_ext, check_ext)) - break; - else if (!strcmp(ext, check_ext)) - { - /* Higher priority extension found, replace old */ - efreet_icon_free(value); - value = efreet_icon_new(file_path); - break; - } - } - value = NULL; - ecore_string_release(key); - } - - /* Add icon to cache */ - if (value) - { - printf("Cached %s: %s\n", key, file_path); - ecore_hash_set(theme->icon_cache, (void *)key, value); - } - FREE(icon_name); - } - IF_FREE_LIST(icon_list); - } -} - -/** - * @internal - * @param theme: The theme to work with - * @param dir: The theme directory to work with - * @param icon_name: The icon name to search for - * @param size; The icon size to search for - * @return Returns the Efreet_Icon for the given information or NULL if none - * found - * @brief Returns the icon for the given information - */ -static Efreet_Icon * -efreet_icon_lookup_directory_size_match(Efreet_Icon_Theme *theme, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, unsigned int size) -{ - const char *path; - Efreet_Icon *icon = NULL; - - printf("path size %d: %s/%s\n", size, theme->name.internal, dir->name); - - if (theme->paths.count == 0) return NULL; - - if (theme->paths.count == 1) - { - path = theme->paths.path; - if (efreet_icon_directory_size_match(dir, size)) - { - efreet_icon_directory_cache(theme, dir, path, size); - } - } - else - { - ecore_list_goto_first(theme->paths.path); - while ((path = ecore_list_next(theme->paths.path))) - { - if (efreet_icon_directory_size_match(dir, size)) - { - break; - } - } - - /* Pre-load the cache for this directory at the size specified */ - if (dir) efreet_icon_directory_cache(theme, dir, path, size); - } - - if (path) - { - char size_ext[PATH_MAX]; - - if (snprintf(size_ext, sizeof(size_ext), "%dx%d", size, size)) - { - char icon_path[PATH_MAX]; - const char *share_key[] = { icon_name, "@", size_ext, NULL }; - - efreet_array_cat(icon_path, sizeof(icon_path), share_key); - icon = efreet_icon_cache_get(theme, icon_path); - } - } - - return icon; -} - -/** - * @internal - * @param theme: The theme to use - * @param dir: The theme directory to look in - * @param icon_name: The icon name to look for - * @param size: The icon size to look for - * @param minimal_size: The current minimal size seen - * @return Returns the icon cloest matching the given information or NULL if - * none found - * @brief Tries to find the file closest matching the given icon - */ -static Efreet_Icon * -efreet_icon_lookup_directory_size_distance(Efreet_Icon_Theme *theme, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, unsigned int size, - int *minimal_size) -{ - const char *path; - Efreet_Icon *icon = NULL; - - if (theme->paths.count == 0) return NULL; - - if (theme->paths.count == 1) - { - path = theme->paths.path; - if (efreet_icon_directory_size_distance(dir, size) >= *minimal_size) - { - efreet_icon_directory_cache(theme, dir, path, size); - } - } - else - { - - ecore_list_goto_first(theme->paths.path); - while ((path = ecore_list_next(theme->paths.path))) - { - int distance; - distance = efreet_icon_directory_size_distance(dir, size); - if (distance >= *minimal_size) - { - *minimal_size = distance; - } - } - - /* Pre-load the cache for this directory at the size specified */ - if (dir) efreet_icon_directory_cache(theme, dir, path, size); - } - - if (path) - { - char size_ext[PATH_MAX]; - - if (snprintf(size_ext, sizeof(size_ext), "%dx%d", size, size)) - { - char icon_path[PATH_MAX]; - const char *share_key[] = { icon_name, "@", size_ext, NULL }; - - efreet_array_cat(icon_path, sizeof(icon_path), share_key); - icon = efreet_icon_cache_get(theme, icon_path); - } - } - - return icon; -} - -#if 0 -/** - * @internal - * @param path: The path to search - * @param theme: The theme we're searching in - * @param dir: The theme directory we're searching in - * @param icon_name: The icon name we're search for - * @param size; The icon size we're searching for - * @return Returns the icon matching the given information or NULL if none - * found - * @brief Tries to match an icon to the given information - */ -static Efreet_Icon * -efreet_icon_lookup_directory_size_match_scan(const char *path, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, - unsigned int size) -{ - Efreet_Icon *icon = NULL; - const char *ext; - char file_path[PATH_MAX]; - - /* size doesn't match, we're done */ - if (!efreet_icon_directory_size_match(dir, size)) return NULL; - - ecore_list_goto_first(efreet_icon_extensions); - while ((ext = ecore_list_next(efreet_icon_extensions))) - { - const char *icon_path[] = { path, "/", dir->name, "/", icon_name, ext, NULL }; - efreet_array_cat(file_path, sizeof(file_path), icon_path); - if (ecore_file_exists(file_path)) - return efreet_icon_new(file_path); - } - return icon; -} - -/** - * @internal - * @param path: The path to search - * @param theme: The theme we're searching in - * @param dir: The theme directory we're searching in - * @param icon_name: The icon name we're search for - * @param size; The icon size we're searching for - * @param minimal_size: The minimal size we're working in - * @return Returns the icon matching the given information or NULL if none - * found - * @brief Tries to match an icon to the given information - */ -static Efreet_Icon * -efreet_icon_lookup_directory_size_distance_scan(const char *path, - Efreet_Icon_Theme_Directory *dir, - const char *icon_name, - unsigned int size, - unsigned int *minimal_size) -{ - Efreet_Icon *icon = NULL; - const char *ext; - char file_path[PATH_MAX]; - unsigned int distance; - - /* only care if we're within the required distance */ - distance = efreet_icon_directory_size_distance(dir, size); - if (distance >= *minimal_size) return NULL; - - ecore_list_goto_first(efreet_icon_extensions); - while ((ext = ecore_list_next(efreet_icon_extensions))) - { - const char *icon_path[] = { path, "/", dir->name, "/", icon_name, ext, NULL }; - efreet_array_cat(file_path, sizeof(file_path), icon_path); - if (ecore_file_exists(file_path)) - { - *minimal_size = distance; - icon = efreet_icon_new(file_path); - break; - } - } - - return icon; -} -#endif - -/** - * @internal - * @param theme: The theme to work with - * @param dir: The theme directory to work with - * @param size: The size to check - * @return Returns true if the size matches for the given directory, 0 - * otherwise - * @brief Checks if the size matches for the given directory or not - */ -static int -efreet_icon_directory_size_match(Efreet_Icon_Theme_Directory *dir, - unsigned int size) -{ - if (dir->type == EFREET_ICON_SIZE_TYPE_FIXED) - return (dir->size.normal == size); - - if (dir->type == EFREET_ICON_SIZE_TYPE_SCALABLE) - return ((dir->size.min < size) && (size < dir->size.max)); - - if (dir->type == EFREET_ICON_SIZE_TYPE_THRESHOLD) - return (((dir->size.normal - dir->size.threshold) < size) - && (size < (dir->size.normal + dir->size.threshold))); - - return 0; -} - -/** - * @internal - * @param theme: The theme to work with - * @param dir: The directory to work with - * @param size: The size to check for - * @return Returns the distance this size is away from the desired size - * @brief Returns the distance the given size is away from the desired size - */ -static int -efreet_icon_directory_size_distance(Efreet_Icon_Theme_Directory *dir, - unsigned int size) -{ - if (dir->type == EFREET_ICON_SIZE_TYPE_FIXED) - return (abs(dir->size.normal - size)); - - if (dir->type == EFREET_ICON_SIZE_TYPE_SCALABLE) - { - if (size < dir->size.min) - return dir->size.min - size; - if (dir->size.max < size) - return size - dir->size.max; - - return 0; - } - - if (dir->type == EFREET_ICON_SIZE_TYPE_THRESHOLD) - { - if (size < (dir->size.normal - dir->size.threshold)) - return (dir->size.min - size); - if ((dir->size.normal + dir->size.threshold) < size) - return (size - dir->size.max); - - return 0; - } - - return 0; -} - -/** - * @internal - * @param icon_name: The icon name to look for - * @return Returns the Efreet_Icon for the given name or NULL if none found - * @brief Looks for the un-themed icon in the base directories - */ -static Efreet_Icon * -efreet_icon_fallback_icon(const char *icon_name) -{ - Efreet_Icon *icon; - - if (!icon_name) return NULL; - - icon = efreet_icon_fallback_dir_scan(efreet_icon_dir_get(), icon_name); - if (!icon) - { - Ecore_List *xdg_dirs; - const char *dir; - - xdg_dirs = efreet_data_dirs_get(); - ecore_list_goto_first(xdg_dirs); - while ((dir = ecore_list_next(xdg_dirs))) - { - icon = efreet_icon_fallback_dir_scan(dir, icon_name); - if (icon) return icon; - } - - efreet_icon_fallback_dir_scan("/usr/share/pixmaps", icon_name); - } - - return icon; -} - -/** - * @internal - * @param dir: The directory to scan - * @param icon_name: The icon to look for - * @return Returns the icon for the given name or NULL on failure - * @brief Scans the given @a dir for the given @a icon_name returning the - * Efreet_icon if found, NULL otherwise. - */ -static Efreet_Icon * -efreet_icon_fallback_dir_scan(const char *dir, const char *icon_name) -{ - char path[PATH_MAX], *ext; - - if (!dir || !icon_name) return NULL; - - ecore_list_goto_first(efreet_icon_extensions); - while ((ext = ecore_list_next(efreet_icon_extensions))) - { - const char *icon_path[] = { dir, "/", icon_name, ext, NULL }; - efreet_array_cat(path, sizeof(path), icon_path); - - if (ecore_file_exists(path)) - return efreet_icon_new(path); - } - - return NULL; -} - -/** - * @internal - * @return Returns a new Efreet_Icon struct on success or NULL on failure - * @brief Creates a new Efreet_Icon struct - */ -static Efreet_Icon * -efreet_icon_new(const char *path) -{ - Efreet_Icon *icon; - char *p; - - icon = NEW(Efreet_Icon, 1); - icon->path = strdup(path); - - /* load the .icon file if it's available */ - p = strrchr(icon->path, '.'); - if (p) - { - char ico_path[PATH_MAX]; - - *p = '\0'; - - snprintf(ico_path, sizeof(ico_path), "%s.icon", icon->path); - *p = '.'; - - if (ecore_file_exists(ico_path)) - efreet_icon_populate(icon, ico_path); - } - - if (!icon->name) icon->name = strdup(path); - - return icon; -} - -/** - * @internal - * @param icon: The Efreet_Icon to cleanup - * @return Returns no value. - * @brief Free's the given icon and all its internal data. - */ -static void -efreet_icon_free(Efreet_Icon *icon) -{ - if (!icon || (icon == (void *)NO_MATCH_KEY)) return; - - IF_FREE(icon->path); - IF_FREE(icon->name); - IF_FREE_LIST(icon->attach_points); - - FREE(icon); -} - -/** - * @internal - * @param icon: The icon to populate - * @param file: The file to populate from - * @return Returns no value - * @brief Tries to populate the icon information from the given file - */ -static void -efreet_icon_populate(Efreet_Icon *icon, const char *file) -{ - Efreet_Ini *ini; - const char *tmp; - - ini = efreet_ini_new(file); - if (!ini) return; - - efreet_ini_section_set(ini, "Icon Data"); - tmp = efreet_ini_localestring_get(ini, "DisplayName"); - if (tmp) icon->name = strdup(tmp); - - tmp = efreet_ini_string_get(ini, "EmbeddedTextRectangle"); - if (tmp) - { - int points[4]; - char *t, *s, *p; - int i; - - t = strdup(tmp); - s = t; - for (i = 0; i < 4; i++) - { - p = strchr(s, ','); - - if (!p) - { - points[i] = 0; - continue; - } - - *p = '\0'; - points[i] = atoi(p); - - s = ++p; - } - - icon->has_embedded_text_rectangle = 1; - icon->embedded_text_rectangle.x0 = points[0]; - icon->embedded_text_rectangle.y0 = points[1]; - icon->embedded_text_rectangle.x1 = points[2]; - icon->embedded_text_rectangle.y1 = points[3]; - - FREE(t); - } - - tmp = efreet_ini_string_get(ini, "AttachPoints"); - if (tmp) - { - char *t, *s, *p; - int last = 0; - - icon->attach_points = ecore_list_new(); - ecore_list_set_free_cb(icon->attach_points, - ECORE_FREE_CB(efreet_icon_point_free)); - - t = strdup(tmp); - s = t; - p = t; - while (!last) - { - Efreet_Icon_Point *point; - - p = strchr(s, ','); - if (!p) break; - - point = NEW(Efreet_Icon_Point, 1); - - *p = '\0'; - point->x = atoi(s); - - s = ++p; - p = strchr(s, '|'); - - if (!p) last = 1; - else *p = '\0'; - - point->y = atoi(s); - ecore_list_append(icon->attach_points, point); - - if (!last) s = ++p; - } - FREE(t); - } - - efreet_ini_free(ini); -} - -/** - * @internal - * @return Returns a new Efreet_Icon_Theme on success or NULL on failure - * @brief Creates a new Efreet_Icon_Theme structure - */ -static Efreet_Icon_Theme * -efreet_icon_theme_new(void) -{ - Efreet_Icon_Theme *theme; - - theme = NEW(Efreet_Icon_Theme, 1); - - return theme; -} - -/** - * @internal - * @param theme: The theme to free - * @return Returns no value - * @brief Frees up the @a theme structure. - */ -static void -efreet_icon_theme_free(Efreet_Icon_Theme *theme) -{ - if (!theme) return; - - IF_RELEASE(theme->name.internal); - IF_RELEASE(theme->name.name); - - IF_FREE(theme->comment); - IF_FREE(theme->example_icon); - - if (theme->paths.count == 1) - IF_FREE(theme->paths.path) - else - IF_FREE_LIST(theme->paths.path) - - IF_FREE_LIST(theme->inherits); - IF_FREE_LIST(theme->directories); - - IF_FREE_HASH(theme->icon_cache); - - FREE(theme); -} - -/** - * @internal - * @param theme_name: The theme to look for - * @return Returns the icon theme related to the given theme name or NULL if - * none exists. - * @brief Tries to get the icon theme structure for the given theme name - */ -static Efreet_Icon_Theme * -efreet_icon_theme_find(const char *theme_name) -{ - const char *key; - Efreet_Icon_Theme *theme; - - key = ecore_string_instance(theme_name); - theme = ecore_hash_get(efreet_icon_themes, key); - if (!theme) - { - efreet_icon_theme_dir_scan_all(theme_name); - theme = ecore_hash_get(efreet_icon_themes, key); - } - ecore_string_release(key); - - return theme; -} - -/** - * @internal - * @param theme: The theme to work with - * @param path: The path to add - * @return Returns no value - * @brief This will correctly add the given path to the list of theme paths. - * @Note Assumes you've already verified that @a path is a valid directory. - */ -static void -efreet_icon_theme_path_add(Efreet_Icon_Theme *theme, const char *path) -{ - if (!theme || !path) return; - - if (theme->paths.count == 0) - theme->paths.path = strdup(path); - - else if (theme->paths.count > 1) - ecore_list_append(theme->paths.path, strdup(path)); - - else - { - char *old; - - old = theme->paths.path; - theme->paths.path = ecore_list_new(); - ecore_list_set_free_cb(theme->paths.path, free); - - ecore_list_append(theme->paths.path, old); - ecore_list_append(theme->paths.path, strdup(path)); - } - theme->paths.count ++; -} - -/** - * @internal - * @return Returns no value - * @brief This validates that our cache is still valid. - * - * This is checked by the following algorithm: - * - if we've check less then 5 seconds ago we're good - * - if the mtime on the dir is less then our last check time we're good - * - otherwise, invalidate the caches - */ -static void -efreet_icon_theme_cache_check(Efreet_Icon_Theme *theme) -{ - double new_check; - - new_check = ecore_time_get(); - - /* we're within 5 seconds of the last time we checked the cache */ - if ((new_check - 5) <= theme->last_cache_check) return; - - if (theme->fake) - efreet_icon_theme_dir_scan_all(theme->name.internal); - - else if (theme->paths.count == 1) - efreet_icon_theme_cache_check_dir(theme, theme->paths.path); - - else if (theme->paths.count > 1) - { - char *path; - - ecore_list_goto_first(theme->paths.path); - while ((path = ecore_list_next(theme->paths.path))) - { - if (!efreet_icon_theme_cache_check_dir(theme, path)) - break; - } - } - - /* When the cache is invalided it will delete the cache. Make sure we - * have a cache before we finish */ - if (!theme->icon_cache) - { - theme->icon_cache = ecore_hash_new(NULL, NULL); - ecore_hash_set_free_key(theme->icon_cache, - ECORE_FREE_CB(ecore_string_release)); - ecore_hash_set_free_value(theme->icon_cache, - ECORE_FREE_CB(efreet_icon_free)); - } - - theme->last_cache_check = new_check; -} - -/** - * @internal - * @param theme: The icon theme to check - * @param dir: The directory to check - * @return Returns 1 if the cache is still valid, 0 otherwise - * @brief This will check if the theme cache is still valid. If it isn't the - * cache will be invalided and 0 returned. - */ -static int -efreet_icon_theme_cache_check_dir(Efreet_Icon_Theme *theme, const char *dir) -{ - struct stat buf; - - /* have we modified this directory since our last cache check? */ - if (stat(dir, &buf) || (buf.st_mtime > theme->last_cache_check)) - { - IF_FREE_HASH(theme->icon_cache); - return 0; - } - - return 1; -} - -/** - * @internal - * @param theme_name: The theme to scan for - * @return Returns no value - * @brief Scans the theme directories. If @a theme_name is NULL it will load - * up all theme data. If @a theme_name is not NULL it will look for that - * specific theme data - */ -static void -efreet_icon_theme_dir_scan_all(const char *theme_name) -{ - Ecore_List *xdg_dirs; - char path[PATH_MAX], *dir; - - efreet_icon_theme_dir_scan(efreet_icon_dir_get(), theme_name); - efreet_icon_theme_dir_scan(efreet_data_home_get(), theme_name); - - xdg_dirs = efreet_data_dirs_get(); - ecore_list_goto_first(xdg_dirs); - while ((dir = ecore_list_next(xdg_dirs))) - { - snprintf(path, sizeof(path), "%s/icons", (char *)dir); - efreet_icon_theme_dir_scan(path, theme_name); - } - - efreet_icon_theme_dir_scan("/usr/share/pixmaps", theme_name); -} - -/** - * @internal - * @param search_dir: The directory to scan - * @param theme_name: Scan for this specific theme, set to NULL to find all - * themes. - * @return Returns no value - * @brief Scans the given directory and adds non-hidden icon themes to the - * given list. If the theme isnt' in our cache then load the index.theme and - * add to the cache. - */ -static void -efreet_icon_theme_dir_scan(const char *search_dir, const char *theme_name) -{ - Ecore_List *dirs; - char *dir; - - if (!search_dir) return; - - dirs = ecore_file_ls(search_dir); - if (!dirs) return; - - while ((dir = ecore_list_remove_first(dirs))) - { - Efreet_Icon_Theme *theme; - char path[PATH_MAX]; - - /* only care if this is a directory or the theme name matches the - * given name */ - snprintf(path, sizeof(path), "%s/%s", search_dir, dir); - if (((theme_name != NULL) && (strcmp(theme_name, dir))) - || !ecore_file_is_dir(path)) - { - FREE(dir); - continue; - } - - theme = ecore_hash_get(efreet_icon_themes, dir); - if (!theme) - { - theme = efreet_icon_theme_new(); - theme->name.internal = ecore_string_instance(dir); - ecore_hash_set(efreet_icon_themes, (void *)theme->name.internal, - theme); - } - else if (theme->fake) - theme->fake = 0; - - FREE(dir); - - efreet_icon_theme_path_add(theme, path); - - /* 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 */ - strncat(path, "/index.theme", sizeof(path)); - if (ecore_file_exists(path)) - efreet_icon_theme_index_read(theme, path); - } - ecore_list_destroy(dirs); - - /* if we were given a theme name we want to make sure that that given - * theme is valid before finishing, unless it's a fake theme */ - if (theme_name) - { - Efreet_Icon_Theme *theme; - - theme = ecore_hash_get(efreet_icon_themes, theme_name); - if (theme && !theme->valid && !theme->fake) - { - ecore_hash_remove(efreet_icon_themes, theme_name); - efreet_icon_theme_free(theme); - } - } -} - -/** - * @internal - * @param theme: The theme to set the values into - * @param path: The path to the index.theme file for this theme - * @return Returns no value - * @brief This will load up the theme with the data in the index.theme file - */ -static void -efreet_icon_theme_index_read(Efreet_Icon_Theme *theme, const char *path) -{ - Efreet_Ini *ini; - const char *tmp; - - if (!theme || !path) return; - - ini = efreet_ini_new(path); - if (!ini) return; - - efreet_ini_section_set(ini, "Icon Theme"); - tmp = efreet_ini_localestring_get(ini, "Name"); - if (tmp) theme->name.name = ecore_string_instance(tmp); - - tmp = efreet_ini_localestring_get(ini, "Comment"); - if (tmp) theme->comment = strdup(tmp); - - tmp = efreet_ini_string_get(ini, "Example"); - if (tmp) theme->example_icon = strdup(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; - - theme->inherits = ecore_list_new(); - ecore_list_set_free_cb(theme->inherits, free); - - t = strdup(tmp); - s = t; - p = strchr(s, ','); - - while (p) - { - *p = '\0'; - - ecore_list_append(theme->inherits, strdup(s)); - s = ++p; - p = strchr(s, ','); - } - ecore_list_append(theme->inherits, strdup(s)); - - FREE(t); - } - - /* 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; - int last = 0; - - theme->directories = ecore_list_new(); - ecore_list_set_free_cb(theme->directories, - ECORE_FREE_CB(efreet_icon_theme_directory_free)); - - t = strdup(tmp); - s = t; - p = s; - - while (!last) - { - p = strchr(s, ','); - - if (!p) last = 1; - else *p = '\0'; - - ecore_list_append(theme->directories, - efreet_icon_theme_directory_new(ini, s)); - - if (!last) s = ++p; - } - - FREE(t); - } - - efreet_ini_free(ini); -} - -/** - * @internal - * @return Returns no value - * @brief Because the theme icon directories can be spread over multiple - * base directories we may need to create the icon theme strucutre before - * finding the index.theme file. It may also be that we never find an - * index.theme file as this isn't a valid theme. This function makes sure - * that everything we've got in our hash has a valid key to it. - */ -static void -efreet_icon_theme_dir_validity_check(void) -{ - Ecore_List *keys; - const char *name; - - keys = ecore_hash_keys(efreet_icon_themes); - ecore_list_goto_first(keys); - while ((name = ecore_list_next(keys))) - { - Efreet_Icon_Theme *theme; - - theme = ecore_hash_get(efreet_icon_themes, name); - if (!theme->valid && !theme->fake) - { - ecore_hash_remove(efreet_icon_themes, name); - efreet_icon_theme_free(theme); - } - } - ecore_list_destroy(keys); -} - -/** - * @internal - * @param ini: The ini file with information on this directory - * @param name: The name of the directory - * @return Returns a new Efreet_Icon_Theme_Directory based on the - * information in @a ini. - * @brief Creates and initialises an icon theme directory from the given ini - * information - */ -static Efreet_Icon_Theme_Directory * -efreet_icon_theme_directory_new(Efreet_Ini *ini, const char *name) -{ - Efreet_Icon_Theme_Directory *dir; - int val; - const char *tmp; - - if (!ini) return NULL; - - dir = NEW(Efreet_Icon_Theme_Directory, 1); - dir->name = strdup(name); - - efreet_ini_section_set(ini, name); - - tmp = efreet_ini_string_get(ini, "Context"); - if (tmp) - { - if (!strcasecmp(tmp, "Actions")) - dir->context = EFREET_ICON_THEME_CONTEXT_ACTIONS; - - else if (!strcasecmp(tmp, "Devices")) - dir->context = EFREET_ICON_THEME_CONTEXT_DEVICES; - - else if (!strcasecmp(tmp, "FileSystems")) - dir->context = EFREET_ICON_THEME_CONTEXT_FILESYSTEMS; - - else if (!strcasecmp(tmp, "MimeTypes")) - dir->context = EFREET_ICON_THEME_CONTEXT_MIMETYPES; - } - - tmp = efreet_ini_string_get(ini, "Type"); - if (tmp) - { - if (!strcasecmp(tmp, "Fixed")) - dir->type = EFREET_ICON_SIZE_TYPE_FIXED; - - else if (!strcasecmp(tmp, "Scalable")) - dir->type = EFREET_ICON_SIZE_TYPE_SCALABLE; - - else if (!strcasecmp(tmp, "Threshold")) - dir->type = EFREET_ICON_SIZE_TYPE_THRESHOLD; - } - - dir->size.normal = efreet_ini_int_get(ini, "Size"); - - val = efreet_ini_int_get(ini, "MinSize"); - if (val < 0) dir->size.min = dir->size.normal; - else dir->size.min = val; - - val = efreet_ini_int_get(ini, "MaxSize"); - if (val < 0) dir->size.max = dir->size.normal; - else dir->size.max = val; - - val = efreet_ini_int_get(ini, "Threshold"); - if (val < 0) dir->size.threshold = 2; - else dir->size.threshold = val; - - return dir; -} - -/** - * @internal - * @param dir: The Efreet_Icon_Theme_Directory to free - * @return Returns no value - * @brief Frees the given directory @a dir - */ -static void -efreet_icon_theme_directory_free(Efreet_Icon_Theme_Directory *dir) -{ - if (!dir) return; - - IF_FREE(dir->name); - FREE(dir); -} - -/** - * @internal - * @param point: The Efreet_Icon_Point to free - * @return Returns no value - * @brief Frees the given structure - */ -static void -efreet_icon_point_free(Efreet_Icon_Point *point) -{ - if (!point) return; - - FREE(point); -} - -