From 97f796e97786c5f868565431eb77ec5a9604eab0 Mon Sep 17 00:00:00 2001 From: englebass Date: Mon, 15 Dec 2008 18:39:01 +0000 Subject: [PATCH] Remove ecore-desktop git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@38151 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- Makefile.am | 8 +- configure.ac | 9 - ecore-desktop.pc.in | 11 - src/lib/Makefile.am | 1 - src/lib/ecore_desktop/.cvsignore | 6 - src/lib/ecore_desktop/Ecore_Desktop.h | 281 ---- src/lib/ecore_desktop/Makefile.am | 35 - src/lib/ecore_desktop/ecore_desktop.c | 1195 ---------------- src/lib/ecore_desktop/ecore_desktop_icon.c | 704 ---------- src/lib/ecore_desktop/ecore_desktop_menu.c | 1832 ------------------------- src/lib/ecore_desktop/ecore_desktop_paths.c | 1039 -------------- src/lib/ecore_desktop/ecore_desktop_private.h | 40 - src/lib/ecore_desktop/ecore_desktop_tree.c | 366 ----- src/lib/ecore_desktop/ecore_desktop_xmlame.c | 132 -- 14 files changed, 1 insertion(+), 5658 deletions(-) delete mode 100644 ecore-desktop.pc.in delete mode 100644 src/lib/ecore_desktop/.cvsignore delete mode 100644 src/lib/ecore_desktop/Ecore_Desktop.h delete mode 100644 src/lib/ecore_desktop/Makefile.am delete mode 100644 src/lib/ecore_desktop/ecore_desktop.c delete mode 100644 src/lib/ecore_desktop/ecore_desktop_icon.c delete mode 100644 src/lib/ecore_desktop/ecore_desktop_menu.c delete mode 100644 src/lib/ecore_desktop/ecore_desktop_paths.c delete mode 100644 src/lib/ecore_desktop/ecore_desktop_private.h delete mode 100644 src/lib/ecore_desktop/ecore_desktop_tree.c delete mode 100644 src/lib/ecore_desktop/ecore_desktop_xmlame.c diff --git a/Makefile.am b/Makefile.am index 45e15e9..85e4de2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,7 +13,6 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \ ecore.spec \ ecore-con.pc \ ecore-config.pc \ - ecore-desktop.pc \ ecore-directfb.pc\ ecore-evas.pc \ ecore-fb.pc \ @@ -38,7 +37,6 @@ EXTRA_DIST = AUTHORS COPYING COPYING-PLAIN \ 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 \ @@ -80,10 +78,6 @@ if BUILD_ECORE_FILE pfile = ecore-file.pc endif -if BUILD_ECORE_DESKTOP -pdesktop = ecore-desktop.pc -endif - if BUILD_ECORE_IMF pimf = ecore-imf.pc endif @@ -131,5 +125,5 @@ 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) diff --git a/configure.ac b/configure.ac index 04d79a6..a30fe62 100644 --- a/configure.ac +++ b/configure.ac @@ -44,7 +44,6 @@ AC_SUBST(version_info) # 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="" @@ -886,10 +885,6 @@ if test "x$have_ecore_file" = "xyes"; then 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]) @@ -903,7 +898,6 @@ ECORE_CHECK_MODULE([IMF_EVAS], [yes], [$try_ecore_imf_evas]) 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) @@ -924,7 +918,6 @@ AC_OUTPUT([ Makefile ecore-con.pc ecore-config.pc -ecore-desktop.pc ecore-directfb.pc ecore-evas.pc ecore-fb.pc @@ -959,7 +952,6 @@ src/lib/ecore_ipc/Makefile 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 @@ -982,7 +974,6 @@ if test "x$have_ecore_file" = "xyes" ; then 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" diff --git a/ecore-desktop.pc.in b/ecore-desktop.pc.in deleted file mode 100644 index 48b7bf9..0000000 --- a/ecore-desktop.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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} diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 022febe..40f4640 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -15,6 +15,5 @@ ecore_ipc \ ecore_evas \ ecore_config \ ecore_file \ -ecore_desktop \ ecore_imf \ ecore_imf_evas diff --git a/src/lib/ecore_desktop/.cvsignore b/src/lib/ecore_desktop/.cvsignore deleted file mode 100644 index 09980ae..0000000 --- a/src/lib/ecore_desktop/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la diff --git a/src/lib/ecore_desktop/Ecore_Desktop.h b/src/lib/ecore_desktop/Ecore_Desktop.h deleted file mode 100644 index 2b728db..0000000 --- a/src/lib/ecore_desktop/Ecore_Desktop.h +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef _ECORE_DESKTOP_H -# define _ECORE_DESKTOP_H - -#include -#include - -/** - * @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 diff --git a/src/lib/ecore_desktop/Makefile.am b/src/lib/ecore_desktop/Makefile.am deleted file mode 100644 index 9c7cb3d..0000000 --- a/src/lib/ecore_desktop/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -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 diff --git a/src/lib/ecore_desktop/ecore_desktop.c b/src/lib/ecore_desktop/ecore_desktop.c deleted file mode 100644 index e27f80a..0000000 --- a/src/lib/ecore_desktop/ecore_desktop.c +++ /dev/null @@ -1,1195 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ - -#include "Ecore_Desktop.h" -#include "ecore_desktop_private.h" - -#include -#include - -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 -} diff --git a/src/lib/ecore_desktop/ecore_desktop_icon.c b/src/lib/ecore_desktop/ecore_desktop_icon.c deleted file mode 100644 index 429628b..0000000 --- a/src/lib/ecore_desktop/ecore_desktop_icon.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ -#include -#include - -#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); - } - } - } - } -} diff --git a/src/lib/ecore_desktop/ecore_desktop_menu.c b/src/lib/ecore_desktop/ecore_desktop_menu.c deleted file mode 100644 index 85bdb20..0000000 --- a/src/lib/ecore_desktop/ecore_desktop_menu.c +++ /dev/null @@ -1,1832 +0,0 @@ -/* - * 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 - -#include "Ecore_Desktop.h" -#include "ecore_desktop_private.h" -#include "ecore_private.h" - -#include -#include -#include - -//#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, "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, "elements[element].type = - ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL; - tree->elements[element].element = NULL; - } - else if (strcmp((char *)tree->elements[element].element, "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, "elements[i].type = - ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL; - tree->elements[i].element = NULL; - } - else - if (strcmp - ((char *)tree->elements[i].element, - "elements[i].element, - "elements[i].element, - "elements[i].element, - "elements[i].element, - " - 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, - "elements[1]. - element); - sprintf(temp, - " <%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, "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, - "elements[1]. - element); - sprintf(temp, - " <%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, - " - 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, - "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, " <> <>"); - ecore_desktop_tree_extend(menu, "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, " <%s> <>", - &temp_path[start]); - menu->elements[0].element = strdup(temp); - ecore_desktop_tree_track(menu, - menu->elements[0].element); - sprintf(temp, "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, "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 or would be valid input (which this won't catch) */ - if (strcmp((char *)tree->elements[i].element, "elements[i].element, "elements[i + 1].element); - ecore_desktop_tree_extend(rules, temp); - } - else if (strcmp((char *)tree->elements[i].element, "elements[i + 1].element); - ecore_desktop_tree_extend(rules, temp); - } - else if (strcmp((char *)tree->elements[i].element, " - elements[i + 1].element, - type, sub_type); - } - else if ((strcmp((char *)tree->elements[i].element, "elements[i].element, "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, "elements[1].element); - if (strcmp((char *)sub->elements[0].element, "elements[1].element); - } - } - } - if ((old) && (new)) - { - char temp[PATH_MAX * 2]; - - sprintf(temp, " <%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, "base) - _ecore_desktop_menu_add_dirs(merge, ecore_desktop_paths_menus, - "base, element); - result = 1; - } - else if (strcmp(string, "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, "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(" - %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, "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, "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, "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, "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, "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; -} - -/* - -'s to . -*12000000 expand 's -*12100000 for each dir (recursive) -*12110000 create recursively nested <> element -*12120000 // dirpath -*12130000 dirpath -*12140000 if exist .directory -*12141000 add <.directory> to name -*12150000 -*12160000 for each *.desktop - 12161000 if no categories in bar.desktop -*12161100 prefix-bar.desktop - 12162000 add "Legacy" to categories -*12163000 add any prefix to the desktop ID. -*12164000 add it to the pool -*12170000 -*13000000 for each and element -*13100000 get the root elements from that elements file/s. -*13200000 remove the element from those root elements. -*13300000 replace that element with the child elements of those root elements. -*13400000? expand the to '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 and elements are done, -*14000000 careful to avoid infinite loops in files that reference each other. -*15000000 for each recursively - 15100000 consolidate duplicate child s. -*15200000 expand s and s to s and s. - 15300000 consolidate duplicate child s, s, and s. - 16000000 for each recursively (but from the deepest level out) - 16100000 for each - 16110000 do the move. - 16120000 mark any that has been affected. - 17000000 for each marked recursively - 17100000 consolidate duplicate child s. -*18000000 for each recursively -*18100000 if there are elements that are not ovreridden by a element -*18110000 remove this element and all it's children. - -*20000000 generate menus -*21000000 for each that is (which is the default) -*21100000 for each -*21110000 for each .desktop -*21111000 if it exists in the pool, replace it. -*21112000 else add it to the pool. -*21200000 for each parent -*21210000 for each .desktop in the pool -*21211000 if it doesn't exist in the child pool -*21211100 add it to the pool. -*21300000 for each and -*21310000 if rule is an -*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 -*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 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 -*/ diff --git a/src/lib/ecore_desktop/ecore_desktop_paths.c b/src/lib/ecore_desktop/ecore_desktop_paths.c deleted file mode 100644 index 9e7ea86..0000000 --- a/src/lib/ecore_desktop/ecore_desktop_paths.c +++ /dev/null @@ -1,1039 +0,0 @@ -/* - * 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 - -#include "Ecore_Desktop.h" -#include "ecore_desktop_private.h" - -#include -#include -#include -#include - -/* 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; -} diff --git a/src/lib/ecore_desktop/ecore_desktop_private.h b/src/lib/ecore_desktop/ecore_desktop_private.h deleted file mode 100644 index 4d8c176..0000000 --- a/src/lib/ecore_desktop/ecore_desktop_private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ -#ifndef _ECORE_DESKTOP_PRIVATE_H -# define _ECORE_DESKTOP_PRIVATE_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#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 diff --git a/src/lib/ecore_desktop/ecore_desktop_tree.c b/src/lib/ecore_desktop/ecore_desktop_tree.c deleted file mode 100644 index 8abfb78..0000000 --- a/src/lib/ecore_desktop/ecore_desktop_tree.c +++ /dev/null @@ -1,366 +0,0 @@ -#include - -#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); -} diff --git a/src/lib/ecore_desktop/ecore_desktop_xmlame.c b/src/lib/ecore_desktop/ecore_desktop_xmlame.c deleted file mode 100644 index 6adcaf0..0000000 --- a/src/lib/ecore_desktop/ecore_desktop_xmlame.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "Ecore_Desktop.h" -#include "ecore_desktop_private.h" - -#include -#include -#include - -/** 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; -} -- 2.7.4