forked from enlightenment/efl
parent
48202c24bc
commit
582e0768fe
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
|
@ -15,6 +15,5 @@ ecore_ipc \
|
|||
ecore_evas \
|
||||
ecore_config \
|
||||
ecore_file \
|
||||
ecore_desktop \
|
||||
ecore_imf \
|
||||
ecore_imf_evas
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.lo
|
||||
*.la
|
|
@ -1,281 +0,0 @@
|
|||
#ifndef _ECORE_DESKTOP_H
|
||||
# define _ECORE_DESKTOP_H
|
||||
|
||||
#include <Ecore_Data.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/**
|
||||
* @file Ecore_Desktop.h
|
||||
* @brief The file that provides the freedesktop.org desktop, icon, and menu
|
||||
* functions.
|
||||
*
|
||||
* This header provides the Ecore_Desktop freedesktop.org desktop, icon,
|
||||
* and menu handling functions, as well as ancillary functions for searching
|
||||
* freedesktop.org specific paths. Other freedesktop.org specifications
|
||||
* make use of similar files, paths, and icons, implementors can use / extend
|
||||
* this code to suit.
|
||||
*
|
||||
* Ecore_Desktop is not for every freedesktop.org specification, just those that
|
||||
* are associated with .desktop files.
|
||||
*
|
||||
* For path searching details, see @ref Ecore_Desktop_Paths_Group.
|
||||
*
|
||||
* For desktop file details, see @ref Ecore_Desktop_Main_Group.
|
||||
*
|
||||
* For icon theme details, see @ref Ecore_Desktop_Icon_Group.
|
||||
*
|
||||
* For menu file details, see @ref Ecore_Desktop_Menu_Group.
|
||||
*/
|
||||
|
||||
struct _Ecore_Desktop
|
||||
{
|
||||
/* FIXME: Do the ECORE_MAGIC thing here.
|
||||
* While this might help with segfaults and such, I think it's a waste of
|
||||
* space and cycles that just covers up bugs. On the other hand, it makes
|
||||
* for a more robust library, and it's used everywhere else in ecore.
|
||||
*/
|
||||
Eina_Hash *data, *group, *Categories, *OnlyShowIn, *NotShowIn, *MimeTypes, *Actions;
|
||||
char *original_path;
|
||||
char *original_lang;
|
||||
char *eap_name;
|
||||
char *name;
|
||||
char *generic;
|
||||
char *comment;
|
||||
char *type;
|
||||
char *categories;
|
||||
char *exec;
|
||||
char *exec_params;
|
||||
char *icon_class;
|
||||
char *icon_theme;
|
||||
char *icon;
|
||||
char *icon_path;
|
||||
time_t icon_time; /* For checking if the icon cache is valid. */
|
||||
char *path;
|
||||
char *URL;
|
||||
char *file;
|
||||
char *deletiondate;
|
||||
char *window_class; /* window class */
|
||||
char *window_name; /* window name */
|
||||
char *window_title; /* window title */
|
||||
char *window_role; /* window role */
|
||||
unsigned char wait_exit:1; /* wait for app to exit before execing next */
|
||||
unsigned char startup:1;
|
||||
unsigned char hidden:1;
|
||||
unsigned char no_display:1;
|
||||
unsigned char allocated:1;
|
||||
unsigned char ondisk:1;
|
||||
unsigned char hard_icon:1;
|
||||
/* Actually calling this st_mtime causes compile issues, must be some strange macros at work. */
|
||||
time_t mtime; /* For checking if the cache is valid. */
|
||||
};
|
||||
typedef struct _Ecore_Desktop Ecore_Desktop;
|
||||
|
||||
struct _Ecore_Desktop_Icon_Theme
|
||||
{
|
||||
Eina_Hash *data, *group;
|
||||
Ecore_List *Inherits;
|
||||
Ecore_List *Directories;
|
||||
char *path;
|
||||
char *name;
|
||||
char *comment;
|
||||
char *example;
|
||||
char *example_path;
|
||||
char *inherits;
|
||||
char *directories;
|
||||
int hidden;
|
||||
unsigned char hicolor:1;
|
||||
/* Actually calling this st_mtime causes compile issues, must be some strange macros at work. */
|
||||
time_t mtime; /* For checking if the cache is valid. */
|
||||
double last_checked;
|
||||
};
|
||||
typedef struct _Ecore_Desktop_Icon_Theme Ecore_Desktop_Icon_Theme;
|
||||
|
||||
struct _Ecore_Desktop_Icon_Theme_Directory
|
||||
{
|
||||
Eina_Hash *icons;
|
||||
char *path;
|
||||
char *full_path;
|
||||
char *type;
|
||||
int size, minimum, maximum, threshold;
|
||||
};
|
||||
typedef struct _Ecore_Desktop_Icon_Theme_Directory
|
||||
Ecore_Desktop_Icon_Theme_Directory;
|
||||
|
||||
enum _Ecore_Desktop_Paths_Type
|
||||
{
|
||||
ECORE_DESKTOP_PATHS_CONFIG = 0,
|
||||
ECORE_DESKTOP_PATHS_MENUS = 1,
|
||||
ECORE_DESKTOP_PATHS_DIRECTORIES = 2,
|
||||
ECORE_DESKTOP_PATHS_DESKTOPS = 3,
|
||||
ECORE_DESKTOP_PATHS_ICONS = 4,
|
||||
ECORE_DESKTOP_PATHS_KDE_LEGACY = 5,
|
||||
ECORE_DESKTOP_PATHS_XSESSIONS = 6,
|
||||
ECORE_DESKTOP_PATHS_MAX = 7
|
||||
};
|
||||
typedef enum _Ecore_Desktop_Paths_Type Ecore_Desktop_Paths_Type;
|
||||
|
||||
enum _Ecore_Desktop_Tree_Element_Type
|
||||
{
|
||||
ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL = 0,
|
||||
ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING = 1,
|
||||
ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE = 2,
|
||||
ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH = 3
|
||||
};
|
||||
typedef enum _Ecore_Desktop_Tree_Element_Type Ecore_Desktop_Tree_Element_Type;
|
||||
|
||||
struct _Ecore_Desktop_Tree_Element
|
||||
{
|
||||
void *element; /* A pointer to the element. */
|
||||
Ecore_Desktop_Tree_Element_Type type; /* The type of the element. */
|
||||
};
|
||||
typedef struct _Ecore_Desktop_Tree_Element Ecore_Desktop_Tree_Element;
|
||||
|
||||
typedef struct _Ecore_Desktop_Tree Ecore_Desktop_Tree;
|
||||
struct _Ecore_Desktop_Tree
|
||||
{
|
||||
Ecore_Desktop_Tree_Element *elements; /* An array of elements. */
|
||||
int size; /* The size of the array. */
|
||||
char **buffers; /* An array of pointers to the bits of data. */
|
||||
int buffers_size; /* The size of the array. */
|
||||
Ecore_Desktop_Tree *parent; /* Parent if this is a child. */
|
||||
};
|
||||
|
||||
struct _Ecore_Desktop_Instrumentation
|
||||
{
|
||||
double desktops_time;
|
||||
double desktops_in_cache_time;
|
||||
double desktops_not_found_time;
|
||||
double icons_time;
|
||||
double icons_in_cache_time;
|
||||
double icons_not_found_time;
|
||||
int desktops;
|
||||
int desktops_in_cache;
|
||||
int desktops_not_found;
|
||||
int icons;
|
||||
int icons_in_cache;
|
||||
int icons_not_found;
|
||||
};
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
# endif
|
||||
|
||||
/* Function Prototypes */
|
||||
EAPI int ecore_desktop_paths_init(void);
|
||||
EAPI void ecore_desktop_paths_extras_clear(void);
|
||||
EAPI void ecore_desktop_paths_prepend_user(Ecore_Desktop_Paths_Type
|
||||
type, const char *paths);
|
||||
EAPI void
|
||||
ecore_desktop_paths_prepend_system(Ecore_Desktop_Paths_Type type,
|
||||
const char *paths);
|
||||
EAPI void ecore_desktop_paths_append_user(Ecore_Desktop_Paths_Type
|
||||
type, const char *paths);
|
||||
EAPI void
|
||||
ecore_desktop_paths_append_system(Ecore_Desktop_Paths_Type type,
|
||||
const char *paths);
|
||||
EAPI void ecore_desktop_paths_regen(void);
|
||||
char *ecore_desktop_paths_file_find(Ecore_List * paths,
|
||||
const char *file, int sub,
|
||||
int (*func) (void
|
||||
*data,
|
||||
const char
|
||||
*path),
|
||||
void *data);
|
||||
EAPI int ecore_desktop_paths_for_each(Ecore_Desktop_Paths_Type
|
||||
type,
|
||||
Ecore_For_Each function,
|
||||
void *user_data);
|
||||
char *ecore_desktop_paths_recursive_search(const char *path,
|
||||
const char *file,
|
||||
int sub,
|
||||
int (*dir_func)
|
||||
(void *data,
|
||||
const char *path),
|
||||
int (*func) (void
|
||||
*data,
|
||||
const
|
||||
char
|
||||
*path),
|
||||
void *data);
|
||||
EAPI int ecore_desktop_paths_shutdown(void);
|
||||
|
||||
Eina_Hash *ecore_desktop_paths_to_hash(const char *paths);
|
||||
Ecore_List *ecore_desktop_paths_to_list(const char *paths);
|
||||
|
||||
EAPI int ecore_desktop_init(void);
|
||||
EAPI int ecore_desktop_shutdown(void);
|
||||
Eina_Hash *ecore_desktop_ini_get(const char *file);
|
||||
Ecore_Desktop *ecore_desktop_get(const char *file, const char *lang);
|
||||
void ecore_desktop_save(Ecore_Desktop * desktop);
|
||||
EAPI Ecore_List *ecore_desktop_get_command(Ecore_Desktop * desktop,
|
||||
Ecore_List * files, int fill);
|
||||
EAPI char *ecore_desktop_merge_command(char *exec, char *params);
|
||||
void ecore_desktop_destroy(Ecore_Desktop * desktop);
|
||||
|
||||
EAPI int ecore_desktop_icon_init(void);
|
||||
EAPI int ecore_desktop_icon_shutdown(void);
|
||||
EAPI char *ecore_desktop_icon_find(const char *icon,
|
||||
const char *icon_size,
|
||||
const char *icon_theme);
|
||||
|
||||
Eina_Hash *ecore_desktop_icon_theme_list(void);
|
||||
Ecore_Desktop_Icon_Theme *ecore_desktop_icon_theme_get(const char *file,
|
||||
const char *lang);
|
||||
void ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme
|
||||
* icon_theme);
|
||||
|
||||
EAPI void
|
||||
ecore_desktop_menu_for_each(void (*func)
|
||||
(const char *name, const char *path, const char *directory, Eina_Hash * apps));
|
||||
Ecore_Desktop_Tree *ecore_desktop_menu_get(char *file);
|
||||
|
||||
Ecore_Desktop_Tree *ecore_desktop_tree_new(char *buffer);
|
||||
Ecore_Desktop_Tree *ecore_desktop_tree_add(Ecore_Desktop_Tree * tree,
|
||||
const char *element);
|
||||
void ecore_desktop_tree_track(Ecore_Desktop_Tree * tree,
|
||||
void *element);
|
||||
Ecore_Desktop_Tree *ecore_desktop_tree_extend(Ecore_Desktop_Tree * tree,
|
||||
const char *element);
|
||||
Ecore_Desktop_Tree *ecore_desktop_tree_insert(Ecore_Desktop_Tree * tree,
|
||||
int before, void *element,
|
||||
Ecore_Desktop_Tree_Element_Type
|
||||
type);
|
||||
Ecore_Desktop_Tree *ecore_desktop_tree_merge(Ecore_Desktop_Tree * tree,
|
||||
int before,
|
||||
Ecore_Desktop_Tree * element);
|
||||
Ecore_Desktop_Tree *ecore_desktop_tree_add_child(Ecore_Desktop_Tree * tree,
|
||||
Ecore_Desktop_Tree *
|
||||
element);
|
||||
Ecore_Desktop_Tree *ecore_desktop_tree_add_hash(Ecore_Desktop_Tree * tree,
|
||||
Eina_Hash * element);
|
||||
void ecore_desktop_tree_remove(Ecore_Desktop_Tree * tree,
|
||||
int element);
|
||||
int ecore_desktop_tree_exist(Ecore_Desktop_Tree * tree,
|
||||
char *element);
|
||||
int ecore_desktop_tree_foreach(Ecore_Desktop_Tree * tree,
|
||||
int level,
|
||||
int (*func) (const void *data,
|
||||
Ecore_Desktop_Tree
|
||||
* tree,
|
||||
int element,
|
||||
int level),
|
||||
const void *data);
|
||||
void ecore_desktop_tree_dump(Ecore_Desktop_Tree * tree,
|
||||
int level);
|
||||
void ecore_desktop_tree_del(Ecore_Desktop_Tree * tree);
|
||||
|
||||
Ecore_Desktop_Tree *ecore_desktop_xmlame_new(char *buffer);
|
||||
Ecore_Desktop_Tree *ecore_desktop_xmlame_get(char *file);
|
||||
|
||||
char *ecore_desktop_home_get(void);
|
||||
|
||||
EAPI void ecore_desktop_instrumentation_reset(void);
|
||||
EAPI void ecore_desktop_instrumentation_print(void);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -1,704 +0,0 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "Ecore_Desktop.h"
|
||||
#include "ecore_desktop_private.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
static char *_ecore_desktop_icon_find0(const char *icon,
|
||||
const char *icon_size,
|
||||
const char *icon_theme,
|
||||
int *in_cache);
|
||||
|
||||
static int _ecore_desktop_icon_theme_list_add(void *data,
|
||||
const char *path);
|
||||
static void _ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme *
|
||||
icon_theme);
|
||||
static void
|
||||
_ecore_desktop_icon_theme_directory_destroy(Ecore_Desktop_Icon_Theme_Directory *
|
||||
icon_theme_directory);
|
||||
static inline void
|
||||
_ecore_desktop_icon_theme_cache_check(Ecore_Desktop_Icon_Theme *icon_theme);
|
||||
|
||||
/* FIXME: We need a way for the client to disable searching for any of these that they don't support. */
|
||||
static const char *ext[] =
|
||||
{ "", ".edj", ".png", ".svgz", ".svg", ".xpm", NULL }; /* "" is in case the icon already has an extension, search for that first. */
|
||||
static int init_count = 0;
|
||||
static Eina_Hash *icon_theme_cache = NULL;
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Desktop_Icon_Group icon theme Functions
|
||||
*
|
||||
* Functions that deal with freedesktop.org icon themes.
|
||||
*
|
||||
* This conforms with the freedesktop.org XDG Icon Theme Specification version 0.11
|
||||
*/
|
||||
|
||||
/**
|
||||
* Find the path to an icon.
|
||||
*
|
||||
* Using the search algorithm specified by freedesktop.org,
|
||||
* search for an icon in the currently installed set of icon themes.
|
||||
*
|
||||
* The returned string needs to be freed eventually.
|
||||
*
|
||||
* @param icon The name of the required icon.
|
||||
* @param icon_size The size of the required icon.
|
||||
* @param icon_theme The theme of the required icon.
|
||||
* @return The full path to an icon file, or NULL.
|
||||
* @ingroup Ecore_Desktop_Icon_Group
|
||||
*/
|
||||
|
||||
EAPI char *
|
||||
ecore_desktop_icon_find(const char *icon, const char *icon_size,
|
||||
const char *icon_theme)
|
||||
{
|
||||
char *result = NULL, *icn;
|
||||
Ecore_List *icons;
|
||||
int in_cache = 0;
|
||||
double begin;
|
||||
|
||||
begin = ecore_time_get();
|
||||
if (icon)
|
||||
{
|
||||
/* Easy check first, was a full path supplied? */
|
||||
if ((icon[0] == '/') && (ecore_file_exists(icon)))
|
||||
result = strdup(icon);
|
||||
else
|
||||
{
|
||||
icons = ecore_desktop_paths_to_list(icon);
|
||||
if (icons)
|
||||
{
|
||||
|
||||
if (icon_size == NULL)
|
||||
icon_size = "48x48";
|
||||
if (icon_theme == NULL)
|
||||
icon_theme = "hicolor";
|
||||
ecore_list_first_goto(icons);
|
||||
while ((icn = ecore_list_next(icons)))
|
||||
{
|
||||
char *ext;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "\tTrying To Find Icon %s\n", icn);
|
||||
#endif
|
||||
ext = strrchr(icn, '.');
|
||||
/* Check for unsupported extension */
|
||||
if ((ext) && (!strcmp(ext, ".ico")))
|
||||
continue;
|
||||
|
||||
result = _ecore_desktop_icon_find0(icn, icon_size, icon_theme, &in_cache);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
ecore_list_destroy(icons);
|
||||
|
||||
} /* if (icons) */
|
||||
} /* if ((icon[0] == '/') && (ecore_file_exists(icon))) ; else */
|
||||
} /* if (icon) */
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (in_cache)
|
||||
{
|
||||
instrumentation.icons_in_cache_time += ecore_time_get() - begin;
|
||||
instrumentation.icons_in_cache++;
|
||||
}
|
||||
else
|
||||
{
|
||||
instrumentation.icons_time += ecore_time_get() - begin;
|
||||
instrumentation.icons++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
instrumentation.icons_not_found_time += ecore_time_get() - begin;
|
||||
instrumentation.icons_not_found++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Search for an icon the fdo way.
|
||||
*
|
||||
* This complies with the freedesktop.org Icon Theme Specification version 0.7
|
||||
*
|
||||
* @param icon The icon to search for.
|
||||
* @param icon_size The icon size to search for.
|
||||
* @param icon_theme The icon theme to search in.
|
||||
* @return The full path to the found icon.
|
||||
*/
|
||||
static char *
|
||||
_ecore_desktop_icon_find0(const char *icon, const char *icon_size,
|
||||
const char *icon_theme, int *in_cache)
|
||||
{
|
||||
Ecore_Desktop_Icon_Theme *theme;
|
||||
char path[PATH_MAX];
|
||||
char *found = NULL;
|
||||
int wanted_size;
|
||||
int minimal_size = INT_MAX;
|
||||
int has_ext = 0;
|
||||
int has_icon_ext = 0;
|
||||
int i;
|
||||
char *closest = NULL;
|
||||
Ecore_Desktop_Icon_Theme_Directory *directory;
|
||||
|
||||
if ((icon == NULL) || (icon[0] == '\0'))
|
||||
return NULL;
|
||||
|
||||
/* Check the file extension, if any. */
|
||||
found = strrchr(icon, '.');
|
||||
if (found != NULL)
|
||||
{
|
||||
has_ext = 1;
|
||||
for (i = 0; ext[i] != NULL; i++)
|
||||
{
|
||||
if (strcmp(found, ext[i]) == 0)
|
||||
{
|
||||
has_icon_ext = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
found = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "\tTrying To Find Icon %s (%s) in theme %s\n", icon,
|
||||
icon_size, icon_theme);
|
||||
#endif
|
||||
|
||||
/* Get the theme description file. */
|
||||
theme = ecore_desktop_icon_theme_get(icon_theme, NULL);
|
||||
#ifdef DEBUG
|
||||
printf("SEARCHING FOR %s\n", icon_theme);
|
||||
#endif
|
||||
|
||||
if (!theme) return NULL;
|
||||
if (!theme->Directories) goto done;
|
||||
|
||||
wanted_size = atoi(icon_size);
|
||||
|
||||
/* Loop through the themes directories. */
|
||||
ecore_list_first_goto(theme->Directories);
|
||||
while ((directory = ecore_list_next(theme->Directories)) != NULL)
|
||||
{
|
||||
if (directory->size)
|
||||
{
|
||||
int match = 0;
|
||||
int result_size = 0;
|
||||
|
||||
/* Does this theme directory match the required icon size? */
|
||||
switch (directory->type[0])
|
||||
{
|
||||
case 'F': /* Fixed. */
|
||||
match = (wanted_size == directory->size);
|
||||
result_size = abs(directory->size - wanted_size);
|
||||
break;
|
||||
case 'S': /* Scaled. */
|
||||
match = ((directory->minimum <= wanted_size) &&
|
||||
(wanted_size <= directory->maximum));
|
||||
if (wanted_size < directory->minimum)
|
||||
result_size = directory->minimum - wanted_size;
|
||||
if (wanted_size > directory->maximum)
|
||||
result_size = wanted_size - directory->maximum;
|
||||
break;
|
||||
default: /* Threshold. */
|
||||
match = (((directory->size - directory->threshold) <= wanted_size) &&
|
||||
(wanted_size <= (directory->size + directory->threshold)));
|
||||
if (wanted_size < (directory->size - directory->threshold))
|
||||
result_size = directory->minimum - wanted_size;
|
||||
if (wanted_size > (directory->size + directory->threshold))
|
||||
result_size = wanted_size - directory->maximum;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Do we need to check this directory? */
|
||||
if ((match) || (result_size < minimal_size))
|
||||
{
|
||||
/* Look for icon with all extensions. */
|
||||
for (i = 0; ext[i] != NULL; i++)
|
||||
{
|
||||
/* Check if there will be an extension to check. */
|
||||
if ((ext[i][0] == '\0') && (!has_ext))
|
||||
continue;
|
||||
if ((ext[i][0] != '\0') && (has_icon_ext))
|
||||
continue;
|
||||
if (directory->icons)
|
||||
{
|
||||
snprintf(path, PATH_MAX, "%s%s", icon, ext[i]);
|
||||
#ifdef DEBUG
|
||||
printf("FDO icon = %s\n", path);
|
||||
#endif
|
||||
found = eina_hash_find(directory->icons, path);
|
||||
if (found)
|
||||
{
|
||||
found = strdup(found);
|
||||
if (match)
|
||||
*in_cache = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(path, PATH_MAX, "%s/%s%s", directory->full_path, icon, ext[i]);
|
||||
#ifdef DEBUG
|
||||
printf("FDO icon = %s\n", path);
|
||||
#endif
|
||||
if (ecore_file_exists(path))
|
||||
found = strdup(path);
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
if (ecore_file_is_dir(found))
|
||||
{
|
||||
free(found);
|
||||
found = NULL;
|
||||
}
|
||||
else if (match) /* If there is a match in sizes, return the icon. */
|
||||
goto done;
|
||||
else if (result_size < minimal_size) /* While we are here, figure out our next fallback strategy. */
|
||||
{
|
||||
minimal_size = result_size;
|
||||
if (closest) free(closest);
|
||||
closest = found;
|
||||
found = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(found);
|
||||
found = NULL;
|
||||
}
|
||||
}
|
||||
} /* for (i = 0; ext[i] != NULL; i++) */
|
||||
} /* if ((match) || (result_size < minimal_size)) */
|
||||
} /* if (directory->size) */
|
||||
} /* while ((directory = ecore_list_next(directory_paths)) != NULL) */
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/* Fall back strategy #1, look for closest size in this theme. */
|
||||
found = closest;
|
||||
if (found)
|
||||
{
|
||||
closest = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Fall back strategy #2, Try again with the parent themes. */
|
||||
if (!theme->hicolor)
|
||||
{
|
||||
if (theme->Inherits)
|
||||
{
|
||||
char *inherits;
|
||||
|
||||
ecore_list_first_goto(theme->Inherits);
|
||||
while ((inherits = ecore_list_next(theme->Inherits)) != NULL)
|
||||
{
|
||||
found = _ecore_desktop_icon_find0(icon, icon_size, inherits, in_cache);
|
||||
if (found) goto done;
|
||||
}
|
||||
}
|
||||
else /* Fall back strategy #3, Try the default hicolor theme. */
|
||||
{
|
||||
found = _ecore_desktop_icon_find0(icon, icon_size, "hicolor", in_cache);
|
||||
if (found) goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall back strategy #4, Just search in the base of the icon directories. */
|
||||
for (i = 0; ext[i] != NULL; i++)
|
||||
{
|
||||
/* Check if there will be an extension to check. */
|
||||
if ((ext[i][0] == '\0') && (!has_ext))
|
||||
continue;
|
||||
if ((ext[i][0] != '\0') && (has_icon_ext))
|
||||
continue;
|
||||
snprintf(path, PATH_MAX, "%s%s", icon, ext[i]);
|
||||
#ifdef DEBUG
|
||||
printf("FDO icon = %s\n", path);
|
||||
#endif
|
||||
found = ecore_desktop_paths_file_find(ecore_desktop_paths_icons, path, 0, NULL, NULL);
|
||||
if (found)
|
||||
{
|
||||
if (ecore_file_is_dir(found))
|
||||
{
|
||||
free(found);
|
||||
found = NULL;
|
||||
}
|
||||
else
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (closest) free(closest);
|
||||
ecore_desktop_icon_theme_destroy(theme);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
Eina_Hash*
|
||||
ecore_desktop_icon_theme_list(void)
|
||||
{
|
||||
static int loaded = 0;
|
||||
if (!loaded)
|
||||
{
|
||||
char *tmp;
|
||||
tmp = ecore_desktop_paths_file_find(ecore_desktop_paths_icons, "index.theme", 2,
|
||||
_ecore_desktop_icon_theme_list_add, NULL);
|
||||
loaded = 1;
|
||||
free(tmp);
|
||||
}
|
||||
return icon_theme_cache;
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_desktop_icon_theme_list_add(void *data __UNUSED__, const char *path)
|
||||
{
|
||||
char icn[PATH_MAX];
|
||||
|
||||
snprintf(icn, PATH_MAX, "%sindex.theme", path);
|
||||
if (ecore_desktop_icon_theme_get(icn, NULL))
|
||||
return 1; /* Should stop it from recursing this directory, but let it continue searching the next. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup what ever needs to be setup to support ecore_desktop_icon.
|
||||
*
|
||||
* There are internal structures that are needed for ecore_desktop_icon
|
||||
* functions to operate, this sets them up.
|
||||
*
|
||||
* @ingroup Ecore_Desktop_Icon_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_desktop_icon_init()
|
||||
{
|
||||
if (++init_count != 1)
|
||||
return init_count;
|
||||
|
||||
if (!icon_theme_cache)
|
||||
icon_theme_cache = eina_hash_string_superfast_new(_ecore_desktop_icon_theme_destroy);
|
||||
|
||||
return init_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down what ever needs to be torn down to support ecore_desktop_ycon.
|
||||
*
|
||||
* There are internal structures that are needed for ecore_desktop_icon
|
||||
* functions to operate, this tears them down.
|
||||
*
|
||||
* @ingroup Ecore_Desktop_Icon_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_desktop_icon_shutdown()
|
||||
{
|
||||
if (--init_count != 0)
|
||||
return init_count;
|
||||
|
||||
if (icon_theme_cache)
|
||||
{
|
||||
eina_hash_free(icon_theme_cache);
|
||||
icon_theme_cache = NULL;
|
||||
}
|
||||
|
||||
return init_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of an index.theme file.
|
||||
*
|
||||
* Everything that is in the index.theme file is returned in the
|
||||
* data member of the Ecore_Desktop_Icon_Theme structure, it's an Eina_Hash
|
||||
* as returned by ecore_desktop_ini_get(). Some of the data in the
|
||||
* index.theme file is decoded into specific members of the returned
|
||||
* structure.
|
||||
*
|
||||
* Use ecore_desktop_icon_theme_destroy() to free this structure.
|
||||
*
|
||||
* @param icon_theme Name of the icon theme, or full path to the index.theme file.
|
||||
* @param lang Language to use, or NULL for default.
|
||||
* @return An Ecore_Desktop_Icon_Theme containing the files contents.
|
||||
* @ingroup Ecore_Desktop_Icon_Group
|
||||
*/
|
||||
Ecore_Desktop_Icon_Theme *
|
||||
ecore_desktop_icon_theme_get(const char *icon_theme, const char *lang __UNUSED__)
|
||||
{
|
||||
Ecore_Desktop_Icon_Theme *result = NULL;
|
||||
char *theme_path = NULL, *theme_dir = NULL;
|
||||
const char *value;
|
||||
Ecore_List *Directories;
|
||||
char *directory;
|
||||
|
||||
if (icon_theme[0] == '/')
|
||||
{
|
||||
theme_path = strdup(icon_theme);
|
||||
theme_dir = ecore_file_dir_get(theme_path);
|
||||
if (theme_dir)
|
||||
icon_theme = ecore_file_file_get(theme_dir);
|
||||
#ifdef DEBUG
|
||||
printf("LOADING THEME %s - %s\n", icon_theme, theme_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
result = eina_hash_find(icon_theme_cache, icon_theme);
|
||||
if (result) goto done;
|
||||
if (!theme_dir)
|
||||
{
|
||||
char icn[PATH_MAX];
|
||||
|
||||
snprintf(icn, PATH_MAX, "%s/index.theme", icon_theme);
|
||||
#ifdef DEBUG
|
||||
printf("SEARCHING FOR %s\n", icn);
|
||||
#endif
|
||||
theme_path = ecore_desktop_paths_file_find(ecore_desktop_paths_icons, icn,
|
||||
2, NULL, NULL);
|
||||
if (!theme_path) goto error;
|
||||
theme_dir = ecore_file_dir_get(theme_path);
|
||||
}
|
||||
if (!theme_path) goto error;
|
||||
result = calloc(1, sizeof(Ecore_Desktop_Icon_Theme));
|
||||
if (!result) goto error;
|
||||
result->data = ecore_desktop_ini_get(theme_path);
|
||||
if (!result->data) goto error;
|
||||
result->group = eina_hash_find(result->data, "Icon Theme");
|
||||
if (!result->group) goto error;
|
||||
|
||||
|
||||
if ((strcmp(icon_theme, "hicolor") == 0))
|
||||
result->hicolor = 1;
|
||||
|
||||
/* According to the spec, name and comment are required, but we can fake those easily enough. */
|
||||
value = eina_hash_find(result->group, "Name");
|
||||
if (!value) value = icon_theme;
|
||||
result->name = strdup(value);
|
||||
value = eina_hash_find(result->group, "Comment");
|
||||
if (!value) value = "No comment provided.";
|
||||
result->comment = strdup(value);
|
||||
value = eina_hash_find(result->group, "Inherits");
|
||||
if (value)
|
||||
{
|
||||
result->inherits = strdup(value);
|
||||
if (result->inherits)
|
||||
result->Inherits = ecore_desktop_paths_to_list(result->inherits);
|
||||
}
|
||||
value = eina_hash_find(result->group, "Example");
|
||||
if (!value) value = "exec";
|
||||
result->example = strdup(value);
|
||||
value = eina_hash_find(result->group, "Directories");
|
||||
/* FIXME: Directories is also required, don't feel like faking it for now. */
|
||||
if (!value) goto error;
|
||||
result->directories = strdup(value);
|
||||
Directories = ecore_desktop_paths_to_list(result->directories);
|
||||
if (!Directories) goto error;
|
||||
result->Directories = ecore_list_new();
|
||||
if (!result->Directories) goto error;
|
||||
ecore_list_free_cb_set(result->Directories,
|
||||
ECORE_FREE_CB(_ecore_desktop_icon_theme_directory_destroy));
|
||||
ecore_list_first_goto(Directories);
|
||||
while ((directory = ecore_list_next(Directories)) != NULL)
|
||||
{
|
||||
Eina_Hash *sub_group;
|
||||
Ecore_Desktop_Icon_Theme_Directory *dir;
|
||||
|
||||
/* Get the details for this theme directory. */
|
||||
sub_group = eina_hash_find(result->data, directory);
|
||||
dir = calloc(1, sizeof (Ecore_Desktop_Icon_Theme_Directory));
|
||||
if ((dir) && (sub_group))
|
||||
{
|
||||
const char *size, *minsize, *maxsize, *threshold;
|
||||
char full_path[PATH_MAX];
|
||||
|
||||
dir->path = strdup(directory);
|
||||
snprintf(full_path, PATH_MAX, "%s/%s", theme_dir, directory);
|
||||
dir->full_path = strdup(full_path);
|
||||
value = eina_hash_find(sub_group, "Type");
|
||||
if (!value)
|
||||
value = "Threshold";
|
||||
dir->type = strdup(value);
|
||||
size = eina_hash_find(sub_group, "Size");
|
||||
minsize = eina_hash_find(sub_group, "MinSize");
|
||||
maxsize = eina_hash_find(sub_group, "MaxSize");
|
||||
threshold = eina_hash_find(sub_group, "Threshold");
|
||||
if (size)
|
||||
{
|
||||
if (!minsize)
|
||||
minsize = size;
|
||||
if (!maxsize)
|
||||
maxsize = size;
|
||||
if (!threshold)
|
||||
threshold = "2";
|
||||
dir->minimum = atoi(minsize);
|
||||
dir->maximum = atoi(maxsize);
|
||||
dir->threshold = atoi(threshold);
|
||||
|
||||
dir->size = atoi(size);
|
||||
ecore_list_append(result->Directories, dir);
|
||||
}
|
||||
else
|
||||
_ecore_desktop_icon_theme_directory_destroy(dir);
|
||||
}
|
||||
else if (dir)
|
||||
_ecore_desktop_icon_theme_directory_destroy(dir);
|
||||
}
|
||||
ecore_list_destroy(Directories);
|
||||
|
||||
/* This passes the basic validation tests, mark it as real and cache it. */
|
||||
result->path = strdup(theme_path);
|
||||
eina_hash_add(icon_theme_cache, icon_theme, result);
|
||||
eina_hash_free(result->data);
|
||||
result->data = NULL;
|
||||
result->group = NULL;
|
||||
|
||||
done:
|
||||
if (theme_dir) free(theme_dir);
|
||||
if (theme_path) free(theme_path);
|
||||
|
||||
/* Cache the directories. */
|
||||
_ecore_desktop_icon_theme_cache_check(result);
|
||||
return result;
|
||||
|
||||
error:
|
||||
if (theme_dir) free(theme_dir);
|
||||
if (theme_path) free(theme_path);
|
||||
if (result)
|
||||
{
|
||||
if (result->data) eina_hash_free(result->data);
|
||||
_ecore_desktop_icon_theme_destroy(result);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free whatever resources are used by an Ecore_Desktop_Icon_Theme.
|
||||
*
|
||||
* There are internal resources used by each Ecore_Desktop_Icon_Theme
|
||||
* This releases those resources.
|
||||
*
|
||||
* @param icon_theme An Ecore_Desktop_Icon_Theme.
|
||||
* @ingroup Ecore_Desktop_Icon_Group
|
||||
*/
|
||||
void
|
||||
ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme * icon_theme)
|
||||
{
|
||||
/* This is just a dummy, because these structures are cached. */
|
||||
/* Later versions of the cache may reference count, then this will be useful. */
|
||||
|
||||
icon_theme = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_desktop_icon_theme_destroy(Ecore_Desktop_Icon_Theme * icon_theme)
|
||||
{
|
||||
if (icon_theme->path)
|
||||
free(icon_theme->path);
|
||||
if (icon_theme->name)
|
||||
free(icon_theme->name);
|
||||
if (icon_theme->comment)
|
||||
free(icon_theme->comment);
|
||||
if (icon_theme->example)
|
||||
free(icon_theme->example);
|
||||
if (icon_theme->inherits)
|
||||
free(icon_theme->inherits);
|
||||
if (icon_theme->directories)
|
||||
free(icon_theme->directories);
|
||||
if (icon_theme->Directories)
|
||||
ecore_list_destroy(icon_theme->Directories);
|
||||
if (icon_theme->Inherits)
|
||||
ecore_list_destroy(icon_theme->Inherits);
|
||||
free(icon_theme);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_desktop_icon_theme_directory_destroy(Ecore_Desktop_Icon_Theme_Directory *
|
||||
icon_theme_directory)
|
||||
{
|
||||
if (icon_theme_directory->path)
|
||||
free(icon_theme_directory->path);
|
||||
if (icon_theme_directory->full_path)
|
||||
free(icon_theme_directory->full_path);
|
||||
if (icon_theme_directory->type)
|
||||
free(icon_theme_directory->type);
|
||||
if (icon_theme_directory->icons)
|
||||
eina_hash_free(icon_theme_directory->icons);
|
||||
free(icon_theme_directory);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_ecore_desktop_icon_theme_cache_check(Ecore_Desktop_Icon_Theme *icon_theme)
|
||||
{
|
||||
/* The spec has this to say -
|
||||
*
|
||||
* "The algorithm as described in this document works by always looking up
|
||||
* filenames in directories (a stat in unix terminology). A good
|
||||
* implementation is expected to read the directories once, and do all
|
||||
* lookups in memory using that information.
|
||||
*
|
||||
* "This caching can make it impossible for users to add icons without having
|
||||
* to restart applications. In order to handle this, any implementation that
|
||||
* does caching is required to look at the mtime of the toplevel icon
|
||||
* directories when doing a cache lookup, unless it already did so less than
|
||||
* 5 seconds ago. This means that any icon editor or theme installation
|
||||
* program need only to change the mtime of the the toplevel directory where
|
||||
* it changed the theme to make sure that the new icons will eventually get
|
||||
* used."
|
||||
*
|
||||
* The phrase "toplevel icon directories" is ambigous, but I guess they mean
|
||||
* the directory where the index.theme file lives.
|
||||
*/
|
||||
|
||||
struct stat st;
|
||||
int clear = 0;
|
||||
|
||||
if (ecore_time_get() > (icon_theme->last_checked + 5.0))
|
||||
{
|
||||
if (stat(icon_theme->path, &st) >= 0)
|
||||
{
|
||||
icon_theme->last_checked = ecore_time_get();
|
||||
if (st.st_mtime > icon_theme->mtime)
|
||||
{
|
||||
clear = 1;
|
||||
icon_theme->mtime = st.st_mtime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clear)
|
||||
{
|
||||
Ecore_Desktop_Icon_Theme_Directory *dir;
|
||||
char full_path[PATH_MAX];
|
||||
|
||||
ecore_list_first_goto(icon_theme->Directories);
|
||||
while ((dir = ecore_list_next(icon_theme->Directories)) != NULL)
|
||||
{
|
||||
if (dir->icons)
|
||||
{
|
||||
eina_hash_free(dir->icons);
|
||||
dir->icons = NULL;
|
||||
}
|
||||
dir->icons = eina_hash_string_superfast_new(NULL);
|
||||
if (dir->icons)
|
||||
{
|
||||
Ecore_List *files;
|
||||
|
||||
files = ecore_file_ls(dir->full_path);
|
||||
if (files)
|
||||
{
|
||||
const char *file;
|
||||
|
||||
while ((file = ecore_list_next(files)))
|
||||
{
|
||||
snprintf(full_path, PATH_MAX, "%s/%s", dir->full_path, file);
|
||||
eina_hash_add(dir->icons, file, strdup(full_path));
|
||||
}
|
||||
ecore_list_destroy(files);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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 <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_File.h>
|
||||
|
||||
#define E_FN_DEL(_fn, _h) if (_h) { _fn(_h); _h = NULL; }
|
||||
#define E_REALLOC(p, s, n) p = (s *)realloc(p, sizeof(s) * n)
|
||||
#define E_NEW(s, n) (s *)calloc(n, sizeof(s))
|
||||
#define E_NEW_BIG(s, n) (s *)malloc(n * sizeof(s))
|
||||
#define E_FREE(p) { if (p) {free(p); p = NULL;} }
|
||||
|
||||
extern Ecore_List *ecore_desktop_paths_config;
|
||||
extern Ecore_List *ecore_desktop_paths_menus;
|
||||
extern Ecore_List *ecore_desktop_paths_directories;
|
||||
extern Ecore_List *ecore_desktop_paths_desktops;
|
||||
extern Ecore_List *ecore_desktop_paths_icons;
|
||||
extern Ecore_List *ecore_desktop_paths_kde_legacy;
|
||||
extern Ecore_List *ecore_desktop_paths_xsessions;
|
||||
extern struct _Ecore_Desktop_Instrumentation instrumentation;
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
# endif
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
|
@ -1,366 +0,0 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include "Ecore_Desktop.h"
|
||||
#include "ecore_desktop_private.h"
|
||||
|
||||
static Eina_Bool
|
||||
ecore_desktop_tree_dump_each_hash_node(const Eina_Hash *hash,
|
||||
const void *key,
|
||||
void *value,
|
||||
void *user_data);
|
||||
|
||||
/* Just a quick and dirty tree implemtation that will likely get replaced by
|
||||
* something much saner at a later date. I wrote most of this while falling
|
||||
* asleep. It will probably scare me when I wake up. B-)
|
||||
*
|
||||
* Devilhorns said to make it portable, so we can't rely on any external tree
|
||||
* implementation. So this tree is designed specifically for this task. Then
|
||||
* we finally found a place for the genmenu code, and Ecore was back on the
|
||||
* menu. However, speed could be an issue later, so it might be worth it to
|
||||
* stick with a custom tree implementation, so that we can optimize it for this
|
||||
* task.
|
||||
*
|
||||
* The trees will be tiny.
|
||||
* They only store strings.
|
||||
* There is no insertion or deletion, only append.
|
||||
* Append order must be maintained.
|
||||
* The trees will only ever be accessed sequentially, from begining to end.
|
||||
* The tree data will come in two ways, all in one big string, or a bunch of
|
||||
* seperate strings, one per element. Any particular tree might have both.
|
||||
*
|
||||
* No duplicates in the tree,
|
||||
* This is the nasty part of this tree implementation.
|
||||
* Insertions involve a linear search for dupes, most of the
|
||||
* time there won't be any dupes, so the tree is searched in
|
||||
* it's entirety. These trees will be really small, and only created at
|
||||
* the begining, so no big drama there.
|
||||
* The tree may allow duplicates.
|
||||
*/
|
||||
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_tree_new(char *buffer)
|
||||
{
|
||||
Ecore_Desktop_Tree *tree;
|
||||
|
||||
tree = E_NEW(Ecore_Desktop_Tree, 1);
|
||||
if ((tree) && (buffer))
|
||||
{
|
||||
tree->buffers =
|
||||
(char **)realloc(tree->buffers,
|
||||
(tree->buffers_size + 1) * sizeof(char *));
|
||||
tree->buffers[tree->buffers_size++] = strdup(buffer);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_tree_add(Ecore_Desktop_Tree * tree, const char *element)
|
||||
{
|
||||
tree->elements =
|
||||
(Ecore_Desktop_Tree_Element *) realloc(tree->elements,
|
||||
(tree->size +
|
||||
1) *
|
||||
sizeof
|
||||
(Ecore_Desktop_Tree_Element));
|
||||
tree->elements[tree->size].element = (char*)element;
|
||||
tree->elements[tree->size++].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING;
|
||||
return tree;
|
||||
}
|
||||
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_tree_extend(Ecore_Desktop_Tree * tree, const char *element)
|
||||
{
|
||||
tree->buffers =
|
||||
(char **)realloc(tree->buffers,
|
||||
(tree->buffers_size + 1) * sizeof(char *));
|
||||
tree->buffers[tree->buffers_size++] = strdup(element);
|
||||
tree = ecore_desktop_tree_add(tree, tree->buffers[tree->buffers_size - 1]);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_desktop_tree_track(Ecore_Desktop_Tree * tree, void *element)
|
||||
{
|
||||
tree->buffers =
|
||||
(char **)realloc(tree->buffers,
|
||||
(tree->buffers_size + 1) * sizeof(char *));
|
||||
tree->buffers[tree->buffers_size++] = element;
|
||||
}
|
||||
|
||||
/* OK, so we need an insert after all, and it falls into the dumb category. */
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_tree_insert(Ecore_Desktop_Tree * tree, int before, void *element,
|
||||
Ecore_Desktop_Tree_Element_Type type)
|
||||
{
|
||||
int i;
|
||||
|
||||
tree->elements =
|
||||
(Ecore_Desktop_Tree_Element *) realloc(tree->elements,
|
||||
(tree->size +
|
||||
1) *
|
||||
sizeof
|
||||
(Ecore_Desktop_Tree_Element));
|
||||
tree->size++;
|
||||
for (i = tree->size - 1; i > before; i--)
|
||||
{
|
||||
tree->elements[i].element = tree->elements[i - 1].element;
|
||||
tree->elements[i].type = tree->elements[i - 1].type;
|
||||
}
|
||||
tree->elements[before].element = element;
|
||||
tree->elements[before].type = type;
|
||||
return tree;
|
||||
}
|
||||
|
||||
/* OK, so we need a tree merge after all, and it falls into the dumb category. */
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_tree_merge(Ecore_Desktop_Tree * tree, int before,
|
||||
Ecore_Desktop_Tree * element)
|
||||
{
|
||||
int i, size;
|
||||
|
||||
size = element->size;
|
||||
if (size)
|
||||
{
|
||||
tree->elements =
|
||||
(Ecore_Desktop_Tree_Element *) realloc(tree->elements,
|
||||
(tree->size +
|
||||
size) *
|
||||
sizeof
|
||||
(Ecore_Desktop_Tree_Element));
|
||||
tree->size += size;
|
||||
for (i = tree->size - 1; (i > before) && ((i - size) > 0); i--)
|
||||
{
|
||||
tree->elements[i].element = tree->elements[i - size].element;
|
||||
tree->elements[i].type = tree->elements[i - size].type;
|
||||
}
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
tree->elements[before + i].element = element->elements[i].element;
|
||||
tree->elements[before + i].type = element->elements[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
/* Careful, this might screw up the freeing order if that is important. */
|
||||
size = element->buffers_size;
|
||||
if (size)
|
||||
{
|
||||
/*
|
||||
tree->buffers = (char **) realloc(tree->buffers, (tree->buffers_size + size) * sizeof(char *));
|
||||
tree->buffers_size += size;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
tree->buffers[tree->buffers_size + i] = element->buffers[i];
|
||||
element->buffers[i] = NULL;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_tree_add_child(Ecore_Desktop_Tree * tree,
|
||||
Ecore_Desktop_Tree * element)
|
||||
{
|
||||
tree->elements =
|
||||
(Ecore_Desktop_Tree_Element *) realloc(tree->elements,
|
||||
(tree->size +
|
||||
1) *
|
||||
sizeof
|
||||
(Ecore_Desktop_Tree_Element));
|
||||
tree->elements[tree->size].element = element;
|
||||
tree->elements[tree->size++].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE;
|
||||
element->parent = tree;
|
||||
return tree;
|
||||
}
|
||||
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_tree_add_hash(Ecore_Desktop_Tree * tree, Eina_Hash * element)
|
||||
{
|
||||
tree->elements =
|
||||
(Ecore_Desktop_Tree_Element *) realloc(tree->elements,
|
||||
(tree->size +
|
||||
1) *
|
||||
sizeof
|
||||
(Ecore_Desktop_Tree_Element));
|
||||
tree->elements[tree->size].element = element;
|
||||
tree->elements[tree->size++].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH;
|
||||
return tree;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_desktop_tree_remove(Ecore_Desktop_Tree * tree, int element)
|
||||
{
|
||||
if (tree->size > element)
|
||||
{
|
||||
tree->elements[element].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
|
||||
tree->elements[element].element = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ecore_desktop_tree_exist(Ecore_Desktop_Tree * tree, char *element)
|
||||
{
|
||||
int exist = 0;
|
||||
int i;
|
||||
|
||||
/* This is the dumb part of the tree, a linear search. */
|
||||
for (i = 0; i < tree->size; i++)
|
||||
{
|
||||
if ((tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING)
|
||||
&& (strcmp((char *)tree->elements[i].element, element) == 0))
|
||||
{
|
||||
exist = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
int
|
||||
ecore_desktop_tree_foreach(Ecore_Desktop_Tree * tree, int level,
|
||||
int (*func) (const void *data,
|
||||
Ecore_Desktop_Tree * tree, int element,
|
||||
int level), const void *data)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tree->size; i++)
|
||||
{
|
||||
if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
|
||||
{
|
||||
if (ecore_desktop_tree_foreach
|
||||
((Ecore_Desktop_Tree *) tree->elements[i].element, level + 1,
|
||||
func, data))
|
||||
result = 1;
|
||||
}
|
||||
else if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL)
|
||||
{
|
||||
/* This falls into the dumb category. */
|
||||
int j = i;
|
||||
int k = i;
|
||||
int moved = 0;
|
||||
|
||||
/* Find the next non NULL element. */
|
||||
while ((j < tree->size)
|
||||
&& (tree->elements[j].type ==
|
||||
ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL))
|
||||
j++;
|
||||
/* Move the next batch of non NULL up. */
|
||||
while ((j < tree->size)
|
||||
&& (tree->elements[j].type !=
|
||||
ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL))
|
||||
{
|
||||
moved = 1;
|
||||
tree->elements[k].type = tree->elements[j].type;
|
||||
tree->elements[k].element = tree->elements[j].element;
|
||||
tree->elements[j].type = ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL;
|
||||
tree->elements[j].element = NULL;
|
||||
j++;
|
||||
k++;
|
||||
}
|
||||
if (moved)
|
||||
i--;
|
||||
else
|
||||
tree->size = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (func(data, tree, i, level))
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_desktop_tree_dump(Ecore_Desktop_Tree * tree, int level)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tree->size; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < level; j++)
|
||||
printf(".");
|
||||
switch (tree->elements[i].type)
|
||||
{
|
||||
case ECORE_DESKTOP_TREE_ELEMENT_TYPE_NULL:
|
||||
{
|
||||
printf("NULL\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case ECORE_DESKTOP_TREE_ELEMENT_TYPE_STRING:
|
||||
{
|
||||
printf("%s\n", (char *)tree->elements[i].element);
|
||||
}
|
||||
break;
|
||||
|
||||
case ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE:
|
||||
{
|
||||
printf("TREE ELEMENT TYPE\n");
|
||||
ecore_desktop_tree_dump((Ecore_Desktop_Tree *) tree->
|
||||
elements[i].element, level + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH:
|
||||
{
|
||||
int lev;
|
||||
|
||||
lev = level + 1;
|
||||
printf("HASH ELEMENT TYPE\n");
|
||||
eina_hash_foreach((Eina_Hash *) tree->elements[i].
|
||||
element,
|
||||
ecore_desktop_tree_dump_each_hash_node,
|
||||
&lev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
printf("UNKNOWN ELEMENT TYPE!\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
ecore_desktop_tree_dump_each_hash_node(const Eina_Hash *hash,
|
||||
const void *key,
|
||||
void *value,
|
||||
void *user_data)
|
||||
{
|
||||
int level;
|
||||
int j;
|
||||
|
||||
level = *((int *)user_data);
|
||||
for (j = 0; j < level; j++)
|
||||
printf(".");
|
||||
printf("%s = %s\n", (char *)key, (char *)value);
|
||||
}
|
||||
|
||||
void
|
||||
ecore_desktop_tree_del(Ecore_Desktop_Tree * tree)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = tree->size - 1; i >= 0; i--)
|
||||
{
|
||||
if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_TREE)
|
||||
ecore_desktop_tree_del((Ecore_Desktop_Tree *) tree->elements[i].
|
||||
element);
|
||||
else if (tree->elements[i].type == ECORE_DESKTOP_TREE_ELEMENT_TYPE_HASH)
|
||||
eina_hash_free((Eina_Hash *) tree->elements[i].element);
|
||||
}
|
||||
|
||||
E_FREE(tree->elements);
|
||||
|
||||
for (i = tree->buffers_size - 1; i >= 0; i--)
|
||||
E_FREE(tree->buffers[i]);
|
||||
E_FREE(tree);
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
#include "Ecore_Desktop.h"
|
||||
#include "ecore_desktop_private.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/** xmlame.c Extensively Mocked Language Approximately Mangled for Enlightenment.
|
||||
*
|
||||
* This is NOT a real XML parser. There were a few ways we could go when it came
|
||||
* to parsing the freedesktop.org (fdo) XML menu files. Whatever way we went, we
|
||||
* needed some sort of XML parser if we wanted to fully support fdo menu files.
|
||||
* Nothing we can do about that, fdo set the standard and they choose XML to do it.
|
||||
*
|
||||
* After a discussion with raster, three things led to the decision to do it this
|
||||
* way. It is likely that this will get included as a core part of the E17 window
|
||||
* manager (E17) coz E17 needs this functionality. E17 is in a dependency freeze
|
||||
* and there is no XML parser in it's current dependencies. The fdo XML menu files
|
||||
* look to be simple enough to parse that this sort of fake, brain dead, XML parser
|
||||
* may get away with it. Much testing on lots of systems is highly recommended.
|
||||
*
|
||||
* The final '>' of a tag is replaced with a '\0', but it's existance can be implied.
|
||||
*/
|
||||
|
||||
static char *_ecore_desktop_xmlame_parse(Ecore_Desktop_Tree * tree,
|
||||
char *buffer);
|
||||
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_xmlame_new(char *buffer)
|
||||
{
|
||||
Ecore_Desktop_Tree *tree;
|
||||
|
||||
tree = ecore_desktop_tree_new(buffer);
|
||||
return tree;
|
||||
}
|
||||
|
||||
Ecore_Desktop_Tree *
|
||||
ecore_desktop_xmlame_get(char *file)
|
||||
{
|
||||
int size;
|
||||
char *buffer;
|
||||
Ecore_Desktop_Tree *tree = NULL;
|
||||
|
||||
size = ecore_file_size(file);
|
||||
buffer = (char *)malloc(size + 1);
|
||||
if (buffer)
|
||||
{
|
||||
int fd;
|
||||
|
||||
buffer[0] = '\0';
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd != -1)
|
||||
{
|
||||
if (read(fd, buffer, size) == size)
|
||||
buffer[size] = '\0';
|
||||
}
|
||||
tree = ecore_desktop_xmlame_new(buffer);
|
||||
if (tree)
|
||||
{
|
||||
/* Have the file name as the first item on the tree, for later reference. */
|
||||
ecore_desktop_tree_extend(tree, file);
|
||||
_ecore_desktop_xmlame_parse(tree, buffer);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
static char *
|
||||
_ecore_desktop_xmlame_parse(Ecore_Desktop_Tree * tree, char *buffer)
|
||||
{
|
||||
while (*buffer != '\0')
|
||||
{
|
||||
char *text;
|
||||
|
||||
/* Skip any white space at the beginning. */
|
||||
while ((*buffer != '\0') && (isspace(*buffer)))
|
||||
buffer++;
|
||||
text = buffer;
|
||||
/* Find the beginning of a tag. */
|
||||
while ((*buffer != '<') && (*buffer != '\0'))
|
||||
buffer++;
|
||||
/* Check for data between tags. */
|
||||
if (buffer != text)
|
||||
{
|
||||
char t;
|
||||
|
||||
t = *buffer;
|
||||
*buffer = '\0';
|
||||
ecore_desktop_tree_extend(tree, text);
|
||||
*buffer = t;
|
||||
}
|
||||
if (*buffer != '\0')
|
||||
{
|
||||
char *begin;
|
||||
|
||||
begin = buffer++;
|
||||
/* Find the end of the tag. */
|
||||
while ((*buffer != '>') && (*buffer != '\0'))
|
||||
buffer++;
|
||||
/* We have our tag, do something with it. */
|
||||
if (*buffer != '\0')
|
||||
{
|
||||
*buffer++ = '\0';
|
||||
if (begin[1] == '/')
|
||||
{ /* The end of an element. */
|
||||
ecore_desktop_tree_add(tree, begin);
|
||||
break;
|
||||
}
|
||||
else if ((begin[1] == '!') || (begin[1] == '-')
|
||||
|| (*(buffer - 2) == '/'))
|
||||
{ /* This is a script, a comment, or a stand alone tag. */
|
||||
ecore_desktop_tree_add(tree, begin);
|
||||
}
|
||||
else
|
||||
{ /* The beginning of an element. */
|
||||
Ecore_Desktop_Tree *new_tree;
|
||||
|
||||
new_tree = ecore_desktop_xmlame_new(NULL);
|
||||
if (new_tree)
|
||||
{
|
||||
ecore_desktop_tree_add_child(tree, new_tree);
|
||||
ecore_desktop_tree_add(new_tree, begin);
|
||||
buffer =
|
||||
_ecore_desktop_xmlame_parse(new_tree, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
Loading…
Reference in New Issue