2009-04-20 16:20:40 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2010-11-25 15:48:59 -08:00
|
|
|
#undef alloca
|
|
|
|
#ifdef HAVE_ALLOCA_H
|
|
|
|
# include <alloca.h>
|
|
|
|
#elif defined __GNUC__
|
|
|
|
# define alloca __builtin_alloca
|
|
|
|
#elif defined _AIX
|
|
|
|
# define alloca __alloca
|
|
|
|
#elif defined _MSC_VER
|
|
|
|
# include <malloc.h>
|
|
|
|
# define alloca _alloca
|
|
|
|
#else
|
|
|
|
# include <stddef.h>
|
|
|
|
# ifdef __cplusplus
|
|
|
|
extern "C"
|
|
|
|
# endif
|
|
|
|
void *alloca (size_t);
|
|
|
|
#endif
|
|
|
|
|
2009-04-20 16:20:40 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
2010-11-26 13:32:34 -08:00
|
|
|
#include <Ecore.h>
|
2010-11-25 15:52:57 -08:00
|
|
|
#include <Ecore_File.h>
|
|
|
|
|
2011-02-05 11:05:55 -08:00
|
|
|
/* define macros and variable for using the eina logging system */
|
2010-11-16 13:50:53 -08:00
|
|
|
#define EFREET_MODULE_LOG_DOM _efreet_icon_log_dom
|
|
|
|
static int _efreet_icon_log_dom = -1;
|
|
|
|
|
2011-02-05 11:05:55 -08:00
|
|
|
#include "Efreet.h"
|
|
|
|
#include "efreet_private.h"
|
|
|
|
|
2010-11-16 13:50:53 -08:00
|
|
|
static const char *efreet_icon_deprecated_user_dir = NULL;
|
|
|
|
static const char *efreet_icon_user_dir = NULL;
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
static Eina_List *efreet_icon_extensions = NULL;
|
|
|
|
static Eina_List *efreet_extra_icon_dirs = NULL;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-11-24 13:10:52 -08:00
|
|
|
static Eina_Hash *change_monitors = NULL;
|
|
|
|
|
2007-08-14 22:33:04 -07:00
|
|
|
typedef struct Efreet_Icon_Cache Efreet_Icon_Cache;
|
|
|
|
struct Efreet_Icon_Cache
|
|
|
|
{
|
2010-04-01 12:41:03 -07:00
|
|
|
const char *key;
|
|
|
|
const char *path;
|
2007-08-14 22:33:04 -07:00
|
|
|
time_t lasttime;
|
|
|
|
};
|
|
|
|
|
2007-07-17 12:21:20 -07:00
|
|
|
static char *efreet_icon_remove_extension(const char *icon);
|
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
static Efreet_Icon *efreet_icon_new(const char *path);
|
|
|
|
static void efreet_icon_populate(Efreet_Icon *icon, const char *file);
|
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
static const char *efreet_icon_lookup_icon(Efreet_Cache_Icon *icon, unsigned int size);
|
|
|
|
static const char *efreet_icon_list_lookup_icon(Efreet_Icon_Theme *theme, Eina_List *icons, unsigned int size);
|
|
|
|
static int efreet_icon_size_match(Efreet_Cache_Icon_Element *elem, unsigned int size);
|
|
|
|
static double efreet_icon_size_distance(Efreet_Cache_Icon_Element *elem, unsigned int size);
|
|
|
|
static const char *efreet_icon_lookup_path(Efreet_Cache_Icon_Element *elem);
|
|
|
|
static const char *efreet_icon_lookup_path_path(Efreet_Cache_Icon_Element *elem, const char *path);
|
|
|
|
static const char *efreet_icon_fallback_lookup_path(Efreet_Cache_Fallback_Icon *icon);
|
|
|
|
static const char *efreet_icon_fallback_lookup_path_path(Efreet_Cache_Fallback_Icon *icon,
|
2010-11-26 06:56:23 -08:00
|
|
|
const char *path);
|
2010-11-24 13:10:52 -08:00
|
|
|
|
|
|
|
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,
|
2010-11-26 06:56:23 -08:00
|
|
|
Ecore_File_Event event, const char *path);
|
2010-11-24 13:10:52 -08:00
|
|
|
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* @return Returns 1 on success or 0 on failure
|
|
|
|
* @brief Initializes the icon system
|
|
|
|
*/
|
2007-07-26 04:30:10 -07:00
|
|
|
int
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_icon_init(void)
|
|
|
|
{
|
2010-11-22 12:48:24 -08:00
|
|
|
const char *default_exts[] = {".png", ".xpm", NULL};
|
|
|
|
int i;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-11-22 12:48:24 -08:00
|
|
|
_efreet_icon_log_dom = eina_log_domain_register
|
|
|
|
("efreet_icon", EFREET_DEFAULT_LOG_COLOR);
|
|
|
|
if (_efreet_icon_log_dom < 0)
|
|
|
|
return 0;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-11-22 12:48:24 -08:00
|
|
|
/* setup the default extension list */
|
|
|
|
for (i = 0; default_exts[i]; i++)
|
|
|
|
efreet_icon_extensions = eina_list_append(efreet_icon_extensions, eina_stringshare_add(default_exts[i]));
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-11-24 13:10:52 -08:00
|
|
|
efreet_icon_changes_listen();
|
2010-12-09 00:56:56 -08:00
|
|
|
|
|
|
|
efreet_extra_icon_dirs = NULL;
|
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* @return Returns no value
|
|
|
|
* @brief Shuts down the icon system
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
efreet_icon_shutdown(void)
|
|
|
|
{
|
2010-11-16 13:50:53 -08:00
|
|
|
IF_RELEASE(efreet_icon_user_dir);
|
|
|
|
IF_RELEASE(efreet_icon_deprecated_user_dir);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-04-01 12:41:03 -07:00
|
|
|
IF_FREE_LIST(efreet_icon_extensions, eina_stringshare_del);
|
2009-03-23 05:19:31 -07:00
|
|
|
efreet_extra_icon_dirs = eina_list_free(efreet_extra_icon_dirs);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-11-16 13:50:53 -08:00
|
|
|
eina_log_domain_unregister(_efreet_icon_log_dom);
|
2011-02-05 11:06:55 -08:00
|
|
|
_efreet_icon_log_dom = -1;
|
2010-11-24 13:10:52 -08:00
|
|
|
IF_FREE_HASH(change_monitors);
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-01-27 09:49:45 -08:00
|
|
|
* @return Returns the deprecated user icon directory
|
|
|
|
* @brief Returns the deprecated user icon directory
|
2007-02-03 05:05:30 -08:00
|
|
|
*/
|
2010-11-16 02:32:01 -08:00
|
|
|
EAPI const char *
|
2007-04-14 21:51:37 -07:00
|
|
|
efreet_icon_deprecated_user_dir_get(void)
|
2007-02-03 05:05:30 -08:00
|
|
|
{
|
|
|
|
const char *user;
|
2010-11-16 13:50:53 -08:00
|
|
|
char *tmp;
|
2007-02-03 05:05:30 -08:00
|
|
|
int len;
|
|
|
|
|
2007-04-14 21:51:37 -07:00
|
|
|
if (efreet_icon_deprecated_user_dir) return efreet_icon_deprecated_user_dir;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
user = efreet_home_dir_get();
|
|
|
|
len = strlen(user) + strlen("/.icons") + 1;
|
2010-11-16 13:50:53 -08:00
|
|
|
tmp = alloca(len);
|
|
|
|
snprintf(tmp, len, "%s/.icons", user);
|
|
|
|
|
|
|
|
efreet_icon_deprecated_user_dir = eina_stringshare_add_length(tmp, len - 1);
|
2007-04-14 21:51:37 -07:00
|
|
|
|
|
|
|
return efreet_icon_deprecated_user_dir;
|
|
|
|
}
|
|
|
|
|
2011-01-27 09:49:45 -08:00
|
|
|
/**
|
|
|
|
* @return Returns the user icon directory
|
|
|
|
* @brief Returns the user icon directory
|
|
|
|
*/
|
2007-11-04 01:32:35 -08:00
|
|
|
EAPI const char *
|
2007-04-14 21:51:37 -07:00
|
|
|
efreet_icon_user_dir_get(void)
|
|
|
|
{
|
|
|
|
const char *user;
|
2010-11-16 13:50:53 -08:00
|
|
|
char *tmp;
|
2007-04-14 21:51:37 -07:00
|
|
|
int len;
|
|
|
|
|
|
|
|
if (efreet_icon_user_dir) return efreet_icon_user_dir;
|
|
|
|
|
|
|
|
user = efreet_data_home_get();
|
|
|
|
len = strlen(user) + strlen("/icons") + 1;
|
2010-11-16 13:50:53 -08:00
|
|
|
tmp = alloca(len);
|
|
|
|
snprintf(tmp, len, "%s/icons", user);
|
|
|
|
|
|
|
|
efreet_icon_user_dir = eina_stringshare_add_length(tmp, len - 1);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
return efreet_icon_user_dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param ext The extension to add to the list of checked extensions
|
2007-02-03 05:05:30 -08:00
|
|
|
* @return Returns no value.
|
|
|
|
* @brief Adds the given extension to the list of possible icon extensions
|
|
|
|
*/
|
2007-11-04 01:32:35 -08:00
|
|
|
EAPI void
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_icon_extension_add(const char *ext)
|
|
|
|
{
|
2010-05-15 10:55:41 -07:00
|
|
|
Eina_List *l;
|
2010-05-17 12:45:20 -07:00
|
|
|
|
2010-05-15 10:55:41 -07:00
|
|
|
ext = eina_stringshare_add(ext);
|
2010-05-17 12:45:20 -07:00
|
|
|
|
2010-05-15 10:55:41 -07:00
|
|
|
if ((l = eina_list_data_find_list(efreet_icon_extensions, ext)))
|
|
|
|
{
|
2010-05-15 11:38:50 -07:00
|
|
|
efreet_icon_extensions = eina_list_promote_list(efreet_icon_extensions, l);
|
|
|
|
eina_stringshare_del(ext);
|
2010-05-15 10:55:41 -07:00
|
|
|
}
|
2010-05-15 11:38:50 -07:00
|
|
|
else
|
|
|
|
efreet_icon_extensions = eina_list_prepend(efreet_icon_extensions, ext);
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
2007-03-30 18:16:15 -07:00
|
|
|
/**
|
|
|
|
* @return Returns a list of strings that are paths to other icon directories
|
|
|
|
* @brief Gets the list of all extra directories to look for icons. These
|
|
|
|
* directories are used to look for icons after looking in the user icon dir
|
|
|
|
* and before looking in standard system directories. The order of search is
|
|
|
|
* from first to last directory in this list. the strings in the list should
|
2008-10-15 07:48:03 -07:00
|
|
|
* be created with eina_stringshare_add().
|
2007-03-30 18:16:15 -07:00
|
|
|
*/
|
2009-02-25 19:46:35 -08:00
|
|
|
EAPI Eina_List **
|
2007-03-30 18:16:15 -07:00
|
|
|
efreet_icon_extra_list_get(void)
|
|
|
|
{
|
2009-02-25 19:46:35 -08:00
|
|
|
return &efreet_extra_icon_dirs;
|
2007-03-30 18:16:15 -07:00
|
|
|
}
|
|
|
|
|
2011-02-02 14:58:15 -08:00
|
|
|
/**
|
|
|
|
* @return Returns a list of strings that are icon extensions to look for
|
|
|
|
* @brief Gets the list of all icon extensions to look for
|
|
|
|
*/
|
|
|
|
EAPI Eina_List *
|
|
|
|
efreet_icon_extensions_list_get(void)
|
|
|
|
{
|
|
|
|
return efreet_icon_extensions;
|
|
|
|
}
|
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
/**
|
|
|
|
* @return Returns a list of Efreet_Icon structs for all the non-hidden icon
|
2007-07-26 04:30:10 -07:00
|
|
|
* themes
|
|
|
|
* @brief Retrieves all of the non-hidden icon themes available on the system.
|
2007-02-03 05:05:30 -08:00
|
|
|
* The returned list must be freed. Do not free the list data.
|
|
|
|
*/
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
EAPI Eina_List *
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_icon_theme_list_get(void)
|
|
|
|
{
|
2011-02-09 09:09:16 -08:00
|
|
|
return efreet_cache_icon_theme_list();
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param theme_name The theme to look for
|
2007-02-03 05:05:30 -08:00
|
|
|
* @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
|
|
|
|
*/
|
2007-11-04 01:32:35 -08:00
|
|
|
EAPI Efreet_Icon_Theme *
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_icon_theme_find(const char *theme_name)
|
|
|
|
{
|
2010-08-04 05:23:00 -07:00
|
|
|
if (!theme_name) return NULL;
|
2009-02-25 08:46:51 -08:00
|
|
|
|
2011-02-09 09:09:16 -08:00
|
|
|
return efreet_cache_icon_theme_find(theme_name);
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
2007-07-17 12:21:20 -07:00
|
|
|
/**
|
|
|
|
* @internal
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param icon The icon name to strip extension
|
2007-07-17 12:21:20 -07:00
|
|
|
* @return Extension removed if in list of extensions, else untouched.
|
|
|
|
* @brief Removes extension from icon name if in list of extensions.
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
efreet_icon_remove_extension(const char *icon)
|
|
|
|
{
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
Eina_List *l;
|
2007-07-17 12:21:20 -07:00
|
|
|
char *tmp = NULL, *ext = NULL;
|
|
|
|
|
2009-09-14 13:18:25 -07:00
|
|
|
if (!icon) return NULL;
|
|
|
|
|
2007-07-17 12:21:20 -07:00
|
|
|
tmp = strdup(icon);
|
|
|
|
ext = strrchr(tmp, '.');
|
|
|
|
if (ext)
|
|
|
|
{
|
|
|
|
const char *ext2;
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
EINA_LIST_FOREACH(efreet_icon_extensions, l, ext2)
|
2007-07-17 12:21:20 -07:00
|
|
|
{
|
|
|
|
if (!strcmp(ext, ext2))
|
|
|
|
{
|
|
|
|
#ifdef STRICT_SPEC
|
2009-09-21 09:36:29 -07:00
|
|
|
WRN("[Efreet]: Requesting an icon with an extension: %s",
|
2010-11-27 12:36:39 -08:00
|
|
|
icon);
|
2007-07-17 12:21:20 -07:00
|
|
|
#endif
|
|
|
|
*ext = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
/**
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param theme_name The icon theme to look for
|
|
|
|
* @param icon The icon to look for
|
2007-02-03 05:05:30 -08:00
|
|
|
* @param size; The icon size to look for
|
2007-08-14 22:33:04 -07:00
|
|
|
* @return Returns the path to the given icon or NULL if none found
|
|
|
|
* @brief Retrives the path to the given icon.
|
2007-02-03 05:05:30 -08:00
|
|
|
*/
|
2010-11-09 12:15:55 -08:00
|
|
|
EAPI const char *
|
2008-08-14 13:48:41 -07:00
|
|
|
efreet_icon_path_find(const char *theme_name, const char *icon, unsigned int size)
|
2007-02-03 05:05:30 -08:00
|
|
|
{
|
2011-02-03 14:19:52 -08:00
|
|
|
char *tmp;
|
2010-11-09 12:15:55 -08:00
|
|
|
const char *value = NULL;
|
2007-02-03 05:05:30 -08:00
|
|
|
Efreet_Icon_Theme *theme;
|
2007-09-06 09:15:10 -07:00
|
|
|
|
2010-12-09 00:56:56 -08:00
|
|
|
theme = efreet_icon_theme_find(theme_name);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-08-04 05:23:00 -07:00
|
|
|
#ifdef SLOPPY_SPEC
|
2011-02-03 14:19:52 -08:00
|
|
|
tmp = efreet_icon_remove_extension(icon);
|
|
|
|
if (!tmp) return NULL;
|
2010-11-16 13:50:53 -08:00
|
|
|
#else
|
2011-02-03 14:19:52 -08:00
|
|
|
tmp = icon;
|
2010-11-16 13:50:53 -08:00
|
|
|
#endif
|
2010-12-04 07:13:47 -08:00
|
|
|
|
2011-02-03 14:19:52 -08:00
|
|
|
if (theme)
|
|
|
|
{
|
|
|
|
Efreet_Cache_Icon *cache;
|
2010-12-04 07:13:47 -08:00
|
|
|
cache = efreet_cache_icon_find(theme, tmp);
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_lookup_icon(cache, size);
|
2011-02-05 11:07:07 -08:00
|
|
|
if (!value) INF("lookup for `%s` failed in theme `%s` with %p.", icon, theme_name, cache);
|
2010-08-04 05:23:00 -07:00
|
|
|
}
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
/* we didn't find the icon in the theme or in the inherited directories
|
2007-07-26 04:30:10 -07:00
|
|
|
* then just look for a non theme icon
|
2007-07-17 12:21:20 -07:00
|
|
|
*/
|
2011-02-10 06:34:03 -08:00
|
|
|
if (!value)
|
2010-11-27 12:36:39 -08:00
|
|
|
{
|
|
|
|
Efreet_Cache_Fallback_Icon *cache;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-03 14:19:52 -08:00
|
|
|
cache = efreet_cache_icon_fallback_find(tmp);
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_fallback_lookup_path(cache);
|
2011-02-05 11:07:07 -08:00
|
|
|
if (!value) INF("lookup for `%s` failed in fallback too with %p.", icon, cache);
|
2010-11-27 12:36:39 -08:00
|
|
|
}
|
2007-08-14 22:33:04 -07:00
|
|
|
|
2011-02-03 14:19:52 -08:00
|
|
|
#ifdef SLOPPY_SPEC
|
|
|
|
FREE(tmp);
|
|
|
|
#endif
|
2007-02-03 05:05:30 -08:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2007-07-17 12:21:20 -07:00
|
|
|
/**
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param theme_name The icon theme to look for
|
|
|
|
* @param icons List of icons to look for
|
2007-07-17 12:21:20 -07:00
|
|
|
* @param size; The icon size to look for
|
2007-07-26 04:30:10 -07:00
|
|
|
* @return Returns the path representing first found icon or
|
2007-07-17 12:21:20 -07:00
|
|
|
* NULL if none of the icons are found
|
2007-07-26 04:30:10 -07:00
|
|
|
* @brief Retrieves all of the information about the first found icon in
|
2007-07-17 12:21:20 -07:00
|
|
|
* the list.
|
|
|
|
* @note This function will search the given theme for all icons before falling
|
2007-07-26 04:30:10 -07:00
|
|
|
* back. This is useful when searching for mimetype icons.
|
2007-07-17 12:21:20 -07:00
|
|
|
*/
|
2010-11-09 12:15:55 -08:00
|
|
|
EAPI const char *
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
efreet_icon_list_find(const char *theme_name, Eina_List *icons,
|
2010-11-27 12:36:39 -08:00
|
|
|
unsigned int size)
|
2007-07-17 12:21:20 -07:00
|
|
|
{
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
Eina_List *l;
|
2011-02-03 14:19:52 -08:00
|
|
|
Eina_List *tmps = NULL;
|
2007-07-17 12:21:20 -07:00
|
|
|
const char *icon = NULL;
|
2010-11-09 12:15:55 -08:00
|
|
|
const char *value = NULL;
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
char *data;
|
2007-07-17 12:21:20 -07:00
|
|
|
Efreet_Icon_Theme *theme;
|
2007-07-26 04:30:10 -07:00
|
|
|
|
2010-12-09 00:56:56 -08:00
|
|
|
theme = efreet_icon_theme_find(theme_name);
|
2007-07-26 04:30:10 -07:00
|
|
|
|
2011-02-03 14:19:52 -08:00
|
|
|
#ifdef SLOPPY_SPEC
|
|
|
|
EINA_LIST_FOREACH(icons, l, icon)
|
|
|
|
{
|
|
|
|
data = efreet_icon_remove_extension(icon);
|
|
|
|
if (!data) return NULL;
|
|
|
|
tmps = eina_list_append(tmps, data);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
tmps = icons;
|
|
|
|
#endif
|
|
|
|
|
2010-08-04 05:23:00 -07:00
|
|
|
if (theme)
|
2010-08-03 14:32:45 -07:00
|
|
|
{
|
2010-12-04 05:59:48 -08:00
|
|
|
Eina_List *tmps2 = NULL;
|
|
|
|
Efreet_Cache_Icon *cache;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(tmps, l, icon)
|
|
|
|
{
|
|
|
|
cache = efreet_cache_icon_find(theme, icon);
|
|
|
|
if (cache)
|
2010-08-04 05:23:00 -07:00
|
|
|
{
|
2010-12-04 05:59:48 -08:00
|
|
|
/* If the icon is in the asked for theme, return it */
|
|
|
|
if (!strcmp(cache->theme, theme->name.internal))
|
|
|
|
{
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_lookup_icon(cache, size);
|
2010-12-04 05:59:48 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
tmps2 = eina_list_append(tmps2, cache);
|
2010-08-04 05:23:00 -07:00
|
|
|
}
|
2010-12-04 05:59:48 -08:00
|
|
|
}
|
|
|
|
if (tmps2)
|
|
|
|
{
|
|
|
|
if (!value)
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_list_lookup_icon(theme, tmps2, size);
|
2011-02-01 13:03:40 -08:00
|
|
|
eina_list_free(tmps2);
|
2010-08-04 05:23:00 -07:00
|
|
|
}
|
|
|
|
}
|
2007-07-17 12:21:20 -07:00
|
|
|
|
|
|
|
/* we didn't find the icons in the theme or in the inherited directories
|
2007-07-26 04:30:10 -07:00
|
|
|
* then just look for a non theme icon
|
2007-07-17 12:21:20 -07:00
|
|
|
*/
|
2011-02-10 06:34:03 -08:00
|
|
|
if (!value)
|
2007-07-17 12:21:20 -07:00
|
|
|
{
|
2010-12-04 05:59:48 -08:00
|
|
|
Efreet_Cache_Fallback_Icon *cache;
|
2011-02-03 14:19:52 -08:00
|
|
|
EINA_LIST_FOREACH(tmps, l, icon)
|
2007-07-17 12:21:20 -07:00
|
|
|
{
|
2010-12-04 05:59:48 -08:00
|
|
|
cache = efreet_cache_icon_fallback_find(icon);
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_fallback_lookup_path(cache);
|
2011-02-10 06:34:03 -08:00
|
|
|
if (value)
|
2007-07-17 12:21:20 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-03 14:19:52 -08:00
|
|
|
#ifdef SLOPPY_SPEC
|
|
|
|
EINA_LIST_FREE(tmps, data)
|
|
|
|
free(data);
|
|
|
|
#endif
|
|
|
|
|
2007-07-17 12:21:20 -07:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
/**
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param theme_name The icon theme to look for
|
|
|
|
* @param icon The icon to look for
|
|
|
|
* @param size The icon size to look for
|
2007-08-14 22:33:04 -07:00
|
|
|
* @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.
|
2007-02-03 05:05:30 -08:00
|
|
|
*/
|
2007-11-04 01:32:35 -08:00
|
|
|
EAPI Efreet_Icon *
|
2008-08-14 13:48:41 -07:00
|
|
|
efreet_icon_find(const char *theme_name, const char *icon, unsigned int size)
|
2007-02-03 05:05:30 -08:00
|
|
|
{
|
2010-11-09 12:15:55 -08:00
|
|
|
const char *path;
|
2007-07-26 04:30:10 -07:00
|
|
|
|
2008-08-14 09:59:41 -07:00
|
|
|
path = efreet_icon_path_find(theme_name, icon, size);
|
2007-07-26 04:30:10 -07:00
|
|
|
if (path)
|
|
|
|
{
|
2010-03-01 13:43:59 -08:00
|
|
|
Efreet_Icon *ic;
|
2011-01-31 03:43:31 -08:00
|
|
|
|
|
|
|
ic = efreet_icon_new(path);
|
|
|
|
return ic;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
2011-01-31 03:43:31 -08:00
|
|
|
|
|
|
|
return NULL;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
2010-08-03 12:31:44 -07:00
|
|
|
if (!icon) return NULL;
|
2010-04-01 12:41:03 -07:00
|
|
|
icon->path = eina_stringshare_add(path);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2007-05-29 13:18:21 -07:00
|
|
|
if (!icon->name)
|
|
|
|
{
|
2007-06-06 18:22:48 -07:00
|
|
|
const char *file;
|
2007-05-29 13:18:21 -07:00
|
|
|
|
2007-07-25 10:01:04 -07:00
|
|
|
file = ecore_file_file_get(icon->path);
|
2007-05-29 13:18:21 -07:00
|
|
|
p = strrchr(icon->path, '.');
|
|
|
|
if (p) *p = '\0';
|
2010-04-01 12:41:03 -07:00
|
|
|
icon->name = eina_stringshare_add(file);
|
2007-05-29 13:18:21 -07:00
|
|
|
if (p) *p = '.';
|
|
|
|
}
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param icon The Efreet_Icon to cleanup
|
2007-02-03 05:05:30 -08:00
|
|
|
* @return Returns no value.
|
|
|
|
* @brief Free's the given icon and all its internal data.
|
|
|
|
*/
|
2007-11-04 01:32:35 -08:00
|
|
|
EAPI void
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_icon_free(Efreet_Icon *icon)
|
|
|
|
{
|
2007-07-26 04:30:10 -07:00
|
|
|
if (!icon) return;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
icon->ref_count --;
|
|
|
|
if (icon->ref_count > 0) return;
|
|
|
|
|
2010-04-01 12:41:03 -07:00
|
|
|
IF_RELEASE(icon->path);
|
|
|
|
IF_RELEASE(icon->name);
|
2009-03-23 05:19:31 -07:00
|
|
|
IF_FREE_LIST(icon->attach_points, free);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
FREE(icon);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
2011-01-27 09:49:45 -08:00
|
|
|
* @param icon The icon to populate
|
|
|
|
* @param file The file to populate from
|
2007-02-03 05:05:30 -08:00
|
|
|
* @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);
|
2010-08-04 12:15:38 -07:00
|
|
|
if (!ini) return;
|
2007-02-03 05:05:30 -08:00
|
|
|
if (!ini->data)
|
|
|
|
{
|
|
|
|
efreet_ini_free(ini);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
efreet_ini_section_set(ini, "Icon Data");
|
|
|
|
tmp = efreet_ini_localestring_get(ini, "DisplayName");
|
2010-04-01 12:41:03 -07:00
|
|
|
if (tmp) icon->name = eina_stringshare_add(tmp);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
tmp = efreet_ini_string_get(ini, "EmbeddedTextRectangle");
|
|
|
|
if (tmp)
|
|
|
|
{
|
|
|
|
int points[4];
|
|
|
|
char *t, *s, *p;
|
|
|
|
int i;
|
2010-04-01 12:41:03 -07:00
|
|
|
size_t len;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-04-01 12:41:03 -07:00
|
|
|
len = strlen(tmp) + 1;
|
|
|
|
t = alloca(len);
|
|
|
|
memcpy(t, tmp, len);
|
2007-02-03 05:05:30 -08:00
|
|
|
s = t;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
2007-05-29 13:24:27 -07:00
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
p = strchr(s, ',');
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2007-05-29 13:24:27 -07:00
|
|
|
if (p) *p = '\0';
|
|
|
|
points[i] = atoi(s);
|
|
|
|
|
|
|
|
if (p) s = ++p;
|
|
|
|
else s = NULL;
|
|
|
|
}
|
|
|
|
else
|
2007-02-03 05:05:30 -08:00
|
|
|
{
|
|
|
|
points[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = efreet_ini_string_get(ini, "AttachPoints");
|
|
|
|
if (tmp)
|
|
|
|
{
|
|
|
|
char *t, *s, *p;
|
2010-04-01 12:41:03 -07:00
|
|
|
size_t len;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2010-04-01 12:41:03 -07:00
|
|
|
len = strlen(tmp) + 1;
|
|
|
|
t = alloca(len);
|
|
|
|
memcpy(t, tmp, len);
|
2007-02-03 05:05:30 -08:00
|
|
|
s = t;
|
2007-05-29 12:29:46 -07:00
|
|
|
while (s)
|
2007-02-03 05:05:30 -08:00
|
|
|
{
|
|
|
|
Efreet_Icon_Point *point;
|
|
|
|
|
|
|
|
p = strchr(s, ',');
|
2007-05-29 12:29:46 -07:00
|
|
|
/* If this happens there is something wrong with the .icon file */
|
2007-02-03 05:05:30 -08:00
|
|
|
if (!p) break;
|
|
|
|
|
|
|
|
point = NEW(Efreet_Icon_Point, 1);
|
2010-08-03 12:31:44 -07:00
|
|
|
if (!point) goto error;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
*p = '\0';
|
|
|
|
point->x = atoi(s);
|
|
|
|
|
|
|
|
s = ++p;
|
|
|
|
p = strchr(s, '|');
|
2007-05-29 12:29:46 -07:00
|
|
|
if (p) *p = '\0';
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
point->y = atoi(s);
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
|
|
|
|
icon->attach_points = eina_list_append(icon->attach_points, point);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2007-05-29 12:29:46 -07:00
|
|
|
if (p) s = ++p;
|
|
|
|
else s = NULL;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-03 12:31:44 -07:00
|
|
|
error:
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_ini_free(ini);
|
|
|
|
}
|
|
|
|
|
2010-11-16 13:50:53 -08:00
|
|
|
static const char *
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_lookup_icon(Efreet_Cache_Icon *icon, unsigned int size)
|
2010-11-16 13:50:53 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
const char *path = NULL;
|
|
|
|
double minimal_distance = INT_MAX;
|
|
|
|
unsigned int ret_size = 0;
|
|
|
|
unsigned int i;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
if (!icon) return NULL;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
/* search for allowed size == requested size */
|
|
|
|
for (i = 0; i < icon->icons_count; ++i)
|
|
|
|
{
|
2011-02-10 06:25:00 -08:00
|
|
|
if (!efreet_icon_size_match(icon->icons[i], size)) continue;
|
|
|
|
path = efreet_icon_lookup_path(icon->icons[i]);
|
2010-11-16 13:50:53 -08:00
|
|
|
if (path) return path;
|
2010-11-27 12:36:39 -08:00
|
|
|
}
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
/* search for any icon that matches */
|
|
|
|
for (i = 0; i < icon->icons_count; ++i)
|
|
|
|
{
|
2010-11-26 06:56:23 -08:00
|
|
|
const char *tmp = NULL;
|
2010-11-16 13:50:53 -08:00
|
|
|
double distance;
|
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
distance = efreet_icon_size_distance(icon->icons[i], size);
|
2010-11-16 13:50:53 -08:00
|
|
|
if (distance > minimal_distance) continue;
|
|
|
|
// prefer downsizing
|
|
|
|
if ((distance == minimal_distance) && (size < ret_size)) continue;
|
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
tmp = efreet_icon_lookup_path(icon->icons[i]);
|
2010-11-16 13:50:53 -08:00
|
|
|
if (tmp)
|
2010-11-27 12:36:39 -08:00
|
|
|
{
|
|
|
|
path = tmp;
|
|
|
|
minimal_distance = distance;
|
|
|
|
ret_size = size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
2010-11-16 13:50:53 -08:00
|
|
|
}
|
|
|
|
|
2010-12-04 05:59:48 -08:00
|
|
|
static const char *
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_list_lookup_icon(Efreet_Icon_Theme *theme, Eina_List *icons, unsigned int size)
|
2010-12-04 05:59:48 -08:00
|
|
|
{
|
|
|
|
const char *value = NULL;
|
|
|
|
Efreet_Cache_Icon *cache;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(icons, l, cache)
|
|
|
|
{
|
|
|
|
if (!strcmp(cache->theme, theme->name.internal))
|
|
|
|
{
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_lookup_icon(cache, size);
|
2010-12-04 05:59:48 -08:00
|
|
|
if (value) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (value) return value;
|
|
|
|
if (theme->inherits)
|
|
|
|
{
|
|
|
|
const char *parent;
|
|
|
|
EINA_LIST_FOREACH(theme->inherits, l, parent)
|
|
|
|
{
|
|
|
|
Efreet_Icon_Theme *parent_theme;
|
|
|
|
|
|
|
|
parent_theme = efreet_icon_theme_find(parent);
|
|
|
|
if ((!parent_theme) || (parent_theme == theme)) continue;
|
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_list_lookup_icon(parent_theme, icons, size);
|
2010-12-04 05:59:48 -08:00
|
|
|
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)
|
2011-02-10 06:25:00 -08:00
|
|
|
value = efreet_icon_list_lookup_icon(parent_theme, icons, size);
|
2010-12-04 05:59:48 -08:00
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2010-11-16 13:50:53 -08:00
|
|
|
static int
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_size_match(Efreet_Cache_Icon_Element *elem, unsigned int size)
|
2010-11-16 13:50:53 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
if (elem->type == EFREET_ICON_SIZE_TYPE_FIXED)
|
|
|
|
return (elem->normal == size);
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
if ((elem->type == EFREET_ICON_SIZE_TYPE_SCALABLE) ||
|
|
|
|
(elem->type == EFREET_ICON_SIZE_TYPE_THRESHOLD))
|
|
|
|
return ((elem->min < size) && (size < elem->max));
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
return 0;
|
2010-11-16 13:50:53 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static double
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_size_distance(Efreet_Cache_Icon_Element *elem, unsigned int size)
|
2010-11-16 13:50:53 -08:00
|
|
|
{
|
|
|
|
if (elem->type == EFREET_ICON_SIZE_TYPE_FIXED)
|
2010-11-26 06:56:23 -08:00
|
|
|
return (abs(elem->normal - size));
|
2010-11-16 13:50:53 -08:00
|
|
|
|
|
|
|
if ((elem->type == EFREET_ICON_SIZE_TYPE_SCALABLE) ||
|
|
|
|
(elem->type == EFREET_ICON_SIZE_TYPE_THRESHOLD))
|
|
|
|
{
|
|
|
|
#ifdef STRICT_SPEC
|
2010-11-26 06:56:23 -08:00
|
|
|
if (size < elem->min)
|
|
|
|
return (elem->min - size);
|
|
|
|
if (elem->max < size)
|
|
|
|
return (size - elem->max);
|
2010-11-16 13:50:53 -08:00
|
|
|
#else
|
2010-11-26 06:56:23 -08:00
|
|
|
if (size < elem->min)
|
|
|
|
return (elem->min / (double)size);
|
|
|
|
if (elem->max < size)
|
|
|
|
return (size / (double)elem->max);
|
2010-11-16 13:50:53 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_lookup_path(Efreet_Cache_Icon_Element *elem)
|
2010-11-16 13:50:53 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
Eina_List *xdg_dirs, *l;
|
|
|
|
const char *path;
|
|
|
|
const char *dir;
|
|
|
|
char buf[PATH_MAX];
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
if (elem->paths_count == 1)
|
|
|
|
{
|
2010-11-22 06:15:30 -08:00
|
|
|
const char *pp, *ext;
|
|
|
|
|
2010-11-26 06:56:23 -08:00
|
|
|
pp = strrchr(elem->paths[0], '.');
|
|
|
|
if (!pp) return NULL;
|
2010-11-22 06:15:30 -08:00
|
|
|
|
|
|
|
EINA_LIST_FOREACH(efreet_icon_extensions, l, ext)
|
2010-11-27 12:36:39 -08:00
|
|
|
if (!strcmp(pp, ext))
|
|
|
|
return elem->paths[0];
|
2010-11-22 06:15:30 -08:00
|
|
|
return NULL;
|
2010-11-27 12:36:39 -08:00
|
|
|
}
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_lookup_path_path(elem, efreet_icon_deprecated_user_dir_get());
|
2010-11-27 12:36:39 -08:00
|
|
|
if (path) return path;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_lookup_path_path(elem, efreet_icon_user_dir_get());
|
2010-11-27 12:36:39 -08:00
|
|
|
if (path) return path;
|
2010-11-16 13:50:53 -08:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
EINA_LIST_FOREACH(efreet_extra_icon_dirs, l, dir)
|
|
|
|
{
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_lookup_path_path(elem, dir);
|
2010-11-16 13:50:53 -08:00
|
|
|
if (path) return path;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
xdg_dirs = efreet_data_dirs_get();
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(xdg_dirs, l, dir)
|
2010-11-27 12:36:39 -08:00
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/icons", dir);
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_lookup_path_path(elem, buf);
|
2010-11-27 12:36:39 -08:00
|
|
|
if (path) return path;
|
|
|
|
}
|
2010-11-16 13:50:53 -08:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_lookup_path_path(Efreet_Cache_Icon_Element *elem, const char *path)
|
2010-11-16 13:50:53 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
Eina_List *ll;
|
|
|
|
const char *ext, *pp;
|
|
|
|
unsigned int i;
|
|
|
|
int len;
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
len = strlen(path);
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
for (i = 0; i < elem->paths_count; ++i)
|
|
|
|
{
|
2010-11-26 06:56:23 -08:00
|
|
|
if (strncmp(path, elem->paths[i], len)) continue;
|
|
|
|
pp = strrchr(elem->paths[i], '.');
|
2010-11-16 13:50:53 -08:00
|
|
|
if (!pp) continue;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(efreet_icon_extensions, ll, ext)
|
2010-11-27 12:36:39 -08:00
|
|
|
if (!strcmp(pp, ext))
|
|
|
|
return elem->paths[i];
|
|
|
|
}
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
return NULL;
|
2010-11-16 13:50:53 -08:00
|
|
|
}
|
2010-11-22 12:51:34 -08:00
|
|
|
|
|
|
|
static const char *
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_fallback_lookup_path(Efreet_Cache_Fallback_Icon *icon)
|
2010-11-22 12:51:34 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
const char *path;
|
|
|
|
Eina_List *xdg_dirs, *l;
|
|
|
|
const char *dir;
|
|
|
|
char buf[PATH_MAX];
|
2010-11-22 12:51:34 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
if (!icon) return NULL;
|
2010-11-22 12:51:34 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
if (icon->icons_count == 1)
|
|
|
|
{
|
2010-11-22 12:51:34 -08:00
|
|
|
const char *pp, *ext;
|
|
|
|
|
2010-11-26 06:56:23 -08:00
|
|
|
pp = strrchr(icon->icons[0], '.');
|
|
|
|
if (!pp) return NULL;
|
2010-11-22 12:51:34 -08:00
|
|
|
|
|
|
|
EINA_LIST_FOREACH(efreet_icon_extensions, l, ext)
|
2010-11-27 12:36:39 -08:00
|
|
|
if (!strcmp(pp, ext))
|
|
|
|
return icon->icons[0];
|
2010-11-22 12:51:34 -08:00
|
|
|
return NULL;
|
2010-11-27 12:36:39 -08:00
|
|
|
}
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_fallback_lookup_path_path(icon, efreet_icon_deprecated_user_dir_get());
|
2010-11-27 12:36:39 -08:00
|
|
|
if (path) return path;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_fallback_lookup_path_path(icon, efreet_icon_user_dir_get());
|
2010-11-27 12:36:39 -08:00
|
|
|
if (path) return path;
|
2010-11-22 12:51:34 -08:00
|
|
|
|
|
|
|
EINA_LIST_FOREACH(efreet_extra_icon_dirs, l, dir)
|
|
|
|
{
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_fallback_lookup_path_path(icon, dir);
|
2010-11-22 12:51:34 -08:00
|
|
|
if (path) return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
xdg_dirs = efreet_data_dirs_get();
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(xdg_dirs, l, dir)
|
2010-11-27 12:36:39 -08:00
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/icons", dir);
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_fallback_lookup_path_path(icon, buf);
|
2010-11-27 12:36:39 -08:00
|
|
|
if (path) return path;
|
|
|
|
}
|
2010-11-22 12:51:34 -08:00
|
|
|
|
|
|
|
#ifndef STRICT_SPEC
|
|
|
|
EINA_LIST_FOREACH(xdg_dirs, l, dir)
|
2010-11-27 12:36:39 -08:00
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/pixmaps", dir);
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_fallback_lookup_path_path(icon, buf);
|
2010-11-27 12:36:39 -08:00
|
|
|
if (path) return path;
|
|
|
|
}
|
2010-11-22 12:51:34 -08:00
|
|
|
#endif
|
|
|
|
|
2011-02-10 06:25:00 -08:00
|
|
|
path = efreet_icon_fallback_lookup_path_path(icon, "/usr/share/pixmaps");
|
2010-11-22 12:51:34 -08:00
|
|
|
if (path) return path;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
2011-02-10 06:25:00 -08:00
|
|
|
efreet_icon_fallback_lookup_path_path(Efreet_Cache_Fallback_Icon *icon, const char *path)
|
2010-11-22 12:51:34 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
Eina_List *ll;
|
|
|
|
const char *ext, *pp;
|
|
|
|
unsigned int i;
|
|
|
|
int len;
|
2010-11-22 12:51:34 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
len = strlen(path);
|
2010-11-22 12:51:34 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
for (i = 0; i < icon->icons_count; ++i)
|
|
|
|
{
|
2010-11-26 06:56:23 -08:00
|
|
|
if (strncmp(path, icon->icons[i], len)) continue;
|
2010-11-22 12:51:34 -08:00
|
|
|
|
2010-11-26 06:56:23 -08:00
|
|
|
pp = strrchr(icon->icons[i], '.');
|
2010-11-22 12:51:34 -08:00
|
|
|
if (!pp) continue;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(efreet_icon_extensions, ll, ext)
|
2010-11-27 12:36:39 -08:00
|
|
|
if (!strcmp(pp, ext))
|
|
|
|
return icon->icons[i];
|
|
|
|
}
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
return NULL;
|
2010-11-22 12:51:34 -08:00
|
|
|
}
|
|
|
|
|
2010-11-24 13:10:52 -08:00
|
|
|
static void
|
|
|
|
efreet_icon_changes_listen(void)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Eina_List *xdg_dirs;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
const char *dir;
|
|
|
|
|
|
|
|
if (!efreet_cache_update) return;
|
|
|
|
|
|
|
|
change_monitors = eina_hash_string_superfast_new(EINA_FREE_CB(ecore_file_monitor_del));
|
|
|
|
if (!change_monitors) return;
|
|
|
|
|
|
|
|
efreet_icon_changes_monitor_add(efreet_icon_deprecated_user_dir_get());
|
|
|
|
efreet_icon_changes_monitor_add(efreet_icon_user_dir_get());
|
|
|
|
EINA_LIST_FOREACH(efreet_extra_icon_dirs, l, dir)
|
|
|
|
efreet_icon_changes_monitor_add(dir);
|
|
|
|
|
|
|
|
xdg_dirs = efreet_data_dirs_get();
|
|
|
|
EINA_LIST_FOREACH(xdg_dirs, l, dir)
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/icons", dir);
|
|
|
|
efreet_icon_changes_monitor_add(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef STRICT_SPEC
|
|
|
|
EINA_LIST_FOREACH(xdg_dirs, l, dir)
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/pixmaps", dir);
|
|
|
|
efreet_icon_changes_monitor_add(buf);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
efreet_icon_changes_monitor_add("/usr/share/pixmaps");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
efreet_icon_changes_monitor_add(const char *path)
|
|
|
|
{
|
|
|
|
char rp[PATH_MAX];
|
|
|
|
|
|
|
|
if (!realpath(path, rp)) return;
|
2010-11-24 13:18:56 -08:00
|
|
|
if (!ecore_file_is_dir(rp)) return;
|
2010-11-24 13:10:52 -08:00
|
|
|
if (eina_hash_find(change_monitors, rp)) return;
|
|
|
|
eina_hash_add(change_monitors, rp,
|
|
|
|
ecore_file_monitor_add(rp,
|
|
|
|
efreet_icon_changes_cb,
|
|
|
|
NULL));
|
2010-11-24 13:18:56 -08:00
|
|
|
|
|
|
|
if (ecore_file_is_dir(rp))
|
|
|
|
{
|
|
|
|
Eina_Iterator *it;
|
|
|
|
const char *ent;
|
|
|
|
|
|
|
|
it = eina_file_ls(rp);
|
|
|
|
if (!it) return;
|
|
|
|
EINA_ITERATOR_FOREACH(it, ent)
|
|
|
|
{
|
|
|
|
if (!realpath(ent, rp)) continue;
|
|
|
|
if (!ecore_file_is_dir(rp)) continue;
|
|
|
|
eina_hash_add(change_monitors, rp,
|
2010-11-27 12:36:39 -08:00
|
|
|
ecore_file_monitor_add(rp,
|
|
|
|
efreet_icon_changes_cb,
|
|
|
|
NULL));
|
2010-11-24 13:18:56 -08:00
|
|
|
}
|
2010-12-09 00:56:36 -08:00
|
|
|
eina_iterator_free(it);
|
2010-11-24 13:18:56 -08:00
|
|
|
}
|
2010-11-24 13:10:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
efreet_icon_changes_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__,
|
2010-11-27 12:36:39 -08:00
|
|
|
Ecore_File_Event event, const char *path)
|
2010-11-24 13:10:52 -08:00
|
|
|
{
|
2011-02-11 05:49:25 -08:00
|
|
|
/* TODO: If we get a stale symlink, we need to rerun cache creation */
|
2010-11-24 13:10:52 -08:00
|
|
|
switch (event)
|
|
|
|
{
|
|
|
|
case ECORE_FILE_EVENT_NONE:
|
|
|
|
/* noop */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ECORE_FILE_EVENT_CREATED_FILE:
|
|
|
|
case ECORE_FILE_EVENT_DELETED_FILE:
|
|
|
|
case ECORE_FILE_EVENT_MODIFIED:
|
|
|
|
case ECORE_FILE_EVENT_DELETED_DIRECTORY:
|
|
|
|
case ECORE_FILE_EVENT_CREATED_DIRECTORY:
|
|
|
|
efreet_cache_icon_update();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ECORE_FILE_EVENT_DELETED_SELF:
|
|
|
|
eina_hash_del_by_key(change_monitors, path);
|
|
|
|
efreet_cache_icon_update();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|