forked from enlightenment/efl
move cache file handling from desktop to cache
SVN revision: 54901
This commit is contained in:
parent
69e2339c4f
commit
e2c6e11724
|
@ -3,12 +3,21 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "Efreet.h"
|
#include "Efreet.h"
|
||||||
#include "efreet_private.h"
|
#include "efreet_private.h"
|
||||||
|
|
||||||
/* TODO: Listen for changes for icon dirs */
|
/* TODO: Listen for changes for icon dirs */
|
||||||
/* TODO: Transfer some of desktop cache to this file, to share some infrastructure */
|
|
||||||
|
typedef struct _Efreet_Old_Cache Efreet_Old_Cache;
|
||||||
|
|
||||||
|
struct _Efreet_Old_Cache
|
||||||
|
{
|
||||||
|
Eina_Hash *hash;
|
||||||
|
Eet_File *ef;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data for cache files
|
* Data for cache files
|
||||||
|
@ -21,25 +30,44 @@ static Eet_File *icon_cache = NULL;
|
||||||
static const char *icon_cache_name = NULL;
|
static const char *icon_cache_name = NULL;
|
||||||
static Eet_File *icon_fallback_cache = NULL;
|
static Eet_File *icon_fallback_cache = NULL;
|
||||||
|
|
||||||
static Ecore_File_Monitor *icon_cache_monitor = NULL;
|
static Eet_Data_Descriptor *desktop_edd = NULL;
|
||||||
static Ecore_Timer *icon_cache_timer = NULL;
|
|
||||||
|
|
||||||
|
static Eet_File *desktop_cache = NULL;
|
||||||
|
static const char *desktop_cache_dirs = NULL;
|
||||||
|
static const char *desktop_cache_file = NULL;
|
||||||
|
|
||||||
|
static Ecore_File_Monitor *cache_monitor = NULL;
|
||||||
|
|
||||||
|
static Ecore_Timer *cache_timer = NULL;
|
||||||
|
|
||||||
|
static Ecore_Event_Handler *cache_exe_handler = NULL;
|
||||||
|
static Ecore_Job *icon_cache_job = NULL;
|
||||||
static Ecore_Exe *icon_cache_exe = NULL;
|
static Ecore_Exe *icon_cache_exe = NULL;
|
||||||
static int icon_cache_exe_lock = -1;
|
static int icon_cache_exe_lock = -1;
|
||||||
static Ecore_Event_Handler *icon_cache_exe_handler;
|
static Ecore_Job *desktop_cache_job = NULL;
|
||||||
|
static Ecore_Exe *desktop_cache_exe = NULL;
|
||||||
|
static int desktop_cache_exe_lock = -1;
|
||||||
|
|
||||||
|
static Eina_List *old_desktop_caches = NULL;
|
||||||
|
|
||||||
static void efreet_icon_edd_shutdown(void);
|
static void efreet_icon_edd_shutdown(void);
|
||||||
|
static void efreet_desktop_edd_shutdown(void);
|
||||||
|
|
||||||
static Eina_Bool icon_cache_exe_cb(void *data, int type, void *event);
|
static Eina_Bool cache_exe_cb(void *data, int type, void *event);
|
||||||
static void icon_cache_update_cb(void *data, Ecore_File_Monitor *em,
|
static void cache_update_cb(void *data, Ecore_File_Monitor *em,
|
||||||
Ecore_File_Event event, const char *path);
|
Ecore_File_Event event, const char *path);
|
||||||
|
|
||||||
static void icon_cache_timer_update(void);
|
static void cache_timer_update(void);
|
||||||
static Eina_Bool icon_cache_timer_cb(void *data);
|
static Eina_Bool cache_timer_cb(void *data);
|
||||||
|
|
||||||
static void icon_cache_close(void);
|
static void icon_cache_close(void);
|
||||||
|
|
||||||
|
static void desktop_cache_update_cache_job(void *data);
|
||||||
|
static void icon_cache_update_cache_job(void *data);
|
||||||
|
static void desktop_cache_update_free(void *data, void *ev);
|
||||||
|
|
||||||
EAPI int EFREET_EVENT_ICON_CACHE_UPDATE = 0;
|
EAPI int EFREET_EVENT_ICON_CACHE_UPDATE = 0;
|
||||||
|
EAPI int EFREET_EVENT_DESKTOP_CACHE_UPDATE = 0;
|
||||||
|
|
||||||
int
|
int
|
||||||
efreet_cache_init(void)
|
efreet_cache_init(void)
|
||||||
|
@ -47,55 +75,85 @@ efreet_cache_init(void)
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
if (!efreet_icon_edd_init())
|
if (!efreet_icon_edd_init())
|
||||||
{
|
goto error;
|
||||||
efreet_icon_edd_shutdown();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!efreet_icon_fallback_edd_init())
|
if (!efreet_icon_fallback_edd_init())
|
||||||
{
|
goto error;
|
||||||
efreet_icon_edd_shutdown();
|
if (!efreet_desktop_edd_init())
|
||||||
return 0;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
EFREET_EVENT_ICON_CACHE_UPDATE = ecore_event_type_new();
|
EFREET_EVENT_ICON_CACHE_UPDATE = ecore_event_type_new();
|
||||||
|
EFREET_EVENT_DESKTOP_CACHE_UPDATE = ecore_event_type_new();
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s/.efreet", efreet_home_dir_get());
|
snprintf(buf, sizeof(buf), "%s/.efreet", efreet_home_dir_get());
|
||||||
if (!ecore_file_mkpath(buf)) goto cache_error;
|
if (!ecore_file_mkpath(buf)) goto error;
|
||||||
|
|
||||||
if (efreet_cache_update)
|
if (efreet_cache_update)
|
||||||
{
|
{
|
||||||
icon_cache_exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
cache_exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
||||||
icon_cache_exe_cb, NULL);
|
cache_exe_cb, NULL);
|
||||||
if (!icon_cache_exe_handler) goto cache_error;
|
if (!cache_exe_handler) goto error;
|
||||||
|
|
||||||
icon_cache_monitor = ecore_file_monitor_add(buf,
|
cache_monitor = ecore_file_monitor_add(buf,
|
||||||
icon_cache_update_cb,
|
cache_update_cb,
|
||||||
NULL);
|
NULL);
|
||||||
if (!icon_cache_monitor) goto cache_error;
|
if (!cache_monitor) goto error;
|
||||||
|
|
||||||
#if 0
|
|
||||||
efreet_desktop_changes_listen();
|
efreet_desktop_changes_listen();
|
||||||
|
#if 0
|
||||||
|
efreet_icon_changes_listen();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_icon_cache_create", NULL);
|
efreet_cache_icon_update();
|
||||||
|
efreet_cache_desktop_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
cache_error:
|
error:
|
||||||
if (icon_cache_exe_handler) ecore_event_handler_del(icon_cache_exe_handler);
|
if (cache_exe_handler) ecore_event_handler_del(cache_exe_handler);
|
||||||
if (icon_cache_monitor) ecore_file_monitor_del(icon_cache_monitor);
|
if (cache_monitor) ecore_file_monitor_del(cache_monitor);
|
||||||
|
efreet_icon_edd_shutdown();
|
||||||
|
efreet_desktop_edd_shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
efreet_cache_shutdown(void)
|
efreet_cache_shutdown(void)
|
||||||
{
|
{
|
||||||
if (icon_cache_timer) ecore_timer_del(icon_cache_timer);
|
Efreet_Old_Cache *d;
|
||||||
icon_cache_close();
|
|
||||||
|
|
||||||
if (icon_cache_exe_handler) ecore_event_handler_del(icon_cache_exe_handler);
|
if (cache_timer) ecore_timer_del(cache_timer);
|
||||||
if (icon_cache_monitor) ecore_file_monitor_del(icon_cache_monitor);
|
icon_cache_close();
|
||||||
|
if (desktop_cache) eet_close(desktop_cache);
|
||||||
|
IF_RELEASE(desktop_cache_file);
|
||||||
|
IF_RELEASE(desktop_cache_dirs);
|
||||||
|
|
||||||
|
if (cache_exe_handler) ecore_event_handler_del(cache_exe_handler);
|
||||||
|
if (cache_monitor) ecore_file_monitor_del(cache_monitor);
|
||||||
efreet_icon_edd_shutdown();
|
efreet_icon_edd_shutdown();
|
||||||
|
efreet_desktop_edd_shutdown();
|
||||||
|
if (desktop_cache_job)
|
||||||
|
{
|
||||||
|
ecore_job_del(desktop_cache_job);
|
||||||
|
desktop_cache_job = NULL;
|
||||||
|
}
|
||||||
|
if (icon_cache_exe) ecore_exe_terminate(icon_cache_exe);
|
||||||
|
if (desktop_cache_exe) ecore_exe_terminate(desktop_cache_exe);
|
||||||
|
if (icon_cache_exe_lock > 0)
|
||||||
|
{
|
||||||
|
close(icon_cache_exe_lock);
|
||||||
|
icon_cache_exe_lock = -1;
|
||||||
|
}
|
||||||
|
if (desktop_cache_exe_lock > 0)
|
||||||
|
{
|
||||||
|
close(desktop_cache_exe_lock);
|
||||||
|
desktop_cache_exe_lock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EINA_LIST_FREE(old_desktop_caches, d)
|
||||||
|
{
|
||||||
|
eina_hash_free(d->hash);
|
||||||
|
free(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -114,6 +172,51 @@ efreet_icon_cache_file(const char *theme)
|
||||||
return cache_file;
|
return cache_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Needs EAPI because of helper binaries
|
||||||
|
*/
|
||||||
|
EAPI const char *
|
||||||
|
efreet_desktop_cache_file(void)
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX] = { '\0' };
|
||||||
|
const char *home, *lang, *country, *modifier;
|
||||||
|
|
||||||
|
if (desktop_cache_file) return desktop_cache_file;
|
||||||
|
|
||||||
|
home = efreet_home_dir_get();
|
||||||
|
lang = efreet_lang_get();
|
||||||
|
country = efreet_lang_country_get();
|
||||||
|
modifier = efreet_lang_modifier_get();
|
||||||
|
|
||||||
|
if (lang && country && modifier)
|
||||||
|
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s@%s.cache", home, lang, country, modifier);
|
||||||
|
else if (lang && country)
|
||||||
|
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s.cache", home, lang, country);
|
||||||
|
else if (lang)
|
||||||
|
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s.cache", home, lang);
|
||||||
|
else
|
||||||
|
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop.cache", home);
|
||||||
|
|
||||||
|
desktop_cache_file = eina_stringshare_add(tmp);
|
||||||
|
return desktop_cache_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Needs EAPI because of helper binaries
|
||||||
|
*/
|
||||||
|
EAPI const char *
|
||||||
|
efreet_desktop_cache_dirs(void)
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX] = { '\0' };
|
||||||
|
|
||||||
|
if (desktop_cache_dirs) return desktop_cache_dirs;
|
||||||
|
|
||||||
|
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_dirs.cache", efreet_home_dir_get());
|
||||||
|
|
||||||
|
desktop_cache_dirs = eina_stringshare_add(tmp);
|
||||||
|
return desktop_cache_dirs;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Needs EAPI because of helper binaries
|
* Needs EAPI because of helper binaries
|
||||||
*/
|
*/
|
||||||
|
@ -196,6 +299,52 @@ efreet_icon_edd_shutdown(void)
|
||||||
cache_icon_fallback_edd = NULL;
|
cache_icon_fallback_edd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Needs EAPI because of helper binaries
|
||||||
|
*/
|
||||||
|
EAPI Eet_Data_Descriptor *
|
||||||
|
efreet_desktop_edd_init(void)
|
||||||
|
{
|
||||||
|
if (!desktop_edd)
|
||||||
|
{
|
||||||
|
Eet_Data_Descriptor_Class eddc;
|
||||||
|
|
||||||
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop);
|
||||||
|
desktop_edd = eet_data_descriptor_file_new(&eddc);
|
||||||
|
if (!desktop_edd) return NULL;
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "type", type, EET_T_INT);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "version", version, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "orig_path", orig_path, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "load_time", load_time, EET_T_LONG_LONG);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "name", name, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "generic_name", generic_name, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "comment", comment, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "icon", icon, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "try_exec", try_exec, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "exec", exec, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "path", path, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_wm_class", startup_wm_class, EET_T_STRING);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "url", url, EET_T_STRING);
|
||||||
|
eet_data_descriptor_element_add(desktop_edd, "only_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, only_show_in), 0, NULL, NULL);
|
||||||
|
eet_data_descriptor_element_add(desktop_edd, "not_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, not_show_in), 0, NULL, NULL);
|
||||||
|
eet_data_descriptor_element_add(desktop_edd, "categories", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, categories), 0, NULL, NULL);
|
||||||
|
eet_data_descriptor_element_add(desktop_edd, "mime_types", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, mime_types), 0, NULL, NULL);
|
||||||
|
eet_data_descriptor_element_add(desktop_edd, "x", EET_T_STRING, EET_G_HASH, offsetof(Efreet_Desktop, x), 0, NULL, NULL);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "no_display", no_display, EET_T_UCHAR);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "hidden", hidden, EET_T_UCHAR);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "terminal", terminal, EET_T_UCHAR);
|
||||||
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_notify", startup_notify, EET_T_UCHAR);
|
||||||
|
}
|
||||||
|
return desktop_edd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
efreet_desktop_edd_shutdown(void)
|
||||||
|
{
|
||||||
|
if (desktop_edd) eet_data_descriptor_free(desktop_edd);
|
||||||
|
desktop_edd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Needs EAPI because of helper binaries
|
* Needs EAPI because of helper binaries
|
||||||
*/
|
*/
|
||||||
|
@ -263,7 +412,7 @@ efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon)
|
||||||
if (icon_cache)
|
if (icon_cache)
|
||||||
{
|
{
|
||||||
icon_cache_name = eina_stringshare_add(theme->name.internal);
|
icon_cache_name = eina_stringshare_add(theme->name.internal);
|
||||||
icon_cache_timer_update();
|
cache_timer_update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (icon_cache)
|
if (icon_cache)
|
||||||
|
@ -281,67 +430,175 @@ efreet_cache_icon_fallback_find(const char *icon)
|
||||||
path = efreet_icon_cache_file("_fallback");
|
path = efreet_icon_cache_file("_fallback");
|
||||||
icon_fallback_cache = eet_open(path, EET_FILE_MODE_READ);
|
icon_fallback_cache = eet_open(path, EET_FILE_MODE_READ);
|
||||||
if (icon_fallback_cache)
|
if (icon_fallback_cache)
|
||||||
icon_cache_timer_update();
|
cache_timer_update();
|
||||||
}
|
}
|
||||||
if (icon_fallback_cache)
|
if (icon_fallback_cache)
|
||||||
return eet_data_read(icon_fallback_cache, cache_icon_fallback_edd, icon);
|
return eet_data_read(icon_fallback_cache, cache_icon_fallback_edd, icon);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Efreet_Desktop *
|
||||||
|
efreet_cache_desktop_find(const char *file)
|
||||||
|
{
|
||||||
|
Efreet_Desktop *desktop;
|
||||||
|
char rp[PATH_MAX];
|
||||||
|
|
||||||
|
if (!realpath(file, rp)) return NULL;
|
||||||
|
|
||||||
|
if (!desktop_cache)
|
||||||
|
desktop_cache = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ);
|
||||||
|
if (!desktop_cache)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cache_timer_update();
|
||||||
|
|
||||||
|
desktop = eet_data_read(desktop_cache, desktop_edd, rp);
|
||||||
|
if (!desktop) return NULL;
|
||||||
|
desktop->ref = 1;
|
||||||
|
desktop->eet = 1;
|
||||||
|
return desktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
efreet_cache_desktop_update(void)
|
||||||
|
{
|
||||||
|
if (!efreet_cache_update) return;
|
||||||
|
|
||||||
|
/* TODO: Make sure we don't create a lot of execs, maybe use a timer? */
|
||||||
|
if (desktop_cache_job) ecore_job_del(desktop_cache_job);
|
||||||
|
desktop_cache_job = ecore_job_add(desktop_cache_update_cache_job, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
efreet_cache_icon_update(void)
|
||||||
|
{
|
||||||
|
if (!efreet_cache_update) return;
|
||||||
|
|
||||||
|
/* TODO: Make sure we don't create a lot of execs, maybe use a timer? */
|
||||||
|
if (icon_cache_job) ecore_job_del(icon_cache_job);
|
||||||
|
icon_cache_job = ecore_job_add(icon_cache_update_cache_job, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
efreet_cache_desktop_free(Efreet_Desktop *desktop)
|
||||||
|
{
|
||||||
|
Efreet_Old_Cache *d;
|
||||||
|
Efreet_Desktop *curr;
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
if (!old_desktop_caches) return;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(old_desktop_caches, l, d)
|
||||||
|
{
|
||||||
|
curr = eina_hash_find(d->hash, desktop->orig_path);
|
||||||
|
if (curr && curr == desktop)
|
||||||
|
{
|
||||||
|
eina_hash_del_by_key(d->hash, desktop->orig_path);
|
||||||
|
if (eina_hash_population(d->hash) == 0)
|
||||||
|
{
|
||||||
|
eina_hash_free(d->hash);
|
||||||
|
d->hash = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
icon_cache_exe_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
|
cache_exe_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||||
{
|
{
|
||||||
Ecore_Exe_Event_Del *ev;
|
Ecore_Exe_Event_Del *ev;
|
||||||
|
|
||||||
ev = event;
|
ev = event;
|
||||||
if (ev->exe != icon_cache_exe) return ECORE_CALLBACK_RENEW;
|
if (ev->exe == icon_cache_exe)
|
||||||
|
{
|
||||||
if (icon_cache_exe_lock > 0)
|
if (icon_cache_exe_lock > 0)
|
||||||
{
|
{
|
||||||
close(icon_cache_exe_lock);
|
close(icon_cache_exe_lock);
|
||||||
icon_cache_exe_lock = -1;
|
icon_cache_exe_lock = -1;
|
||||||
}
|
}
|
||||||
|
icon_cache_exe = NULL;
|
||||||
|
}
|
||||||
|
else if (ev->exe == desktop_cache_exe)
|
||||||
|
{
|
||||||
|
if (desktop_cache_exe_lock > 0)
|
||||||
|
{
|
||||||
|
close(desktop_cache_exe_lock);
|
||||||
|
desktop_cache_exe_lock = -1;
|
||||||
|
}
|
||||||
|
desktop_cache_exe = NULL;
|
||||||
|
}
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
icon_cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__,
|
cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__,
|
||||||
Ecore_File_Event event, const char *path)
|
Ecore_File_Event event, const char *path)
|
||||||
{
|
{
|
||||||
/* TODO: This is stupid, we should only emit event when the complete
|
const char *file;
|
||||||
* cache update process is done. Else we will reload icons several times
|
|
||||||
* during cache update */
|
|
||||||
const char *file, *ext;
|
|
||||||
Efreet_Event_Cache_Update *ev = NULL;
|
Efreet_Event_Cache_Update *ev = NULL;
|
||||||
|
Eet_File *tmp = NULL;
|
||||||
|
Efreet_Old_Cache *d = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (event != ECORE_FILE_EVENT_CREATED_FILE &&
|
if (event != ECORE_FILE_EVENT_CREATED_FILE &&
|
||||||
event != ECORE_FILE_EVENT_MODIFIED) return;
|
event != ECORE_FILE_EVENT_MODIFIED) return;
|
||||||
file = ecore_file_file_get(path);
|
|
||||||
if (!file || strncmp(file, "icon_", 5)) return;
|
|
||||||
ext = strrchr(file, '.');
|
|
||||||
if (!ext || strcmp(ext, ".cache")) return;
|
|
||||||
|
|
||||||
|
file = ecore_file_file_get(path);
|
||||||
|
if (!file) return;
|
||||||
|
if (!strcmp(file, "icon_data.update"))
|
||||||
|
{
|
||||||
|
printf("update icon cache\n");
|
||||||
icon_cache_close();
|
icon_cache_close();
|
||||||
|
|
||||||
ev = NEW(Efreet_Event_Cache_Update, 1);
|
ev = NEW(Efreet_Event_Cache_Update, 1);
|
||||||
if (!ev) return;
|
if (!ev) return;
|
||||||
ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, NULL, NULL);
|
ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, NULL, NULL);
|
||||||
|
}
|
||||||
|
else if (!strcmp(file, "desktop_data.update"))
|
||||||
|
{
|
||||||
|
printf("update desktop cache\n");
|
||||||
|
tmp = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ);
|
||||||
|
if (!tmp) return;
|
||||||
|
ev = NEW(Efreet_Event_Cache_Update, 1);
|
||||||
|
if (!ev) goto error;
|
||||||
|
d = NEW(Efreet_Old_Cache, 1);
|
||||||
|
if (!d) goto error;
|
||||||
|
|
||||||
|
d->hash = efreet_desktop_cache;
|
||||||
|
d->ef = desktop_cache;
|
||||||
|
old_desktop_caches = eina_list_append(old_desktop_caches, d);
|
||||||
|
|
||||||
|
efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
|
||||||
|
desktop_cache = tmp;
|
||||||
|
|
||||||
|
efreet_util_desktop_cache_reload();
|
||||||
|
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, ev, desktop_cache_update_free, d);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
IF_FREE(ev);
|
||||||
|
IF_FREE(d);
|
||||||
|
if(tmp) eet_close(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
icon_cache_timer_update(void)
|
cache_timer_update(void)
|
||||||
{
|
{
|
||||||
if (icon_cache_timer)
|
if (cache_timer)
|
||||||
ecore_timer_interval_set(icon_cache_timer, 60.0);
|
ecore_timer_interval_set(cache_timer, 60.0);
|
||||||
else
|
else
|
||||||
icon_cache_timer = ecore_timer_add(60.0, icon_cache_timer_cb, NULL);
|
cache_timer = ecore_timer_add(60.0, cache_timer_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
icon_cache_timer_cb(void *data __UNUSED__)
|
cache_timer_cb(void *data __UNUSED__)
|
||||||
{
|
{
|
||||||
icon_cache_timer = NULL;
|
cache_timer = NULL;
|
||||||
|
|
||||||
icon_cache_close();
|
icon_cache_close();
|
||||||
|
if (desktop_cache) eet_close(desktop_cache);
|
||||||
|
desktop_cache = NULL;
|
||||||
return ECORE_CALLBACK_DONE;
|
return ECORE_CALLBACK_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,3 +611,119 @@ icon_cache_close(void)
|
||||||
icon_fallback_cache = NULL;
|
icon_fallback_cache = NULL;
|
||||||
IF_RELEASE(icon_cache_name);
|
IF_RELEASE(icon_cache_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
desktop_cache_update_cache_job(void *data __UNUSED__)
|
||||||
|
{
|
||||||
|
char file[PATH_MAX];
|
||||||
|
struct flock fl;
|
||||||
|
|
||||||
|
desktop_cache_job = NULL;
|
||||||
|
|
||||||
|
/* TODO: Retry update cache later */
|
||||||
|
if (desktop_cache_exe_lock > 0) return;
|
||||||
|
|
||||||
|
if (!efreet_desktop_write_cache_dirs_file()) return;
|
||||||
|
|
||||||
|
snprintf(file, sizeof(file), "%s/.efreet/desktop_exec.lock", efreet_home_dir_get());
|
||||||
|
|
||||||
|
desktop_cache_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
|
if (desktop_cache_exe_lock < 0) return;
|
||||||
|
memset(&fl, 0, sizeof(struct flock));
|
||||||
|
fl.l_type = F_WRLCK;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
if (fcntl(desktop_cache_exe_lock, F_SETLK, &fl) < 0) goto error;
|
||||||
|
desktop_cache_exe = ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", NULL);
|
||||||
|
if (!desktop_cache_exe) goto error;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (desktop_cache_exe_lock > 0)
|
||||||
|
{
|
||||||
|
close(desktop_cache_exe_lock);
|
||||||
|
desktop_cache_exe_lock = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
icon_cache_update_cache_job(void *data __UNUSED__)
|
||||||
|
{
|
||||||
|
char file[PATH_MAX];
|
||||||
|
struct flock fl;
|
||||||
|
|
||||||
|
icon_cache_job = NULL;
|
||||||
|
|
||||||
|
/* TODO: Retry update cache later */
|
||||||
|
if (icon_cache_exe_lock > 0) return;
|
||||||
|
|
||||||
|
snprintf(file, sizeof(file), "%s/.efreet/icon_exec.lock", efreet_home_dir_get());
|
||||||
|
|
||||||
|
icon_cache_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
|
if (icon_cache_exe_lock < 0) return;
|
||||||
|
memset(&fl, 0, sizeof(struct flock));
|
||||||
|
fl.l_type = F_WRLCK;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
if (fcntl(icon_cache_exe_lock, F_SETLK, &fl) < 0) goto error;
|
||||||
|
icon_cache_exe = ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_icon_cache_create", NULL);
|
||||||
|
if (!icon_cache_exe) goto error;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (icon_cache_exe_lock > 0)
|
||||||
|
{
|
||||||
|
close(icon_cache_exe_lock);
|
||||||
|
icon_cache_exe_lock = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
desktop_cache_update_free(void *data, void *ev)
|
||||||
|
{
|
||||||
|
Efreet_Old_Cache *d;
|
||||||
|
int dangling = 0;
|
||||||
|
|
||||||
|
d = data;
|
||||||
|
/*
|
||||||
|
* All users should now had the chance to update their pointers, so we can now
|
||||||
|
* free the old cache
|
||||||
|
*/
|
||||||
|
if (d->hash)
|
||||||
|
{
|
||||||
|
Eina_Iterator *it;
|
||||||
|
Eina_Hash_Tuple *tuple;
|
||||||
|
|
||||||
|
it = eina_hash_iterator_tuple_new(d->hash);
|
||||||
|
EINA_ITERATOR_FOREACH(it, tuple)
|
||||||
|
{
|
||||||
|
printf("Efreet: %d:%s still in cache on cache close!\n",
|
||||||
|
((Efreet_Desktop *)tuple->data)->ref, (char *)tuple->key);
|
||||||
|
dangling++;
|
||||||
|
}
|
||||||
|
eina_iterator_free(it);
|
||||||
|
|
||||||
|
eina_hash_free(d->hash);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If there are dangling references the eet file won't be closed - to
|
||||||
|
* avoid crashes, but this will leak instead.
|
||||||
|
*/
|
||||||
|
if (dangling == 0)
|
||||||
|
{
|
||||||
|
if (d->ef) eet_close(d->ef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Efreet: ERROR. There are still %i desktop files with old\n"
|
||||||
|
"dangling references to desktop files. This application\n"
|
||||||
|
"has not handled the EFREET_EVENT_DESKTOP_CACHE_UPDATE\n"
|
||||||
|
"fully and released its references. Please fix the application\n"
|
||||||
|
"so it does this.\n",
|
||||||
|
dangling);
|
||||||
|
}
|
||||||
|
old_desktop_caches = eina_list_remove(old_desktop_caches, d);
|
||||||
|
free(d);
|
||||||
|
free(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,11 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <sys/types.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
|
@ -22,53 +17,26 @@
|
||||||
|
|
||||||
#define DESKTOP_VERSION "1.0"
|
#define DESKTOP_VERSION "1.0"
|
||||||
|
|
||||||
typedef struct _Efreet_Old_Cache Efreet_Old_Cache;
|
/**
|
||||||
|
* A cache of all loaded desktops, hashed by file name.
|
||||||
struct _Efreet_Old_Cache
|
* Values are Efreet_Desktop structures
|
||||||
{
|
*/
|
||||||
Eina_Hash *desktop_cache;
|
Eina_Hash *efreet_desktop_cache = NULL;
|
||||||
Eet_File *cache;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current desktop environment (e.g. "Enlightenment" or "Gnome")
|
* The current desktop environment (e.g. "Enlightenment" or "Gnome")
|
||||||
*/
|
*/
|
||||||
static const char *desktop_environment = NULL;
|
static const char *desktop_environment = NULL;
|
||||||
|
|
||||||
/**
|
|
||||||
* A cache of all loaded desktops, hashed by file name.
|
|
||||||
* Values are Efreet_Desktop structures
|
|
||||||
*/
|
|
||||||
static Eina_Hash *efreet_desktop_cache = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of the desktop types available
|
|
||||||
*/
|
|
||||||
static Eina_List *efreet_desktop_types = NULL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cache of all unknown desktop dirs
|
* A cache of all unknown desktop dirs
|
||||||
*/
|
*/
|
||||||
static Eina_List *efreet_desktop_dirs = NULL;
|
static Eina_List *efreet_desktop_dirs = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A job pointer for cache updates
|
* A list of the desktop types available
|
||||||
*/
|
*/
|
||||||
static Ecore_Job *efreet_desktop_job = NULL;
|
static Eina_List *efreet_desktop_types = NULL;
|
||||||
static Ecore_Exe *efreet_desktop_exe = NULL;
|
|
||||||
static int efreet_desktop_exe_lock = -1;
|
|
||||||
static Ecore_Event_Handler *efreet_desktop_exe_handler = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data for cache files
|
|
||||||
*/
|
|
||||||
static const char *cache_dirs = NULL;
|
|
||||||
static const char *cache_file = NULL;
|
|
||||||
static Eet_File *cache = NULL;
|
|
||||||
static Eet_Data_Descriptor *desktop_edd = NULL;
|
|
||||||
static Ecore_File_Monitor *cache_monitor = NULL;
|
|
||||||
|
|
||||||
static Eina_List *old_caches = NULL;
|
|
||||||
|
|
||||||
static Eina_Hash *change_monitors = NULL;
|
static Eina_Hash *change_monitors = NULL;
|
||||||
|
|
||||||
|
@ -83,8 +51,6 @@ EAPI int EFREET_DESKTOP_TYPE_APPLICATION = 0;
|
||||||
EAPI int EFREET_DESKTOP_TYPE_LINK = 0;
|
EAPI int EFREET_DESKTOP_TYPE_LINK = 0;
|
||||||
EAPI int EFREET_DESKTOP_TYPE_DIRECTORY = 0;
|
EAPI int EFREET_DESKTOP_TYPE_DIRECTORY = 0;
|
||||||
|
|
||||||
EAPI int EFREET_EVENT_DESKTOP_CACHE_UPDATE = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* Information about custom types
|
* Information about custom types
|
||||||
|
@ -125,18 +91,6 @@ static Eina_Bool efreet_desktop_x_fields_save(const Eina_Hash *hash,
|
||||||
void *fdata);
|
void *fdata);
|
||||||
static int efreet_desktop_environment_check(Efreet_Desktop *desktop);
|
static int efreet_desktop_environment_check(Efreet_Desktop *desktop);
|
||||||
|
|
||||||
static void efreet_desktop_edd_shutdown(void);
|
|
||||||
static int efreet_desktop_write_cache_dirs_file(void);
|
|
||||||
|
|
||||||
static void efreet_desktop_cache_update_cb(void *data, Ecore_File_Monitor *em,
|
|
||||||
Ecore_File_Event event, const char *path);
|
|
||||||
static void efreet_desktop_cache_update_free(void *data, void *ev);
|
|
||||||
|
|
||||||
static void efreet_desktop_update_cache(void);
|
|
||||||
static void efreet_desktop_update_cache_job(void *data);
|
|
||||||
static Eina_Bool efreet_desktop_exe_cb(void *data, int type, void *event);
|
|
||||||
|
|
||||||
static void efreet_desktop_changes_listen(void);
|
|
||||||
static void efreet_desktop_changes_listen_recursive(const char *path);
|
static void efreet_desktop_changes_listen_recursive(const char *path);
|
||||||
static void efreet_desktop_changes_monitor_add(const char *path);
|
static void efreet_desktop_changes_monitor_add(const char *path);
|
||||||
static void efreet_desktop_changes_cb(void *data, Ecore_File_Monitor *em,
|
static void efreet_desktop_changes_cb(void *data, Ecore_File_Monitor *em,
|
||||||
|
@ -150,8 +104,6 @@ static void efreet_desktop_changes_cb(void *data, Ecore_File_Monitor *em,
|
||||||
int
|
int
|
||||||
efreet_desktop_init(void)
|
efreet_desktop_init(void)
|
||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
|
||||||
|
|
||||||
_efreet_desktop_log_dom = eina_log_domain_register
|
_efreet_desktop_log_dom = eina_log_domain_register
|
||||||
("efreet_desktop", EFREET_DEFAULT_LOG_COLOR);
|
("efreet_desktop", EFREET_DEFAULT_LOG_COLOR);
|
||||||
if (_efreet_desktop_log_dom < 0)
|
if (_efreet_desktop_log_dom < 0)
|
||||||
|
@ -159,8 +111,6 @@ efreet_desktop_init(void)
|
||||||
ERROR("Efreet: Could not create a log domain for efreet_desktop");
|
ERROR("Efreet: Could not create a log domain for efreet_desktop");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!efreet_desktop_edd_init())
|
|
||||||
goto edd_error;
|
|
||||||
|
|
||||||
efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
|
efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
|
||||||
efreet_desktop_types = NULL;
|
efreet_desktop_types = NULL;
|
||||||
|
@ -175,40 +125,7 @@ efreet_desktop_init(void)
|
||||||
EFREET_DESKTOP_TYPE_DIRECTORY = efreet_desktop_type_add("Directory", NULL,
|
EFREET_DESKTOP_TYPE_DIRECTORY = efreet_desktop_type_add("Directory", NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
EFREET_EVENT_DESKTOP_CACHE_UPDATE = ecore_event_type_new();
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s/.efreet", efreet_home_dir_get());
|
|
||||||
if (!ecore_file_mkpath(buf)) goto cache_error;
|
|
||||||
|
|
||||||
if (efreet_cache_update)
|
|
||||||
{
|
|
||||||
efreet_desktop_exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
|
||||||
efreet_desktop_exe_cb, NULL);
|
|
||||||
if (!efreet_desktop_exe_handler) goto cache_error;
|
|
||||||
|
|
||||||
cache_monitor = ecore_file_monitor_add(buf,
|
|
||||||
efreet_desktop_cache_update_cb,
|
|
||||||
NULL);
|
|
||||||
if (!cache_monitor) goto handler_error;
|
|
||||||
|
|
||||||
efreet_desktop_changes_listen();
|
|
||||||
|
|
||||||
ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", NULL);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Defer eet open until we actually need it open. */
|
|
||||||
cache = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
handler_error:
|
|
||||||
if (efreet_desktop_exe_handler) ecore_event_handler_del(efreet_desktop_exe_handler);
|
|
||||||
cache_error:
|
|
||||||
if (efreet_desktop_cache) eina_hash_free(efreet_desktop_cache);
|
|
||||||
edd_error:
|
|
||||||
eina_log_domain_unregister(_efreet_desktop_log_dom);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -222,25 +139,14 @@ efreet_desktop_shutdown(void)
|
||||||
Efreet_Desktop_Type_Info *info;
|
Efreet_Desktop_Type_Info *info;
|
||||||
char *dir;
|
char *dir;
|
||||||
|
|
||||||
if (efreet_desktop_exe_handler) ecore_event_handler_del(efreet_desktop_exe_handler);
|
|
||||||
IF_RELEASE(desktop_environment);
|
IF_RELEASE(desktop_environment);
|
||||||
IF_FREE_HASH(efreet_desktop_cache);
|
IF_FREE_HASH(efreet_desktop_cache);
|
||||||
EINA_LIST_FREE(efreet_desktop_types, info)
|
EINA_LIST_FREE(efreet_desktop_types, info)
|
||||||
efreet_desktop_type_info_free(info);
|
efreet_desktop_type_info_free(info);
|
||||||
EINA_LIST_FREE(efreet_desktop_dirs, dir)
|
EINA_LIST_FREE(efreet_desktop_dirs, dir)
|
||||||
eina_stringshare_del(dir);
|
eina_stringshare_del(dir);
|
||||||
if (cache_monitor) ecore_file_monitor_del(cache_monitor);
|
|
||||||
if (change_monitors) eina_hash_free(change_monitors);
|
if (change_monitors) eina_hash_free(change_monitors);
|
||||||
if (cache) eet_close(cache);
|
|
||||||
efreet_desktop_edd_shutdown();
|
|
||||||
eina_log_domain_unregister(_efreet_desktop_log_dom);
|
eina_log_domain_unregister(_efreet_desktop_log_dom);
|
||||||
IF_RELEASE(cache_file);
|
|
||||||
IF_RELEASE(cache_dirs);
|
|
||||||
if (efreet_desktop_job)
|
|
||||||
{
|
|
||||||
ecore_job_del(efreet_desktop_job);
|
|
||||||
efreet_desktop_job = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -299,7 +205,7 @@ efreet_desktop_get(const char *file)
|
||||||
p = dirname(buf);
|
p = dirname(buf);
|
||||||
if (!eina_list_search_unsorted(efreet_desktop_dirs, EINA_COMPARE_CB(strcmp), p))
|
if (!eina_list_search_unsorted(efreet_desktop_dirs, EINA_COMPARE_CB(strcmp), p))
|
||||||
efreet_desktop_dirs = eina_list_append(efreet_desktop_dirs, eina_stringshare_add(p));
|
efreet_desktop_dirs = eina_list_append(efreet_desktop_dirs, eina_stringshare_add(p));
|
||||||
efreet_desktop_update_cache();
|
efreet_cache_desktop_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (efreet_desktop_cache) eina_hash_add(efreet_desktop_cache, desktop->orig_path, desktop);
|
if (efreet_desktop_cache) eina_hash_add(efreet_desktop_cache, desktop->orig_path, desktop);
|
||||||
|
@ -356,16 +262,11 @@ efreet_desktop_new(const char *file)
|
||||||
Efreet_Desktop *desktop = NULL;
|
Efreet_Desktop *desktop = NULL;
|
||||||
|
|
||||||
if (!file) return NULL;
|
if (!file) return NULL;
|
||||||
if (cache)
|
desktop = efreet_cache_desktop_find(file);
|
||||||
|
if (desktop)
|
||||||
{
|
{
|
||||||
char rp[PATH_MAX];
|
if (desktop->load_time == ecore_file_mod_time(desktop->orig_path))
|
||||||
if (!realpath(file, rp)) return NULL;
|
|
||||||
|
|
||||||
desktop = eet_data_read(cache, desktop_edd, rp);
|
|
||||||
if (desktop && desktop->load_time == ecore_file_mod_time(desktop->orig_path))
|
|
||||||
{
|
{
|
||||||
desktop->ref = 1;
|
|
||||||
desktop->eet = 1;
|
|
||||||
if (!efreet_desktop_environment_check(desktop))
|
if (!efreet_desktop_environment_check(desktop))
|
||||||
{
|
{
|
||||||
efreet_desktop_free(desktop);
|
efreet_desktop_free(desktop);
|
||||||
|
@ -373,6 +274,7 @@ efreet_desktop_new(const char *file)
|
||||||
}
|
}
|
||||||
return desktop;
|
return desktop;
|
||||||
}
|
}
|
||||||
|
efreet_desktop_free(desktop);
|
||||||
}
|
}
|
||||||
return efreet_desktop_uncached_new(file);
|
return efreet_desktop_uncached_new(file);
|
||||||
}
|
}
|
||||||
|
@ -510,22 +412,7 @@ efreet_desktop_free(Efreet_Desktop *desktop)
|
||||||
{
|
{
|
||||||
eina_hash_del_by_key(efreet_desktop_cache, desktop->orig_path);
|
eina_hash_del_by_key(efreet_desktop_cache, desktop->orig_path);
|
||||||
}
|
}
|
||||||
else if (old_caches)
|
efreet_cache_desktop_free(desktop);
|
||||||
{
|
|
||||||
Efreet_Old_Cache *d;
|
|
||||||
Efreet_Desktop *curr;
|
|
||||||
Eina_List *l;
|
|
||||||
|
|
||||||
EINA_LIST_FOREACH(old_caches, l, d)
|
|
||||||
{
|
|
||||||
curr = eina_hash_find(d->desktop_cache, desktop->orig_path);
|
|
||||||
if (curr && curr == desktop)
|
|
||||||
{
|
|
||||||
eina_hash_del_by_key(d->desktop_cache, desktop->orig_path);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desktop->eet)
|
if (desktop->eet)
|
||||||
|
@ -838,49 +725,127 @@ efreet_desktop_string_list_join(Eina_List *list)
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int
|
||||||
* Needs EAPI because of helper binaries
|
efreet_desktop_write_cache_dirs_file(void)
|
||||||
*/
|
|
||||||
EAPI const char *
|
|
||||||
efreet_desktop_cache_file(void)
|
|
||||||
{
|
{
|
||||||
char tmp[PATH_MAX] = { '\0' };
|
char file[PATH_MAX];
|
||||||
const char *home, *lang, *country, *modifier;
|
int fd = -1;
|
||||||
|
int cachefd = -1;
|
||||||
|
char *dir;
|
||||||
|
struct stat st;
|
||||||
|
struct flock fl;
|
||||||
|
|
||||||
if (cache_file) return cache_file;
|
if (!efreet_desktop_dirs) return 1;
|
||||||
|
|
||||||
home = efreet_home_dir_get();
|
snprintf(file, sizeof(file), "%s/.efreet/desktop_data.lock", efreet_home_dir_get());
|
||||||
lang = efreet_lang_get();
|
fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
country = efreet_lang_country_get();
|
if (fd < 0) return 0;
|
||||||
modifier = efreet_lang_modifier_get();
|
/* TODO: Retry update cache later */
|
||||||
|
memset(&fl, 0, sizeof(struct flock));
|
||||||
|
fl.l_type = F_WRLCK;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
if (fcntl(fd, F_SETLK, &fl) < 0) goto error;
|
||||||
|
|
||||||
if (lang && country && modifier)
|
cachefd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s@%s.cache", home, lang, country, modifier);
|
if (cachefd < 0) goto error;
|
||||||
else if (lang && country)
|
if (fstat(cachefd, &st) < 0) goto error;
|
||||||
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s.cache", home, lang, country);
|
if (st.st_size > 0)
|
||||||
else if (lang)
|
{
|
||||||
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s.cache", home, lang);
|
Eina_List *l, *ln;
|
||||||
else
|
char *p;
|
||||||
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop.cache", home);
|
char *map;
|
||||||
|
|
||||||
cache_file = eina_stringshare_add(tmp);
|
map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, cachefd, 0);
|
||||||
return cache_file;
|
if (map == MAP_FAILED) goto error;
|
||||||
|
p = map;
|
||||||
|
while (p < map + st.st_size)
|
||||||
|
{
|
||||||
|
unsigned int size = *(unsigned int *)p;
|
||||||
|
p += sizeof(unsigned int);
|
||||||
|
EINA_LIST_FOREACH_SAFE(efreet_desktop_dirs, l, ln, dir)
|
||||||
|
{
|
||||||
|
if (!strcmp(dir, p))
|
||||||
|
{
|
||||||
|
efreet_desktop_dirs = eina_list_remove_list(efreet_desktop_dirs, l);
|
||||||
|
eina_stringshare_del(dir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p += size;
|
||||||
|
}
|
||||||
|
munmap(map, st.st_size);
|
||||||
|
}
|
||||||
|
EINA_LIST_FREE(efreet_desktop_dirs, dir)
|
||||||
|
{
|
||||||
|
unsigned int size = strlen(dir) + 1;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
count = write(cachefd, &size, sizeof(int));
|
||||||
|
count += write(cachefd, dir, size);
|
||||||
|
|
||||||
|
if (count != sizeof(int) + size)
|
||||||
|
DBG("Didn't write all data on cachefd");
|
||||||
|
|
||||||
|
efreet_desktop_changes_monitor_add(dir);
|
||||||
|
eina_stringshare_del(dir);
|
||||||
|
}
|
||||||
|
efreet_desktop_dirs = NULL;
|
||||||
|
if (fd >= 0) close(fd);
|
||||||
|
if (cachefd >= 0) close(cachefd);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (fd >= 0) close(fd);
|
||||||
|
if (cachefd >= 0) close(cachefd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void
|
||||||
* Needs EAPI because of helper binaries
|
efreet_desktop_changes_listen(void)
|
||||||
*/
|
|
||||||
EAPI const char *
|
|
||||||
efreet_desktop_cache_dirs(void)
|
|
||||||
{
|
{
|
||||||
char tmp[PATH_MAX] = { '\0' };
|
int dirsfd = -1;
|
||||||
|
Eina_List *dirs;
|
||||||
|
char *path;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
if (cache_dirs) return cache_dirs;
|
change_monitors = eina_hash_string_superfast_new(EINA_FREE_CB(ecore_file_monitor_del));
|
||||||
|
if (!change_monitors) return;
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_dirs.cache", efreet_home_dir_get());
|
dirs = efreet_default_dirs_get(efreet_data_home_get(),
|
||||||
|
efreet_data_dirs_get(), "applications");
|
||||||
|
|
||||||
cache_dirs = eina_stringshare_add(tmp);
|
EINA_LIST_FREE(dirs, path)
|
||||||
return cache_dirs;
|
{
|
||||||
|
efreet_desktop_changes_listen_recursive(path);
|
||||||
|
eina_stringshare_del(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
dirsfd = open(efreet_desktop_cache_dirs(), O_RDONLY, S_IRUSR | S_IWUSR);
|
||||||
|
if (dirsfd >= 0)
|
||||||
|
{
|
||||||
|
if ((fstat(dirsfd, &st) == 0) && (st.st_size > 0))
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
char *map;
|
||||||
|
|
||||||
|
map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, dirsfd, 0);
|
||||||
|
if (map == MAP_FAILED) goto error;
|
||||||
|
p = map;
|
||||||
|
while (p < map + st.st_size)
|
||||||
|
{
|
||||||
|
unsigned int size = *(unsigned int *)p;
|
||||||
|
p += sizeof(unsigned int);
|
||||||
|
efreet_desktop_changes_monitor_add(p);
|
||||||
|
p += size;
|
||||||
|
}
|
||||||
|
munmap(map, st.st_size);
|
||||||
|
}
|
||||||
|
close(dirsfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
if (dirsfd >= 0) close(dirsfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1293,318 +1258,6 @@ efreet_desktop_environment_check(Efreet_Desktop *desktop)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Needs EAPI because of helper binaries
|
|
||||||
*/
|
|
||||||
EAPI Eet_Data_Descriptor *
|
|
||||||
efreet_desktop_edd_init(void)
|
|
||||||
{
|
|
||||||
if (!desktop_edd)
|
|
||||||
{
|
|
||||||
Eet_Data_Descriptor_Class eddc;
|
|
||||||
|
|
||||||
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop);
|
|
||||||
desktop_edd = eet_data_descriptor_file_new(&eddc);
|
|
||||||
if (!desktop_edd) return NULL;
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "type", type, EET_T_INT);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "version", version, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "orig_path", orig_path, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "load_time", load_time, EET_T_LONG_LONG);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "name", name, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "generic_name", generic_name, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "comment", comment, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "icon", icon, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "try_exec", try_exec, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "exec", exec, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "path", path, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_wm_class", startup_wm_class, EET_T_STRING);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "url", url, EET_T_STRING);
|
|
||||||
eet_data_descriptor_element_add(desktop_edd, "only_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, only_show_in), 0, NULL, NULL);
|
|
||||||
eet_data_descriptor_element_add(desktop_edd, "not_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, not_show_in), 0, NULL, NULL);
|
|
||||||
eet_data_descriptor_element_add(desktop_edd, "categories", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, categories), 0, NULL, NULL);
|
|
||||||
eet_data_descriptor_element_add(desktop_edd, "mime_types", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, mime_types), 0, NULL, NULL);
|
|
||||||
eet_data_descriptor_element_add(desktop_edd, "x", EET_T_STRING, EET_G_HASH, offsetof(Efreet_Desktop, x), 0, NULL, NULL);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "no_display", no_display, EET_T_UCHAR);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "hidden", hidden, EET_T_UCHAR);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "terminal", terminal, EET_T_UCHAR);
|
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_notify", startup_notify, EET_T_UCHAR);
|
|
||||||
}
|
|
||||||
return desktop_edd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
efreet_desktop_edd_shutdown(void)
|
|
||||||
{
|
|
||||||
if (desktop_edd) eet_data_descriptor_free(desktop_edd);
|
|
||||||
desktop_edd = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
efreet_desktop_write_cache_dirs_file(void)
|
|
||||||
{
|
|
||||||
char file[PATH_MAX];
|
|
||||||
int fd = -1;
|
|
||||||
int cachefd = -1;
|
|
||||||
char *dir;
|
|
||||||
struct stat st;
|
|
||||||
struct flock fl;
|
|
||||||
|
|
||||||
if (!efreet_desktop_dirs) return 1;
|
|
||||||
|
|
||||||
snprintf(file, sizeof(file), "%s/.efreet/desktop_data.lock", efreet_home_dir_get());
|
|
||||||
fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
|
||||||
if (fd < 0) return 0;
|
|
||||||
/* TODO: Retry update cache later */
|
|
||||||
memset(&fl, 0, sizeof(struct flock));
|
|
||||||
fl.l_type = F_WRLCK;
|
|
||||||
fl.l_whence = SEEK_SET;
|
|
||||||
if (fcntl(fd, F_SETLK, &fl) < 0) goto error;
|
|
||||||
|
|
||||||
cachefd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR);
|
|
||||||
if (cachefd < 0) goto error;
|
|
||||||
if (fstat(cachefd, &st) < 0) goto error;
|
|
||||||
if (st.st_size > 0)
|
|
||||||
{
|
|
||||||
Eina_List *l, *ln;
|
|
||||||
char *p;
|
|
||||||
char *map;
|
|
||||||
|
|
||||||
map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, cachefd, 0);
|
|
||||||
if (map == MAP_FAILED) goto error;
|
|
||||||
p = map;
|
|
||||||
while (p < map + st.st_size)
|
|
||||||
{
|
|
||||||
unsigned int size = *(unsigned int *)p;
|
|
||||||
p += sizeof(unsigned int);
|
|
||||||
EINA_LIST_FOREACH_SAFE(efreet_desktop_dirs, l, ln, dir)
|
|
||||||
{
|
|
||||||
if (!strcmp(dir, p))
|
|
||||||
{
|
|
||||||
efreet_desktop_dirs = eina_list_remove_list(efreet_desktop_dirs, l);
|
|
||||||
eina_stringshare_del(dir);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p += size;
|
|
||||||
}
|
|
||||||
munmap(map, st.st_size);
|
|
||||||
}
|
|
||||||
EINA_LIST_FREE(efreet_desktop_dirs, dir)
|
|
||||||
{
|
|
||||||
unsigned int size = strlen(dir) + 1;
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
count = write(cachefd, &size, sizeof(int));
|
|
||||||
count += write(cachefd, dir, size);
|
|
||||||
|
|
||||||
if (count != sizeof(int) + size)
|
|
||||||
DBG("Didn't write all data on cachefd");
|
|
||||||
|
|
||||||
efreet_desktop_changes_monitor_add(dir);
|
|
||||||
eina_stringshare_del(dir);
|
|
||||||
}
|
|
||||||
efreet_desktop_dirs = NULL;
|
|
||||||
if (fd >= 0) close(fd);
|
|
||||||
if (cachefd >= 0) close(cachefd);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
error:
|
|
||||||
if (fd >= 0) close(fd);
|
|
||||||
if (cachefd >= 0) close(cachefd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
efreet_desktop_cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__,
|
|
||||||
Ecore_File_Event event, const char *path)
|
|
||||||
{
|
|
||||||
Eet_File *tmp;
|
|
||||||
Efreet_Event_Cache_Update *ev = NULL;
|
|
||||||
Efreet_Old_Cache *d = NULL;
|
|
||||||
|
|
||||||
if (strcmp(path, efreet_desktop_cache_file())) return;
|
|
||||||
if (event != ECORE_FILE_EVENT_CREATED_FILE &&
|
|
||||||
event != ECORE_FILE_EVENT_MODIFIED) return;
|
|
||||||
|
|
||||||
tmp = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ);
|
|
||||||
if (!tmp) return;
|
|
||||||
ev = NEW(Efreet_Event_Cache_Update, 1);
|
|
||||||
if (!ev) goto error;
|
|
||||||
d = NEW(Efreet_Old_Cache, 1);
|
|
||||||
if (!d) goto error;
|
|
||||||
|
|
||||||
d->desktop_cache = efreet_desktop_cache;
|
|
||||||
d->cache = cache;
|
|
||||||
old_caches = eina_list_append(old_caches, d);
|
|
||||||
|
|
||||||
efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
|
|
||||||
cache = tmp;
|
|
||||||
|
|
||||||
efreet_util_desktop_cache_reload();
|
|
||||||
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, ev, efreet_desktop_cache_update_free, d);
|
|
||||||
return;
|
|
||||||
error:
|
|
||||||
IF_FREE(ev);
|
|
||||||
IF_FREE(d);
|
|
||||||
eet_close(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
efreet_desktop_cache_update_free(void *data, void *ev)
|
|
||||||
{
|
|
||||||
Efreet_Old_Cache *d;
|
|
||||||
int dangling = 0;
|
|
||||||
|
|
||||||
d = data;
|
|
||||||
/*
|
|
||||||
* All users should now had the chance to update their pointers, so we can now
|
|
||||||
* free the old cache
|
|
||||||
*/
|
|
||||||
if (d->desktop_cache)
|
|
||||||
{
|
|
||||||
Eina_Iterator *it;
|
|
||||||
Eina_Hash_Tuple *tuple;
|
|
||||||
|
|
||||||
it = eina_hash_iterator_tuple_new(d->desktop_cache);
|
|
||||||
EINA_ITERATOR_FOREACH(it, tuple)
|
|
||||||
{
|
|
||||||
printf("Efreet: %d:%s still in cache on cache close!\n",
|
|
||||||
((Efreet_Desktop *)tuple->data)->ref, (char *)tuple->key);
|
|
||||||
dangling++;
|
|
||||||
}
|
|
||||||
eina_iterator_free(it);
|
|
||||||
|
|
||||||
eina_hash_free(d->desktop_cache);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If there are dangling references the eet file won't be closed - to
|
|
||||||
* avoid crashes, but this will leak instead.
|
|
||||||
*/
|
|
||||||
if (dangling == 0)
|
|
||||||
{
|
|
||||||
if (d->cache) eet_close(d->cache);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Efreet: ERROR. There are still %i desktop files with old\n"
|
|
||||||
"dangling references to desktop files. This application\n"
|
|
||||||
"has not handled the EFREET_EVENT_DESKTOP_CACHE_UPDATE\n"
|
|
||||||
"fully and released its references. Please fix the application\n"
|
|
||||||
"so it does this.\n",
|
|
||||||
dangling);
|
|
||||||
}
|
|
||||||
old_caches = eina_list_remove(old_caches, d);
|
|
||||||
free(d);
|
|
||||||
free(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
efreet_desktop_update_cache(void)
|
|
||||||
{
|
|
||||||
if (!efreet_cache_update) return;
|
|
||||||
|
|
||||||
/* TODO: Make sure we don't create a lot of execs, maybe use a timer? */
|
|
||||||
if (efreet_desktop_job) ecore_job_del(efreet_desktop_job);
|
|
||||||
efreet_desktop_job = ecore_job_add(efreet_desktop_update_cache_job, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
efreet_desktop_update_cache_job(void *data __UNUSED__)
|
|
||||||
{
|
|
||||||
char file[PATH_MAX];
|
|
||||||
struct flock fl;
|
|
||||||
|
|
||||||
efreet_desktop_job = NULL;
|
|
||||||
|
|
||||||
/* TODO: Retry update cache later */
|
|
||||||
if (efreet_desktop_exe_lock > 0) return;
|
|
||||||
|
|
||||||
if (!efreet_desktop_write_cache_dirs_file()) return;
|
|
||||||
|
|
||||||
snprintf(file, sizeof(file), "%s/.efreet/desktop_exec.lock", efreet_home_dir_get());
|
|
||||||
|
|
||||||
efreet_desktop_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
|
||||||
if (efreet_desktop_exe_lock < 0) return;
|
|
||||||
memset(&fl, 0, sizeof(struct flock));
|
|
||||||
fl.l_type = F_WRLCK;
|
|
||||||
fl.l_whence = SEEK_SET;
|
|
||||||
if (fcntl(efreet_desktop_exe_lock, F_SETLK, &fl) < 0) goto error;
|
|
||||||
efreet_desktop_exe = ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", NULL);
|
|
||||||
if (!efreet_desktop_exe) goto error;
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
if (efreet_desktop_exe_lock > 0)
|
|
||||||
{
|
|
||||||
close(efreet_desktop_exe_lock);
|
|
||||||
efreet_desktop_exe_lock = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
efreet_desktop_exe_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
|
|
||||||
{
|
|
||||||
Ecore_Exe_Event_Del *ev;
|
|
||||||
|
|
||||||
ev = event;
|
|
||||||
if (ev->exe != efreet_desktop_exe) return ECORE_CALLBACK_RENEW;
|
|
||||||
if (efreet_desktop_exe_lock > 0)
|
|
||||||
{
|
|
||||||
close(efreet_desktop_exe_lock);
|
|
||||||
efreet_desktop_exe_lock = -1;
|
|
||||||
}
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
efreet_desktop_changes_listen(void)
|
|
||||||
{
|
|
||||||
int dirsfd = -1;
|
|
||||||
Eina_List *dirs;
|
|
||||||
char *path;
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
change_monitors = eina_hash_string_superfast_new(EINA_FREE_CB(ecore_file_monitor_del));
|
|
||||||
if (!change_monitors) return;
|
|
||||||
|
|
||||||
dirs = efreet_default_dirs_get(efreet_data_home_get(),
|
|
||||||
efreet_data_dirs_get(), "applications");
|
|
||||||
|
|
||||||
EINA_LIST_FREE(dirs, path)
|
|
||||||
{
|
|
||||||
efreet_desktop_changes_listen_recursive(path);
|
|
||||||
eina_stringshare_del(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
dirsfd = open(efreet_desktop_cache_dirs(), O_RDONLY, S_IRUSR | S_IWUSR);
|
|
||||||
if (dirsfd >= 0)
|
|
||||||
{
|
|
||||||
if ((fstat(dirsfd, &st) == 0) && (st.st_size > 0))
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
char *map;
|
|
||||||
|
|
||||||
map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, dirsfd, 0);
|
|
||||||
if (map == MAP_FAILED) goto error;
|
|
||||||
p = map;
|
|
||||||
while (p < map + st.st_size)
|
|
||||||
{
|
|
||||||
unsigned int size = *(unsigned int *)p;
|
|
||||||
p += sizeof(unsigned int);
|
|
||||||
efreet_desktop_changes_monitor_add(p);
|
|
||||||
p += size;
|
|
||||||
}
|
|
||||||
munmap(map, st.st_size);
|
|
||||||
}
|
|
||||||
close(dirsfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
error:
|
|
||||||
if (dirsfd >= 0) close(dirsfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
efreet_desktop_changes_listen_recursive(const char *path)
|
efreet_desktop_changes_listen_recursive(const char *path)
|
||||||
{
|
{
|
||||||
|
@ -1653,18 +1306,18 @@ efreet_desktop_changes_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED
|
||||||
case ECORE_FILE_EVENT_CREATED_FILE:
|
case ECORE_FILE_EVENT_CREATED_FILE:
|
||||||
case ECORE_FILE_EVENT_DELETED_FILE:
|
case ECORE_FILE_EVENT_DELETED_FILE:
|
||||||
case ECORE_FILE_EVENT_MODIFIED:
|
case ECORE_FILE_EVENT_MODIFIED:
|
||||||
efreet_desktop_update_cache();
|
efreet_cache_desktop_update();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECORE_FILE_EVENT_DELETED_SELF:
|
case ECORE_FILE_EVENT_DELETED_SELF:
|
||||||
case ECORE_FILE_EVENT_DELETED_DIRECTORY:
|
case ECORE_FILE_EVENT_DELETED_DIRECTORY:
|
||||||
eina_hash_del_by_key(change_monitors, path);
|
eina_hash_del_by_key(change_monitors, path);
|
||||||
efreet_desktop_update_cache();
|
efreet_cache_desktop_update();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECORE_FILE_EVENT_CREATED_DIRECTORY:
|
case ECORE_FILE_EVENT_CREATED_DIRECTORY:
|
||||||
efreet_desktop_changes_monitor_add(path);
|
efreet_desktop_changes_monitor_add(path);
|
||||||
efreet_desktop_update_cache();
|
efreet_cache_desktop_update();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,8 @@ extern int _efreet_log_dom_global;
|
||||||
#endif
|
#endif
|
||||||
#define WRN(...) EINA_LOG_DOM_WARN(EFREET_MODULE_LOG_DOM, __VA_ARGS__)
|
#define WRN(...) EINA_LOG_DOM_WARN(EFREET_MODULE_LOG_DOM, __VA_ARGS__)
|
||||||
|
|
||||||
|
extern Eina_Hash *efreet_desktop_cache;
|
||||||
|
|
||||||
#ifdef ICON_CACHE
|
#ifdef ICON_CACHE
|
||||||
typedef struct Efreet_Cache_Icon Efreet_Cache_Icon;
|
typedef struct Efreet_Cache_Icon Efreet_Cache_Icon;
|
||||||
struct Efreet_Cache_Icon
|
struct Efreet_Cache_Icon
|
||||||
|
@ -208,6 +210,16 @@ void efreet_util_desktop_cache_reload(void);
|
||||||
EAPI const char *efreet_desktop_util_cache_file(void);
|
EAPI const char *efreet_desktop_util_cache_file(void);
|
||||||
EAPI const char *efreet_desktop_cache_file(void);
|
EAPI const char *efreet_desktop_cache_file(void);
|
||||||
EAPI const char *efreet_desktop_cache_dirs(void);
|
EAPI const char *efreet_desktop_cache_dirs(void);
|
||||||
|
int efreet_desktop_write_cache_dirs_file(void);
|
||||||
|
void efreet_desktop_changes_listen(void);
|
||||||
|
|
||||||
|
void efreet_cache_desktop_update(void);
|
||||||
|
void efreet_cache_icon_update(void);
|
||||||
|
void efreet_cache_desktop_free(Efreet_Desktop *desktop);
|
||||||
|
Efreet_Desktop *efreet_cache_desktop_find(const char *file);
|
||||||
|
#if 0
|
||||||
|
void efreet_icon_update_cache(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ICON_CACHE
|
#ifdef ICON_CACHE
|
||||||
EAPI const char *efreet_icon_cache_file(const char *theme);
|
EAPI const char *efreet_icon_cache_file(const char *theme);
|
||||||
|
|
Loading…
Reference in New Issue