static void _e_app_free (E_App *a);
static void _e_app_fields_fill (E_App *a, const char *path);
-static void _e_app_fields_empty (E_App *a);
-static Ecore_List *_e_app_dir_file_list_get (E_App *a);
static E_App *_e_app_subapp_file_find (E_App *a, const char *file);
static void _e_app_change (E_App *a, E_App_Change ch);
static int _e_apps_cb_exit (void *data, int type, void *event);
char *home;
char buf[PATH_MAX];
+ e_app_cache_init();
home = e_user_homedir_get();
snprintf(buf, sizeof(buf), "%s/.e/e/applications/trash", home);
_e_apps_path_trash = strdup(buf);
printf("BUG: References %d %s\n", E_OBJECT(a)->references, a->path);
}
}
+ e_app_cache_shutdown();
return 1;
}
E_App *
-e_app_new(const char *path, int scan_subdirs)
+e_app_raw_new(void)
{
E_App *a;
+
+ a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
+ return a;
+}
+
+static void
+_e_app_cache_copy(E_App_Cache *ac, E_App *a)
+{
+#define IF_DUP(x) if (ac->x) a->x = strdup(ac->x)
+ IF_DUP(name);
+ IF_DUP(generic);
+ IF_DUP(comment);
+ IF_DUP(exe);
+ IF_DUP(win_name);
+ IF_DUP(win_class);
+ IF_DUP(win_title);
+ IF_DUP(win_role);
+ IF_DUP(icon_class);
+ a->startup_notify = ac->startup_notify;
+ a->wait_exit = ac->wait_exit;
+}
+
+static E_App *
+_e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs)
+{
+ Evas_List *l;
+ E_App *a;
char buf[PATH_MAX];
+
+ a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
+ _e_app_cache_copy(ac, a);
+ a->path = strdup(path);
+ a->scanned = 1;
+ for (l = ac->subapps; l; l = l->next)
+ {
+ E_App_Cache *ac2;
+ E_App *a2;
+ int is_dir;
+
+ ac2 = l->data;
+ snprintf(buf, sizeof(buf), "%s/%s", path, ac2->file);
+ is_dir = ecore_file_is_dir(buf);
+ if ((is_dir) && (scan_subdirs))
+ {
+ a2 = e_app_new(buf, scan_subdirs);
+ a2->parent = a;
+ a->subapps = evas_list_append(a->subapps, a2);
+ }
+ else
+ {
+ if (ecore_file_exists(buf))
+ {
+ a2 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
+ _e_app_cache_copy(ac2, a2);
+ if (is_dir)
+ {
+ E_FREE(a2->exe);
+ }
+ a2->parent = a;
+ a2->path = strdup(buf);
+ a->subapps = evas_list_append(a->subapps, a2);
+ _e_apps = evas_hash_add(_e_apps, a2->path, a2);
+ _e_apps_list = evas_list_prepend(_e_apps_list, a2);
+ }
+ else
+ {
+ E_App *a3;
+ Evas_List *pl;
+ pl = _e_apps_repositories;
+ a2 = NULL;
+ while ((!a2) && (pl))
+ {
+ snprintf(buf, sizeof(buf), "%s/%s", (char *)pl->data, ac2->file);
+ a2 = e_app_new(buf, scan_subdirs);
+ pl = pl->next;
+ }
+ if (a2)
+ {
+ a3 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
+ if (a3)
+ {
+ if (_e_app_copy(a3, a2))
+ {
+ a3->parent = a;
+ a->subapps = evas_list_append(a->subapps, a3);
+ a2->references = evas_list_append(a2->references, a3);
+ }
+ else
+ e_object_del(E_OBJECT(a3));
+ }
+ }
+ }
+ }
+ }
+
+ /* FIXME: create timer object to scan this slowly and fixup */
+
+ // and at the end of the slow scan add this:
+ // a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a);
+ return a;
+}
+
+E_App *
+e_app_new(const char *path, int scan_subdirs)
+{
+ E_App *a;
+ char buf[PATH_MAX];
+ E_App_Cache *ac;
+
a = evas_hash_find(_e_apps, path);
if (a)
{
e_object_ref(E_OBJECT(a));
return a;
}
-
- if (ecore_file_exists(path))
+/*
+ ac = e_app_cache_load((char *)path);
+ if (ac)
{
- a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
- /* record the path */
- a->path = strdup(path);
-
- if (ecore_file_is_dir(a->path))
+ a = _e_app_cache_new(ac, path, scan_subdirs);
+ if (a)
{
- snprintf(buf, sizeof(buf), "%s/.directory.eap", path);
- if (ecore_file_exists(buf))
- _e_app_fields_fill(a, buf);
- else
- a->name = strdup(ecore_file_get_file(a->path));
- if (scan_subdirs) e_app_subdir_scan(a, scan_subdirs);
-
- a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a);
+ _e_apps = evas_hash_add(_e_apps, a->path, a);
+ _e_apps_list = evas_list_prepend(_e_apps_list, a);
}
- else if (_e_app_is_eapp(path))
+ e_app_cache_free(ac);
+ }
+ else
+ */
+ {
+ if (ecore_file_exists(path))
{
- _e_app_fields_fill(a, path);
-
- /* no exe field.. not valid. drop it */
- if (!a->exe)
+ a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
+ /* record the path */
+ a->path = strdup(path);
+
+ if (ecore_file_is_dir(a->path))
+ {
+ snprintf(buf, sizeof(buf), "%s/.directory.eap", path);
+ if (ecore_file_exists(buf))
+ e_app_fields_fill(a, buf);
+ else
+ a->name = strdup(ecore_file_get_file(a->path));
+ if (scan_subdirs) e_app_subdir_scan(a, scan_subdirs);
+
+ a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a);
+ }
+ else if (_e_app_is_eapp(path))
+ {
+ e_app_fields_fill(a, path);
+
+ /* no exe field.. not valid. drop it */
+ if (!a->exe)
+ goto error;
+ }
+ else
goto error;
}
else
- goto error;
+ return NULL;
+ _e_apps = evas_hash_add(_e_apps, a->path, a);
+ _e_apps_list = evas_list_prepend(_e_apps_list, a);
+
+ ac = e_app_cache_generate(a);
+ e_app_cache_save(ac, a->path);
+ e_app_cache_free(ac);
}
- else
- return NULL;
-
- _e_apps = evas_hash_add(_e_apps, a->path, a);
- _e_apps_list = evas_list_prepend(_e_apps_list, a);
return a;
error:
if (a->monitor) ecore_file_monitor_del(a->monitor);
if (a->path) free(a->path);
- _e_app_fields_empty(a);
+ e_app_fields_empty(a);
free(a);
return NULL;
}
Ecore_List *files;
char *s;
char buf[PATH_MAX];
-
+ E_App_Cache *ac;
+
E_OBJECT_CHECK(a);
E_OBJECT_TYPE_CHECK(a, E_APP_TYPE);
if (a->exe) return;
return;
}
a->scanned = 1;
- files = _e_app_dir_file_list_get(a);
+ files = e_app_dir_file_list_get(a);
if (files)
{
while ((s = ecore_list_next(files)))
}
ecore_list_destroy(files);
}
+
+ ac = e_app_cache_generate(a);
+ e_app_cache_save(ac, a->path);
+ e_app_cache_free(ac);
}
int
ecore_file_monitor_del(a->monitor);
_e_apps = evas_hash_del(_e_apps, a->path, a);
_e_apps_list = evas_list_remove(_e_apps_list, a);
- _e_app_fields_empty(a);
+ e_app_fields_empty(a);
E_FREE(a->path);
free(a);
}
}
-static void
-_e_app_fields_fill(E_App *a, const char *path)
+void
+e_app_fields_fill(E_App *a, const char *path)
{
Eet_File *ef;
char buf[PATH_MAX];
eet_close(ef);
}
-static void
-_e_app_fields_empty(E_App *a)
+void
+e_app_fields_empty(E_App *a)
{
E_FREE(a->name);
E_FREE(a->generic);
E_FREE(a->win_role);
}
-static Ecore_List *
-_e_app_dir_file_list_get(E_App *a)
+Ecore_List *
+e_app_dir_file_list_get(E_App *a)
{
Ecore_List *files, *files2;
char *file;
if ((event == ECORE_FILE_EVENT_CREATED_FILE)
|| (event == ECORE_FILE_EVENT_MODIFIED))
{
- _e_app_fields_empty(app);
- _e_app_fields_fill(app, path);
+ e_app_fields_empty(app);
+ e_app_fields_fill(app, path);
_e_app_change(app, E_APP_CHANGE);
}
else if (event == ECORE_FILE_EVENT_DELETED_FILE)
{
- _e_app_fields_empty(app);
+ e_app_fields_empty(app);
app->name = strdup(ecore_file_get_file(app->path));
}
else
{
Evas_List *l;
- _e_app_fields_empty(a2);
- _e_app_fields_fill(a2, path);
+ e_app_fields_empty(a2);
+ e_app_fields_fill(a2, path);
_e_app_change(a2, E_APP_CHANGE);
for (l = a2->references; l; l = l->next)
char buf[PATH_MAX];
char *s;
- files = _e_app_dir_file_list_get(app);
+ files = e_app_dir_file_list_get(app);
if (files)
{
while ((s = ecore_list_next(files)))
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
+
+#define NEWD(str, typ) \
+ eet_data_descriptor_new(str, sizeof(typ), \
+ (void *(*) (void *))evas_list_next, \
+ (void *(*) (void *, void *))evas_list_append, \
+ (void *(*) (void *))evas_list_data, \
+ (void *(*) (void *))evas_list_free, \
+ (void (*) (void *, int (*) (void *, const char *, void *, void *), void *))evas_hash_foreach, \
+ (void *(*) (void *, const char *, void *))evas_hash_add, \
+ (void (*) (void *))evas_hash_free)
+
+#define FREED(eed) \
+ if (eed) \
+ { \
+ eet_data_descriptor_free((eed)); \
+ (eed) = NULL; \
+ }
+#define NEWI(str, it, type) \
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_e_app_cache_edd, E_App_Cache, str, it, type)
+#define NEWL(str, it, type) \
+ EET_DATA_DESCRIPTOR_ADD_LIST(_e_app_cache_edd, E_App_Cache, str, it, type)
+
+static void _e_eapp_cache_fill(E_App_Cache *ac, E_App *a);
+
+static Eet_Data_Descriptor *_e_app_cache_edd = NULL;
+
+int
+e_app_cache_init(void)
+{
+ _e_app_cache_edd = NEWD("E_App_Cache", E_App_Cache);
+ NEWI("nm", name, EET_T_STRING);
+ NEWI("gn", generic, EET_T_STRING);
+ NEWI("cm", comment, EET_T_STRING);
+ NEWI("ex", exe, EET_T_STRING);
+ NEWI("fl", file, EET_T_STRING);
+ NEWI("fm", file_mod_time, EET_T_ULONG_LONG);
+ NEWI("wn", win_name, EET_T_STRING);
+ NEWI("wc", win_class, EET_T_STRING);
+ NEWI("wt", win_title, EET_T_STRING);
+ NEWI("wr", win_role, EET_T_STRING);
+ NEWI("ic", icon_class, EET_T_STRING);
+ NEWL("ap", subapps, _e_app_cache_edd);
+ NEWI("sn", startup_notify, EET_T_UCHAR);
+ NEWI("wx", wait_exit, EET_T_UCHAR);
+ return 1;
+}
+
+int
+e_app_cache_shutdown(void)
+{
+ FREED(_e_app_cache_edd);
+ return 1;
+}
+
+E_App_Cache *
+e_app_cache_load(char *path)
+{
+ Eet_File *ef;
+ char buf[PATH_MAX];
+ E_App_Cache *ac;
+
+ if (!path) return NULL;
+ snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", path);
+ ef = eet_open(buf, EET_FILE_MODE_READ);
+ if (!ef) return NULL;
+ ac = eet_data_read(ef, _e_app_cache_edd, "cache");
+ eet_close(ef);
+ return ac;
+}
+
+E_App_Cache *
+e_app_cache_generate(E_App *a)
+{
+ E_App_Cache *ac;
+ Evas_List *l;
+
+ if (!a) return NULL;
+ ac = calloc(1, sizeof(E_App_Cache));
+ if (!ac) return NULL;
+ _e_eapp_cache_fill(ac, a);
+ for (l = a->subapps; l; l = l->next)
+ {
+ E_App *a2;
+ E_App_Cache *ac2;
+
+ a2 = l->data;
+ ac2 = calloc(1, sizeof(E_App_Cache));
+ if (ac2)
+ {
+ _e_eapp_cache_fill(ac2, a2);
+ ac->subapps = evas_list_append(ac->subapps, ac2);
+ ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2);
+ }
+ }
+ return ac;
+}
+
+E_App_Cache *
+e_app_cache_path_generate(char *path)
+{
+ E_App_Cache *ac;
+ E_App *a;
+ char buf[PATH_MAX];
+ Ecore_List *files;
+
+ if (!path) return NULL;
+ ac = calloc(1, sizeof(E_App_Cache));
+ if (!ac) return NULL;
+ a = e_app_raw_new();
+ a->path = strdup(path);
+ _e_eapp_cache_fill(ac, a);
+ if (ecore_file_is_dir(a->path))
+ {
+ snprintf(buf, sizeof(buf), "%s/.directory.eap", path);
+ if (ecore_file_exists(buf))
+ e_app_fields_fill(a, buf);
+ else
+ a->name = strdup(ecore_file_get_file(a->path));
+
+ files = e_app_dir_file_list_get(a);
+ if (files)
+ {
+ char *s = NULL;
+
+ while ((s = ecore_list_next(files)))
+ {
+ E_App *a2;
+ E_App_Cache *ac2;
+
+ ac2 = calloc(1, sizeof(E_App_Cache));
+ if (ac2)
+ {
+ a2 = e_app_raw_new();
+ if (a2)
+ {
+ snprintf(buf, sizeof(buf), "%s/%s", a->path, s);
+ a2->path = strdup(buf);
+ if (ecore_file_is_dir(a2->path))
+ {
+ snprintf(buf, sizeof(buf), "%s/.directory.eap", a2->path);
+ e_app_fields_fill(a2, buf);
+ }
+ else
+ e_app_fields_fill(a2, a2->path);
+ _e_eapp_cache_fill(ac2, a2);
+ e_app_fields_empty(a2);
+ free(a2);
+ }
+ ac->subapps = evas_list_append(ac->subapps, ac2);
+ ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2);
+ }
+ }
+ ecore_list_destroy(files);
+ }
+ }
+ e_app_fields_empty(a);
+ free(a);
+
+ return ac;
+}
+
+void
+e_app_cache_free(E_App_Cache *ac)
+{
+ if (!ac) return;
+ E_FREE(ac->name);
+ E_FREE(ac->generic);
+ E_FREE(ac->comment);
+ E_FREE(ac->exe);
+ E_FREE(ac->file);
+ E_FREE(ac->win_name);
+ E_FREE(ac->win_class);
+ E_FREE(ac->win_title);
+ E_FREE(ac->win_role);
+ E_FREE(ac->icon_class);
+ while (ac->subapps)
+ {
+ E_App_Cache *ac2;
+
+ ac2 = ac->subapps->data;
+ ac->subapps = evas_list_remove_list(ac->subapps, ac->subapps);
+ e_app_cache_free(ac2);
+ }
+ evas_hash_free(ac->subapps_hash);
+ free(ac);
+}
+
+
+
+int
+e_app_cache_save(E_App_Cache *ac, char *path)
+{
+ Eet_File *ef;
+ char buf[4096];
+ int ret;
+
+ if ((!ac) || (!path)) return 0;
+ snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", path);
+ ef = eet_open(buf, EET_FILE_MODE_WRITE);
+ if (!ef) return 0;
+ ret = eet_data_write(ef, _e_app_cache_edd, "cache", ac, 1);
+ eet_close(ef);
+ return ret;
+}
+
+
+
+static void
+_e_eapp_cache_fill(E_App_Cache *ac, E_App *a)
+{
+#define IF_DUP(x) if (a->x) ac->x = strdup(a->x)
+ IF_DUP(name);
+ IF_DUP(generic);
+ IF_DUP(comment);
+ IF_DUP(exe);
+ ac->file = strdup(ecore_file_get_file(a->path));
+ ac->file_mod_time = ecore_file_mod_time(a->path);
+ IF_DUP(win_name);
+ IF_DUP(win_class);
+ IF_DUP(win_title);
+ IF_DUP(win_role);
+ IF_DUP(icon_class);
+ ac->startup_notify = a->startup_notify;
+ ac->wait_exit = a->wait_exit;
+}
+