efl/legacy/ecore/src/lib/ecore_desktop/ecore_desktop_paths.c

1042 lines
28 KiB
C

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
/*
* This conforms with the freedesktop.org XDG Base Directory Specification version 0.6
*
* The policy here is to add extra directories to the possible search paths to
* cater for quirks of different OS's. It doesn't take long to eliminate an
* excess directory from the paths.
*/
#include <Ecore.h>
#include "Ecore_Desktop.h"
#include "ecore_desktop_private.h"
#include <dirent.h>
#include <sys/stat.h>
#include <libgen.h>
#include <strings.h>
/* This really slows things down and no doubt drags in some KDE bloat at start up.
* To work around this, I add a few extra things to try in the _ecore_desktop_paths_get()
* calls below.
*
#define KDE_SUPPORT 1
*/
/* This is nowhere near as bloated and slow as the KDE stuff, but worthwhile
* making it optional anyway.
*
#define GNOME_SUPPORT 1
*/
/* FIXME: remove those two defines, preload a cache with the guesses, whenever
* we have a few seconds of idle time, run the gnome and kde config proggies
* and correct those guesses.
*/
Ecore_List *ecore_desktop_paths_config = NULL;
Ecore_List *ecore_desktop_paths_menus = NULL;
Ecore_List *ecore_desktop_paths_directories = NULL;
Ecore_List *ecore_desktop_paths_desktops = NULL;
Ecore_List *ecore_desktop_paths_icons = NULL;
Ecore_List *ecore_desktop_paths_kde_legacy = NULL;
Ecore_List *ecore_desktop_paths_xsessions = NULL;
static Ecore_List *_ecore_desktop_paths_get(Ecore_Desktop_Paths_Type path_type,
const char *before, const char *env_home,
const char *env, const char *env_home_default,
const char *env_default, const char *type,
const char *gnome_extra, const char *kde);
static void _ecore_desktop_paths_massage_path(char *path, char *home,
char *first,
char *second);
static void _ecore_desktop_paths_check_and_add(Ecore_List * paths,
const char *path);
static void _ecore_desktop_paths_create(void);
static void _ecore_desktop_paths_destroy(void);
static Ecore_List *gnome_data = NULL;
static Ecore_List *prepend_user_paths[ECORE_DESKTOP_PATHS_MAX];
static Ecore_List *prepend_system_paths[ECORE_DESKTOP_PATHS_MAX];
static Ecore_List *append_user_paths[ECORE_DESKTOP_PATHS_MAX];
static Ecore_List *append_system_paths[ECORE_DESKTOP_PATHS_MAX];
static char *home;
static int init_count = 0;
#if defined GNOME_SUPPORT || defined KDE_SUPPORT
struct _config_exe_data
{
char *home;
Ecore_List *paths, *types;
int done;
};
static void _ecore_desktop_paths_exec_config(Ecore_List * paths,
char *home,
Ecore_List * extras,
char *cmd);
static int _ecore_desktop_paths_cb_exe_exit(void *data, int type,
void *event);
static Ecore_Event_Handler *exit_handler = NULL;
#endif
EAPI int
ecore_desktop_paths_init(void)
{
if (++init_count != 1)
return init_count;
#if defined GNOME_SUPPORT || defined KDE_SUPPORT
exit_handler =
ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
_ecore_desktop_paths_cb_exe_exit, NULL);
#endif
ecore_desktop_paths_extras_clear();
gnome_data = ecore_list_new();
home = ecore_desktop_home_get();
if (gnome_data)
{
#ifdef GNOME_SUPPORT
if (exit_handler)
{
ecore_list_free_cb_set(gnome_data, free);
_ecore_desktop_paths_exec_config(gnome_data, home, NULL,
"gnome-config --datadir");
}
#else
Ecore_List *config_list;
config_list = ecore_desktop_paths_to_list("/opt/gnome/share");
if (config_list)
{
char *this_config;
char path[PATH_MAX];
ecore_list_first_goto(config_list);
while ((this_config = ecore_list_next(config_list)) != NULL)
{
_ecore_desktop_paths_massage_path(path, home,
this_config, NULL);
_ecore_desktop_paths_check_and_add(gnome_data, path);
}
E_FN_DEL(ecore_list_destroy, config_list);
}
#endif
}
_ecore_desktop_paths_create();
return init_count;
}
EAPI int
ecore_desktop_paths_shutdown(void)
{
int i;
if (--init_count != 0)
return init_count;
for (i = 0; i < ECORE_DESKTOP_PATHS_MAX; i++)
{
E_FN_DEL(ecore_list_destroy, prepend_user_paths[i]);
E_FN_DEL(ecore_list_destroy, prepend_system_paths[i]);
E_FN_DEL(ecore_list_destroy, append_user_paths[i]);
E_FN_DEL(ecore_list_destroy, append_system_paths[i]);
}
_ecore_desktop_paths_destroy();
E_FN_DEL(ecore_list_destroy, gnome_data);
#if defined GNOME_SUPPORT || defined KDE_SUPPORT
if (exit_handler)
ecore_event_handler_del(exit_handler);
#endif
free(home);
return init_count;
}
EAPI void
ecore_desktop_paths_regen(void)
{
_ecore_desktop_paths_destroy();
_ecore_desktop_paths_create();
}
static void
_ecore_desktop_paths_create(void)
{
if (!ecore_desktop_paths_desktops)
{
ecore_desktop_paths_desktops =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_DESKTOPS, NULL,
"XDG_DATA_HOME", "XDG_DATA_DIRS",
"~/.local/share:~/.kde/share",
"/usr/local/share:/usr/share",
// "applications:applnk:applications/kde",
"applications:applnk",
"dist/desktop-files:dist/short-menu:gnome/apps",
"xdgdata-apps:apps");
_ecore_desktop_paths_check_and_add(ecore_desktop_paths_desktops,
"/usr/local/share/update-desktop-files/templates");
_ecore_desktop_paths_check_and_add(ecore_desktop_paths_desktops,
"/usr/share/update-desktop-files/templates");
}
if (!ecore_desktop_paths_kde_legacy)
{
#ifdef KDE_SUPPORT
ecore_desktop_paths_kde_legacy =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_KDE_LEGACY, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, "apps");
#else
ecore_desktop_paths_kde_legacy =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_KDE_LEGACY, NULL,
"XDG_DATA_HOME", "XDG_DATA_DIRS",
"~/.local/share:~/.kde/share",
"/usr/local/share:/usr/share", "applnk",
NULL, "apps");
#endif
if (ecore_desktop_paths_kde_legacy)
{
char temp[PATH_MAX], *path;
Ecore_List *temp_list;
/* Copy it, cause Ecore_List walks can not be nested. */
temp_list = ecore_list_new();
if (temp_list)
{
ecore_list_first_goto(ecore_desktop_paths_kde_legacy);
while ((path =
ecore_list_next(ecore_desktop_paths_kde_legacy)) !=
NULL)
ecore_list_append(temp_list, path);
ecore_list_first_goto(temp_list);
while ((path = ecore_list_next(temp_list)) != NULL)
{
char *t1, *t2;
t1 = rindex(path, '/');
*t1 = '\0';
t2 = rindex(path, '/');
*t2 = '\0';
sprintf(temp, "%s/apps/kappfinder/apps/", path);
*t2 = '/';
*t1 = '/';
_ecore_desktop_paths_check_and_add
(ecore_desktop_paths_kde_legacy, temp);
}
}
ecore_list_destroy(temp_list);
}
}
if (!ecore_desktop_paths_icons)
{
char *gnome;
ecore_desktop_paths_icons =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_ICONS, "~/.icons",
"XDG_DATA_HOME", "XDG_DATA_DIRS",
"~/.local/share:~/.kde/share",
"/usr/local/share:/usr/share:/usr/X11R6/share",
"icons:pixmaps", "dist/icons",
"icon:pixmap");
_ecore_desktop_paths_check_and_add(ecore_desktop_paths_icons,
"/usr/local/share/pixmaps/");
_ecore_desktop_paths_check_and_add(ecore_desktop_paths_icons,
"/usr/share/pixmaps/");
_ecore_desktop_paths_check_and_add(ecore_desktop_paths_icons,
"/usr/share/update-desktop-files/kappfinder-icons/");
gnome = getenv("GNOME_ICON_PATH");
if (gnome)
_ecore_desktop_paths_check_and_add(ecore_desktop_paths_icons, gnome);
}
if (!ecore_desktop_paths_menus)
ecore_desktop_paths_menus =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_MENUS, NULL,
"XDG_CONFIG_HOME", "XDG_CONFIG_DIRS",
"~/.config", "/etc/xdg:/var/lib/menu-xdg",
"menus", NULL, "xdgconf-menu");
if (!ecore_desktop_paths_directories)
ecore_desktop_paths_directories =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_DIRECTORIES, NULL,
"XDG_DATA_HOME", "XDG_DATA_DIRS",
"~/.local/share:~/.kde/share",
"/usr/local/share:/usr/share",
"desktop-directories", "gnome/vfolders",
"xdgdata-dirs");
if (!ecore_desktop_paths_config)
ecore_desktop_paths_config =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_CONFIG, NULL,
"XDG_CONFIG_HOME", "XDG_CONFIG_DIRS",
"~/.config", "/etc/xdg", NULL, NULL, NULL);
if (!ecore_desktop_paths_xsessions)
ecore_desktop_paths_xsessions =
_ecore_desktop_paths_get(ECORE_DESKTOP_PATHS_XSESSIONS, NULL,
"XDG_DATA_HOME", "XDG_DATA_DIRS",
"~/.local/share:~/.kde/share",
"/usr/local/share:/usr/share", "xsessions",
NULL, NULL);
}
static void
_ecore_desktop_paths_destroy(void)
{
E_FN_DEL(ecore_list_destroy, ecore_desktop_paths_xsessions);
E_FN_DEL(ecore_list_destroy, ecore_desktop_paths_config);
E_FN_DEL(ecore_list_destroy, ecore_desktop_paths_directories);
E_FN_DEL(ecore_list_destroy, ecore_desktop_paths_menus);
E_FN_DEL(ecore_list_destroy, ecore_desktop_paths_icons);
E_FN_DEL(ecore_list_destroy, ecore_desktop_paths_kde_legacy);
E_FN_DEL(ecore_list_destroy, ecore_desktop_paths_desktops);
}
EAPI void
ecore_desktop_paths_extras_clear(void)
{
int i;
for (i = 0; i < ECORE_DESKTOP_PATHS_MAX; i++)
{
E_FN_DEL(ecore_list_destroy, prepend_user_paths[i]);
E_FN_DEL(ecore_list_destroy, prepend_system_paths[i]);
E_FN_DEL(ecore_list_destroy, append_user_paths[i]);
E_FN_DEL(ecore_list_destroy, append_system_paths[i]);
prepend_user_paths[i] = ecore_list_new();
if (prepend_user_paths[i])
ecore_list_free_cb_set(prepend_user_paths[i], free);
prepend_system_paths[i] = ecore_list_new();
if (prepend_system_paths[i])
ecore_list_free_cb_set(prepend_system_paths[i], free);
append_user_paths[i] = ecore_list_new();
if (append_user_paths[i])
ecore_list_free_cb_set(append_user_paths[i], free);
append_system_paths[i] = ecore_list_new();
if (append_system_paths[i])
ecore_list_free_cb_set(append_system_paths[i], free);
}
}
EAPI void
ecore_desktop_paths_prepend_user(Ecore_Desktop_Paths_Type type, const char *paths)
{
if (prepend_user_paths[type])
ecore_list_append(prepend_user_paths[type], strdup(paths));
}
EAPI void
ecore_desktop_paths_prepend_system(Ecore_Desktop_Paths_Type type, const char *paths)
{
if (prepend_system_paths[type])
ecore_list_append(prepend_system_paths[type], strdup(paths));
}
EAPI void
ecore_desktop_paths_append_user(Ecore_Desktop_Paths_Type type, const char *paths)
{
if (append_user_paths[type])
ecore_list_append(append_user_paths[type], strdup(paths));
}
EAPI void
ecore_desktop_paths_append_system(Ecore_Desktop_Paths_Type type, const char *paths)
{
if (append_system_paths[type])
ecore_list_append(append_system_paths[type], strdup(paths));
}
/** Search for a file in fdo compatible locations.
*
* This will search through all the diretories of a particular type, looking
* for the file. It will recurse into subdirectories. If func is NULL, then
* only the first file found will be returned. If func is defined, then each
* file found will be passed to func, until func returns 1.
*
* The returned string will have to be freed eventually.
*
* @param type The type of directories to search.
* @param file The file to search for.
* @param sub Levels of sub directories to search, -1 = all, 0 = none.
* @param func A function to call for each file found.
* @param data A pointer to pass on to func.
*/
char *
ecore_desktop_paths_file_find(Ecore_List * paths, const char *file, int sub,
int (*func) (void *data, const char *path),
void *data)
{
char *path = NULL, *this_path;
char temp[PATH_MAX];
struct stat path_stat;
if (!paths) return NULL;
ecore_list_first_goto(paths);
while ((this_path = ecore_list_next(paths)) != NULL)
{
if (path)
{
free(path);
path = NULL;
}
snprintf(temp, PATH_MAX, "%s%s", this_path, file);
if (stat(temp, &path_stat) == 0)
{
path = strdup(temp);
if ((func) && (func(data, temp)))
break;
}
else if (sub != 0)
path =
ecore_desktop_paths_recursive_search(this_path, file, sub,
NULL, func, data);
if (path && (!func))
break;
}
return path;
}
/* We need -
config file full of paths
menus=pathlist
desktops=pathlist
directories=pathlist
icons=pathlist
*/
static Ecore_List *
_ecore_desktop_paths_get(Ecore_Desktop_Paths_Type path_type,
const char *before, const char *env_home, const char *env,
const char *env_home_default, const char *env_default, const char *type,
const char *gnome_extra, const char *kde)
{
Ecore_List *paths = NULL;
Ecore_List *types = NULL;
Ecore_List *gnome_extras = NULL;
char path[PATH_MAX];
Ecore_List *env_list;
#ifdef KDE_SUPPORT
Ecore_List *kdes = NULL;
#endif
paths = ecore_list_new();
if (!paths) return NULL;
ecore_list_free_cb_set(paths, free);
/* Don't sort them, as they are in preferred order from each source. */
/* Merge the results, there are probably some duplicates. */
if (type)
types = ecore_desktop_paths_to_list(type);
if (gnome_extra)
gnome_extras = ecore_desktop_paths_to_list(gnome_extra);
#ifdef KDE_SUPPORT
if (kde)
kdes = ecore_desktop_paths_to_list(kde);
#else
kde = NULL;
#endif
if (before)
{
Ecore_List *befores;
befores = ecore_desktop_paths_to_list(before);
if (befores)
{
char *this_before;
ecore_list_first_goto(befores);
while ((this_before = ecore_list_next(befores)) != NULL)
{
_ecore_desktop_paths_massage_path(path, home,
this_before, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
E_FN_DEL(ecore_list_destroy, befores);
}
}
if (prepend_user_paths[path_type])
{
char *this_path;
ecore_list_first_goto(prepend_user_paths[path_type]);
while ((this_path = ecore_list_next(prepend_user_paths[path_type])) != NULL)
{
_ecore_desktop_paths_massage_path(path, home, this_path, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
if (env_home)
{
const char *value;
value = getenv(env_home);
if ((value == NULL) || (value[0] == '\0'))
value = env_home_default;
env_list = ecore_desktop_paths_to_list(value);
if (env_list)
{
char *this_env;
ecore_list_first_goto(env_list);
while ((this_env = ecore_list_next(env_list)) != NULL)
{
if (types)
{
char *this_type;
ecore_list_first_goto(types);
while ((this_type = ecore_list_next(types)) != NULL)
{
_ecore_desktop_paths_massage_path(path, home,
this_env, this_type);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
else
{
_ecore_desktop_paths_massage_path(path, home, this_env, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
E_FN_DEL(ecore_list_destroy, env_list);
}
}
if (append_user_paths[path_type])
{
char *this_path;
ecore_list_first_goto(append_user_paths[path_type]);
while ((this_path = ecore_list_next(append_user_paths[path_type])) != NULL)
{
_ecore_desktop_paths_massage_path(path, home, this_path, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
if (prepend_system_paths[path_type])
{
char *this_path;
ecore_list_first_goto(prepend_system_paths[path_type]);
while ((this_path = ecore_list_next(prepend_system_paths[path_type])) != NULL)
{
_ecore_desktop_paths_massage_path(path, home, this_path, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
if (env)
{
const char *value;
value = getenv(env);
if ((value == NULL) || (value[0] == '\0'))
value = env_default;
env_list = ecore_desktop_paths_to_list(value);
if (env_list)
{
char *this_env;
ecore_list_first_goto(env_list);
while ((this_env = ecore_list_next(env_list)) != NULL)
{
if (types)
{
char *this_type;
ecore_list_first_goto(types);
while ((this_type = ecore_list_next(types)) != NULL)
{
_ecore_desktop_paths_massage_path(path, home,
this_env, this_type);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
else
{
_ecore_desktop_paths_massage_path(path, home, this_env, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
E_FN_DEL(ecore_list_destroy, env_list);
}
}
if (append_system_paths[path_type])
{
char *this_path;
ecore_list_first_goto(append_system_paths[path_type]);
while ((this_path = ecore_list_next(append_system_paths[path_type])) != NULL)
{
_ecore_desktop_paths_massage_path(path, home, this_path, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
/*
* Get the pathlist from the config file - type=pathlist
* for each path in config
* if it is already in paths, skip it
* if it exists, add it to end of paths
*/
if (gnome_data)
{
char *this_gnome;
ecore_list_first_goto(gnome_data);
while ((this_gnome = ecore_list_next(gnome_data)) != NULL)
{
if (types)
{
char *this_type;
ecore_list_first_goto(types);
while ((this_type = ecore_list_next(types)) != NULL)
{
_ecore_desktop_paths_massage_path(path, home,
this_gnome, this_type);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
else
{
_ecore_desktop_paths_massage_path(path, home, this_gnome, NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
}
if (gnome_data && gnome_extras)
{
char *this_gnome, *this_type;
ecore_list_first_goto(gnome_data);
while ((this_gnome = ecore_list_next(gnome_data)) != NULL)
{
ecore_list_first_goto(gnome_extras);
while ((this_type = ecore_list_next(gnome_extras)) != NULL)
{
_ecore_desktop_paths_massage_path(path, home,
this_gnome, this_type);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
}
#ifdef KDE_SUPPORT
if ((exit_handler != NULL) && (kdes != NULL))
{
char *this_kde;
ecore_list_first_goto(kdes);
while ((this_kde = ecore_list_next(kdes)) != NULL)
{
char cmd[128];
sprintf(cmd, "kde-config --path %s", this_kde);
_ecore_desktop_paths_exec_config(paths, home, NULL, cmd);
}
}
#endif
#ifdef KDE_SUPPORT
E_FN_DEL(ecore_list_destroy, kdes);
#endif
E_FN_DEL(ecore_list_destroy, gnome_extras);
E_FN_DEL(ecore_list_destroy, types);
return paths;
}
static void
_ecore_desktop_paths_massage_path(char *path, char *home, char *first,
char *second)
{
int last;
/* Strip traling slash of first. */
last = strlen(first) - 1;
while ((last >= 0) && (first[last] == '/'))
{
first[last] = '\0';
last--;
}
if (second)
{
/* Strip traling slash of second. */
last = strlen(second) - 1;
while ((last >= 0) && (second[last] == '/'))
{
second[last] = '\0';
last--;
}
}
if ((second) && (second[0] != '\0'))
{
if (first[0] == '~')
sprintf(path, "%s%s/%s/", home, &first[1],
&second[(second[0] == '/') ? 1 : 0]);
else
sprintf(path, "%s/%s/", first, &second[(second[0] == '/') ? 1 : 0]);
}
else
{
if (first[0] == '~')
sprintf(path, "%s%s/", home, &first[1]);
else
sprintf(path, "%s/", first);
}
}
static void
_ecore_desktop_paths_check_and_add(Ecore_List * paths, const char *path)
{
struct stat path_stat;
char *this_path;
if (!paths) return;
/* Check if we have it already. */
ecore_list_first_goto(paths);
while ((this_path = ecore_list_next(paths)) != NULL)
{
if (strcmp(path, this_path) == 0)
return;
}
/* Check if the path exists. */
if ((stat(path, &path_stat) == 0) && (S_ISDIR(path_stat.st_mode)))
ecore_list_append(paths, strdup(path));
}
char *
ecore_desktop_paths_recursive_search(const char *path, const char *file,
int sub, int (*dir_func) (void *data,
const char
*path),
int (*func) (void *data, const char *path),
void *data)
{
char *fpath = NULL;
DIR *dir = NULL;
struct dirent *script;
if ((sub != 0) && (sub != -1))
sub -= 1;
dir = opendir(path);
if (!dir) return NULL;
while ((script = readdir(dir)) != NULL)
{
struct stat script_stat;
char info_text[PATH_MAX];
sprintf(info_text, "%s%s", path, script->d_name);
if ((stat(info_text, &script_stat) == 0))
{
if (S_ISDIR(script_stat.st_mode))
{
if ((strcmp(basename(info_text), ".") != 0) &&
(strcmp(basename(info_text), "..") != 0))
{
snprintf(info_text, PATH_MAX, "%s%s/", path, script->d_name);
if ((dir_func) && (dir_func(data, info_text)))
break;
if (sub != 0)
{
if (fpath) free(fpath);
fpath =
ecore_desktop_paths_recursive_search(info_text, file, sub,
dir_func, func, data);
}
}
}
else
{
if (file)
{
if (strcmp(basename(info_text), file) == 0)
{
if (fpath)
free(fpath);
fpath = strdup(info_text);
if ((func) && (func(data, path)))
break;
}
}
else
{
if ((func) && (func(data, info_text)))
break;
}
}
if (fpath && (!func))
break;
}
}
closedir(dir);
return fpath;
}
#if defined GNOME_SUPPORT || defined KDE_SUPPORT
static void
_ecore_desktop_paths_exec_config(Ecore_List * paths, char *home,
Ecore_List * extras, char *cmd)
{
Ecore_Exe *exe;
struct _config_exe_data ced;
ced.home = home;
ced.paths = paths;
ced.types = extras;
ced.done = 0;
exe =
ecore_exe_pipe_run(cmd,
ECORE_EXE_PIPE_AUTO | ECORE_EXE_PIPE_READ |
ECORE_EXE_PIPE_READ_LINE_BUFFERED, &ced);
if (exe)
{
ecore_exe_tag_set(exe, "genmenu/fdo");
while (ced.done == 0)
{
/* FIXME: raster is paranoid. If too much time passes, give up.
* Or find a way to let the usual event loop shit do this without
* spinning our wheels. On the other hand, these are quick
* commands, and we NEED this data before we can continue. On
* the gripping hand, some tweaking of the stuff searched for not
* only gets rid of the need for this, but also speeds things up
* drastically.
*/
ecore_main_loop_iterate();
usleep(10);
}
}
}
static int
_ecore_desktop_paths_cb_exe_exit(void *data, int type, void *event)
{
Ecore_Exe_Event_Del *ev;
Ecore_List *paths;
Ecore_List *config_list;
Ecore_Exe_Event_Data *read;
struct _config_exe_data *ced;
char *value;
char path[PATH_MAX];
ev = event;
if (!ev->exe)
return 1;
value = ecore_exe_tag_get(ev->exe);
if ((!value) || (strcmp(value, "genmenu/fdo")) != 0)
return 1;
ced = ecore_exe_data_get(ev->exe);
if (!ced)
return 1;
paths = ced->paths;
if (!paths)
return 1;
read = ecore_exe_event_data_get(ev->exe, ECORE_EXE_PIPE_READ);
if ((read) && (read->lines[0].line))
{
value = read->lines[0].line;
config_list = ecore_desktop_paths_to_list(value);
if (config_list)
{
char *this_config, *this_type;
ecore_list_first_goto(config_list);
while ((this_config = ecore_list_next(config_list)) != NULL)
{
if (ced->types)
{
ecore_list_first_goto(ced->types);
while ((this_type =
ecore_list_next(ced->types)) != NULL)
{
_ecore_desktop_paths_massage_path(path,
ced->home,
this_config,
this_type);
_ecore_desktop_paths_check_and_add(paths,
path);
}
}
else
{
_ecore_desktop_paths_massage_path(path, ced->home,
this_config,
NULL);
_ecore_desktop_paths_check_and_add(paths, path);
}
}
E_FN_DEL(ecore_list_destroy, config_list);
}
}
ced->done = 1;
return 1;
}
#endif
/** Split a list of paths into an Ecore_Hash.
*
* The list of paths can use any one of ;:, to seperate the paths.
* You can also escape the :;, with \.
*
* @param paths A list of paths.
*/
Ecore_Hash *
ecore_desktop_paths_to_hash(const char *paths)
{
Ecore_Hash *result;
char *path;
char buf[PATH_MAX], *p, *pp;
if (!paths) return NULL;
result = ecore_hash_new(ecore_str_hash, ecore_str_compare);
if (!result) return NULL;
ecore_hash_free_key_cb_set(result, free);
ecore_hash_free_value_cb_set(result, free);
path = strdup(paths);
if (path)
{
p = path;
while (p)
{
pp = buf;
while (*p)
{
/* Check for escape */
if (*p == '\\')
{
/* If separator, skip escape */
if ((*(p + 1) == ';') || (*(p + 1) == ':') || (*(p + 1) == ','))
p++;
}
/* Check for separator */
else if ((*p == ';') || (*p == ':') || (*p == ','))
break;
*pp = *p;
pp++;
p++;
}
*pp = '\0';
if (*buf) ecore_hash_set(result, strdup(buf), strdup(buf));
if (*p) p++;
else p = NULL;
}
free(path);
}
return result;
}
/** Split a list of paths into an Ecore_Hash.
*
* The list of paths can use any one of ;:, to seperate the paths.
* You can also escape the :;, with \.
*
* @param paths A list of paths.
*/
Ecore_List *
ecore_desktop_paths_to_list(const char *paths)
{
Ecore_List *result;
char *path;
char buf[PATH_MAX], *p, *pp;
if (!paths) return NULL;
result = ecore_list_new();
if (!result) return NULL;
ecore_list_free_cb_set(result, free);
path = strdup(paths);
if (path)
{
p = path;
while (p)
{
pp = buf;
while (*p)
{
/* Check for escape */
if (*p == '\\')
{
/* If separator, skip escape */
if ((*(p + 1) == ';') || (*(p + 1) == ':') || (*(p + 1) == ','))
p++;
}
/* Check for separator */
else if ((*p == ';') || (*p == ':') || (*p == ','))
break;
*pp = *p;
pp++;
p++;
}
*pp = '\0';
if (*buf) ecore_list_append(result, strdup(buf));
if (*p) p++;
else p = NULL;
}
free(path);
}
return result;
}
EAPI int
ecore_desktop_paths_for_each(Ecore_Desktop_Paths_Type type,
Ecore_For_Each function, void *user_data)
{
Ecore_List *list = NULL;
switch (type)
{
case ECORE_DESKTOP_PATHS_CONFIG:
list = ecore_desktop_paths_config;
break;
case ECORE_DESKTOP_PATHS_MENUS:
list = ecore_desktop_paths_menus;
break;
case ECORE_DESKTOP_PATHS_DIRECTORIES:
list = ecore_desktop_paths_directories;
break;
case ECORE_DESKTOP_PATHS_DESKTOPS:
list = ecore_desktop_paths_desktops;
break;
case ECORE_DESKTOP_PATHS_ICONS:
list = ecore_desktop_paths_icons;
break;
case ECORE_DESKTOP_PATHS_KDE_LEGACY:
list = ecore_desktop_paths_kde_legacy;
break;
case ECORE_DESKTOP_PATHS_XSESSIONS:
list = ecore_desktop_paths_xsessions;
break;
case ECORE_DESKTOP_PATHS_MAX:
break;
}
if (list)
return ecore_list_for_each(list, function, user_data);
return 0;
}