diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index db2649d75..020698fb0 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -8,7 +8,11 @@ INCLUDES = -I$(includedir) \ @cf_cflags@ \ @EDJE_DEF@ -bin_PROGRAMS = enlightenment enlightenment_remote enlightenment_eapp +bin_PROGRAMS = \ +enlightenment \ +enlightenment_remote \ +enlightenment_eapp \ +enlightenment_eapp_cache_gen ENLIGHTENMENTHEADERS = \ e.h \ @@ -32,7 +36,6 @@ e_menu.h \ e_object.h \ e_icon.h \ e_box.h \ -e_entry.h \ e_int_menus.h \ e_module.h \ e_apps.h \ @@ -74,10 +77,10 @@ e_dialog.h \ e_configure.h \ e_about.h \ e_theme_about.h \ -e_apps_cache.h +e_apps_cache.h \ +e_entry.h -enlightenment_SOURCES = \ -e_main.c \ +enlightenment_src = \ e_user.c \ e_manager.c \ e_path.c \ @@ -94,7 +97,6 @@ e_menu.c \ e_object.c \ e_icon.c \ e_box.c \ -e_entry.c \ e_int_menus.c \ e_module.c \ e_apps.c \ @@ -137,8 +139,13 @@ e_configure.c \ e_about.c \ e_theme_about.c \ e_apps_cache.c \ +e_entry.c \ $(ENLIGHTENMENTHEADERS) +enlightenment_SOURCES = \ +e_main.c \ +$(enlightenment_src) + enlightenment_LDFLAGS = -export-dynamic @e_libs@ @x_libs@ @dlopen_libs@ @cf_libs@ enlightenment_remote_SOURCES = \ @@ -154,6 +161,13 @@ e_eapp_main.c enlightenment_eapp_LDFLAGS = @e_libs@ @dlopen_libs@ +enlightenment_eapp_cache_gen_SOURCES = \ +e_eapp_cache_gen_main.c \ +$(enlightenment_src) + +enlightenment_eapp_cache_gen_LDFLAGS = @e_libs@ @dlopen_libs@ + + installed_headersdir = $(prefix)/include/enlightenment installed_headers_DATA = $(ENLIGHTENMENTHEADERS) diff --git a/src/bin/e_apps.c b/src/bin/e_apps.c index 88198a875..ccea92584 100644 --- a/src/bin/e_apps.c +++ b/src/bin/e_apps.c @@ -16,6 +16,7 @@ /* local subsystem functions */ typedef struct _E_App_Change_Info E_App_Change_Info; typedef struct _E_App_Callback E_App_Callback; +typedef struct _E_App_Scan_Cache E_App_Scan_Cache; struct _E_App_Change_Info { @@ -30,6 +31,16 @@ struct _E_App_Callback unsigned char delete_me : 1; }; +struct _E_App_Scan_Cache +{ + char *path; + E_App_Cache *cache; + E_App *app; + Ecore_List *files; + Ecore_Timer *timer; + unsigned char need_rewrite : 1; +}; + static void _e_app_free (E_App *a); static void _e_app_fields_fill (E_App *a, const char *path); static E_App *_e_app_subapp_file_find (E_App *a, const char *file); @@ -143,12 +154,92 @@ _e_app_cache_copy(E_App_Cache *ac, E_App *a) a->wait_exit = ac->wait_exit; } +Evas_Bool +_e_app_cb_scan_hash_foreach(Evas_Hash *hash, const char *key, void *data, void *fdata) +{ + E_App_Scan_Cache *sc; + E_App_Cache *ac; + char *s; + char buf[4096]; + + sc = fdata; + s = (char *)key; + ac = data; + /* file "s" has been deleted */ + printf("Cache %s - DELETED\n", s); + sc->need_rewrite = 1; + return 1; +} + +static int +_e_app_cb_scan_cache_timer(void *data) +{ + E_App_Scan_Cache *sc; + char *s; + char buf[4096]; + E_App_Cache *ac; + int is_dir = 0; + + sc = data; + s = ecore_list_next(sc->files); + if (!s) + { + evas_hash_foreach(sc->cache->subapps_hash, _e_app_cb_scan_hash_foreach, sc); + if (sc->need_rewrite) + _e_app_subdir_rescan(sc->app); + sc->app->monitor = ecore_file_monitor_add(sc->app->path, _e_app_cb_monitor, sc->app); + e_object_unref(E_OBJECT(sc->app)); + ecore_list_destroy(sc->files); + e_app_cache_free(sc->cache); + ecore_timer_del(sc->timer); + free(sc->path); + free(sc); + printf("Cache scan finish.\n"); + return 0; + } + snprintf(buf, sizeof(buf), "%s/%s", sc->path, s); + is_dir = ecore_file_is_dir(buf); + if (e_util_glob_match(s, "*.eap") || is_dir) + { + ac = evas_hash_find(sc->cache->subapps_hash, s); + if (ac) + { + if (is_dir != ac->is_dir) + { + printf("Cache %s - CHANGED TYPE\n", s); + sc->need_rewrite =1 ; + } + else if (!is_dir) + { + unsigned long long mtime; + + mtime = ecore_file_mod_time(buf); + if (mtime != ac->file_mod_time) + { + /* file "s" has changed */ + printf("Cache %s - MODIFIED\n", s); + sc->need_rewrite = 1; + } + } + sc->cache->subapps_hash = evas_hash_del(sc->cache->subapps_hash, s, ac); + } + else + { + /* file "s" has been added */ + printf("Cache %s - MODIFIED\n", s); + sc->need_rewrite = 1; + } + } + return 1; +} + 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]; + E_App_Scan_Cache *sc; a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); _e_app_cache_copy(ac, a); @@ -158,12 +249,10 @@ _e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs) { 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)) + if ((ac2->is_dir) && (scan_subdirs)) { a2 = e_app_new(buf, scan_subdirs); a2->parent = a; @@ -171,11 +260,11 @@ _e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs) } else { - if (ecore_file_exists(buf)) + if (!ac2->is_link) { a2 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); _e_app_cache_copy(ac2, a2); - if (is_dir) + if (ac2->is_dir) { E_FREE(a2->exe); } @@ -216,11 +305,19 @@ _e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs) } } } - - /* 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); + + sc = calloc(1, sizeof(E_App_Scan_Cache)); + if (sc) + { + sc->path = strdup(path); + sc->cache = ac; + sc->app = a; + sc->files = e_app_dir_file_list_get(a); + sc->timer = ecore_timer_add(0.001, _e_app_cb_scan_cache_timer, sc); + e_object_ref(E_OBJECT(sc->app)); + } + else + e_app_cache_free(ac); return a; } @@ -239,20 +336,19 @@ e_app_new(const char *path, int scan_subdirs) e_object_ref(E_OBJECT(a)); return a; } -/* + ac = e_app_cache_load((char *)path); if (ac) { - a = _e_app_cache_new(ac, path, scan_subdirs); + a = _e_app_cache_new(ac, (char *)path, scan_subdirs); if (a) { _e_apps = evas_hash_add(_e_apps, a->path, a); _e_apps_list = evas_list_prepend(_e_apps_list, a); } - e_app_cache_free(ac); +// e_app_cache_free(ac); } else - */ { if (ecore_file_exists(path)) { @@ -1480,6 +1576,14 @@ _e_app_subdir_rescan(E_App *app) e_object_unref(E_OBJECT(ch->app)); free(ch); } + if (changes) + { + E_App_Cache *ac; + + ac = e_app_cache_generate(app); + e_app_cache_save(ac, app->path); + e_app_cache_free(ac); + } evas_list_free(changes); } diff --git a/src/bin/e_apps_cache.c b/src/bin/e_apps_cache.c index 16b3427e4..0183e8aaf 100644 --- a/src/bin/e_apps_cache.c +++ b/src/bin/e_apps_cache.c @@ -46,6 +46,8 @@ e_app_cache_init(void) NEWL("ap", subapps, _e_app_cache_edd); NEWI("sn", startup_notify, EET_T_UCHAR); NEWI("wx", wait_exit, EET_T_UCHAR); + NEWI("il", is_link, EET_T_UCHAR); + NEWI("id", is_dir, EET_T_UCHAR); return 1; } @@ -69,6 +71,18 @@ e_app_cache_load(char *path) if (!ef) return NULL; ac = eet_data_read(ef, _e_app_cache_edd, "cache"); eet_close(ef); + if (ac) + { + Evas_List *l; + + for (l = ac->subapps; l; l = l->next) + { + E_App_Cache *ac2; + + ac2 = l->data; + ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2); + } + } return ac; } @@ -77,6 +91,7 @@ e_app_cache_generate(E_App *a) { E_App_Cache *ac; Evas_List *l; + char buf[PATH_MAX]; if (!a) return NULL; ac = calloc(1, sizeof(E_App_Cache)); @@ -92,6 +107,11 @@ e_app_cache_generate(E_App *a) if (ac2) { _e_eapp_cache_fill(ac2, a2); + ac2->is_dir = ecore_file_is_dir(a2->path); + snprintf(buf, sizeof(buf), "%s/%s", a->path, ecore_file_get_file(a2->path)); + if (a2->orig) ac2->is_link = 1; + if ((!ac2->is_link) && (!ac2->is_dir)) + ac2->file_mod_time = ecore_file_mod_time(buf); ac->subapps = evas_list_append(ac->subapps, ac2); ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2); } @@ -99,70 +119,6 @@ e_app_cache_generate(E_App *a) 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) { @@ -189,8 +145,6 @@ e_app_cache_free(E_App_Cache *ac) free(ac); } - - int e_app_cache_save(E_App_Cache *ac, char *path) { @@ -218,7 +172,6 @@ _e_eapp_cache_fill(E_App_Cache *ac, E_App *a) 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); @@ -227,4 +180,3 @@ _e_eapp_cache_fill(E_App_Cache *ac, E_App *a) ac->startup_notify = a->startup_notify; ac->wait_exit = a->wait_exit; } - diff --git a/src/bin/e_apps_cache.h b/src/bin/e_apps_cache.h index 328c4276b..1ae1ff307 100644 --- a/src/bin/e_apps_cache.h +++ b/src/bin/e_apps_cache.h @@ -30,6 +30,9 @@ struct _E_App_Cache unsigned char startup_notify; /* disable while starting etc. */ unsigned char wait_exit; /* wait for app to exit before execing next */ + + unsigned char is_link; /* cached .order logic info */ + unsigned char is_dir; /* cached stat info */ /* these are generated post-load */ Evas_Hash *subapps_hash; /* a quick lookup hash */ @@ -40,7 +43,6 @@ EAPI int e_app_cache_shutdown(void); EAPI E_App_Cache *e_app_cache_load(char *path); EAPI E_App_Cache *e_app_cache_generate(E_App *a); -EAPI E_App_Cache *e_app_cache_path_generate(char *path); EAPI void e_app_cache_free(E_App_Cache *ac); EAPI int e_app_cache_save(E_App_Cache *ac, char *path); diff --git a/src/bin/e_eapp_cache_gen_main.c b/src/bin/e_eapp_cache_gen_main.c new file mode 100644 index 000000000..cdf6bfe8a --- /dev/null +++ b/src/bin/e_eapp_cache_gen_main.c @@ -0,0 +1,128 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +static void _e_gen_cache(char *path, int recurse); +static int _e_cb_signal_exit(void *data, int ev_type, void *ev); +static void _e_help(void); + +/* local subsystem globals */ + +int +main(int argc, char **argv) +{ + int i; + char *dir = NULL; + int recurse = 0; + + for (i = 1; i < argc; i++) + { + if ((!strcmp(argv[i], "-h")) || + (!strcmp(argv[i], "-help")) || + (!strcmp(argv[i], "--h")) || + (!strcmp(argv[i], "--help"))) + { + _e_help(); + exit(0); + } + else if (!strcmp(argv[i], "-r")) + { + recurse = 1; + } + else + { + dir = argv[i]; + } + } + if (!dir) + { + printf("ERROR: No directory specified!\n"); + _e_help(); + exit(0); + } + + /* basic ecore init */ + if (!ecore_init()) + { + printf("ERROR: Enlightenment_eapp_cache_gen cannot Initialize Ecore!\n" + "Perhaps you are out of memory?\n"); + exit(-1); + } + ecore_app_args_set((int)argc, (const char **)argv); + /* setup a handler for when e is asked to exit via a system signal */ + if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _e_cb_signal_exit, NULL)) + { + printf("ERROR: Enlightenment_eapp_cache_gen cannot set up an exit signal handler.\n" + "Perhaps you are out of memory?\n"); + exit(-1); + } + + e_app_init(); + _e_gen_cache(dir, recurse); + e_app_shutdown(); + + ecore_shutdown(); + /* just return 0 to keep the compiler quiet */ + return 0; +} + +static void +_e_gen_cache(char *path, int recurse) +{ + E_App_Cache *ac; + E_App *a; + char buf[PATH_MAX], *file; + + a = e_app_new(path, recurse); + if (!a) return; + ac = e_app_cache_generate(a); + if (!ac) return; + e_app_cache_save(ac, path); + e_app_cache_free(ac); + if (recurse) + { + Ecore_List *files; + + files = ecore_file_ls(path); + if (files) + { + ecore_list_goto_first(files); + while ((file = ecore_list_next(files))) + { + if (file[0] != '.') + { + snprintf(buf, sizeof(buf), "%s/%s", path, file); + if (ecore_file_is_dir(buf)) _e_gen_cache(buf, recurse); + } + } + ecore_list_destroy(files); + } + } + return; +} + +/* local subsystem functions */ +static int +_e_cb_signal_exit(void *data, int ev_type, void *ev) +{ + /* called on ctrl-c, kill (pid) (also SIGINT, SIGTERM and SIGQIT) */ + exit(-1); + return 1; +} + +static void +_e_help(void) +{ + printf("enlightenment_eapp_cache_gen [directory] [OPTIONS]\n" + "\n" + "OPTIONS:\n" + " -h This help\n" + " -help This help\n" + " --help This help\n" + " --h This help\n" + " -r Recursively generate caches for all subdirectories too\n" + ); +} + + diff --git a/src/bin/e_main.c b/src/bin/e_main.c index b5cc1fb4d..f4669a447 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -30,19 +30,6 @@ static int _e_main_cb_startup_fake_end(void *data); static void _e_main_desk_save(void); static void _e_main_desk_restore(E_Manager *man, E_Container *con); -E_Path *path_data = NULL; -E_Path *path_images = NULL; -E_Path *path_fonts = NULL; -E_Path *path_themes = NULL; -E_Path *path_init = NULL; -E_Path *path_icons = NULL; -E_Path *path_modules = NULL; -E_Path *path_backgrounds = NULL; -int restart = 0; -int good = 0; -int evil = 0; -int starting = 1; - /* local subsystem globals */ #define MAX_LEVEL 32 static int (*_e_main_shutdown_func[MAX_LEVEL]) (void); diff --git a/src/bin/e_utils.c b/src/bin/e_utils.c index 8755c5c0a..39396bb3d 100644 --- a/src/bin/e_utils.c +++ b/src/bin/e_utils.c @@ -3,6 +3,19 @@ */ #include "e.h" +E_Path *path_data = NULL; +E_Path *path_images = NULL; +E_Path *path_fonts = NULL; +E_Path *path_themes = NULL; +E_Path *path_init = NULL; +E_Path *path_icons = NULL; +E_Path *path_modules = NULL; +E_Path *path_backgrounds = NULL; +int restart = 0; +int good = 0; +int evil = 0; +int starting = 1; + typedef struct _E_Util_Fake_Mouse_Up_Info E_Util_Fake_Mouse_Up_Info; struct _E_Util_Fake_Mouse_Up_Info