ecore.spec \
ecore-con.pc \
ecore-config.pc \
- ecore-desktop.pc \
ecore-directfb.pc\
ecore-evas.pc \
ecore-fb.pc \
ecore.pc.in \
ecore-con.pc.in \
ecore-config.pc.in \
- ecore-desktop.pc.in \
ecore-directfb.pc.in\
ecore-evas.pc.in \
ecore-fb.pc.in \
pfile = ecore-file.pc
endif
-if BUILD_ECORE_DESKTOP
-pdesktop = ecore-desktop.pc
-endif
-
if BUILD_ECORE_IMF
pimf = ecore-imf.pc
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = \
ecore.pc $(pcon) $(pconfig) $(pdfb) $(pevas) \
- $(pfb) $(pfile) $(pdesktop) $(pimf) $(pimfevas) $(pipc) $(pjob) $(ptxt) \
+ $(pfb) $(pfile) $(pimf) $(pimfevas) $(pipc) $(pjob) $(ptxt) \
$(px) $(pwin32) $(pwince) $(psdl) $(pquartz)
# only the trivial requirements go here.
requirements_ecore_con=""
requirements_ecore_config=""
-requirements_ecore_desktop=""
requirements_ecore_directfb=""
requirements_ecore_evas="evas"
requirements_ecore_fb=""
requirements_ecore_file="$requirements_ecore_file $requirements_ecore_con"
fi
-dnl ecore_desktop
-ECORE_CHECK_MODULE([Desktop], [no], [$have_ecore_file],
- [requirements_ecore_desktop="ecore-file"])
-
dnl ecore_imf
ECORE_CHECK_MODULE([IMF], [yes])
dnl requirements
AC_SUBST(requirements_ecore_con)
AC_SUBST(requirements_ecore_config)
-AC_SUBST(requirements_ecore_desktop)
AC_SUBST(requirements_ecore_directfb)
AC_SUBST(requirements_ecore_evas)
AC_SUBST(requirements_ecore_fb)
Makefile
ecore-con.pc
ecore-config.pc
-ecore-desktop.pc
ecore-directfb.pc
ecore-evas.pc
ecore-fb.pc
src/lib/ecore_txt/Makefile
src/lib/ecore_config/Makefile
src/lib/ecore_file/Makefile
-src/lib/ecore_desktop/Makefile
src/lib/ecore_directfb/Makefile
src/lib/ecore_win32/Makefile
src/lib/ecore_wince/Makefile
echo " Poll.......................: $have_poll"
echo " CURL.......................: $have_curl"
fi
-echo " Ecore_Desktop................: $have_ecore_desktop"
echo " Ecore_Con....................: $have_ecore_con"
if test "x$have_ecore_con" = "xyes" ; then
echo -n " OpenSSL....................: $have_openssl"
+++ /dev/null
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: ecore-desktop
-Description: E core library, Desktop module
-Requires: ecore @requirements_ecore_desktop@
-Version: @VERSION@
-Libs: -L${libdir} -lecore_desktop
-Cflags: -I${includedir}
ecore_evas \
ecore_config \
ecore_file \
-ecore_desktop \
ecore_imf \
ecore_imf_evas
+++ /dev/null
-.deps
-.libs
-Makefile
-Makefile.in
-*.lo
-*.la
+++ /dev/null
-#ifndef _ECORE_DESKTOP_H
-# define _ECORE_DESKTOP_H
-
-#include <Ecore_Data.h>
-#include <sys/types.h>
-
-/**
- * @file Ecore_Desktop.h
- * @brief The file that provides the freedesktop.org desktop, icon, and menu
- * functions.
- *
- * This header provides the Ecore_Desktop freedesktop.org desktop, icon,
- * and menu handling functions, as well as ancillary functions for searching
- * freedesktop.org specific paths. Other freedesktop.org specifications
- * make use of similar files, paths, and icons, implementors can use / extend
- * this code to suit.
- *
- * Ecore_Desktop is not for every freedesktop.org specification, just those that
- * are associated with .desktop files.
- *
- * For path searching details, see @ref Ecore_Desktop_Paths_Group.
- *
- * For desktop file details, see @ref Ecore_Desktop_Main_Group.
- *
- * For icon theme details, see @ref Ecore_Desktop_Icon_Group.
- *
- * For menu file details, see @ref Ecore_Desktop_Menu_Group.
- */
-
-struct _Ecore_Desktop
-{
- /* FIXME: Do the ECORE_MAGIC thing here.
- * While this might help with segfaults and such, I think it's a waste of
- * space and cycles that just covers up bugs. On the other hand, it makes
- * for a more robust library, and it's used everywhere else in ecore.
- */
- Eina_Hash *data, *group, *Categories, *OnlyShowIn, *NotShowIn, *MimeTypes, *Actions;
- char *original_path;
- char *original_lang;
- char *eap_name;
- char *name;
- char *generic;
- char *comment;
- char *type;
- char *categories;
- char *exec;
- char *exec_params;
- char *icon_class;
- char *icon_theme;
- char *icon;
- char *icon_path;
- time_t icon_time; /* For checking if the icon cache is valid. */
- char *path;
- char *URL;
- char *file;
- char *deletiondate;
- char *window_class; /* window class */
- char *window_name; /* window name */
- char *window_title; /* window title */
- char *window_role; /* window role */
- unsigned char wait_exit:1; /* wait for app to exit before execing next */
- unsigned char startup:1;
- unsigned char hidden:1;
- unsigned char no_display:1;
- unsigned char allocated:1;
- unsigned char ondisk:1;
- unsigned char hard_icon:1;
- /* Actually calling this st_mtime causes compile issues, must be some strange macros at work. */
- time_t mtime; /* For checking if the cache is valid. */
-};
-typedef struct _Ecore_Desktop Ecore_Desktop;
-
-struct _Ecore_Desktop_Icon_Theme
-{
- Eina_Hash *data, *group;
- Ecore_List *Inherits;
- Ecore_List *Directories;
- char *path;
- char *name;
- char *comment;
- char *example;
- char *example_path;
- char *inherits;
- char *directories;
- int hidden;
- unsigned char hicolor:1;
- /* Actually calling this st_mtime causes compile issues, must be some strange macros at work. */
- time_t mtime; /* For checking if the cache is valid. */
- double last_checked;
-};
-typedef struct _Ecore_Desktop_Icon_Theme Ecore_Desktop_Icon_Theme;
-
-struct _Ecore_Desktop_Icon_Theme_Directory
-{
- Eina_Hash *icons;
- char *path;
- char *full_path;
- char *type;
- int size, minimum, maximum, threshold;
-};
-typedef struct _Ecore_Desktop_Icon_Theme_Directory
- Ecore_Desktop_Icon_Theme_Directory;
-
-enum _Ecore_Desktop_Paths_Type
-{
- ECORE_DESKTOP_PATHS_CONFIG = 0,
- ECORE_DESKTOP_PATHS_MENUS = 1,
- ECORE_DESKTOP_PATHS_DIRECTORIES = 2,
- ECORE_DESKTOP_PATHS_DESKTOPS = 3,
- ECORE_DESKTOP_PATHS_ICONS = 4,
- ECORE_DESKTOP_PATHS_KDE_LEGACY = 5,
- ECORE_DESKTOP_PATHS_XSESSIONS = 6,
- ECORE_DESKTOP_PATHS_MAX = 7
-};
-typedef enum _Ecore_Desktop_Paths_Type Ecore_Desktop_Paths_Type;
-
-enum _Ecore_Desktop_Tree_Element_Type
-{
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL = 0,
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING = 1,
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE = 2,
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH = 3
-};
-typedef enum _Ecore_Desktop_Tree_Element_Type Ecore_Desktop_Tree_Element_Type;
-
-struct _Ecore_Desktop_Tree_Element
-{
- void *element; /* A pointer to the element. */
- Ecore_Desktop_Tree_Element_Type type; /* The type of the element. */
-};
-typedef struct _Ecore_Desktop_Tree_Element Ecore_Desktop_Tree_Element;
-
-typedef struct _Ecore_Desktop_Tree Ecore_Desktop_Tree;
-struct _Ecore_Desktop_Tree
-{
- Ecore_Desktop_Tree_Element *elements; /* An array of elements. */
- int size; /* The size of the array. */
- char **buffers; /* An array of pointers to the bits of data. */
- int buffers_size; /* The size of the array. */
- Ecore_Desktop_Tree *parent; /* Parent if this is a child. */
-};
-
-struct _Ecore_Desktop_Instrumentation
-{
- double desktops_time;
- double desktops_in_cache_time;
- double desktops_not_found_time;
- double icons_time;
- double icons_in_cache_time;
- double icons_not_found_time;
- int desktops;
- int desktops_in_cache;
- int desktops_not_found;
- int icons;
- int icons_in_cache;
- int icons_not_found;
-};
-
-
-# ifdef __cplusplus
-extern "C"
-{
-# endif
-
- /* Function Prototypes */
- EAPI int ecore_desktop_paths_init(void);
- EAPI void ecore_desktop_paths_extras_clear(void);
- EAPI void ecore_desktop_paths_prepend_user(Ecore_Desktop_Paths_Type
- type, const char *paths);
- EAPI void
- ecore_desktop_paths_prepend_system(Ecore_Desktop_Paths_Type type,
- const char *paths);
- EAPI void ecore_desktop_paths_append_user(Ecore_Desktop_Paths_Type
- type, const char *paths);
- EAPI void
- ecore_desktop_paths_append_system(Ecore_Desktop_Paths_Type type,
- const char *paths);
- EAPI void ecore_desktop_paths_regen(void);
- char *ecore_desktop_paths_file_find(Ecore_List * paths,
- const char *file, int sub,
- int (*func) (void
- *data,
- const char
- *path),
- void *data);
- EAPI int ecore_desktop_paths_for_each(Ecore_Desktop_Paths_Type
- type,
- Ecore_For_Each function,
- void *user_data);
- 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);
- EAPI int ecore_desktop_paths_shutdown(void);
-
- Eina_Hash *ecore_desktop_paths_to_hash(const char *paths);
- Ecore_List *ecore_desktop_paths_to_list(const char *paths);
-
- EAPI int ecore_desktop_init(void);
- EAPI int ecore_desktop_shutdown(void);
- Eina_Hash *ecore_desktop_ini_get(const char *file);
- Ecore_Desktop *ecore_desktop_get(const char *file, const char *lang);
- void ecore_desktop_save(Ecore_Desktop * desktop);
- EAPI Ecore_List *ecore_desktop_get_command(Ecore_Desktop * desktop,
- Ecore_List * files, int fill);
- EAPI char *ecore_desktop_merge_command(char *exec, char *params);
- void ecore_desktop_destroy(Ecore_Desktop * desktop);
-
- EAPI int ecore_desktop_icon_init(void);
- EAPI int ecore_desktop_icon_shutdown(void);
- EAPI char *ecore_desktop_icon_find(const char *icon,
- const char *icon_size,
- const char *icon_theme);
-
- Eina_Hash *ecore_desktop_icon_theme_list(void);
- Ecore_Desktop_Icon_Theme *ecore_desktop_icon_theme_get(const char *file,
- const char *lang);
- void ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme
- * icon_theme);
-
- EAPI void
- ecore_desktop_menu_for_each(void (*func)
- (const char *name, const char *path, const char *directory, Eina_Hash * apps));
- Ecore_Desktop_Tree *ecore_desktop_menu_get(char *file);
-
- Ecore_Desktop_Tree *ecore_desktop_tree_new(char *buffer);
- Ecore_Desktop_Tree *ecore_desktop_tree_add(Ecore_Desktop_Tree * tree,
- const char *element);
- void ecore_desktop_tree_track(Ecore_Desktop_Tree * tree,
- void *element);
- Ecore_Desktop_Tree *ecore_desktop_tree_extend(Ecore_Desktop_Tree * tree,
- const char *element);
- Ecore_Desktop_Tree *ecore_desktop_tree_insert(Ecore_Desktop_Tree * tree,
- int before, void *element,
- Ecore_Desktop_Tree_Element_Type
- type);
- Ecore_Desktop_Tree *ecore_desktop_tree_merge(Ecore_Desktop_Tree * tree,
- int before,
- Ecore_Desktop_Tree * element);
- Ecore_Desktop_Tree *ecore_desktop_tree_add_child(Ecore_Desktop_Tree * tree,
- Ecore_Desktop_Tree *
- element);
- Ecore_Desktop_Tree *ecore_desktop_tree_add_hash(Ecore_Desktop_Tree * tree,
- Eina_Hash * element);
- void ecore_desktop_tree_remove(Ecore_Desktop_Tree * tree,
- int element);
- int ecore_desktop_tree_exist(Ecore_Desktop_Tree * tree,
- char *element);
- int ecore_desktop_tree_foreach(Ecore_Desktop_Tree * tree,
- int level,
- int (*func) (const void *data,
- Ecore_Desktop_Tree
- * tree,
- int element,
- int level),
- const void *data);
- void ecore_desktop_tree_dump(Ecore_Desktop_Tree * tree,
- int level);
- void ecore_desktop_tree_del(Ecore_Desktop_Tree * tree);
-
- Ecore_Desktop_Tree *ecore_desktop_xmlame_new(char *buffer);
- Ecore_Desktop_Tree *ecore_desktop_xmlame_get(char *file);
-
- char *ecore_desktop_home_get(void);
-
- EAPI void ecore_desktop_instrumentation_reset(void);
- EAPI void ecore_desktop_instrumentation_print(void);
-
-# ifdef __cplusplus
-}
-# endif
-
-#endif
+++ /dev/null
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CPPFLAGS = \
--I$(top_srcdir)/src/lib/ecore \
--I$(top_builddir)/src/lib/ecore_file \
--I$(top_builddir)/src/lib/ecore_desktop \
--I$(top_builddir)/src/lib/ecore \
--I$(top_srcdir)/src/lib/ecore_file \
--I$(top_srcdir)/src/lib/ecore_desktop \
-@EINA_CFLAGS@
-
-if BUILD_ECORE_DESKTOP
-
-lib_LTLIBRARIES = libecore_desktop.la
-include_HEADERS = \
-Ecore_Desktop.h
-
-libecore_desktop_la_SOURCES = \
-ecore_desktop.c \
-ecore_desktop_tree.c \
-ecore_desktop_icon.c \
-ecore_desktop_menu.c \
-ecore_desktop_paths.c \
-ecore_desktop_xmlame.c
-
-libecore_desktop_la_LIBADD = \
-$(top_builddir)/src/lib/ecore/libecore.la \
-$(top_builddir)/src/lib/ecore_file/libecore_file.la \
-@EINA_LIBS@
-
-libecore_desktop_la_LDFLAGS = -version-info @version_info@
-
-endif
-
-EXTRA_DIST = ecore_desktop_private.h
+++ /dev/null
-/*
- * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
- */
-
-#include "Ecore_Desktop.h"
-#include "ecore_desktop_private.h"
-
-#include <ctype.h>
-#include <sys/stat.h>
-
-struct _Ecore_Desktop_Instrumentation instrumentation;
-
-extern int reject_count, not_over_count;
-
-static int init_count = 0;
-
-static Eina_Hash *desktop_cache = NULL;
-
-Ecore_Desktop *_ecore_desktop_get(const char *file, const char *lang);
-void _ecore_desktop_destroy(Ecore_Desktop * desktop);
-
-#define IFGETDUP(src, key, dst) src = (char *)eina_hash_find(result->group, key); if (src) dst = strdup(src); else dst = NULL;
-#define IFFREE(src) if (src) free(src); src = NULL;
-
-/**
- * @defgroup Ecore_Desktop_Main_Group .desktop file Functions
- *
- * Functions that deal with freedesktop.org desktop files.
- *
- * This conforms with the freedesktop.org XDG Desktop Entry Specification version 0.9.4
- */
-
-/**
- * Get the contents of a .ini style file.
- *
- * The Eina_Hash returned is a two level hash, the first level
- * is the groups in the file, one per group, keyed by the name
- * of that group. The value of each of those first level hashes
- * is the second level Eina_Hash, the contents of each group.
- *
- * @param file Full path to the .ini style file.
- * @return An Eina_Hash of the files contents.
- * @ingroup Ecore_Desktop_Main_Group
- */
-Eina_Hash *
-ecore_desktop_ini_get(const char *file)
-{
- Eina_Hash *result;
- FILE *f;
- char buffer[PATH_MAX];
- Eina_Hash *current = NULL;
-
- result = eina_hash_string_superfast_new(eina_hash_free);
- if (!result) return NULL;
-
- f = fopen(file, "r");
- if (!f)
- {
- fprintf(stderr, "ERROR: Cannot Open File %s\n", file);
- eina_hash_free(result);
- return NULL;
- }
- *buffer = '\0';
-#ifdef DEBUG
- fprintf(stdout, "PARSING INI %s\n", file);
-#endif
- while (fgets(buffer, sizeof(buffer), f) != NULL)
- {
- char *c;
- char *key;
- char *value;
-
- c = buffer;
- /* Strip preceeding blanks. Note that \n is treated differently from the other white space. */
- while ((*c == ' ') || (*c == '\t'))
- c++;
- /* Skip blank lines and comments */
- if ((*c == '\0') || (*c == '\n') || (*c == '#')) continue;
- if (*c == '[') /* New group. */
- {
- key = c + 1;
- while ((*c != ']') && (*c != '\n') && (*c != '\0'))
- c++;
- *c++ = '\0';
- current = ein_hash_string_superfast_new(free);
- if (current)
- {
- eina_hash_add(result, key, current);
-#ifdef DEBUG
- fprintf(stdout, " GROUP [%s]\n", key);
-#endif
- }
- }
- else if (current) /* key=value pair of current group. */
- {
- char *tv;
-
- key = c;
- /* Find trailing blanks or =. */
- while ((*c != '=') && (*c != ' ') && (*c != '\t') && (*c != '\n') && (*c != '\0'))
- c++;
- if (*c != '=') /* Find equals. */
- {
- *c++ = '\0';
- while ((*c != '=') && (*c != '\n') && (*c != '\0'))
- c++;
- }
- if (*c == '=') /* Equals found. */
- {
- *c++ = '\0';
- /* Strip preceeding blanks. Note that \n is treated differently from the other white space. */
- while ((*c == ' ') || (*c == '\t'))
- c++;
- value = c;
- /* Find end. */
- while ((*c != '\n') && (*c != '\0'))
- c++;
- *c++ = '\0';
- /* FIXME: should strip space at end, then unescape value. */
- eina_hash_del(current, key);
- if (value[0] != '\0')
- eina_hash_add(current, key, strdup(value));
-#ifdef DEBUG
- fprintf(stdout, " %s=%s\n", key, value);
-#endif
- }
- }
-
- }
-
- fclose(f);
- return result;
-}
-
-/**
- * Get the contents of a .desktop file.
- *
- * Use ecore_desktop_destroy() to free this structure.
- *
- * @param file Full path to the .desktop file.
- * @param lang Language to use, or NULL for default.
- * @return An Ecore_Desktop containing the files contents.
- * @ingroup Ecore_Desktop_Main_Group
- */
-Ecore_Desktop *
-ecore_desktop_get(const char *file, const char *lang)
-{
- Ecore_Desktop *result;
-
- result = _ecore_desktop_get(file, lang);
- if (result)
- {
- /* Kill the hash, it takes up way too much memory. */
- if (result->data)
- {
- eina_hash_free(result->data);
- result->data = NULL;
- }
- result->group = NULL;
- }
-
- return result;
-}
-
-Ecore_Desktop *
-_ecore_desktop_get(const char *file, const char *lang)
-{
- Ecore_Desktop *result;
- struct stat st;
- char *value;
- int stated = 0;
- int in_cache = 0;
- double begin;
-
- begin = ecore_time_get();
- result = eina_hash_find(desktop_cache, (char *)file);
- /* Check if the cache is still valid. */
- if (result)
- {
- in_cache = 1;
- if (stat(result->original_path, &st) >= 0)
- {
- if (st.st_mtime > result->mtime)
- {
- eina_hash_del(desktop_cache, result->original_path);
- result = NULL;
- }
- stated = 1;
- }
- }
- /* Not in cache, get it the slow way. */
- if (!result)
- {
- result = calloc(1, sizeof(Ecore_Desktop));
- if (!result) goto error;
- result->ondisk = 1;
- result->original_path = strdup(file);
- if (lang)
- result->original_lang = strdup(lang);
- result->data = ecore_desktop_ini_get(result->original_path);
- if (!result->data)
- {
- IFFREE(result->original_path);
- IFFREE(result->original_lang);
- free(result);
- result = NULL;
- goto error;
- }
- /* Timestamp the cache, and no need to stat the file twice if the cache was stale. */
- if ((stated) || (stat(result->original_path, &st) >= 0))
- result->mtime = st.st_mtime;
- result->group = eina_hash_find(result->data, "Desktop Entry");
- if (!result->group)
- result->group = eina_hash_find(result->data, "KDE Desktop Entry");
- /* This is a "Desktop" file, probably an application. */
- if (result->group)
- {
- int size = 0;
-
- value = (char *) ecore_file_file_get(result->original_path);
- /* Figure out the eap_name. */
- if (value)
- {
- char *temp;
-
- temp = strrchr(value, '.');
-
- if (temp) *temp = '\0';
- result->eap_name = malloc(strlen(value) + 5);
- if (result->eap_name)
- sprintf(result->eap_name, "%s.edj", value);
- if (temp) *temp = '.';
- }
-
- IFGETDUP(value, "Name", result->name);
- IFGETDUP(value, "GenericName", result->generic);
- IFGETDUP(value, "Comment", result->comment);
- IFGETDUP(value, "Type", result->type);
-
- IFGETDUP(value, "Path", result->path);
- IFGETDUP(value, "URL", result->URL);
- IFGETDUP(value, "File", result->file);
-
- IFGETDUP(value, "Exec", result->exec);
- /* Seperate out the params. */
- if (result->exec)
- {
- char *exe = NULL;
-
- exe = strchr(result->exec, ' ');
- if (exe)
- {
- *exe = '\0';
- exe++;
- /* trim the parameter string */
- for(; isspace(*exe) && ((exe - result->exec) < PATH_MAX) && (*exe != '\0'); exe++);
- if(*exe != '\0')
- result->exec_params = strdup(exe);
- }
- }
-
- IFGETDUP(value, "StartupWMClass", result->window_class);
- /* Guess a window class - exe name with first letter capitalized. */
- if ((!value) && (result->exec))
- {
- char *tmp;
-
- tmp = strdup(result->exec);
- if (tmp)
- {
- char *p;
-
- value = (char *)ecore_file_file_get(tmp); /* In case the exe included a path. */
- p = value;
- while ((*p != '\0') && (*p != ' '))
- {
- *p = tolower(*p);
- p++;
- }
- *p = '\0';
- *value = toupper(*value);
- result->window_class = strdup(value);
- free(tmp);
- }
- }
- IFGETDUP(value, "X-Enlightenment-WindowName", result->window_name);
- IFGETDUP(value, "X-Enlightenment-WindowTitle", result->window_title);
- IFGETDUP(value, "X-Enlightenment-WindowRole", result->window_role);
-
- IFGETDUP(value, "Categories", result->categories);
- if (result->categories)
- result->Categories =
- ecore_desktop_paths_to_hash(result->categories);
- IFGETDUP(value, "Icon", result->icon);
- IFGETDUP(value, "X-Enlightenment-IconTheme", result->icon_theme);
- IFGETDUP(value, "X-Enlightenment-IconClass", result->icon_class);
- IFGETDUP(value, "X-Enlightenment-IconPath", result->icon_path);
-
- /* If the icon is a path put the full path into the icon_path member.*/
- if ((result->icon != NULL) && (result->icon_path == NULL) &&
- (strchr(result->icon, '/') != NULL))
- {
- if (result->icon[0] == '/')
- {
- result->icon_path = strdup(result->icon);
- }
- else /* It's a relative path. */
- {
- char *temp;
-
- size =
- strlen(result->original_path) +
- strlen(result->icon) + 2;
- temp = malloc(size);
- if (temp)
- {
- char *dir;
-
- dir =
- ecore_file_dir_get(result->original_path);
- if (dir)
- {
- sprintf(temp, "%s/%s", dir, result->icon);
- result->icon_path =
- ecore_file_realpath(temp);
- free(dir);
- }
- free(temp);
- }
- }
- result->hard_icon = 1;
- }
-
- if ((result->icon_theme == NULL) && (result->icon_path != NULL))
- result->hard_icon = 1;
-
- /* icon/class is a list of standard icons from the theme that can override the icon created above.
- * Use (from .desktop) name.edj,exec,categories. It's case sensitive, the reccomendation is to lowercase it.
- * It should be most specific to most generic. firefox,browser,internet for instance
- * If the icon in the file is not a full path, just put it first in the class, greatly simplifies things later
- * when it's time to do the search.
- */
- if (!result->icon_class)
- {
- size = 0;
- if ((result->icon) && (strchr(result->icon, '/') == NULL))
- size += strlen(result->icon) + 1;
- if (result->eap_name)
- size += strlen(result->eap_name) + 1;
- if (result->exec)
- size += strlen(result->exec) + 1;
- if (result->categories)
- size += strlen(result->categories) + 1;
- result->icon_class = malloc(size + 1);
- if (result->icon_class)
- {
- char *p;
- int done = 0;
-
- result->icon_class[0] = '\0';
- if ((result->icon) && (strchr(result->icon, '/') == NULL) &&
- (result->icon[0] != '\0'))
- {
- strcat(result->icon_class, result->icon);
- done = 1;
- }
- /* We do this here coz we don't want to lower case the result->icon part later. */
- p = result->icon_class;
- p += strlen(result->icon_class);
- if ((result->eap_name) && (result->eap_name[0] != '\0'))
- {
- if (done)
- strcat(result->icon_class, ",");
- strcat(result->icon_class, result->eap_name);
- done = 1;
- }
- if ((result->exec) && (result->exec[0] != '\0'))
- {
- char *tmp;
-
- tmp = strdup(ecore_file_file_get(result->exec));
- if (tmp)
- {
- char *p2;
-
- p2 = tmp;
- while (*p2 != '\0')
- {
- if (*p2 == ' ')
- {
- *p2 = '\0';
- break;
- }
- p2++;
- }
- if (done)
- strcat(result->icon_class, ",");
- strcat(result->icon_class, tmp);
- done = 1;
- free(tmp);
- }
- }
- if ((result->categories) && (result->categories[0] != '\0'))
- {
- if (done)
- strcat(result->icon_class, ",");
- strcat(result->icon_class, result->categories);
- done = 1;
- }
- while (*p != '\0')
- {
- if (*p == ';')
- *p = ',';
- else
- *p = tolower(*p);
- p++;
- }
- if (result->icon_class[0] == '\0')
- {
- free(result->icon_class);
- result->icon_class = NULL;
- }
- }
- }
-
- value = eina_hash_find(result->group, "MimeType");
- if (value)
- result->MimeTypes =
- ecore_desktop_paths_to_hash(value);
- value = eina_hash_find(result->group, "Actions");
- if (value)
- result->Actions =
- ecore_desktop_paths_to_hash(value);
- value = eina_hash_find(result->group, "OnlyShowIn");
- if (value)
- result->OnlyShowIn =
- ecore_desktop_paths_to_hash(value);
- value = eina_hash_find(result->group, "NotShowIn");
- if (value)
- result->NotShowIn =
- ecore_desktop_paths_to_hash(value);
- value = eina_hash_find(result->group, "X-KDE-StartupNotify");
- if (value)
- result->startup = (strcmp(value, "true") == 0);
- value = eina_hash_find(result->group, "StartupNotify");
- if (value)
- result->startup = (strcmp(value, "true") == 0);
- value = eina_hash_find(result->group, "X-Enlightenment-WaitExit");
- if (value)
- result->wait_exit = (strcmp(value, "true") == 0);
- value = eina_hash_find(result->group, "NoDisplay");
- if (value)
- result->no_display = (strcmp(value, "true") == 0);
- value = eina_hash_find(result->group, "Hidden");
- if (value)
- result->hidden = (strcmp(value, "true") == 0);
- }
- else
- {
- /*Maybe it's a 'trash' file - which also follows the Desktop FDO spec */
- result->group = eina_hash_find(result->data, "Trash Info");
- if (result->group)
- {
- IFGETDUP(value, "Path", result->path);
- IFGETDUP(value, "DeletionDate",
- result->deletiondate);
- }
- }
-
- /* Final sanity check. */
- if ((result->data) && (!result->group))
- {
- _ecore_desktop_destroy(result);
- result = NULL;
- }
- else
- eina_hash_add(desktop_cache, result->original_path, result);
- }
-
-error:
- if (result)
- {
- if (in_cache)
- {
- instrumentation.desktops_in_cache_time += ecore_time_get() - begin;
- instrumentation.desktops_in_cache++;
- }
- else
- {
- instrumentation.desktops_time += ecore_time_get() - begin;
- instrumentation.desktops++;
- }
- }
- else
- {
- instrumentation.desktops_not_found_time += ecore_time_get() - begin;
- instrumentation.desktops_not_found++;
- }
- return result;
-}
-
-static Eina_Bool
-_hash_keys(Eina_Hash *hash, const void *key, void *data, void *list)
-{
- ecore_list_append(list, key);
- return EINA_TRUE;
-}
-
-void
-ecore_desktop_save(Ecore_Desktop * desktop)
-{
- Ecore_List *commands;
- char *temp;
- int trash = 0;
-
- if (!desktop->group)
- {
- if ((desktop->ondisk) && (desktop->original_path))
- {
- desktop->data = ecore_desktop_ini_get(desktop->original_path);
- desktop->group =
- (Eina_Hash *) eina_hash_find(desktop->data, "Desktop Entry");
- if (!desktop->group)
- desktop->group =
- (Eina_Hash *) eina_hash_find(desktop->data,
- "KDE Desktop Entry");
- if (!desktop->group)
- {
- trash = 1;
- desktop->group =
- (Eina_Hash *) eina_hash_find(desktop->data, "Trash Info");
- }
- }
- else
- desktop->group = eina_hash_string_superfast_new(free);
- }
-
- if (desktop->group)
- {
- if (desktop->original_path)
- {
- struct stat st;
-
- if (stat(desktop->original_path, &st) >= 0)
- {
- char *real;
-
- real = ecore_file_readlink(desktop->original_path);
- if (real)
- eina_hash_add(desktop->group,
- "X-Enlightenment-OriginalPath",
- real);
- }
- }
-
- /* We are not passing a list of files, so we only expect one command. */
- commands = ecore_desktop_get_command(desktop, NULL, 0);
- if (commands)
- {
- temp = ecore_list_first(commands);
- if (temp)
- eina_hash_add(desktop->group, "Exec", strdup(temp));
- ecore_list_destroy(commands);
- }
-
- if (desktop->name)
- eina_hash_add(desktop->group, "Name",
- strdup(desktop->name));
- if (desktop->generic)
- eina_hash_add(desktop->group, "GenericName",
- strdup(desktop->generic));
- if (desktop->comment)
- eina_hash_add(desktop->group, "Comment",
- strdup(desktop->comment));
- if (desktop->type)
- eina_hash_add(desktop->group, "Type",
- strdup(desktop->type));
- if (desktop->URL)
- eina_hash_add(desktop->group, "URL", strdup(desktop->URL));
- if (desktop->file)
- eina_hash_add(desktop->group, "File",
- strdup(desktop->file));
- if (desktop->icon)
- eina_hash_add(desktop->group, "Icon",
- strdup(desktop->icon));
- if (desktop->icon_theme)
- eina_hash_add(desktop->group, "X-Enlightenment-IconTheme",
- strdup(desktop->icon_theme));
- else
- eina_hash_del(desktop->group, "X-Enlightenment-IconTheme");
- if (desktop->icon_class)
- eina_hash_add(desktop->group, "X-Enlightenment-IconClass",
- strdup(desktop->icon_class));
- else
- eina_hash_del(desktop->group, "X-Enlightenment-IconClass");
- if (desktop->icon_path)
- eina_hash_add(desktop->group, "X-Enlightenment-IconPath",
- strdup(desktop->icon_path));
- else
- eina_hash_del(desktop->group, "X-Enlightenment-IconPath");
- if (desktop->window_class)
- eina_hash_add(desktop->group, "StartupWMClass",
- strdup(desktop->window_class));
- if (desktop->categories)
- eina_hash_add(desktop->group, "Categories",
- strdup(desktop->categories));
- if (desktop->window_name)
- eina_hash_add(desktop->group, "X-Enlightenment-WindowName",
- strdup(desktop->window_name));
- else
- eina_hash_del(desktop->group, "X-Enlightenment-WindowName");
- if (desktop->window_title)
- eina_hash_add(desktop->group, "X-Enlightenment-WindowTitle",
- strdup(desktop->window_title));
- else
- eina_hash_del(desktop->group, "X-Enlightenment-WindowTitle");
- if (desktop->window_role)
- eina_hash_add(desktop->group, "X-Enlightenment-WindowRole",
- strdup(desktop->window_role));
- else
- eina_hash_del(desktop->group, "X-Enlightenment-WindowRole");
- eina_hash_del(desktop->group, "X-KDE-StartupNotify");
- if (desktop->wait_exit)
- eina_hash_add(desktop->group, "X-Enlightenment-WaitExit",
- strdup("true"));
- else
- eina_hash_del(desktop->group, "X-Enlightenment-WaitExit");
- if (desktop->startup)
- eina_hash_add(desktop->group, "StartupNotify",
- strdup("true"));
- else
- eina_hash_del(desktop->group, "StartupNotify");
- if (desktop->no_display)
- eina_hash_add(desktop->group, "NoDisplay", strdup("true"));
- else
- eina_hash_del(desktop->group, "NoDisplay");
- if (desktop->hidden)
- eina_hash_add(desktop->group, "Hidden", strdup("true"));
- else
- eina_hash_del(desktop->group, "Hidden");
-
- /* FIXME: deal with the ShowIn's and mime stuff. */
-
- if (desktop->path)
- eina_hash_add(desktop->group, "Path",
- strdup(desktop->path));
- if (desktop->deletiondate)
- eina_hash_add(desktop->group, "DeletionDate",
- strdup(desktop->deletiondate));
-
- if (desktop->original_path)
- {
- FILE *f;
- Ecore_List *list;
- char *key;
- Eina_Iterator *it = NULL;
-
- ecore_file_unlink(desktop->original_path);
- f = fopen(desktop->original_path, "wb");
-
- if ((list = ecore_list_new()))
- return;
-
- if ((it = eina_hash_iterator_key_new(desktop->group)))
- {
- ecore_list_destroy(list);
- return;
- }
-
- eina_iterator_foreach(it, EINA_EACH(_hash_keys), list);
- eina_iterator_free(it);
-
- if ((!f) || (!list))
- return;
-
- if (trash)
- fprintf(f, "[Trash Info]\n");
- else
- fprintf(f, "[Desktop Entry]\n");
- ecore_list_first_goto(list);
- while ((key = (char *)ecore_list_next(list)))
- {
- char *value;
-
- value = (char *)eina_hash_find(desktop->group, key);
- if ((value) && (value[0] != '\0'))
- fprintf(f, "%s=%s\n", key, value);
- }
- fclose(f);
- }
-
- if (desktop->data)
- {
- eina_hash_free(desktop->data);
- desktop->data = NULL;
- }
- else
- eina_hash_free(desktop->group);
- desktop->group = NULL;
- }
-}
-
-/**
- * Setup what ever needs to be setup to support Ecore_Desktop.
- *
- * There are internal structures that are needed for Ecore_Desktop
- * functions to operate, this sets them up.
- *
- * @ingroup Ecore_Desktop_Main_Group
- */
-EAPI int
-ecore_desktop_init()
-{
- if (++init_count != 1)
- return init_count;
-
- if (!ecore_desktop_paths_init())
- return --init_count;
-
- if (!desktop_cache)
- desktop_cache = eina_hash_string_superfast_new(_ecore_desktop_destroy);
-
- if (!ecore_desktop_icon_init())
- return --init_count;
-
- return init_count;
-}
-
-/**
- * Tear down what ever needs to be torn down to support Ecore_Desktop.
- *
- * There are internal structures that are needed for Ecore_Desktop
- * functions to operate, this tears them down.
- *
- * @ingroup Ecore_Desktop_Main_Group
- */
-EAPI int
-ecore_desktop_shutdown()
-{
- if (--init_count != 0)
- return init_count;
-
- ecore_desktop_icon_shutdown();
-
- if (desktop_cache)
- {
- eina_hash_free(desktop_cache);
- desktop_cache = NULL;
- }
-
- ecore_desktop_paths_shutdown();
-
- return init_count;
-}
-
-/**
- * Free whatever resources are used by an Ecore_Desktop.
- *
- * There are internal resources used by each Ecore_Desktop
- * This releases those resources.
- *
- * @param desktop An Ecore_Desktop that was previously returned by ecore_desktop_get().
- * @ingroup Ecore_Desktop_Main_Group
- */
-void
-ecore_desktop_destroy(Ecore_Desktop * desktop)
-{
- /* This is just a dummy, because these structures are cached. */
- /* Later versions of the cache may reference count, then this will be useful. */
- desktop = NULL;
-}
-
-void
-_ecore_desktop_destroy(Ecore_Desktop * desktop)
-{
- IFFREE(desktop->original_path);
- IFFREE(desktop->original_lang);
- IFFREE(desktop->eap_name);
- IFFREE(desktop->name);
- IFFREE(desktop->generic);
- IFFREE(desktop->comment);
- IFFREE(desktop->type);
- IFFREE(desktop->exec);
- IFFREE(desktop->exec_params);
- IFFREE(desktop->categories);
- IFFREE(desktop->icon);
- IFFREE(desktop->icon_theme);
- IFFREE(desktop->icon_class);
- IFFREE(desktop->icon_path);
- IFFREE(desktop->path);
- IFFREE(desktop->URL);
- IFFREE(desktop->file);
- IFFREE(desktop->deletiondate);
- IFFREE(desktop->window_class);
- IFFREE(desktop->window_name);
- IFFREE(desktop->window_title);
- IFFREE(desktop->window_role);
- if (desktop->NotShowIn) eina_hash_free(desktop->NotShowIn);
- if (desktop->OnlyShowIn) eina_hash_free(desktop->OnlyShowIn);
- if (desktop->Categories) eina_hash_free(desktop->Categories);
- if (desktop->MimeTypes) eina_hash_free(desktop->MimeTypes);
- if (desktop->Actions) eina_hash_free(desktop->Actions);
- if (desktop->data)
- {
- eina_hash_free(desktop->data);
- desktop->data = NULL;
- }
- desktop->group = NULL;
- free(desktop);
-}
-
-/**
- * Get and massage the users home directory.
- *
- * This is an internal function that may be useful elsewhere.
- *
- * @return The users howe directory.
- * @ingroup Ecore_Desktop_Main_Group
- */
-char *
-ecore_desktop_home_get()
-{
- char home[PATH_MAX];
- int len;
-
- /* Get Home Dir, check for trailing '/', strip it */
- if (getenv("HOME"))
- strncpy(home, getenv("HOME"), PATH_MAX);
- else
- strcpy(home, "/");
- len = strlen(home) - 1;
- while ((len >= 0) && (home[len] == '/'))
- {
- home[len] = '\0';
- len--;
- }
-
- return strdup(home);
-}
-
-EAPI Ecore_List *
-ecore_desktop_get_command(Ecore_Desktop * desktop, Ecore_List * files, int fill)
-{
- Ecore_List *result;
- char *sub_result = NULL, *params = NULL;
- int is_single = 0, do_file = 0;
-
- result = ecore_list_new();
- if (!result) return NULL;
- ecore_list_free_cb_set(result, free);
-
- if (desktop->exec_params)
- params = strdup(desktop->exec_params);
-
-#ifdef DEBUG
-if (files)
- {
- char *file;
-
- ecore_list_first_goto(files);
- while((file = ecore_list_next(files)) != NULL)
- printf("FILE FOR COMMAND IS - %s\n", file);
- }
-#endif
-
- if (files)
- ecore_list_first_goto(files);
-
- /* FIXME: The string handling could be better, but it's good enough for now. */
- do
- {
- if (fill)
- {
- Ecore_DList *command;
- char *p, buf[PATH_MAX + 10], *big_buf = NULL;
- const char *t;
- int len = 0;
-
- command = ecore_dlist_new();
- if (!command) goto error;
-
- ecore_dlist_free_cb_set(command, free);
- /* Grab a fresh copy of the params. The default is %F as per rasters request. */
- if (params) free(params);
- if (desktop->exec_params)
- params = strdup(desktop->exec_params);
- else
- params = strdup("%F");
- if (!params) goto error;
- /* Split it up. */
- t = params;
- for (p = params; *p; p++)
- {
- if (*p == '%')
- {
- *p = '\0';
- ecore_dlist_append(command, strdup(t));
- len += strlen(t) + 1;
- *p = '%';
- t = p;
- }
- }
- if (t < p)
- {
- ecore_dlist_append(command, strdup(t));
- len += strlen(t) + 1;
- }
- free(params);
- params = NULL;
- t = NULL;
- p = NULL;
- /* Check the bits for replacables. */
- if (!ecore_dlist_empty_is(command))
- {
- ecore_dlist_first_goto(command);
- while ((p = ecore_dlist_next(command)) != NULL)
- {
- int is_URL = 0, is_directory = 0, is_file = 0;
-
- t = NULL;
- do_file = 0;
- is_single = 0;
- if (p[0] == '%')
- switch (p[1])
- {
- case 'f': /* Single file name, multiple invokations if multiple files. If the file is on the net, download first and point to temp file. */
- do_file = 1;
- is_single = 1;
- break;
-
- case 'u': /* Single URL, multiple invokations if multiple URLs. */
- do_file = 1;
- is_single = 1;
- is_URL = 1;
- break;
-
- case 'c': /* Translated Name field from .desktop file. */
- t = desktop->name;
- break;
-
- case 'k': /* Location of the .desktop file, may be a URL, or empty. */
- t = desktop->original_path;
- break;
-
- case 'F': /* Multiple file names. If the files are on the net, download first and point to temp files. */
- do_file = 1;
- break;
-
- case 'U': /* Multiple URLs. */
- do_file = 1;
- is_URL = 1;
- break;
-
- case 'd': /* Directory of the file in %f. */
- do_file = 1;
- is_single = 1;
- is_directory = 1;
- break;
-
- case 'D': /* Directories of the files in %F. */
- do_file = 1;
- is_directory = 1;
- break;
-
- case 'n': /* Single filename without path. */
- do_file = 1;
- is_single = 1;
- is_file = 1;
- break;
-
- case 'N': /* Multiple filenames without paths. */
- do_file = 1;
- is_file = 1;
- break;
-
- case 'i': /* "--icon Icon" field from .desktop file, or empty. */
- if (desktop->icon)
- {
- snprintf(buf, sizeof(buf), "--icon %s", desktop->icon);
- t = buf;
- }
- break;
-
- case 'm': /* Deprecated mini icon, the spec says we can just drop it. */
- break;
-
- case 'v': /* Device field from .desktop file. */
- break;
-
- case '%': /* A '%' character. */
- t = "%";
- break;
-
- default:
- break;
- }
- /* Take care of any file expansions. */
- if (do_file && (files))
- {
- char *file;
- size_t big_len;
-
- /* Pre load the big_buf so that the reallocs are quick. WEemight eventually need more than PATH_MAX. */
- big_buf = malloc(PATH_MAX);
- big_buf[0] = '\0';
- big_len = 0;
- while((file = ecore_list_next(files)) != NULL)
- {
- char *text = NULL, *escaped = NULL;
-
- if (is_URL)
- {
- /* FIXME: The spec is unclear about what they mean by URL,
- * GIMP uses %U, but doesn't understand file://foo
- * GIMP is also happy if you pass it a raw file name.
- * For now, just make this the same as is_file.
- */
- text = strdup(file);
- }
- else if (is_directory)
- {
- /* FIXME: for onefang
- * if filename does not start with ./ or ../ or / then assume it
- * is a path relative to cwd i.e. "file.png" or "blah/file.png" and
- * thus %d/%D would be ./ implicitly (but may need to be explicit
- * in the command line)
- */
- text = ecore_file_dir_get(file);
- }
- else if (is_file)
- text = strdup(ecore_file_file_get(file));
- else
- {
- /* FIXME: If the file is on the net, download
- * first and point to temp file.
- *
- * This I think is the clue to how the whole
- * file/url thing is supposed to work. This is
- * purely speculation though, and you can get
- * into lots of trouble with specs that require
- * geussing like this.
- *
- * %u%U - pass filenames or URLS.
- * %f%F - pass filenames, download URLS and pass path to temp file.
- *
- * WE are not currently getting URLs passed to us anyway.
- */
- text = strdup(file);
- }
- if (text)
- {
- escaped = ecore_file_escape_name(text);
- free(text);
- text = NULL;
- }
- /* Add it to the big buf. */
- if (escaped)
- {
- big_len += strlen(escaped) + 2;
- big_buf = realloc(big_buf, big_len);
- strcat(big_buf, " ");
- strcat(big_buf, escaped);
- t = big_buf;
- free(escaped);
- escaped = NULL;
- }
- if (is_single)
- break;
- }
- }
- /* Insert this bit into the command. */
- if (t)
- {
- ecore_dlist_previous(command);
- ecore_dlist_insert(command, strdup(t));
- len += strlen(t) + 1;
- ecore_dlist_next(command);
- ecore_dlist_next(command);
- }
- if (big_buf)
- {
- free(big_buf);
- big_buf = NULL;
- }
- }
-
- /* Put it all together. */
- params = malloc(len + 1);
- if (params)
- {
- params[0] = '\0';
- ecore_dlist_first_goto(command);
- while ((p = ecore_dlist_next(command)) != NULL)
- {
- if (p[0] == '%')
- strcat(params, &p[2]);
- else
- strcat(params, p);
- }
- }
- }
- ecore_list_destroy(command);
- }
-
- /* Add the command to the list of commands. */
- /* NOTE: params might be just desktop->exec_params, or it might have been built from bits. */
- sub_result = ecore_desktop_merge_command(desktop->exec, params);
- if (sub_result)
- {
-#ifdef DEBUG
- printf("FULL COMMAND IS - %s\n", sub_result);
-#endif
- ecore_list_append(result, sub_result);
- }
- /* If there is any "single file" things to fill in, and we have more files,
- * go back and do it all again for the next file.
- */
- }
- while((do_file) && (is_single) && (fill) && (files) && (ecore_list_current(files)));
-
-error:
- if (params) free(params);
- return result;
-}
-
-EAPI char *
-ecore_desktop_merge_command(char *exec, char *params)
-{
- int size;
- char *end, *result = NULL;
-
- if ((exec) && (params))
- {
- size = strlen(exec);
- end = exec + size;
- /* Two possibilities, it was just split at the space, or it was setup seperatly. */
- if (params == (end + 1))
- {
- *end = ' ';
- result = strdup(exec);
- *end = '\0';
- }
- else
- {
- size += strlen(params) + 2;
- result = malloc(size);
- if (result)
- sprintf(result, "%s %s", exec, params);
- }
- }
- else if (exec)
- result = strdup(exec);
-
- return result;
-}
-
-EAPI void
-ecore_desktop_instrumentation_reset(void)
-{
- instrumentation.desktops = 0;
- instrumentation.desktops_in_cache = 0;
- instrumentation.desktops_not_found = 0;
- instrumentation.icons = 0;
- instrumentation.icons_in_cache = 0;
- instrumentation.icons_not_found = 0;
- instrumentation.desktops_time = 0.0;
- instrumentation.desktops_in_cache_time = 0.0;
- instrumentation.desktops_not_found_time = 0.0;
- instrumentation.icons_time = 0.0;
- instrumentation.icons_in_cache_time = 0.0;
- instrumentation.icons_not_found_time = 0.0;
-#ifdef DEBUG
- printf("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
- printf("Desktop instrumentation reset.\n");
- printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
-#endif
-}
-
-EAPI void
-ecore_desktop_instrumentation_print(void)
-{
-#ifdef DEBUG
- if ((instrumentation.desktops + instrumentation.desktops_in_cache + instrumentation.desktops_not_found + instrumentation.icons + instrumentation.icons_in_cache + instrumentation.icons_not_found) > 0)
- {
- printf("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
- printf(" Found %5d desktops %2.5f (%2.6f/desktop)\n", instrumentation.desktops, instrumentation.desktops_time, instrumentation.desktops_time / instrumentation.desktops);
- printf(" Found %5d desktops in cache %2.5f (%2.6f/desktop)\n", instrumentation.desktops_in_cache, instrumentation.desktops_in_cache_time, instrumentation.desktops_in_cache_time / instrumentation.desktops_in_cache);
- printf("Not found %5d desktops %2.5f (%2.6f/desktop)\n", instrumentation.desktops_not_found, instrumentation.desktops_not_found_time, instrumentation.desktops_not_found_time / instrumentation.desktops_not_found);
- printf(" Found %5d icons %2.5f (%2.6f/icon)\n", instrumentation.icons, instrumentation.icons_time, instrumentation.icons_time / instrumentation.icons);
- printf(" Found %5d icons in cache %2.5f (%2.6f/icon)\n", instrumentation.icons_in_cache, instrumentation.icons_in_cache_time, instrumentation.icons_in_cache_time / instrumentation.icons_in_cache);
- printf("Not found %5d icons %2.5f (%2.6f/icon)\n", instrumentation.icons_not_found, instrumentation.icons_not_found_time, instrumentation.icons_not_found_time / instrumentation.icons_not_found);
- printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
- }
-#endif
-}
+++ /dev/null
-/*
- * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
- */
-#include <limits.h>
-#include <sys/stat.h>
-
-#include "Ecore_Desktop.h"
-#include "ecore_desktop_private.h"
-#include "ecore_private.h"
-
-//#define DEBUG 1
-
-static char *_ecore_desktop_icon_find0(const char *icon,
- const char *icon_size,
- const char *icon_theme,
- int *in_cache);
-
-static int _ecore_desktop_icon_theme_list_add(void *data,
- const char *path);
-static void _ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme *
- icon_theme);
-static void
-_ecore_desktop_icon_theme_directory_destroy(Ecore_Desktop_Icon_Theme_Directory *
- icon_theme_directory);
-static inline void
-_ecore_desktop_icon_theme_cache_check(Ecore_Desktop_Icon_Theme *icon_theme);
-
-/* FIXME: We need a way for the client to disable searching for any of these that they don't support. */
-static const char *ext[] =
- { "", ".edj", ".png", ".svgz", ".svg", ".xpm", NULL }; /* "" is in case the icon already has an extension, search for that first. */
-static int init_count = 0;
-static Eina_Hash *icon_theme_cache = NULL;
-
-/**
- * @defgroup Ecore_Desktop_Icon_Group icon theme Functions
- *
- * Functions that deal with freedesktop.org icon themes.
- *
- * This conforms with the freedesktop.org XDG Icon Theme Specification version 0.11
- */
-
-/**
- * Find the path to an icon.
- *
- * Using the search algorithm specified by freedesktop.org,
- * search for an icon in the currently installed set of icon themes.
- *
- * The returned string needs to be freed eventually.
- *
- * @param icon The name of the required icon.
- * @param icon_size The size of the required icon.
- * @param icon_theme The theme of the required icon.
- * @return The full path to an icon file, or NULL.
- * @ingroup Ecore_Desktop_Icon_Group
- */
-
-EAPI char *
-ecore_desktop_icon_find(const char *icon, const char *icon_size,
- const char *icon_theme)
-{
- char *result = NULL, *icn;
- Ecore_List *icons;
- int in_cache = 0;
- double begin;
-
- begin = ecore_time_get();
- if (icon)
- {
- /* Easy check first, was a full path supplied? */
- if ((icon[0] == '/') && (ecore_file_exists(icon)))
- result = strdup(icon);
- else
- {
- icons = ecore_desktop_paths_to_list(icon);
- if (icons)
- {
-
- if (icon_size == NULL)
- icon_size = "48x48";
- if (icon_theme == NULL)
- icon_theme = "hicolor";
- ecore_list_first_goto(icons);
- while ((icn = ecore_list_next(icons)))
- {
- char *ext;
-#ifdef DEBUG
- fprintf(stderr, "\tTrying To Find Icon %s\n", icn);
-#endif
- ext = strrchr(icn, '.');
- /* Check for unsupported extension */
- if ((ext) && (!strcmp(ext, ".ico")))
- continue;
-
- result = _ecore_desktop_icon_find0(icn, icon_size, icon_theme, &in_cache);
- if (result)
- break;
- }
- ecore_list_destroy(icons);
-
- } /* if (icons) */
- } /* if ((icon[0] == '/') && (ecore_file_exists(icon))) ; else */
- } /* if (icon) */
-
- if (result)
- {
- if (in_cache)
- {
- instrumentation.icons_in_cache_time += ecore_time_get() - begin;
- instrumentation.icons_in_cache++;
- }
- else
- {
- instrumentation.icons_time += ecore_time_get() - begin;
- instrumentation.icons++;
- }
- }
- else
- {
- instrumentation.icons_not_found_time += ecore_time_get() - begin;
- instrumentation.icons_not_found++;
- }
-
- return result;
-}
-
-/** Search for an icon the fdo way.
- *
- * This complies with the freedesktop.org Icon Theme Specification version 0.7
- *
- * @param icon The icon to search for.
- * @param icon_size The icon size to search for.
- * @param icon_theme The icon theme to search in.
- * @return The full path to the found icon.
- */
-static char *
-_ecore_desktop_icon_find0(const char *icon, const char *icon_size,
- const char *icon_theme, int *in_cache)
-{
- Ecore_Desktop_Icon_Theme *theme;
- char path[PATH_MAX];
- char *found = NULL;
- int wanted_size;
- int minimal_size = INT_MAX;
- int has_ext = 0;
- int has_icon_ext = 0;
- int i;
- char *closest = NULL;
- Ecore_Desktop_Icon_Theme_Directory *directory;
-
- if ((icon == NULL) || (icon[0] == '\0'))
- return NULL;
-
- /* Check the file extension, if any. */
- found = strrchr(icon, '.');
- if (found != NULL)
- {
- has_ext = 1;
- for (i = 0; ext[i] != NULL; i++)
- {
- if (strcmp(found, ext[i]) == 0)
- {
- has_icon_ext = 1;
- break;
- }
- }
- found = NULL;
- }
-
-#ifdef DEBUG
- fprintf(stderr, "\tTrying To Find Icon %s (%s) in theme %s\n", icon,
- icon_size, icon_theme);
-#endif
-
- /* Get the theme description file. */
- theme = ecore_desktop_icon_theme_get(icon_theme, NULL);
-#ifdef DEBUG
- printf("SEARCHING FOR %s\n", icon_theme);
-#endif
-
- if (!theme) return NULL;
- if (!theme->Directories) goto done;
-
- wanted_size = atoi(icon_size);
-
- /* Loop through the themes directories. */
- ecore_list_first_goto(theme->Directories);
- while ((directory = ecore_list_next(theme->Directories)) != NULL)
- {
- if (directory->size)
- {
- int match = 0;
- int result_size = 0;
-
- /* Does this theme directory match the required icon size? */
- switch (directory->type[0])
- {
- case 'F': /* Fixed. */
- match = (wanted_size == directory->size);
- result_size = abs(directory->size - wanted_size);
- break;
- case 'S': /* Scaled. */
- match = ((directory->minimum <= wanted_size) &&
- (wanted_size <= directory->maximum));
- if (wanted_size < directory->minimum)
- result_size = directory->minimum - wanted_size;
- if (wanted_size > directory->maximum)
- result_size = wanted_size - directory->maximum;
- break;
- default: /* Threshold. */
- match = (((directory->size - directory->threshold) <= wanted_size) &&
- (wanted_size <= (directory->size + directory->threshold)));
- if (wanted_size < (directory->size - directory->threshold))
- result_size = directory->minimum - wanted_size;
- if (wanted_size > (directory->size + directory->threshold))
- result_size = wanted_size - directory->maximum;
- break;
- }
-
- /* Do we need to check this directory? */
- if ((match) || (result_size < minimal_size))
- {
- /* Look for icon with all extensions. */
- for (i = 0; ext[i] != NULL; i++)
- {
- /* Check if there will be an extension to check. */
- if ((ext[i][0] == '\0') && (!has_ext))
- continue;
- if ((ext[i][0] != '\0') && (has_icon_ext))
- continue;
- if (directory->icons)
- {
- snprintf(path, PATH_MAX, "%s%s", icon, ext[i]);
-#ifdef DEBUG
- printf("FDO icon = %s\n", path);
-#endif
- found = eina_hash_find(directory->icons, path);
- if (found)
- {
- found = strdup(found);
- if (match)
- *in_cache = 1;
- }
- }
- else
- {
- snprintf(path, PATH_MAX, "%s/%s%s", directory->full_path, icon, ext[i]);
-#ifdef DEBUG
- printf("FDO icon = %s\n", path);
-#endif
- if (ecore_file_exists(path))
- found = strdup(path);
- }
- if (found)
- {
- if (ecore_file_is_dir(found))
- {
- free(found);
- found = NULL;
- }
- else if (match) /* If there is a match in sizes, return the icon. */
- goto done;
- else if (result_size < minimal_size) /* While we are here, figure out our next fallback strategy. */
- {
- minimal_size = result_size;
- if (closest) free(closest);
- closest = found;
- found = NULL;
- }
- else
- {
- free(found);
- found = NULL;
- }
- }
- } /* for (i = 0; ext[i] != NULL; i++) */
- } /* if ((match) || (result_size < minimal_size)) */
- } /* if (directory->size) */
- } /* while ((directory = ecore_list_next(directory_paths)) != NULL) */
-
- if (!found)
- {
- /* Fall back strategy #1, look for closest size in this theme. */
- found = closest;
- if (found)
- {
- closest = NULL;
- goto done;
- }
-
- /* Fall back strategy #2, Try again with the parent themes. */
- if (!theme->hicolor)
- {
- if (theme->Inherits)
- {
- char *inherits;
-
- ecore_list_first_goto(theme->Inherits);
- while ((inherits = ecore_list_next(theme->Inherits)) != NULL)
- {
- found = _ecore_desktop_icon_find0(icon, icon_size, inherits, in_cache);
- if (found) goto done;
- }
- }
- else /* Fall back strategy #3, Try the default hicolor theme. */
- {
- found = _ecore_desktop_icon_find0(icon, icon_size, "hicolor", in_cache);
- if (found) goto done;
- }
- }
-
- /* Fall back strategy #4, Just search in the base of the icon directories. */
- for (i = 0; ext[i] != NULL; i++)
- {
- /* Check if there will be an extension to check. */
- if ((ext[i][0] == '\0') && (!has_ext))
- continue;
- if ((ext[i][0] != '\0') && (has_icon_ext))
- continue;
- snprintf(path, PATH_MAX, "%s%s", icon, ext[i]);
-#ifdef DEBUG
- printf("FDO icon = %s\n", path);
-#endif
- found = ecore_desktop_paths_file_find(ecore_desktop_paths_icons, path, 0, NULL, NULL);
- if (found)
- {
- if (ecore_file_is_dir(found))
- {
- free(found);
- found = NULL;
- }
- else
- goto done;
- }
- }
- }
-
-done:
- if (closest) free(closest);
- ecore_desktop_icon_theme_destroy(theme);
-
- return found;
-}
-
-Eina_Hash*
-ecore_desktop_icon_theme_list(void)
-{
- static int loaded = 0;
- if (!loaded)
- {
- char *tmp;
- tmp = ecore_desktop_paths_file_find(ecore_desktop_paths_icons, "index.theme", 2,
- _ecore_desktop_icon_theme_list_add, NULL);
- loaded = 1;
- free(tmp);
- }
- return icon_theme_cache;
-}
-
-static int
-_ecore_desktop_icon_theme_list_add(void *data __UNUSED__, const char *path)
-{
- char icn[PATH_MAX];
-
- snprintf(icn, PATH_MAX, "%sindex.theme", path);
- if (ecore_desktop_icon_theme_get(icn, NULL))
- return 1; /* Should stop it from recursing this directory, but let it continue searching the next. */
- return 0;
-}
-
-/**
- * Setup what ever needs to be setup to support ecore_desktop_icon.
- *
- * There are internal structures that are needed for ecore_desktop_icon
- * functions to operate, this sets them up.
- *
- * @ingroup Ecore_Desktop_Icon_Group
- */
-EAPI int
-ecore_desktop_icon_init()
-{
- if (++init_count != 1)
- return init_count;
-
- if (!icon_theme_cache)
- icon_theme_cache = eina_hash_string_superfast_new(_ecore_desktop_icon_theme_destroy);
-
- return init_count;
-}
-
-/**
- * Tear down what ever needs to be torn down to support ecore_desktop_ycon.
- *
- * There are internal structures that are needed for ecore_desktop_icon
- * functions to operate, this tears them down.
- *
- * @ingroup Ecore_Desktop_Icon_Group
- */
-EAPI int
-ecore_desktop_icon_shutdown()
-{
- if (--init_count != 0)
- return init_count;
-
- if (icon_theme_cache)
- {
- eina_hash_free(icon_theme_cache);
- icon_theme_cache = NULL;
- }
-
- return init_count;
-}
-
-/**
- * Get the contents of an index.theme file.
- *
- * Everything that is in the index.theme file is returned in the
- * data member of the Ecore_Desktop_Icon_Theme structure, it's an Eina_Hash
- * as returned by ecore_desktop_ini_get(). Some of the data in the
- * index.theme file is decoded into specific members of the returned
- * structure.
- *
- * Use ecore_desktop_icon_theme_destroy() to free this structure.
- *
- * @param icon_theme Name of the icon theme, or full path to the index.theme file.
- * @param lang Language to use, or NULL for default.
- * @return An Ecore_Desktop_Icon_Theme containing the files contents.
- * @ingroup Ecore_Desktop_Icon_Group
- */
-Ecore_Desktop_Icon_Theme *
-ecore_desktop_icon_theme_get(const char *icon_theme, const char *lang __UNUSED__)
-{
- Ecore_Desktop_Icon_Theme *result = NULL;
- char *theme_path = NULL, *theme_dir = NULL;
- const char *value;
- Ecore_List *Directories;
- char *directory;
-
- if (icon_theme[0] == '/')
- {
- theme_path = strdup(icon_theme);
- theme_dir = ecore_file_dir_get(theme_path);
- if (theme_dir)
- icon_theme = ecore_file_file_get(theme_dir);
-#ifdef DEBUG
- printf("LOADING THEME %s - %s\n", icon_theme, theme_path);
-#endif
- }
-
- result = eina_hash_find(icon_theme_cache, icon_theme);
- if (result) goto done;
- if (!theme_dir)
- {
- char icn[PATH_MAX];
-
- snprintf(icn, PATH_MAX, "%s/index.theme", icon_theme);
-#ifdef DEBUG
- printf("SEARCHING FOR %s\n", icn);
-#endif
- theme_path = ecore_desktop_paths_file_find(ecore_desktop_paths_icons, icn,
- 2, NULL, NULL);
- if (!theme_path) goto error;
- theme_dir = ecore_file_dir_get(theme_path);
- }
- if (!theme_path) goto error;
- result = calloc(1, sizeof(Ecore_Desktop_Icon_Theme));
- if (!result) goto error;
- result->data = ecore_desktop_ini_get(theme_path);
- if (!result->data) goto error;
- result->group = eina_hash_find(result->data, "Icon Theme");
- if (!result->group) goto error;
-
-
- if ((strcmp(icon_theme, "hicolor") == 0))
- result->hicolor = 1;
-
- /* According to the spec, name and comment are required, but we can fake those easily enough. */
- value = eina_hash_find(result->group, "Name");
- if (!value) value = icon_theme;
- result->name = strdup(value);
- value = eina_hash_find(result->group, "Comment");
- if (!value) value = "No comment provided.";
- result->comment = strdup(value);
- value = eina_hash_find(result->group, "Inherits");
- if (value)
- {
- result->inherits = strdup(value);
- if (result->inherits)
- result->Inherits = ecore_desktop_paths_to_list(result->inherits);
- }
- value = eina_hash_find(result->group, "Example");
- if (!value) value = "exec";
- result->example = strdup(value);
- value = eina_hash_find(result->group, "Directories");
- /* FIXME: Directories is also required, don't feel like faking it for now. */
- if (!value) goto error;
- result->directories = strdup(value);
- Directories = ecore_desktop_paths_to_list(result->directories);
- if (!Directories) goto error;
- result->Directories = ecore_list_new();
- if (!result->Directories) goto error;
- ecore_list_free_cb_set(result->Directories,
- ECORE_FREE_CB(_ecore_desktop_icon_theme_directory_destroy));
- ecore_list_first_goto(Directories);
- while ((directory = ecore_list_next(Directories)) != NULL)
- {
- Eina_Hash *sub_group;
- Ecore_Desktop_Icon_Theme_Directory *dir;
-
- /* Get the details for this theme directory. */
- sub_group = eina_hash_find(result->data, directory);
- dir = calloc(1, sizeof (Ecore_Desktop_Icon_Theme_Directory));
- if ((dir) && (sub_group))
- {
- const char *size, *minsize, *maxsize, *threshold;
- char full_path[PATH_MAX];
-
- dir->path = strdup(directory);
- snprintf(full_path, PATH_MAX, "%s/%s", theme_dir, directory);
- dir->full_path = strdup(full_path);
- value = eina_hash_find(sub_group, "Type");
- if (!value)
- value = "Threshold";
- dir->type = strdup(value);
- size = eina_hash_find(sub_group, "Size");
- minsize = eina_hash_find(sub_group, "MinSize");
- maxsize = eina_hash_find(sub_group, "MaxSize");
- threshold = eina_hash_find(sub_group, "Threshold");
- if (size)
- {
- if (!minsize)
- minsize = size;
- if (!maxsize)
- maxsize = size;
- if (!threshold)
- threshold = "2";
- dir->minimum = atoi(minsize);
- dir->maximum = atoi(maxsize);
- dir->threshold = atoi(threshold);
-
- dir->size = atoi(size);
- ecore_list_append(result->Directories, dir);
- }
- else
- _ecore_desktop_icon_theme_directory_destroy(dir);
- }
- else if (dir)
- _ecore_desktop_icon_theme_directory_destroy(dir);
- }
- ecore_list_destroy(Directories);
-
- /* This passes the basic validation tests, mark it as real and cache it. */
- result->path = strdup(theme_path);
- eina_hash_add(icon_theme_cache, icon_theme, result);
- eina_hash_free(result->data);
- result->data = NULL;
- result->group = NULL;
-
-done:
- if (theme_dir) free(theme_dir);
- if (theme_path) free(theme_path);
-
- /* Cache the directories. */
- _ecore_desktop_icon_theme_cache_check(result);
- return result;
-
-error:
- if (theme_dir) free(theme_dir);
- if (theme_path) free(theme_path);
- if (result)
- {
- if (result->data) eina_hash_free(result->data);
- _ecore_desktop_icon_theme_destroy(result);
- }
- return NULL;
-}
-
-/**
- * Free whatever resources are used by an Ecore_Desktop_Icon_Theme.
- *
- * There are internal resources used by each Ecore_Desktop_Icon_Theme
- * This releases those resources.
- *
- * @param icon_theme An Ecore_Desktop_Icon_Theme.
- * @ingroup Ecore_Desktop_Icon_Group
- */
-void
-ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme * icon_theme)
-{
- /* This is just a dummy, because these structures are cached. */
- /* Later versions of the cache may reference count, then this will be useful. */
-
- icon_theme = NULL;
-}
-
-static void
-_ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme * icon_theme)
-{
- if (icon_theme->path)
- free(icon_theme->path);
- if (icon_theme->name)
- free(icon_theme->name);
- if (icon_theme->comment)
- free(icon_theme->comment);
- if (icon_theme->example)
- free(icon_theme->example);
- if (icon_theme->inherits)
- free(icon_theme->inherits);
- if (icon_theme->directories)
- free(icon_theme->directories);
- if (icon_theme->Directories)
- ecore_list_destroy(icon_theme->Directories);
- if (icon_theme->Inherits)
- ecore_list_destroy(icon_theme->Inherits);
- free(icon_theme);
-}
-
-static void
-_ecore_desktop_icon_theme_directory_destroy(Ecore_Desktop_Icon_Theme_Directory *
- icon_theme_directory)
-{
- if (icon_theme_directory->path)
- free(icon_theme_directory->path);
- if (icon_theme_directory->full_path)
- free(icon_theme_directory->full_path);
- if (icon_theme_directory->type)
- free(icon_theme_directory->type);
- if (icon_theme_directory->icons)
- eina_hash_free(icon_theme_directory->icons);
- free(icon_theme_directory);
-}
-
-static inline void
-_ecore_desktop_icon_theme_cache_check(Ecore_Desktop_Icon_Theme *icon_theme)
-{
- /* The spec has this to say -
- *
- * "The algorithm as described in this document works by always looking up
- * filenames in directories (a stat in unix terminology). A good
- * implementation is expected to read the directories once, and do all
- * lookups in memory using that information.
- *
- * "This caching can make it impossible for users to add icons without having
- * to restart applications. In order to handle this, any implementation that
- * does caching is required to look at the mtime of the toplevel icon
- * directories when doing a cache lookup, unless it already did so less than
- * 5 seconds ago. This means that any icon editor or theme installation
- * program need only to change the mtime of the the toplevel directory where
- * it changed the theme to make sure that the new icons will eventually get
- * used."
- *
- * The phrase "toplevel icon directories" is ambigous, but I guess they mean
- * the directory where the index.theme file lives.
- */
-
- struct stat st;
- int clear = 0;
-
- if (ecore_time_get() > (icon_theme->last_checked + 5.0))
- {
- if (stat(icon_theme->path, &st) >= 0)
- {
- icon_theme->last_checked = ecore_time_get();
- if (st.st_mtime > icon_theme->mtime)
- {
- clear = 1;
- icon_theme->mtime = st.st_mtime;
- }
- }
- }
-
- if (clear)
- {
- Ecore_Desktop_Icon_Theme_Directory *dir;
- char full_path[PATH_MAX];
-
- ecore_list_first_goto(icon_theme->Directories);
- while ((dir = ecore_list_next(icon_theme->Directories)) != NULL)
- {
- if (dir->icons)
- {
- eina_hash_free(dir->icons);
- dir->icons = NULL;
- }
- dir->icons = eina_hash_string_superfast_new(NULL);
- if (dir->icons)
- {
- Ecore_List *files;
-
- files = ecore_file_ls(dir->full_path);
- if (files)
- {
- const char *file;
-
- while ((file = ecore_list_next(files)))
- {
- snprintf(full_path, PATH_MAX, "%s/%s", dir->full_path, file);
- eina_hash_add(dir->icons, file, strdup(full_path));
- }
- ecore_list_destroy(files);
- }
- }
- }
- }
-}
+++ /dev/null
-/*
- * This conforms with the freedesktop.org Desktop Menu Specification version 0.92
- *
- * This is gonna be repetative and slow. The idea is to first get it to correctly
- * follow the spec in a way that is easy to check. Only then can we start to
- * optomize into "ugly but fast".
- *
- * There are notes at the very end about all those nasty steps we need to do to
- * follow the spec.
- */
-
-#include <Ecore.h>
-
-#include "Ecore_Desktop.h"
-#include "ecore_desktop_private.h"
-#include "ecore_private.h"
-
-#include <dirent.h>
-#include <sys/stat.h>
-#include <libgen.h>
-
-//#define DEBUG 1
-
-struct _ecore_desktop_menu_expand_apps_data
-{
- char *path;
- Eina_Hash *pool;
- int length;
-};
-
-struct _ecore_desktop_menu_unxml_data
-{
- char *file;
- char *base;
- char *path;
- Ecore_Desktop_Tree *stack, *merge_stack;
- int unallocated, level;
-};
-
-struct _ecore_desktop_menu_generate_data
-{
- char *name, *path;
- Ecore_Desktop_Tree *rules;
- Eina_Hash *pool, *apps;
- int unallocated;
-
- Ecore_Desktop_Tree *rule;
- int include;
-};
-
-struct _ecore_desktop_menu_legacy_data
-{
- Ecore_Desktop_Tree *merge;
- Ecore_Desktop_Tree *current;
- char *menu;
- char *prefix;
- char *path;
- int length, menu_length, level;
-};
-
-static int _ecore_desktop_menu_make_apps(const void *data,
- Ecore_Desktop_Tree * tree,
- int element, int level);
-static Ecore_Desktop_Tree *_ecore_desktop_menu_get0(char *file,
- Ecore_Desktop_Tree *
- merge_stack, int level);
-static Ecore_Desktop_Tree *_ecore_desktop_menu_create_menu(void);
-static int _ecore_desktop_menu_unxml(const void *data,
- Ecore_Desktop_Tree * tree,
- int element, int level);
-static int _ecore_desktop_menu_check_directory(void *data,
- const char *path);
-static int _ecore_desktop_menu_check_menu(void *data,
- const char *path);
-static int _ecore_desktop_menu_legacy_menu_dir(void *data,
- const char *path);
-static int _ecore_desktop_menu_legacy_menu(void *data,
- const char *path);
-static void _ecore_desktop_menu_unxml_rules(Ecore_Desktop_Tree * rules,
- Ecore_Desktop_Tree * tree,
- char type, char sub_type);
-static void _ecore_desktop_menu_unxml_moves(Ecore_Desktop_Tree * menu,
- Ecore_Desktop_Tree * tree);
-static void _ecore_desktop_menu_add_dirs(Ecore_Desktop_Tree * tree,
- Ecore_List * paths, const char *pre,
- const char *post, char *extra,
- int element);
-static int _ecore_desktop_menu_expand_apps(struct
- _ecore_desktop_menu_unxml_data
- *unxml_data, char *app_dir,
- Eina_Hash * pool);
-static int _ecore_desktop_menu_check_app(void *data, const char *path);
-
-static int _ecore_desktop_menu_merge(const void *data,
- Ecore_Desktop_Tree * tree,
- int element, int level);
-static int _ecore_desktop_menu_expand_default_dirs(const void *data,
- Ecore_Desktop_Tree
- * tree,
- int element,
- int level);
-
-static int _ecore_desktop_menu_generate(const void *data,
- Ecore_Desktop_Tree * tree,
- int element, int level);
-static int _ecore_desktop_menu_is_include(const void *data, Ecore_Desktop_Tree * tree, int element, int level __UNUSED__);
-static void _ecore_desktop_menu_inherit_apps(void *value,
- void *user_data);
-static void _ecore_desktop_menu_select_app(void *value,
- void *user_data);
-static int _ecore_desktop_menu_apply_rules(struct
- _ecore_desktop_menu_generate_data
- *generate_data,
- Ecore_Desktop_Tree * rule,
- char *key,
- Ecore_Desktop * desktop);
-
-/**
- * @defgroup Ecore_Desktop_Menu_Group menu Functions
- *
- * Functions that deal with freedesktop.org menus.
- */
-
-EAPI void
-ecore_desktop_menu_for_each(void (*func)
- (const char *name, const char *path, const char *directory, Eina_Hash * apps))
-{
- char *menu_file;
-
- /* Find the main menu file. */
- menu_file = ecore_desktop_paths_file_find(ecore_desktop_paths_menus,
- "applications.menu", -1, NULL,
- NULL);
- if (!menu_file)
- {
- /* Try various quirks of various systems and other wms. */
- menu_file = ecore_desktop_paths_file_find(ecore_desktop_paths_menus,
- "kde-applications.menu", -1, NULL,
- NULL);
- if (!menu_file)
- {
- menu_file = ecore_desktop_paths_file_find(ecore_desktop_paths_menus,
- "debian-menu.menu", -1, NULL,
- NULL);
- /* FIXME: If all else fails, run debians funky menu generator shit. */
- }
- }
-
- if (menu_file)
- {
- Ecore_Desktop_Tree *menus;
-
- /* convert the xml into menus */
- menus = ecore_desktop_menu_get(menu_file);
- if (menus)
- {
- /* create the .desktop and order files from the menu */
- ecore_desktop_tree_foreach(menus, 0, _ecore_desktop_menu_make_apps,
- func);
-// FIXME: Can't free this just yet, causes major memory corruption.
-// this leaks a LOT (428,200 bytes in one valgrind run...)
-// ecore_desktop_tree_del(menus);
- }
- free(menu_file);
- }
-}
-
-static int
-_ecore_desktop_menu_make_apps(const void *data, Ecore_Desktop_Tree * tree,
- int element, int level __UNUSED__)
-{
- if (tree->elements[element].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- if (strncmp((char *)tree->elements[element].element, "<MENU ", 6) == 0)
- {
- int len;
- char *path;
- char *name;
- char *directory;
- Eina_Hash *apps;
- void (*func) (char *name, char *path, char *directory,
- Eina_Hash * apps);
-
- func = data;
- name = (char *)tree->elements[element].element;
- directory = name;
- directory += 8;
- path = strchr(directory, '<');
- path++;
- directory = strchr(path, '<');
- directory++;
- len = strlen(directory);
- if (len > 2)
- {
- path = strdup(directory);
- if (path)
- {
- path[len - 1] = '\0';
- /* FIXME: Figure out what to do if it's just ".directory". */
- directory = ecore_desktop_paths_file_find(ecore_desktop_paths_directories, path, 0, NULL, NULL);
- free(path);
- }
- else
- directory = NULL;
- }
- else
- directory = NULL;
- path = (char *)tree->elements[element + 1].element;
-// pool = (Eina_Hash *) tree->elements[element + 2].element;
- apps = (Eina_Hash *) tree->elements[element + 4].element;
- path = &path[11];
-#ifdef DEBUG
- printf("OUTPUTTING MENU - %s \t\t%s \t\t%s\n", path, name, directory);
-#endif
- if (func)
- func(name, path, directory, apps);
- free(directory);
- }
- }
- return 0;
-}
-
-/**
- * Decode a freedesktop.org menu XML jungle.
- *
- * Using the algorithm specified by freedesktop.org, fully decode
- * a menu based on an initial menu file.
- *
- * @param file The base file for the menu.
- * @return The resulting menu tree.
- * @ingroup Ecore_Desktop_Menu_Group
- */
-
-Ecore_Desktop_Tree *
-ecore_desktop_menu_get(char *file)
-{
- return _ecore_desktop_menu_get0(file, NULL, 0);
-}
-
-static Ecore_Desktop_Tree *
-_ecore_desktop_menu_get0(char *file, Ecore_Desktop_Tree * merge_stack,
- int level)
-{
- Ecore_Desktop_Tree *menu_xml;
- struct _ecore_desktop_menu_unxml_data data;
- int oops = 0;
-
- /* Preperation. */
- data.stack = ecore_desktop_tree_new(NULL);
- /* FIXME data.base and data.path leak */
- data.base = ecore_file_strip_ext(ecore_file_file_get(file));
- data.path = ecore_file_dir_get(file);
- if ((level == 0) && (merge_stack == NULL))
- merge_stack = ecore_desktop_tree_new(NULL);
-#ifdef DEBUG
-printf("MENU FILE %d - %s\n", level, file);
-#endif
- menu_xml = ecore_desktop_xmlame_get(file);
- if ((data.stack) && (data.base) && (data.path) && (merge_stack)
- && (menu_xml))
- {
- int i;
-
- data.file = file;
- data.level = level;
- data.merge_stack = merge_stack;
-
- /* Setup the merge stack. */
- if (merge_stack->size <= level)
- {
- /* XXX storing a pointer to a static string probably isn't a good idea. this is most likely the cause of the valgrind error mentioned below. (once this function has exited that memory will no longer be valid) */
- while (merge_stack->size < level)
- ecore_desktop_tree_add(merge_stack, "");
- ecore_desktop_tree_add(merge_stack, file);
- }
- else
- merge_stack->elements[level].element = file;
-
- /* Find out if we are looping. */
- for (i = 0; i < level; i++)
- {
- char *text;
-
- /* I can safely assume that they are all strings. */
- text = (char *)merge_stack->elements[i].element;
-/* printf("--- %s --- %s\n", text, file);
- if (text)
- if (file) */
- if (strcmp(text, file) == 0)
- {
-/* FIXME: valgrind says -
-==5761== Conditional jump or move depends on uninitialised value(s)
-==5761== at 0x1B90565C: strcmp (in /usr/lib/valgrind/vgpreload_memcheck.so)
-==5761== by 0x1BA3E984: _ecore_desktop_menu_get0 (ecore_desktop_menu.c:176)
-==5761== by 0x1BA3FE3F: _ecore_desktop_menu_merge (ecore_desktop_menu.c:1146)
-==5761== by 0x1BA3D5A2: ecore_desktop_tree_foreach (ecore_desktop_tree.c:267)
- * which is the strcmp just above. But it doesn't complain about the first two if's,
- * or the printf, which I inserted to try and track this down.
- * No idea what it actually is complaining about, so I'll comment it for future study.
- *
- * This is probably caused by the fact that a static string was passed into the
- * tree. See the comment above where this occurs.
- */
- fprintf(stderr,
- "\n### Oops, infinite menu merging loop detected at %s\n",
- file);
- oops++;
- }
- }
-
- if (oops == 0)
- {
- /* Get on with it. */
- ecore_desktop_tree_foreach(menu_xml, 0, _ecore_desktop_menu_unxml,
- &data);
- ecore_desktop_tree_foreach(menu_xml, 0, _ecore_desktop_menu_merge,
- &data);
-
- /* The rest of this is only done after ALL the menus have been merged. */
- if (level == 0)
- {
- ecore_desktop_tree_foreach(menu_xml, 0,
- _ecore_desktop_menu_expand_default_dirs,
- &data);
-
-#ifdef DEBUG
- ecore_desktop_tree_dump(menu_xml, 0);
- printf("\n\n");
-#endif
-
- data.unallocated = FALSE;
- ecore_desktop_tree_foreach(menu_xml, 0,
- _ecore_desktop_menu_generate,
- &data);
-
- data.unallocated = TRUE;
- ecore_desktop_tree_foreach(menu_xml, 0,
- _ecore_desktop_menu_generate,
- &data);
-
-#ifdef DEBUG
-// ecore_desktop_tree_dump(menu_xml, 0);
-// printf("\n\n");
-#endif
- }
- }
- }
- else
- oops++;
-
- if (oops)
- {
- E_FN_DEL(ecore_desktop_tree_del, (menu_xml));
- if (level == 0)
- {
- E_FN_DEL(ecore_desktop_tree_del, (merge_stack));
- }
- E_FREE(data.path);
- E_FREE(data.base);
- E_FN_DEL(ecore_desktop_tree_del, (data.stack));
- }
-
-
- return menu_xml;
-}
-
-static int
-_ecore_desktop_menu_unxml(const void *data, Ecore_Desktop_Tree * tree,
- int element, int level)
-{
- struct _ecore_desktop_menu_unxml_data *unxml_data;
-
- unxml_data = (struct _ecore_desktop_menu_unxml_data *)data;
- if (tree->elements[element].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- if (strncmp((char *)tree->elements[element].element, "<!", 2) == 0)
- {
- tree->elements[element].type =
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[element].element = NULL;
- }
- else if (strcmp((char *)tree->elements[element].element, "<Menu") == 0)
- {
- Ecore_Desktop_Tree *menu;
-
- menu = _ecore_desktop_menu_create_menu();
- if (menu)
- {
- int i;
- char *flags = " ", *name = "", *directory =
- "", *menu_path = "";
- char temp[PATH_MAX];
-
- flags = (char *)menu->elements[0].element;
- flags += 7;
- tree->elements[element].element = menu;
- tree->elements[element].type =
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE;
- for (i = element + 1; i < tree->size; i++)
- {
- int result = 0;
-
- if (tree->elements[i].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- if (strncmp
- ((char *)tree->elements[i].element, "<!",
- 2) == 0)
- {
- tree->elements[i].type =
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[i].element = NULL;
- }
- else
- if (strcmp
- ((char *)tree->elements[i].element,
- "<Deleted/") == 0)
- {
- flags[1] = 'D';
- result = 1;
- }
- else
- if (strcmp
- ((char *)tree->elements[i].element,
- "<NotDeleted/") == 0)
- {
- flags[1] = ' ';
- result = 1;
- }
- else
- if (strcmp
- ((char *)tree->elements[i].element,
- "<OnlyUnallocated/") == 0)
- {
- flags[2] = 'O';
- result = 1;
- }
- else
- if (strcmp
- ((char *)tree->elements[i].element,
- "<NotOnlyUnallocated/") == 0)
- {
- flags[2] = ' ';
- result = 1;
- }
- else
- if (strcmp
- ((char *)tree->elements[i].element,
- "</Menu") == 0)
- {
- result = 1;
- }
- else
- {
- ecore_desktop_tree_extend(menu,
- (char *)tree->
- elements[i].element);
- result = 1;
- }
- }
- else if (tree->elements[i].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- Ecore_Desktop_Tree *sub;
-
- sub =
- (Ecore_Desktop_Tree *) tree->elements[i].element;
- if ((sub) && (sub->size))
- {
- if (sub->elements[0].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- if (strcmp
- ((char *)sub->elements[0].element,
- "<Name") == 0)
- {
- int i, length = 0;
-
- name =
- strdup((char *)sub->elements[1].
- element);
- sprintf(temp,
- "<MENU <%.4s> <%s> <%s>",
- flags, name, directory);
- menu->elements[0].element =
- strdup(temp);
- ecore_desktop_tree_track(menu, name);
- ecore_desktop_tree_track(menu,
- menu->
- elements[0].
- element);
- flags =
- (char *)menu->elements[0].element;
- flags += 7;
- /* The rest of this is probably not needed, except to ease debugging. */
- if (unxml_data->stack->size <= level)
- {
- while (unxml_data->stack->size <
- level)
- ecore_desktop_tree_add
- (unxml_data->stack, "");
- ecore_desktop_tree_add
- (unxml_data->stack, name);
- }
- else
- unxml_data->stack->
- elements[level].element = name;
- temp[0] = '\0';
- for (i = 0; i <= level; i++)
- {
- char *text;
-
- /* I can safely assume that they are all strings. */
- text =
- (char *)unxml_data->stack->
- elements[i].element;
- if (text[0] != '\0')
- {
- sprintf(&temp[length],
- "%s%s",
- ((length) ? "/" :
- ""), text);
- length +=
- strlen(text) +
- ((length) ? 1 : 0);
- }
- }
- menu_path = strdup(temp);
- sprintf(temp, "<MENU_PATH %s",
- menu_path);
- menu->elements[1].element =
- strdup(temp);
- ecore_desktop_tree_track(menu,
- menu_path);
- ecore_desktop_tree_track(menu,
- menu->
- elements[1].
- element);
- result = 1;
- }
- /* FIXME: Move this to later in the sequence. */
- else
- if (strcmp
- ((char *)sub->elements[0].element,
- "<Directory") == 0)
- {
- directory =
- strdup((char *)sub->elements[1].
- element);
- sprintf(temp,
- "<MENU <%.4s> <%s> <%s>",
- flags, name, directory);
- menu->elements[0].element =
- strdup(temp);
- ecore_desktop_tree_track(menu,
- directory);
- ecore_desktop_tree_track(menu,
- menu->
- elements[0].
- element);
- flags =
- (char *)menu->elements[0].element;
- flags += 7;
- result = 1;
- }
- else
- if (strcmp
- ((char *)sub->elements[0].element,
- "<Menu") == 0)
- {
- _ecore_desktop_menu_unxml(data, sub,
- 0,
- level + 1);
- ecore_desktop_tree_add_child(menu,
- (Ecore_Desktop_Tree
- *)
- sub->
- elements
- [0].
- element);
- /* FIXME: Dunno if this causes a memory leak, but for now we play it safe. */
- tree->elements[i].type =
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[i].element = NULL;
-// result = 1;
- }
- else
- if (strcmp
- ((char *)sub->elements[0].element,
- "<Move") == 0)
- {
- _ecore_desktop_menu_unxml_moves
- (menu, sub);
- result = 1;
- }
- else
- {
- if ((sub->size == 3)
- && (sub->elements[1].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- && (((char *)sub->elements[1].element)[0] != '<'))
- {
- char temp[PATH_MAX];
-
- snprintf(temp, PATH_MAX, "%s %s",
- (char *)sub->elements[0].element,
- (char *)sub->elements[1].element);
- ecore_desktop_tree_extend(menu, temp);
- result = 1;
- }
- else
- {
- ecore_desktop_tree_add_child
- (menu, sub);
- tree->elements[i].type =
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[i].element =
- NULL;
- }
- }
- }
- }
- }
- if (result)
- {
- if (tree->elements[i].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- ecore_desktop_tree_del((Ecore_Desktop_Tree *)
- tree->elements[i].
- element);
- tree->elements[i].type =
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[i].element = NULL;
- }
- }
-
- /* Add it if it has not been deleted. */
- if (flags[1] != 'D')
- {
- tree->elements[element].element = menu;
- tree->elements[element].type =
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE;
- }
- }
- }
- }
- return 0;
-}
-
-static Ecore_Desktop_Tree *
-_ecore_desktop_menu_create_menu()
-{
- Ecore_Desktop_Tree *menu, *rules;
- Eina_Hash *pool, *apps;
-
- menu = ecore_desktop_tree_new(NULL);
- rules = ecore_desktop_tree_new(NULL);
- pool = eina_hash_string_superfast_new(free);
- apps = eina_hash_string_superfast_new(free);
- if ((menu) && (rules) && (pool) && (apps))
- {
- ecore_desktop_tree_extend(menu, "<MENU < > <> <>");
- ecore_desktop_tree_extend(menu, "<MENU_PATH ");
- ecore_desktop_tree_add_hash(menu, pool);
- ecore_desktop_tree_add_child(menu, rules);
- ecore_desktop_tree_add_hash(menu, apps);
- }
- else
- {
- if (apps)
- eina_hash_free(apps);
- if (pool)
- eina_hash_free(pool);
- if (rules)
- ecore_desktop_tree_del(rules);
- if (menu)
- ecore_desktop_tree_del(menu);
- menu = NULL;
- }
-
- return menu;
-}
-
-static int
-_ecore_desktop_menu_check_directory(void *data, const char *path)
-{
- char *p;
- Ecore_Desktop_Tree *merge;
-
- merge = (Ecore_Desktop_Tree *) data;
- p = strrchr(path, '.');
- if (p)
- {
- if (strcmp(p, ".directory") == 0)
- {
- char merge_file[PATH_MAX];
-
- sprintf(merge_file, "<Directory %s", path);
- ecore_desktop_tree_extend(merge, merge_file);
- }
- }
-
- return 0;
-}
-
-static int
-_ecore_desktop_menu_check_menu(void *data, const char *path)
-{
- char *p;
- Ecore_Desktop_Tree *merge;
-
- merge = (Ecore_Desktop_Tree *) data;
- p = strrchr(path, '.');
- if (p)
- {
- if (strcmp(p, ".menu") == 0)
- {
- char merge_file[PATH_MAX];
-
- sprintf(merge_file, "<MergeFile type=\"path\" %s", path);
- ecore_desktop_tree_extend(merge, merge_file);
- }
- }
-
- return 0;
-}
-
-static int
-_ecore_desktop_menu_legacy_menu_dir(void *data, const char *path)
-{
- struct _ecore_desktop_menu_legacy_data *legacy_data;
- Ecore_Desktop_Tree *menu;
- char *temp_path;
- int start;
- int i, count = 0;
-
- legacy_data = (struct _ecore_desktop_menu_legacy_data *)data;
- for (i = legacy_data->length; path[i] != '\0'; i++)
- {
- if (path[i] == '/')
- count++;
- }
- if (count == 1)
- {
- legacy_data->current = legacy_data->merge;
- legacy_data->level = 0;
- }
- else if (count <= legacy_data->level)
- {
- if ((legacy_data->current) && (legacy_data->current->parent))
- {
- legacy_data->current = legacy_data->current->parent;
- legacy_data->level--;
- }
- }
-
- start = legacy_data->length;
- count = 0;
- temp_path = strdup(path);
- if (temp_path)
- {
- for (i = legacy_data->length; temp_path[i] != '\0'; i++)
- {
- if (temp_path[i] == '/')
- {
- if (count >= legacy_data->level)
- {
- temp_path[i] = '\0';
- menu = _ecore_desktop_menu_create_menu();
- if (menu)
- {
- char temp[PATH_MAX];
-
- sprintf(temp, "<MENU < L> <%s> <>",
- &temp_path[start]);
- menu->elements[0].element = strdup(temp);
- ecore_desktop_tree_track(menu,
- menu->elements[0].element);
- sprintf(temp, "<MENU_PATH %s/%s", legacy_data->menu,
- &temp_path[legacy_data->length]);
- menu->elements[1].element = strdup(temp);
- ecore_desktop_tree_track(menu,
- menu->elements[1].element);
-
- ecore_desktop_tree_add_child(legacy_data->current,
- menu);
- /* This is not needed, but if it was, this is where it would go.
- * sprintf(temp, "<AppDir %s/", temp_path);
- * ecore_desktop_tree_extend(menu, temp);
- */
- sprintf(temp, "<DirectoryDir %s/", temp_path);
- ecore_desktop_tree_extend(menu, temp);
-
- legacy_data->current = menu;
- legacy_data->level++;
- }
- temp_path[i] = '/';
- }
- start = i + 1;
- count++;
- }
- }
- free(temp_path);
- }
-
- legacy_data->level = count;
-
- return 0;
-}
-
-static int
-_ecore_desktop_menu_legacy_menu(void *data, const char *path)
-{
- struct _ecore_desktop_menu_legacy_data *legacy_data;
- char *menu_path;
- char *file;
- char temp[PATH_MAX];
- int i, count = 0, menu_count = 0;
-
- legacy_data = (struct _ecore_desktop_menu_legacy_data *)data;
- if ((legacy_data->current) && (legacy_data->current->size > 0) &&
- (legacy_data->current->elements[1].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING))
- {
- menu_path = (char *)legacy_data->current->elements[1].element;
- menu_path += 12 + legacy_data->menu_length;
- }
- else
- {
- menu_path = "";
- printf(" PROBLEM IN LEGACYDIR FILE - %s - %s %s\n",
- legacy_data->prefix, legacy_data->path,
- &path[legacy_data->length]);
- }
-
- for (i = legacy_data->length; path[i] != '\0'; i++)
- {
- if (path[i] == '/')
- count++;
- }
- for (i = 0; menu_path[i] != '\0'; i++)
- {
- if (menu_path[i] == '/')
- menu_count++;
- }
- /* FIXME: The (legacy_data->current) test is just to patch a seggie, find out why. */
- while ((menu_count >= count) && (legacy_data->current))
- {
- legacy_data->current = legacy_data->current->parent;
- menu_count--;
- }
- if ((legacy_data->current) && (legacy_data->current->size > 0) &&
- (legacy_data->current->elements[1].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING))
- {
- menu_path = (char *)legacy_data->current->elements[1].element;
- menu_path += 12 + legacy_data->menu_length;
- }
- else
- {
- /* FIXME: Bugger, a corner case.
- * If this is .directory, then maybe ignore it?
- * If this is a desktop, we need to put it into the pool of the menu that legacy_data->merge will get merged into.
- */
- menu_path = "";
- printf(" LEGACYDIR FILE - %s - %s %s\n", legacy_data->prefix,
- legacy_data->path, &path[legacy_data->length]);
- return 0;
- }
-
- menu_count = strlen(menu_path);
- if (menu_count)
- menu_count++;
- file = (char *)&path[legacy_data->length + menu_count];
- count = strlen(file);
-
- if (strcmp(".directory", file) == 0)
- {
- menu_path = (char *)legacy_data->current->elements[0].element;
- menu_count = strlen(menu_path);
- menu_path[menu_count - 3] = '\0';
- sprintf(temp, "%s <.directory>", menu_path);
- legacy_data->current->elements[0].element = strdup(temp);
- ecore_desktop_tree_track(legacy_data->current,
- legacy_data->current->elements[0].element);
- }
- else if (strcmp(".desktop", &file[count - 8]) == 0)
- {
- Eina_Hash *pool;
- Ecore_Desktop_Tree *rules;
-
- pool = (Eina_Hash *) legacy_data->current->elements[2].element;
- rules =
- (Ecore_Desktop_Tree *) legacy_data->current->elements[3].element;
- if (rules->size == 0)
- {
- Ecore_Desktop_Tree *new_rules;
-
- new_rules = ecore_desktop_tree_new(NULL);
- if (new_rules)
- ecore_desktop_tree_add_child(rules, new_rules);
- }
- sprintf(temp, "%s%s", legacy_data->prefix, file);
- eina_hash_add(pool, temp, strdup(path));
-#ifdef DEBUG
-// printf
-// ("POOLING - _ecore_desktop_menu_legacy_menu(void *data, %s) - %s - %s\n",
-// path, file, temp);
-#endif
- if (rules->size > 0)
- {
- rules = (Ecore_Desktop_Tree *) rules->elements[0].element;
- sprintf(temp, "IOF %s%s", legacy_data->prefix, file);
- ecore_desktop_tree_extend(rules, temp);
- }
- }
-#ifdef DEBUG
- else
- printf("PROBLEM - _ecore_desktop_menu_legacy_menu(void *data, %s) - %s\n",
- path, file);
-#endif
-
- return 0;
-}
-
-static void
-_ecore_desktop_menu_unxml_rules(Ecore_Desktop_Tree * rules,
- Ecore_Desktop_Tree * tree, char type,
- char sub_type)
-{
- int i;
- char temp[PATH_MAX];
-
- for (i = 0; i < tree->size; i++)
- {
- if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- /* FIXME <All /> or <All foo="bar"> would be valid input (which this won't catch) */
- if (strcmp((char *)tree->elements[i].element, "<All/") == 0)
- {
- sprintf(temp, "%c%cA", type, sub_type);
- ecore_desktop_tree_extend(rules, temp);
- }
- else if (strcmp((char *)tree->elements[i].element, "<Filename") ==
- 0)
- {
- sprintf(temp, "%c%cF %s", type, sub_type,
- (char *)tree->elements[i + 1].element);
- ecore_desktop_tree_extend(rules, temp);
- }
- else if (strcmp((char *)tree->elements[i].element, "<Category") ==
- 0)
- {
- sprintf(temp, "%c%cC %s", type, sub_type,
- (char *)tree->elements[i + 1].element);
- ecore_desktop_tree_extend(rules, temp);
- }
- else if (strcmp((char *)tree->elements[i].element, "<Or") == 0)
- {
- _ecore_desktop_menu_unxml_rules(rules,
- (Ecore_Desktop_Tree *) tree->
- elements[i + 1].element,
- type, sub_type);
- }
- else if ((strcmp((char *)tree->elements[i].element, "<And") == 0)
- || (strcmp((char *)tree->elements[i].element, "<Not") ==
- 0))
- {
- char this_type;
- Ecore_Desktop_Tree *sub;
-
- this_type = ((char *)tree->elements[i].element)[1];
- sub = ecore_desktop_tree_new(NULL);
- if (sub)
- {
- ecore_desktop_tree_add_child(rules, sub);
- for (i++; i < tree->size; i++)
- {
- if (tree->elements[i].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- _ecore_desktop_menu_unxml_rules(sub,
- (Ecore_Desktop_Tree
- *) tree->
- elements[i].
- element, type,
- this_type);
- }
- }
- }
- }
- else if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- _ecore_desktop_menu_unxml_rules(rules,
- (Ecore_Desktop_Tree *) tree->
- elements[i].element, type,
- sub_type);
- }
- }
-}
-
-static void
-_ecore_desktop_menu_unxml_moves(Ecore_Desktop_Tree * menu,
- Ecore_Desktop_Tree * tree)
-{
- int i;
- char *old = NULL;
- char *new = NULL;
-
- for (i = 0; i < tree->size; i++)
- {
- if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- Ecore_Desktop_Tree *sub;
-
- sub = (Ecore_Desktop_Tree *) tree->elements[i].element;
- if ((sub) && (sub->size))
- {
- if (sub->elements[0].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- if (strcmp((char *)sub->elements[0].element, "<Old") ==
- 0)
- old = strdup((char *)sub->elements[1].element);
- if (strcmp((char *)sub->elements[0].element, "<New") ==
- 0)
- new = strdup((char *)sub->elements[1].element);
- }
- }
- }
- if ((old) && (new))
- {
- char temp[PATH_MAX * 2];
-
- sprintf(temp, "<MOVE <%s> <%s>", old, new);
- ecore_desktop_tree_extend(menu, temp);
- }
-
- if (old) free(old);
- old = NULL;
- if (new) free(new);
- new = NULL;
- }
-}
-
-static void
-_ecore_desktop_menu_add_dirs(Ecore_Desktop_Tree * tree, Ecore_List * paths,
- const char *pre, const char *post __UNUSED__, char *extra, int element __UNUSED__)
-{
- char t[PATH_MAX], *this_path;
-
- /* reverse the order of the dirs. */
- ecore_list_first_goto(paths);
- while ((this_path = ecore_list_next(paths)) != NULL)
- {
- if (extra)
- sprintf(t, "%s %s%s-merged/", pre, this_path, extra);
- else
- sprintf(t, "%s %s", pre, this_path);
- if (tree)
- ecore_desktop_tree_extend(tree, t);
- }
-}
-
-static int
-_ecore_desktop_menu_expand_apps(struct _ecore_desktop_menu_unxml_data
- *unxml_data, char *app_dir, Eina_Hash * pool)
-{
- if (pool)
- {
- struct _ecore_desktop_menu_expand_apps_data our_data;
- char dir[PATH_MAX];
-
- our_data.pool = pool;
- sprintf(dir, "%s", app_dir);
- if (dir[0] != '/')
- sprintf(dir, "%s/%s", unxml_data->path, app_dir);
- our_data.path = dir;
- our_data.length = strlen(dir);
-#ifdef DEBUG
- printf
- ("EXPANDING - _ecore_desktop_menu_expand_apps(unxml_data, %s) - %s\n",
- app_dir, dir);
-#endif
- ecore_desktop_paths_recursive_search(dir, NULL, -1, NULL,
- _ecore_desktop_menu_check_app,
- &our_data);
- }
- return 0;
-}
-
-static int
-_ecore_desktop_menu_check_app(void *data, const char *path)
-{
- char *p;
- struct _ecore_desktop_menu_expand_apps_data *our_data;
-
- our_data = (struct _ecore_desktop_menu_expand_apps_data *)data;
- p = strrchr(path, '.');
- if (p)
- {
- if (strcmp(p, ".desktop") == 0)
- {
- int i;
- char *file;
-
- file = strdup(path + our_data->length);
- if (file)
- {
- if (path)
- {
- for (i = 0; file[i] != '\0'; i++)
- if (file[i] == '/')
- file[i] = '-';
- eina_hash_add(our_data->pool, file, strdup(path));
- }
- free(file);
- }
-#ifdef DEBUG
-// printf
-// ("POOLING - _ecore_desktop_menu_check_app(void *data, %s) - %s\n",
-// path, file);
-#endif
- }
- }
-#ifdef DEBUG
- else
- printf("PROBLEM - _ecore_desktop_menu_check_app(void *data, %s)\n",
- path);
-#endif
- }
-
- return 0;
-}
-
-static int
-_ecore_desktop_menu_merge(const void *data, Ecore_Desktop_Tree * tree,
- int element, int level)
-{
- struct _ecore_desktop_menu_unxml_data *unxml_data;
- Ecore_Desktop_Tree *merge;
- int result = 0;
-
- unxml_data = (struct _ecore_desktop_menu_unxml_data *)data;
- merge = ecore_desktop_tree_new(NULL);
- if (tree->elements[element].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- char *string;
-
- string = (char *)tree->elements[element].element;
- if (strcmp(string, "<DefaultMergeDirs/") == 0)
- {
- if (unxml_data->base)
- _ecore_desktop_menu_add_dirs(merge, ecore_desktop_paths_menus,
- "<MergeDir", "</MergeDir",
- unxml_data->base, element);
- result = 1;
- }
- else if (strcmp(string, "<KDELegacyDirs/") == 0)
- {
- _ecore_desktop_menu_add_dirs(merge,
- ecore_desktop_paths_kde_legacy,
- "<LegacyDir prefix=\"kde-\"",
- "</LegacyDir", NULL, element);
- result = 1;
- }
- else if (strncmp(string, "<MergeDir ", 10) == 0)
- {
- char merge_path[PATH_MAX];
-
- if (string[10] == '/')
- sprintf(merge_path, "%s", &string[10]);
- else
- sprintf(merge_path, "%s%s", unxml_data->path, &string[10]);
- ecore_desktop_paths_recursive_search(merge_path, NULL, -1, NULL,
- _ecore_desktop_menu_check_menu,
- merge);
- result = 1;
- }
- else if (strncmp(string, "<LegacyDir ", 11) == 0)
- {
- char merge_path[PATH_MAX];
- struct _ecore_desktop_menu_legacy_data legacy_data;
-
- string += 11;
- legacy_data.prefix = NULL;
- legacy_data.merge = merge;
- legacy_data.current = merge;
- legacy_data.level = 0;
- legacy_data.menu = (char *)tree->elements[0].element;
- legacy_data.menu += 14;
- legacy_data.menu_length =
- strchr(legacy_data.menu, '>') - legacy_data.menu;
- legacy_data.menu[legacy_data.menu_length] = '\0';
- if (strncmp(string, "prefix=\"", 8) == 0)
- {
- string += 8;
- legacy_data.prefix = string;
- while ((*string != '"') && (*string != '\0'))
- string++;
- if (*string != '\0')
- *string++ = '\0';
- while ((*string == ' ') && (*string != '\0'))
- string++;
- }
- if (string[0] == '/')
- sprintf(merge_path, "%s", string);
- else
- sprintf(merge_path, "%s%s", unxml_data->path, string);
- legacy_data.path = merge_path;
- legacy_data.length = strlen(merge_path);
-#ifdef DEBUG
- printf("<LEGACYDIR> - %s - %s\n", legacy_data.prefix, merge_path);
-#endif
- ecore_desktop_paths_recursive_search(merge_path, NULL, -1,
- _ecore_desktop_menu_legacy_menu_dir,
- _ecore_desktop_menu_legacy_menu,
- &legacy_data);
- legacy_data.menu[legacy_data.menu_length] = '>';
- result = 1;
- }
- else if (strncmp(string, "<MergeFile ", 11) == 0)
- {
- char merge_path[PATH_MAX];
- int path_type = 1;
-
- /* FIXME: need to weed out duplicate <MergeFile's, use the last one. */
- string += 11;
- if (strncmp(string, "type=\"", 6) == 0)
- {
- string += 6;
- if (strncmp(string, "parent\"", 7) == 0)
- path_type = 0;
- while ((*string != '"') && (*string != '\0'))
- string++;
- if (*string != '\0')
- string++;
- while ((*string == ' ') && (*string != '\0'))
- string++;
- }
- if (path_type)
- {
- if (string[0] == '/')
- snprintf(merge_path, PATH_MAX, "%s", string);
- else
- snprintf(merge_path, PATH_MAX, "%s/%s", unxml_data->path, string);
- }
- else /* This is a parent type MergeFile. */
- {
- char *xdg_path;
- int found = -1;
-
- /* The spec is a little unclear, and the examples may look like they
- * contradict the description, but it all makes sense if you cross
- * reference it with the XDG Base Directory Specification (version 0.6).
- * To make things harder, parent type MergeFiles never appear on my box.
- *
- * What you do is this.
- *
- * Just plain ignore the specified path in the MergeFile element, it's for
- * legacy apps that don't understand parent types.
- *
- * Take the XDG_CONFIG_DIRS stuff as a whole ($XDG_CONFIG_HOME, then
- * $XDG_CONFIG_DIRS), in this code that will be ecore_desktop_paths_config.
- *
- * If this menu file is from one of the directories in ecore_desktop_paths_config,
- * scan the rest of ecore_desktop_paths_config looking for the new menu. In other
- * words start searching in the next ecore_desktop_paths_config entry after the one
- * that this menu is in.
- *
- * The file to look for is the path to this menu with the portion from
- * ecore_desktop_paths_config stripped off the beginning. For instance, the top level
- * menu file is typically /etc/xdg/menus/applications.menu, and /etc/xdg is
- * typically in ecore_desktop_paths_config, so search for menus/applications.menu.
- *
- * If this menu file is NOT from one of the directories in ecore_desktop_paths_menus,
- * insert nothing.
- *
- * The first one found wins, if none are found, don't merge anything.
- */
-
- merge_path[0] = '\0';
- ecore_list_first_goto(ecore_desktop_paths_config);
- while ((xdg_path = ecore_list_next(ecore_desktop_paths_config)) != NULL)
- {
- if (found < 0)
- {
- int length = strlen(xdg_path);
-
- if (strncmp(xdg_path, unxml_data->file, length) == 0)
- found = length;
- }
- else
- {
- snprintf(merge_path, PATH_MAX, "%s%s", xdg_path, &(unxml_data->file)[found]);
- if (ecore_file_exists(merge_path))
- break;
- merge_path[0] = '\0';
- }
- }
-
- }
- if (merge_path[0] != '\0')
- {
- Ecore_Desktop_Tree *new_menu;
-
- new_menu =
- _ecore_desktop_menu_get0(merge_path,
- unxml_data->merge_stack,
- level + 1);
- if (new_menu)
- {
- if (new_menu->size > 1)
- {
- if (new_menu->elements[1].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- new_menu =
- (Ecore_Desktop_Tree *) new_menu->
- elements[1].element;
- if (new_menu->size > 0)
- {
- if (new_menu->elements[0].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- merge =
- (Ecore_Desktop_Tree *) new_menu->
- elements[0].element;
- ecore_desktop_tree_remove(merge, 0);
- ecore_desktop_tree_remove(merge, 1);
- ecore_desktop_tree_remove(merge, 2);
- ecore_desktop_tree_remove(merge, 3);
- ecore_desktop_tree_remove(merge, 4);
- /* FIXME: The MENU_PATHs need to be prefixed. */
- }
- else
- printf
- ("FUCK an error in _ecore_desktop_menu_merge(%s)\n",
- merge_path);
- }
- else
- printf
- ("FUCK another error in _ecore_desktop_menu_merge(%s)\n",
- merge_path);
- }
- else
- printf
- ("FUCK ME! An error in _ecore_desktop_menu_merge(%s)\n",
- merge_path);
- }
- }
- }
- result = 1;
- }
- }
-
- if (result)
- {
- if ((merge) && (merge->size))
- ecore_desktop_tree_merge(tree, element + 1, merge);
-
- tree->elements[element].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[element].element = NULL;
- }
-
- return 0;
-}
-
-static int
-_ecore_desktop_menu_expand_default_dirs(const void *data,
- Ecore_Desktop_Tree * tree, int element,
- int level __UNUSED__)
-{
- struct _ecore_desktop_menu_unxml_data *unxml_data;
- Ecore_Desktop_Tree *merge;
- int result = 0;
-
- unxml_data = (struct _ecore_desktop_menu_unxml_data *)data;
- merge = ecore_desktop_tree_new(NULL);
- if (tree->elements[element].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- char *string;
-
- string = (char *)tree->elements[element].element;
- if (strcmp(string, "<DefaultAppDirs/") == 0)
- {
- _ecore_desktop_menu_add_dirs(merge, ecore_desktop_paths_desktops,
- "<AppDir", "</AppDir", NULL, element);
- result = 1;
- }
- else if (strcmp(string, "<DefaultDirectoryDirs/") == 0)
- {
- _ecore_desktop_menu_add_dirs(merge,
- ecore_desktop_paths_directories,
- "<DirectoryDir", "</DirectoryDir",
- NULL, element);
- result = 1;
- }
- }
- if (result)
- {
- if ((merge) && (merge->size))
- ecore_desktop_tree_merge(tree, element + 1, merge);
-
- tree->elements[element].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[element].element = NULL;
- }
-
- return 0;
-}
-
-static int
-_ecore_desktop_menu_generate(const void *data, Ecore_Desktop_Tree * tree,
- int element, int level)
-{
- struct _ecore_desktop_menu_unxml_data *unxml_data;
-
- unxml_data = (struct _ecore_desktop_menu_unxml_data *)data;
- if (tree->elements[element].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- if (strncmp((char *)tree->elements[element].element, "<MENU ", 6) == 0)
- {
- int i;
- struct _ecore_desktop_menu_generate_data generate_data;
-
- generate_data.unallocated = unxml_data->unallocated;
- generate_data.name = (char *)tree->elements[element].element;
- generate_data.path = (char *)tree->elements[element + 1].element;
- generate_data.pool = (Eina_Hash *) tree->elements[element + 2].element;
- generate_data.rules = (Ecore_Desktop_Tree *) tree->elements[element + 3].element;
- generate_data.apps = (Eina_Hash *) tree->elements[element + 4].element;
-
- /* generate and inherit the pools on the first pass, and preparse the include/exclude logic. */
- if (!generate_data.unallocated)
- {
- int i;
-
- for (i = element + 5; i < tree->size; i++)
- {
- int result = 0;
- char *string;
-
- if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- string = (char *)tree->elements[i].element;
- if (strncmp(string, "<AppDir ", 8) == 0)
- {
- _ecore_desktop_menu_expand_apps(unxml_data, &string[8], generate_data.pool);
- result = 1;
- }
- else if (strncmp(string, "<DirectoryDir ", 14) == 0)
- {
- char merge_path[PATH_MAX];
- Ecore_Desktop_Tree *merge;
-
- if (string[14] == '/')
- sprintf(merge_path, "%s", &string[14]);
- else
- sprintf(merge_path, "%s%s", unxml_data->path, &string[14]);
- merge = ecore_desktop_tree_new(NULL);
- if (merge)
- {
- ecore_desktop_paths_recursive_search(merge_path, NULL, -1, NULL, _ecore_desktop_menu_check_directory, merge);
- ecore_desktop_tree_merge(tree, i + 1, merge);
- }
- result = 1;
- }
- }
- else if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- Ecore_Desktop_Tree *sub;
-
- sub = (Ecore_Desktop_Tree *) tree->elements[i].element;
- if ((sub) && (sub->size))
- {
- if (sub->elements[0].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- string = (char *)sub->elements[0].element;
- if ((strcmp(string, "<Include") == 0) || (strcmp(string, "<Exclude") == 0))
- {
- Ecore_Desktop_Tree *new_sub;
-
- new_sub = ecore_desktop_tree_new(NULL);
- if (new_sub)
- {
- ecore_desktop_tree_add_child(generate_data.rules, new_sub);
- _ecore_desktop_menu_unxml_rules(new_sub, sub, string[1], 'O');
- }
- result = 1;
- }
- }
- }
- }
-
- if (result)
- {
- tree->elements[i].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[i].element = NULL;
- }
- }
-
- if (unxml_data->stack->size <= level)
- {
- while (unxml_data->stack->size < level)
- ecore_desktop_tree_add_hash(unxml_data->stack, generate_data.pool);
- ecore_desktop_tree_add_hash(unxml_data->stack, generate_data.pool);
- }
- else
- {
- unxml_data->stack->elements[level].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH;
- unxml_data->stack->elements[level].element = generate_data.pool;
- }
- for (i = level - 1; i >= 0; i--)
- {
- if (unxml_data->stack->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH)
- {
- Eina_Hash *ancestor;
-
- ancestor = (Eina_Hash *) unxml_data->stack->elements[i].element;
- eina_hash_foreach(ancestor, _ecore_desktop_menu_inherit_apps, generate_data.pool);
- }
- }
- }
-
- /* Process the rules. */
- if (generate_data.name[9] == (generate_data.unallocated ? 'O' : ' '))
- {
-#ifdef DEBUG
- printf("MAKING MENU - %s \t\t%s\n", generate_data.path, generate_data.name);
- ecore_desktop_tree_dump(generate_data.rules, 0);
- printf("\n\n");
-#endif
- for (i = 0; i < generate_data.rules->size; i++)
- {
- if (generate_data.rules->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- generate_data.rule = (Ecore_Desktop_Tree *) generate_data.rules->elements[i].element;
- if (generate_data.rule->size > 0)
- {
- char type = 'I';
-
- /* Find out if this is an include or an exclude. This info may be way down in the tree. */
- if (generate_data.rule->elements[0].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- ecore_desktop_tree_foreach(generate_data.rule, 0, _ecore_desktop_menu_is_include, &type);
- if (type == 'I')
- {
- generate_data.include = TRUE;
- eina_hash_foreach(generate_data.pool, _ecore_desktop_menu_select_app, &generate_data);
- }
- else
- {
- generate_data.include = FALSE;
- eina_hash_foreach(generate_data.apps, _ecore_desktop_menu_select_app, &generate_data);
- }
- }
- }
- else
- printf("Fuck, a bug in _ecore_desktop_menus.\n");
- }
- }
- }
- }
- return 0;
-}
-
-static int
-_ecore_desktop_menu_is_include(const void *data, Ecore_Desktop_Tree * tree, int element, int level __UNUSED__)
-{
- char *result;
-
- result = (char *)data;
- if (tree->elements[element].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- {
- *result = ((char *)tree->elements[element].element)[0];
- return 1;
- }
-
- return 0;
-}
-
-static Eina_Bool
-_ecore_desktop_menu_inherit_apps(const Eina_Hash *hash, const void *key, void *value, void *user_data)
-{
-#ifdef DEBUG
-// printf("CHECKING %s - %s\n", app, key);
-#endif
- if (!eina_hash_find(user_data, key))
- eina_hash_add(user_data, key, strdup(value));
-}
-
-static void
-_ecore_desktop_menu_select_app(const Eina_Hash *hash, const void *key, void *value, void *user_data)
-{
- Ecore_Desktop *desktop;
- struct _ecore_desktop_menu_generate_data *generate_data;
-
- generate_data = (struct _ecore_desktop_menu_generate_data *)user_data;
-
- /* FIXME: pass an actuall language parameter. */
- desktop = ecore_desktop_get(value, NULL);
-
- if (desktop)
- {
- if ((generate_data->unallocated) && (desktop->allocated))
- return;
-
- if (_ecore_desktop_menu_apply_rules(generate_data, generate_data->rule, key, desktop))
- {
- desktop->allocated = TRUE;
- if (generate_data->include)
- {
- eina_hash_add(generate_data->apps, key, strdup(value));
-#ifdef DEBUG
- printf("INCLUDING %s%s - %s\n", ((generate_data->unallocated) ? "UNALLOCATED " : ""), value, key);
-#endif
- }
- else
- {
- eina_hash_del(generate_data->apps, key);
-#ifdef DEBUG
- printf("EXCLUDING %s%s - %s\n", ((generate_data->unallocated) ? "UNALLOCATED " : ""), value, key);
-#endif
- }
- }
- }
-}
-
-static int
-_ecore_desktop_menu_apply_rules(struct _ecore_desktop_menu_generate_data *generate_data, Ecore_Desktop_Tree * rule, char *key, Ecore_Desktop * desktop)
-{
- char type = 'O';
- int result = FALSE;
- int i;
-
- for (i = 0; i < rule->size; i++)
- {
- if (rule->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- result = _ecore_desktop_menu_apply_rules(generate_data, (Ecore_Desktop_Tree *) rule->elements[i].element, key, desktop);
- }
- else
- {
- char *rul;
- char match;
- int sub_result = FALSE;
-
- rul = (char *)rule->elements[i].element;
- type = rul[1];
- match = rul[2];
- switch (match)
- {
- case 'A':
- {
- sub_result = TRUE;
- break;
- }
-
- case 'F':
- {
- if (strcmp(key, &rul[4]) == 0)
- sub_result = TRUE;
- break;
- }
-
- case 'C':
- {
- /* Try to match a category. */
- if ((desktop->Categories) && (eina_hash_find(desktop->Categories, &rul[4]) != NULL))
- sub_result = TRUE;
- break;
- }
- }
- switch (type)
- {
- case 'A': result = TRUE; if (!sub_result) return FALSE; break;
- case 'N': result = TRUE; if (sub_result) return FALSE; break;
- default: if (sub_result) return TRUE; break;
- }
- }
- }
-
- return result;
-}
-
-/*
-
-<Menu (tree)
- name
- flags = " " or "MDO" the first letter of - Marked, Deleted, OnlyUnallocated
- pool (hash)
- id = path
- id = path
- rules (tree)
- rule
- rule
- menu (hash)
- id = path
- id = path
- <Menu (tree)
- <Menu (tree)
-
-rules (tree)
- include/exclude or all/file/category x
- and/not (tree)
- include/exclude and/not all/file/category x
-
-ALL
- return true
-
-FILENAME
- if the rule string matches the desktop id return true
- otherwise return false
-
-CATEGORY
- loop through the apps categories
- as soon as one matches the rule string, return true
- otherwise return false.
-
-OR (implied)
- loop through the rules
- as soon as one matches, return true
- otherwise return false.
-
-SUB RULES
- process the sub rules, return the result
-
-AND
- loop through the rules
- as soon as one doesn't match, return false
- otherwise return true.
-
-NOT (implied OR)
- loop through the rules
- as soon as one matches, return false
- otherwise return true.
- */
-
-/* FDO PARSING STEPS.
-
-An asterisk in the first column marks those bits that are done.
-The spec is not numbered, so I have invented a numbering to help match the
-steps to the code.
-
- 10000000 merge menus
-*11000000 expand <KDELegacyDir>'s to <LegacyDir>.
-*12000000 expand <LegacyDir>'s
-*12100000 for each dir (recursive)
-*12110000 create recursively nested <MENU < L> <dirname> <> element
-*12120000 // <AppDir>dirpath</AppDir>
-*12130000 <DirectoryDir>dirpath</DirectoryDir>
-*12140000 if exist .directory
-*12141000 add <.directory> to name
-*12150000 <Include>
-*12160000 for each *.desktop
- 12161000 if no categories in bar.desktop
-*12161100 <Filename>prefix-bar.desktop</Filename>
- 12162000 add "Legacy" to categories
-*12163000 add any prefix to the desktop ID.
-*12164000 add it to the pool
-*12170000 </Include>
-*13000000 for each <MergeFile> and <MergeDir> element
-*13100000 get the root <Menu> elements from that elements file/s.
-*13200000 remove the <Name> element from those root <Menu> elements.
-*13300000 replace that element with the child elements of those root <Menu> elements.
-*13400000? expand the <DefaultMergeDirs> to <MergeDir>'s $XDG_CONFIG_DIRS/menus/foo-merged/ for the menu file foo.menu
-FIXME: The above should probably move to before 13000000
-*14000000 loop until all <MergeFile> and <MergeDir> elements are done,
-*14000000 careful to avoid infinite loops in files that reference each other.
-*15000000 for each <Menu> recursively
- 15100000 consolidate duplicate child <Menu>s.
-*15200000 expand <DefaultAppDir>s and <DefaultDirectoryDir>s to <AppDir>s and <DirectoryDir>s.
- 15300000 consolidate duplicate child <AppDir>s, <DirectoryDir>s, and <Directory>s.
- 16000000 for each <Menu> recursively (but from the deepest level out)
- 16100000 for each <Move>
- 16110000 do the move.
- 16120000 mark any <Menu> that has been affected.
- 17000000 for each marked <Menu> recursively
- 17100000 consolidate duplicate child <Menu>s.
-*18000000 for each <Menu> recursively
-*18100000 if there are <Deleted> elements that are not ovreridden by a <NotDelete> element
-*18110000 remove this <Menu> element and all it's children.
-
-*20000000 generate menus
-*21000000 for each <Menu> that is <NotOnlyUnallocated> (which is the default)
-*21100000 for each <AppDir>
-*21110000 for each .desktop
-*21111000 if it exists in the pool, replace it.
-*21112000 else add it to the pool.
-*21200000 for each parent <Menu>
-*21210000 for each .desktop in the pool
-*21211000 if it doesn't exist in the child <Menu> pool
-*21211100 add it to the pool.
-*21300000 for each <Include> and <Exclude>
-*21310000 if rule is an <Include>
-*21311000 for each .desktop in pool
-*21311100 for each rule
-*21311110 if rule matches .desktop in pool
-*21311111 add .desktop to menu.
-*21311112 mark it as allocated
-*21320000 if rule is an <Exclude>
-*21321000 for each .desktop in menu
-*21321100 for each rule
-*21321110 if rule matches .desktop in menu
-*21321111 remove .desktop from menu.
-*21321112 leave it as allocated.
-
-*30000000 generate unallocated menus
-*31000000 Same as for generate menus, but only the <OnlyUnallocated> ones.
-*32000000 Only the unallocated .desktop entries can be used.
-
- 40000000 generate menu layout
- This part of the spec is a whole other rabbit hole, and optional. B-)
-*/
-
-
-/* THINGS TAHT CAN BE DUPLICATED
-
-AppDir last dup is used
-.desktop last dup is used
-DirectoryDir last dup is used
-.directory last dup is used
-Directory last dup is used, unless it points to a non existant entry, then work your way backwards
-LegacyDir last dup is used
-MergeDir last dup is used
-MergeFile last dup is used
-
-DefaultMergeDirs dirs that are earlier in the path go later in the menu, so they have priority
-KDELegacyDirs dirs that are earlier in the path go later in the menu, so they have priority
-
-OnlyUnallocated & NotOnlyUnallocated last one wins, default is NotOnlyUnallocated
-Deleted & NotDeleted last one wins
-
-Include & Exclude done in order
-*/
+++ /dev/null
-/*
- * 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 Eina_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.
- */
-Eina_Hash*
-ecore_desktop_paths_to_hash(const char *paths)
-{
- Eina_Hash *result;
- char *path;
- char buf[PATH_MAX], *p, *pp;
-
- if (!paths) return NULL;
- result = eina_hash_string_superfast_new(free);
- if (!result) return NULL;
-
- 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) eina_hash_add(result, buf, strdup(buf));
- if (*p) p++;
- else p = NULL;
- }
- free(path);
- }
- return result;
-}
-
-/** Split a list of paths into an Eina_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;
-}
+++ /dev/null
-/*
- * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
- */
-#ifndef _ECORE_DESKTOP_PRIVATE_H
-# define _ECORE_DESKTOP_PRIVATE_H
-
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-#include <Ecore.h>
-#include <Ecore_File.h>
-
-#define E_FN_DEL(_fn, _h) if (_h) { _fn(_h); _h = NULL; }
-#define E_REALLOC(p, s, n) p = (s *)realloc(p, sizeof(s) * n)
-#define E_NEW(s, n) (s *)calloc(n, sizeof(s))
-#define E_NEW_BIG(s, n) (s *)malloc(n * sizeof(s))
-#define E_FREE(p) { if (p) {free(p); p = NULL;} }
-
-extern Ecore_List *ecore_desktop_paths_config;
-extern Ecore_List *ecore_desktop_paths_menus;
-extern Ecore_List *ecore_desktop_paths_directories;
-extern Ecore_List *ecore_desktop_paths_desktops;
-extern Ecore_List *ecore_desktop_paths_icons;
-extern Ecore_List *ecore_desktop_paths_kde_legacy;
-extern Ecore_List *ecore_desktop_paths_xsessions;
-extern struct _Ecore_Desktop_Instrumentation instrumentation;
-
-
-# ifdef __cplusplus
-extern "C"
-{
-# endif
-# ifdef __cplusplus
-}
-# endif
-
-#endif
+++ /dev/null
-#include <sys/types.h>
-
-#include "Ecore_Desktop.h"
-#include "ecore_desktop_private.h"
-
-static Eina_Bool
-ecore_desktop_tree_dump_each_hash_node(const Eina_Hash *hash,
- const void *key,
- void *value,
- void *user_data);
-
-/* Just a quick and dirty tree implemtation that will likely get replaced by
- * something much saner at a later date. I wrote most of this while falling
- * asleep. It will probably scare me when I wake up. B-)
- *
- * Devilhorns said to make it portable, so we can't rely on any external tree
- * implementation. So this tree is designed specifically for this task. Then
- * we finally found a place for the genmenu code, and Ecore was back on the
- * menu. However, speed could be an issue later, so it might be worth it to
- * stick with a custom tree implementation, so that we can optimize it for this
- * task.
- *
- * The trees will be tiny.
- * They only store strings.
- * There is no insertion or deletion, only append.
- * Append order must be maintained.
- * The trees will only ever be accessed sequentially, from begining to end.
- * The tree data will come in two ways, all in one big string, or a bunch of
- * seperate strings, one per element. Any particular tree might have both.
- *
- * No duplicates in the tree,
- * This is the nasty part of this tree implementation.
- * Insertions involve a linear search for dupes, most of the
- * time there won't be any dupes, so the tree is searched in
- * it's entirety. These trees will be really small, and only created at
- * the begining, so no big drama there.
- * The tree may allow duplicates.
- */
-
-Ecore_Desktop_Tree *
-ecore_desktop_tree_new(char *buffer)
-{
- Ecore_Desktop_Tree *tree;
-
- tree = E_NEW(Ecore_Desktop_Tree, 1);
- if ((tree) && (buffer))
- {
- tree->buffers =
- (char **)realloc(tree->buffers,
- (tree->buffers_size + 1) * sizeof(char *));
- tree->buffers[tree->buffers_size++] = strdup(buffer);
- }
- return tree;
-}
-
-Ecore_Desktop_Tree *
-ecore_desktop_tree_add(Ecore_Desktop_Tree * tree, const char *element)
-{
- tree->elements =
- (Ecore_Desktop_Tree_Element *) realloc(tree->elements,
- (tree->size +
- 1) *
- sizeof
- (Ecore_Desktop_Tree_Element));
- tree->elements[tree->size].element = (char*)element;
- tree->elements[tree->size++].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING;
- return tree;
-}
-
-Ecore_Desktop_Tree *
-ecore_desktop_tree_extend(Ecore_Desktop_Tree * tree, const char *element)
-{
- tree->buffers =
- (char **)realloc(tree->buffers,
- (tree->buffers_size + 1) * sizeof(char *));
- tree->buffers[tree->buffers_size++] = strdup(element);
- tree = ecore_desktop_tree_add(tree, tree->buffers[tree->buffers_size - 1]);
-
- return tree;
-}
-
-void
-ecore_desktop_tree_track(Ecore_Desktop_Tree * tree, void *element)
-{
- tree->buffers =
- (char **)realloc(tree->buffers,
- (tree->buffers_size + 1) * sizeof(char *));
- tree->buffers[tree->buffers_size++] = element;
-}
-
-/* OK, so we need an insert after all, and it falls into the dumb category. */
-Ecore_Desktop_Tree *
-ecore_desktop_tree_insert(Ecore_Desktop_Tree * tree, int before, void *element,
- Ecore_Desktop_Tree_Element_Type type)
-{
- int i;
-
- tree->elements =
- (Ecore_Desktop_Tree_Element *) realloc(tree->elements,
- (tree->size +
- 1) *
- sizeof
- (Ecore_Desktop_Tree_Element));
- tree->size++;
- for (i = tree->size - 1; i > before; i--)
- {
- tree->elements[i].element = tree->elements[i - 1].element;
- tree->elements[i].type = tree->elements[i - 1].type;
- }
- tree->elements[before].element = element;
- tree->elements[before].type = type;
- return tree;
-}
-
-/* OK, so we need a tree merge after all, and it falls into the dumb category. */
-Ecore_Desktop_Tree *
-ecore_desktop_tree_merge(Ecore_Desktop_Tree * tree, int before,
- Ecore_Desktop_Tree * element)
-{
- int i, size;
-
- size = element->size;
- if (size)
- {
- tree->elements =
- (Ecore_Desktop_Tree_Element *) realloc(tree->elements,
- (tree->size +
- size) *
- sizeof
- (Ecore_Desktop_Tree_Element));
- tree->size += size;
- for (i = tree->size - 1; (i > before) && ((i - size) > 0); i--)
- {
- tree->elements[i].element = tree->elements[i - size].element;
- tree->elements[i].type = tree->elements[i - size].type;
- }
- for (i = 0; i < size; i++)
- {
- tree->elements[before + i].element = element->elements[i].element;
- tree->elements[before + i].type = element->elements[i].type;
- }
- }
-
- /* Careful, this might screw up the freeing order if that is important. */
- size = element->buffers_size;
- if (size)
- {
-/*
- tree->buffers = (char **) realloc(tree->buffers, (tree->buffers_size + size) * sizeof(char *));
- tree->buffers_size += size;
- for (i = 0; i < size; i++)
- {
- tree->buffers[tree->buffers_size + i] = element->buffers[i];
- element->buffers[i] = NULL;
- }
-*/
- }
- return tree;
-}
-
-Ecore_Desktop_Tree *
-ecore_desktop_tree_add_child(Ecore_Desktop_Tree * tree,
- Ecore_Desktop_Tree * element)
-{
- tree->elements =
- (Ecore_Desktop_Tree_Element *) realloc(tree->elements,
- (tree->size +
- 1) *
- sizeof
- (Ecore_Desktop_Tree_Element));
- tree->elements[tree->size].element = element;
- tree->elements[tree->size++].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE;
- element->parent = tree;
- return tree;
-}
-
-Ecore_Desktop_Tree *
-ecore_desktop_tree_add_hash(Ecore_Desktop_Tree * tree, Eina_Hash * element)
-{
- tree->elements =
- (Ecore_Desktop_Tree_Element *) realloc(tree->elements,
- (tree->size +
- 1) *
- sizeof
- (Ecore_Desktop_Tree_Element));
- tree->elements[tree->size].element = element;
- tree->elements[tree->size++].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH;
- return tree;
-}
-
-void
-ecore_desktop_tree_remove(Ecore_Desktop_Tree * tree, int element)
-{
- if (tree->size > element)
- {
- tree->elements[element].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[element].element = NULL;
- }
-}
-
-int
-ecore_desktop_tree_exist(Ecore_Desktop_Tree * tree, char *element)
-{
- int exist = 0;
- int i;
-
- /* This is the dumb part of the tree, a linear search. */
- for (i = 0; i < tree->size; i++)
- {
- if ((tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
- && (strcmp((char *)tree->elements[i].element, element) == 0))
- {
- exist = 1;
- break;
- }
- }
- return exist;
-}
-
-int
-ecore_desktop_tree_foreach(Ecore_Desktop_Tree * tree, int level,
- int (*func) (const void *data,
- Ecore_Desktop_Tree * tree, int element,
- int level), const void *data)
-{
- int result = 0;
- int i;
-
- for (i = 0; i < tree->size; i++)
- {
- if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- {
- if (ecore_desktop_tree_foreach
- ((Ecore_Desktop_Tree *) tree->elements[i].element, level + 1,
- func, data))
- result = 1;
- }
- else if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL)
- {
- /* This falls into the dumb category. */
- int j = i;
- int k = i;
- int moved = 0;
-
- /* Find the next non NULL element. */
- while ((j < tree->size)
- && (tree->elements[j].type ==
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL))
- j++;
- /* Move the next batch of non NULL up. */
- while ((j < tree->size)
- && (tree->elements[j].type !=
- ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL))
- {
- moved = 1;
- tree->elements[k].type = tree->elements[j].type;
- tree->elements[k].element = tree->elements[j].element;
- tree->elements[j].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
- tree->elements[j].element = NULL;
- j++;
- k++;
- }
- if (moved)
- i--;
- else
- tree->size = i;
- }
- else
- {
- if (func(data, tree, i, level))
- result = 1;
- }
- }
- return result;
-}
-
-void
-ecore_desktop_tree_dump(Ecore_Desktop_Tree * tree, int level)
-{
- int i;
-
- for (i = 0; i < tree->size; i++)
- {
- int j;
-
- for (j = 0; j < level; j++)
- printf(".");
- switch (tree->elements[i].type)
- {
- case ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL:
- {
- printf("NULL\n");
- }
- break;
-
- case ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING:
- {
- printf("%s\n", (char *)tree->elements[i].element);
- }
- break;
-
- case ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE:
- {
- printf("TREE ELEMENT TYPE\n");
- ecore_desktop_tree_dump((Ecore_Desktop_Tree *) tree->
- elements[i].element, level + 1);
- }
- break;
-
- case ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH:
- {
- int lev;
-
- lev = level + 1;
- printf("HASH ELEMENT TYPE\n");
- eina_hash_foreach((Eina_Hash *) tree->elements[i].
- element,
- ecore_desktop_tree_dump_each_hash_node,
- &lev);
- }
- break;
-
- default:
- {
- printf("UNKNOWN ELEMENT TYPE!\n");
- }
- break;
- }
- }
-}
-
-static Eina_Bool
-ecore_desktop_tree_dump_each_hash_node(const Eina_Hash *hash,
- const void *key,
- void *value,
- void *user_data)
-{
- int level;
- int j;
-
- level = *((int *)user_data);
- for (j = 0; j < level; j++)
- printf(".");
- printf("%s = %s\n", (char *)key, (char *)value);
-}
-
-void
-ecore_desktop_tree_del(Ecore_Desktop_Tree * tree)
-{
- int i;
-
- for (i = tree->size - 1; i >= 0; i--)
- {
- if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
- ecore_desktop_tree_del((Ecore_Desktop_Tree *) tree->elements[i].
- element);
- else if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH)
- eina_hash_free((Eina_Hash *) tree->elements[i].element);
- }
-
- E_FREE(tree->elements);
-
- for (i = tree->buffers_size - 1; i >= 0; i--)
- E_FREE(tree->buffers[i]);
- E_FREE(tree);
-}
+++ /dev/null
-#include "Ecore_Desktop.h"
-#include "ecore_desktop_private.h"
-
-#include <fcntl.h>
-#include <ctype.h>
-#include <sys/stat.h>
-
-/** xmlame.c Extensively Mocked Language Approximately Mangled for Enlightenment.
- *
- * This is NOT a real XML parser. There were a few ways we could go when it came
- * to parsing the freedesktop.org (fdo) XML menu files. Whatever way we went, we
- * needed some sort of XML parser if we wanted to fully support fdo menu files.
- * Nothing we can do about that, fdo set the standard and they choose XML to do it.
- *
- * After a discussion with raster, three things led to the decision to do it this
- * way. It is likely that this will get included as a core part of the E17 window
- * manager (E17) coz E17 needs this functionality. E17 is in a dependency freeze
- * and there is no XML parser in it's current dependencies. The fdo XML menu files
- * look to be simple enough to parse that this sort of fake, brain dead, XML parser
- * may get away with it. Much testing on lots of systems is highly recommended.
- *
- * The final '>' of a tag is replaced with a '\0', but it's existance can be implied.
- */
-
-static char *_ecore_desktop_xmlame_parse(Ecore_Desktop_Tree * tree,
- char *buffer);
-
-Ecore_Desktop_Tree *
-ecore_desktop_xmlame_new(char *buffer)
-{
- Ecore_Desktop_Tree *tree;
-
- tree = ecore_desktop_tree_new(buffer);
- return tree;
-}
-
-Ecore_Desktop_Tree *
-ecore_desktop_xmlame_get(char *file)
-{
- int size;
- char *buffer;
- Ecore_Desktop_Tree *tree = NULL;
-
- size = ecore_file_size(file);
- buffer = (char *)malloc(size + 1);
- if (buffer)
- {
- int fd;
-
- buffer[0] = '\0';
- fd = open(file, O_RDONLY);
- if (fd != -1)
- {
- if (read(fd, buffer, size) == size)
- buffer[size] = '\0';
- }
- tree = ecore_desktop_xmlame_new(buffer);
- if (tree)
- {
- /* Have the file name as the first item on the tree, for later reference. */
- ecore_desktop_tree_extend(tree, file);
- _ecore_desktop_xmlame_parse(tree, buffer);
- }
- }
- return tree;
-}
-
-static char *
-_ecore_desktop_xmlame_parse(Ecore_Desktop_Tree * tree, char *buffer)
-{
- while (*buffer != '\0')
- {
- char *text;
-
- /* Skip any white space at the beginning. */
- while ((*buffer != '\0') && (isspace(*buffer)))
- buffer++;
- text = buffer;
- /* Find the beginning of a tag. */
- while ((*buffer != '<') && (*buffer != '\0'))
- buffer++;
- /* Check for data between tags. */
- if (buffer != text)
- {
- char t;
-
- t = *buffer;
- *buffer = '\0';
- ecore_desktop_tree_extend(tree, text);
- *buffer = t;
- }
- if (*buffer != '\0')
- {
- char *begin;
-
- begin = buffer++;
- /* Find the end of the tag. */
- while ((*buffer != '>') && (*buffer != '\0'))
- buffer++;
- /* We have our tag, do something with it. */
- if (*buffer != '\0')
- {
- *buffer++ = '\0';
- if (begin[1] == '/')
- { /* The end of an element. */
- ecore_desktop_tree_add(tree, begin);
- break;
- }
- else if ((begin[1] == '!') || (begin[1] == '-')
- || (*(buffer - 2) == '/'))
- { /* This is a script, a comment, or a stand alone tag. */
- ecore_desktop_tree_add(tree, begin);
- }
- else
- { /* The beginning of an element. */
- Ecore_Desktop_Tree *new_tree;
-
- new_tree = ecore_desktop_xmlame_new(NULL);
- if (new_tree)
- {
- ecore_desktop_tree_add_child(tree, new_tree);
- ecore_desktop_tree_add(new_tree, begin);
- buffer =
- _ecore_desktop_xmlame_parse(new_tree, buffer);
- }
- }
- }
- }
- }
-
- return buffer;
-}