forked from enlightenment/efl
Add caching for system .desktop files.
SVN revision: 29111
This commit is contained in:
parent
928faa73f5
commit
e164a4edf9
|
@ -4,3 +4,4 @@ Makefile
|
|||
Makefile.in
|
||||
efreet_spec_test
|
||||
efreet_test
|
||||
efreet_cache_test
|
||||
|
|
|
@ -4,7 +4,7 @@ MAINTAINERCLEANFILES = Makefile.in
|
|||
INCLUDES = \
|
||||
-I. -I$(top_srcdir)/src/lib @ECORE_CFLAGS@
|
||||
|
||||
bin_PROGRAMS = efreet_test efreet_spec_test
|
||||
bin_PROGRAMS = efreet_test efreet_spec_test efreet_cache_test
|
||||
|
||||
efreet_test_DEPENDENCIES = $(top_builddir)/src/lib/libefreet.la
|
||||
efreet_test_LDADD = $(top_builddir)/src/lib/libefreet.la @ECORE_LIBS@
|
||||
|
@ -24,3 +24,7 @@ efreet_spec_test_LDADD = $(top_builddir)/src/lib/libefreet.la
|
|||
efreet_spec_test_SOURCES = \
|
||||
efreet_spec_test.c
|
||||
|
||||
efreet_cache_test_DEPENDENCIES = $(top_builddir)/src/lib/libefreet.la
|
||||
efreet_cache_test_LDADD = $(top_builddir)/src/lib/libefreet.la @ECORE_LIBS@
|
||||
efreet_cache_test_SOURCES = \
|
||||
ef_cache.c
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include "Efreet.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (!efreet_init()) return 1;
|
||||
ecore_main_loop_begin();
|
||||
efreet_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -2,15 +2,80 @@
|
|||
#include "Efreet.h"
|
||||
#include "efreet_private.h"
|
||||
|
||||
typedef struct _Efreet_Cache_Fill Efreet_Cache_Fill;
|
||||
typedef struct _Efreet_Cache_Fill_Dir Efreet_Cache_Fill_Dir;
|
||||
|
||||
struct _Efreet_Cache_Fill
|
||||
{
|
||||
Ecore_List *dirs;
|
||||
Efreet_Cache_Fill_Dir *current;
|
||||
DIR *files;
|
||||
};
|
||||
|
||||
struct _Efreet_Cache_Fill_Dir
|
||||
{
|
||||
char *path;
|
||||
char *file_id;
|
||||
};
|
||||
|
||||
static int _efreet_util_cache_fill(void *data);
|
||||
static void _efreet_util_cache_dir_free(void *data);
|
||||
|
||||
static Ecore_Hash *desktop_by_file_id = NULL;
|
||||
static Ecore_Hash *desktop_by_exec = NULL;
|
||||
static Ecore_Hash *file_id_by_desktop_path = NULL;
|
||||
|
||||
static Ecore_Idler *idler = NULL;
|
||||
|
||||
int
|
||||
efreet_util_init(void)
|
||||
{
|
||||
Efreet_Cache_Fill *fill;
|
||||
Ecore_List *dirs;
|
||||
|
||||
desktop_by_file_id = ecore_hash_new(ecore_str_hash, ecore_str_compare);
|
||||
ecore_hash_set_free_key(desktop_by_file_id, ECORE_FREE_CB(ecore_string_release));
|
||||
desktop_by_exec = ecore_hash_new(ecore_str_hash, ecore_str_compare);
|
||||
file_id_by_desktop_path = ecore_hash_new(ecore_str_hash, ecore_str_compare);
|
||||
|
||||
fill = NEW(Efreet_Cache_Fill, 1);
|
||||
fill->dirs = ecore_list_new();
|
||||
ecore_list_set_free_cb(fill->dirs, _efreet_util_cache_dir_free);
|
||||
dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
|
||||
"applications");
|
||||
if (dirs)
|
||||
{
|
||||
Efreet_Cache_Fill_Dir *dir;
|
||||
char *path;
|
||||
|
||||
while ((path = ecore_list_remove_first(dirs)))
|
||||
{
|
||||
dir = NEW(Efreet_Cache_Fill_Dir, 1);
|
||||
dir->path = path;
|
||||
ecore_list_append(fill->dirs, dir);
|
||||
}
|
||||
ecore_list_destroy(dirs);
|
||||
ecore_list_goto_first(fill->dirs);
|
||||
}
|
||||
idler = ecore_idler_add(_efreet_util_cache_fill, fill);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
efreet_util_shutdown(void)
|
||||
{
|
||||
if (idler)
|
||||
{
|
||||
Efreet_Cache_Fill *fill;
|
||||
fill = ecore_idler_del(idler);
|
||||
IF_FREE_LIST(fill->dirs);
|
||||
free(fill);
|
||||
}
|
||||
idler = NULL;
|
||||
|
||||
IF_FREE_HASH(desktop_by_file_id);
|
||||
IF_FREE_HASH(desktop_by_exec);
|
||||
IF_FREE_HASH(file_id_by_desktop_path);
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -44,10 +109,13 @@ char *
|
|||
efreet_util_path_to_file_id(const char *path)
|
||||
{
|
||||
size_t len;
|
||||
char *id, *p;
|
||||
char *file_id, *p;
|
||||
char *base;
|
||||
|
||||
if (!path) return NULL;
|
||||
file_id = ecore_hash_get(file_id_by_desktop_path, path);
|
||||
if (file_id) return file_id;
|
||||
|
||||
base = efreet_util_path_in_default("applications", path);
|
||||
if (!base) return NULL;
|
||||
|
||||
|
@ -63,15 +131,17 @@ efreet_util_path_to_file_id(const char *path)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
id = strdup(path + len + 1);
|
||||
p = id;
|
||||
file_id = strdup(path + len + 1);
|
||||
p = file_id;
|
||||
while (*p)
|
||||
{
|
||||
if (*p == '/') *p = '-';
|
||||
p++;
|
||||
}
|
||||
free(base);
|
||||
return id;
|
||||
if (file_id) ecore_hash_set(file_id_by_desktop_path, (void *)ecore_string_instance(path),
|
||||
(void *)ecore_string_instance(file_id));
|
||||
return file_id;
|
||||
}
|
||||
|
||||
Efreet_Desktop *
|
||||
|
@ -82,6 +152,9 @@ efreet_util_desktop_by_file_id_get(const char *file_id)
|
|||
const char *dir;
|
||||
|
||||
if (!file_id) return NULL;
|
||||
desktop = ecore_hash_get(desktop_by_file_id, file_id);
|
||||
if (desktop) return desktop;
|
||||
desktop = NULL;
|
||||
|
||||
dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
|
||||
"applications");
|
||||
|
@ -108,5 +181,146 @@ efreet_util_desktop_by_file_id_get(const char *file_id)
|
|||
if (desktop) break;
|
||||
}
|
||||
ecore_list_destroy(dirs);
|
||||
if (desktop) ecore_hash_set(desktop_by_file_id, (void *)ecore_string_instance(file_id), desktop);
|
||||
return desktop;
|
||||
}
|
||||
|
||||
Efreet_Desktop *
|
||||
efreet_util_desktop_by_exec_get(const char *exec)
|
||||
{
|
||||
Efreet_Desktop *desktop = NULL;
|
||||
|
||||
if (!exec) return NULL;
|
||||
desktop = ecore_hash_get(desktop_by_exec, exec);
|
||||
if (desktop) return desktop;
|
||||
desktop = NULL;
|
||||
|
||||
/* TODO: Try to search for the .desktop file. But if it isn't in the cache it will be
|
||||
* timeconsuming.*/
|
||||
|
||||
if (desktop) ecore_hash_set(desktop_by_exec, (void *)ecore_string_instance(exec), desktop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
dump(void *value, void *data __UNUSED__)
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
node = value;
|
||||
printf("%s -> %p\n", (char *)node->key, node->value);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
_efreet_util_cache_fill(void *data)
|
||||
{
|
||||
Efreet_Cache_Fill *fill;
|
||||
struct dirent *file = NULL;
|
||||
double start;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
fill = data;
|
||||
if (!fill->dirs)
|
||||
{
|
||||
free(fill);
|
||||
idler = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (!fill->current)
|
||||
{
|
||||
fill->current = ecore_list_remove_first(fill->dirs);
|
||||
if (!fill->current)
|
||||
{
|
||||
IF_FREE_LIST(fill->dirs);
|
||||
free(fill);
|
||||
idler = NULL;
|
||||
#if 0
|
||||
ecore_hash_for_each_node(desktop_by_file_id, dump, NULL);
|
||||
ecore_hash_for_each_node(desktop_by_exec, dump, NULL);
|
||||
ecore_hash_for_each_node(file_id_by_desktop_path, dump, NULL);
|
||||
printf("%d\n", ecore_hash_count(desktop_by_file_id));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
start = ecore_time_get();
|
||||
if (!fill->files) fill->files = opendir(fill->current->path);
|
||||
if (!fill->files)
|
||||
{
|
||||
/* Couldn't open this dir, continue to next */
|
||||
fill->current = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((ecore_time_get() - start) < 0.01)
|
||||
{
|
||||
char file_id[PATH_MAX];
|
||||
|
||||
file = readdir(fill->files);
|
||||
if (!file) break;
|
||||
if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) continue;
|
||||
|
||||
snprintf(buf, PATH_MAX, "%s/%s", fill->current->path, file->d_name);
|
||||
if (fill->current->file_id)
|
||||
snprintf(file_id, PATH_MAX, "%s-%s", fill->current->file_id, file->d_name);
|
||||
else
|
||||
strcpy(file_id, file->d_name);
|
||||
|
||||
if (ecore_file_is_dir(buf))
|
||||
{
|
||||
Efreet_Cache_Fill_Dir *dir;
|
||||
|
||||
dir = NEW(Efreet_Cache_Fill_Dir, 1);
|
||||
dir->path = strdup(buf);
|
||||
dir->file_id = strdup(file_id);
|
||||
ecore_list_append(fill->dirs, dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Efreet_Desktop *desktop;
|
||||
char *ext;
|
||||
char *exec;
|
||||
|
||||
ext = strrchr(buf, '.');
|
||||
if (!ext || strcmp(ext, ".desktop")) continue;
|
||||
desktop = efreet_desktop_get(buf);
|
||||
|
||||
if (!desktop || desktop->type != EFREET_DESKTOP_TYPE_APPLICATION) continue;
|
||||
ecore_hash_set(desktop_by_file_id, (void *)ecore_string_instance(file_id), desktop);
|
||||
exec = ecore_file_app_exe_get(desktop->exec);
|
||||
if (exec)
|
||||
{
|
||||
/* TODO: exec can be with and without full path, we should handle that */
|
||||
ecore_hash_set(desktop_by_exec, (void *)ecore_string_instance(exec), desktop);
|
||||
free(exec);
|
||||
}
|
||||
ecore_hash_set(file_id_by_desktop_path,
|
||||
(void *)ecore_string_instance(desktop->orig_path),
|
||||
(void *)ecore_string_instance(file_id));
|
||||
}
|
||||
}
|
||||
if (!file)
|
||||
{
|
||||
/* This dir has been search through */
|
||||
_efreet_util_cache_dir_free(fill->current);
|
||||
fill->current = NULL;
|
||||
closedir(fill->files);
|
||||
fill->files = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_efreet_util_cache_dir_free(void *data)
|
||||
{
|
||||
Efreet_Cache_Fill_Dir *dir;
|
||||
|
||||
dir = data;
|
||||
IF_FREE(dir->path);
|
||||
IF_FREE(dir->file_id);
|
||||
free(dir);
|
||||
}
|
||||
|
|
|
@ -5,5 +5,6 @@
|
|||
char *efreet_util_path_in_default(const char *section, const char *path);
|
||||
char *efreet_util_path_to_file_id(const char *path);
|
||||
Efreet_Desktop *efreet_util_desktop_by_file_id_get(const char *file_id);
|
||||
Efreet_Desktop *efreet_util_desktop_by_exec_get(const char *exec);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue