diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index a4ae1bb71..11806435e 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -14,7 +14,8 @@ enlightenment_remote \ enlightenment_eapp \ enlightenment_eapp_cache_gen \ enlightenment_imc \ -enlightenment_start +enlightenment_start \ +enlightenment_thumb ENLIGHTENMENTHEADERS = \ e.h \ @@ -335,6 +336,11 @@ e_start_main.c enlightenment_start_LDFLAGS = +enlightenment_thumb_SOURCES = \ +e_thumb_main.c + +enlightenment_thumb_LDFLAGS = @e_libs@ @dlopen_libs@ + installed_headersdir = $(prefix)/include/enlightenment installed_headers_DATA = $(ENLIGHTENMENTHEADERS) diff --git a/src/bin/e_fileman_icon.c b/src/bin/e_fileman_icon.c index 0f64a2a31..24ece0f1c 100644 --- a/src/bin/e_fileman_icon.c +++ b/src/bin/e_fileman_icon.c @@ -12,7 +12,6 @@ struct _E_Smart_Data Evas *evas; Evas_Object *obj; - char *thumb_path; char *saved_title; Evas_Object *event_object; @@ -137,50 +136,32 @@ e_fm_icon_file_set(Evas_Object *obj, E_Fm_File *file) sd = evas_object_smart_data_get(obj); if (!sd) return; - if(!sd->file) - e_object_ref(E_OBJECT(file)); + if (!sd->file) e_object_ref(E_OBJECT(file)); sd->file = file; file->icon_object = obj; - /* FIXME fix this */ if (sd->file->mime->thumbnail) { - sd->thumb_path = e_thumb_file_get(sd->file->path); - if (e_thumb_exists(sd->file->path)) - { - sd->thumb_object = e_thumb_evas_object_get(sd->file->path, - sd->evas, - sd->iw, - sd->ih, - 1); - // evas_object_geometry_get(sd->thumb_object, NULL, NULL, &icon_w, &icon_h); - // sd->iw = icon_w; - // sd->ih = icon_h; - sd->image_object = edje_object_add(sd->evas); - e_theme_edje_object_set(sd->image_object, "base/theme/fileman", - "fileman/icon_thumb"); - edje_extern_object_min_size_set(sd->thumb_object, sd->iw, sd->ih); - edje_extern_object_max_size_set(sd->thumb_object, sd->iw, sd->ih); - edje_object_part_swallow(sd->image_object, "icon_swallow", - sd->thumb_object); - edje_object_size_min_calc(sd->image_object, &icon_w, &icon_h); - sd->iw = icon_w; - sd->ih = icon_h; - edje_extern_object_min_size_set(sd->image_object, icon_w, icon_h); - edje_extern_object_max_size_set(sd->image_object, icon_w, icon_h); - edje_object_part_swallow(sd->icon_object, "icon_swallow", - sd->image_object); - } - else - { - sd->thumb_object = sd->file->mime->thumbnail(sd->file->path, sd->iw, - sd->ih, sd->evas, - &sd->thumb_object, - _e_fm_icon_thumb_generate_cb, - sd); - - _e_fm_icon_icon_mime_get(sd); - } + /* FIXME: should use smart callback to change icon when thumb done */ + sd->thumb_object = e_thumb_icon_add(sd->evas); + e_thumb_icon_file_set(sd->thumb_object, sd->file->path, NULL); + e_thumb_icon_size_set(sd->thumb_object, 64, 64); + e_thumb_icon_begin(sd->thumb_object); + evas_object_show(sd->thumb_object); + sd->image_object = edje_object_add(sd->evas); + e_theme_edje_object_set(sd->image_object, "base/theme/fileman", + "fileman/icon_thumb"); + edje_extern_object_min_size_set(sd->thumb_object, sd->iw, sd->ih); + edje_extern_object_max_size_set(sd->thumb_object, sd->iw, sd->ih); + edje_object_part_swallow(sd->image_object, "icon_swallow", + sd->thumb_object); + edje_object_size_min_calc(sd->image_object, &icon_w, &icon_h); + sd->iw = icon_w; + sd->ih = icon_h; + edje_extern_object_min_size_set(sd->image_object, icon_w, icon_h); + edje_extern_object_max_size_set(sd->image_object, icon_w, icon_h); + edje_object_part_swallow(sd->icon_object, "icon_swallow", + sd->image_object); } else { @@ -513,49 +494,6 @@ _e_fm_icon_icon_mime_get(E_Smart_Data *sd) sd->image_object); } - - -void -_e_fm_icon_thumb_generate_cb(Evas_Object *obj, void *data) -{ - E_Smart_Data *sd; - - sd = data; - - /* FIXME fix this */ -#if 0 - if (e_fm_file_has_mime(sd->file,".eap") || (ecore_file_exists(sd->thumb_path))) - { - Evas_Coord icon_w, icon_h; - - if (sd->image_object) evas_object_del(sd->image_object); - - sd->thumb_object = e_thumb_evas_object_get(sd->file->path, - sd->evas, - sd->iw, - sd->ih, - 1); - - sd->image_object = edje_object_add(sd->evas); - e_theme_edje_object_set(sd->image_object, "base/theme/fileman", - "fileman/icon_thumb"); - evas_object_show(sd->image_object); - evas_object_show(sd->thumb_object); - edje_extern_object_min_size_set(sd->thumb_object, sd->iw, sd->ih); - edje_extern_object_max_size_set(sd->thumb_object, sd->iw, sd->ih); - edje_object_part_swallow(sd->image_object, "icon_swallow", - sd->thumb_object); - edje_object_size_min_calc(sd->image_object, &icon_w, &icon_h); - sd->iw = icon_w; - sd->ih = icon_h; - edje_extern_object_min_size_set(sd->image_object, icon_w, icon_h); - edje_extern_object_max_size_set(sd->image_object, icon_w, icon_h); - edje_object_part_swallow(sd->icon_object, "icon_swallow", - sd->image_object); - } -#endif -} - static void _e_fm_icon_type_set(E_Smart_Data *sd) { diff --git a/src/bin/e_fileman_mime.c b/src/bin/e_fileman_mime.c index ff4606df0..a169464b8 100644 --- a/src/bin/e_fileman_mime.c +++ b/src/bin/e_fileman_mime.c @@ -610,8 +610,7 @@ _e_fm_mime_action_internal_folder_open(E_Fm_Smart_Data *sd) E_Fm_File *file; file = sd->operation.files->data; - e_fm_dir_set(sd->object, file->path); - + if (file) e_fm_dir_set(sd->object, file->path); } static void @@ -621,8 +620,11 @@ _e_fm_mime_action_internal_folder_open_other(E_Fm_Smart_Data *sd) E_Fm_File *file; file = sd->operation.files->data; - fileman = e_fileman_new_to_dir(e_container_current_get(e_manager_current_get()), file->path); - e_fileman_show(fileman); + if (file) + { + fileman = e_fileman_new_to_dir(e_container_current_get(e_manager_current_get()), file->path); + e_fileman_show(fileman); + } } static void _e_fm_mime_action_internal_copy_to(E_Fm_Smart_Data *sd) @@ -637,14 +639,15 @@ _e_fm_mime_action_internal_move_to(E_Fm_Smart_Data *sd) /* thumbnail functions */ /***********************/ -Evas_Object * _e_fm_mime_thumbnail_evas(char *path, Evas_Coord w, Evas_Coord h, Evas *evas, Evas_Object **tmp, void (*cb)(Evas_Object *obj, void *data), void *data) +Evas_Object * +_e_fm_mime_thumbnail_evas(char *path, Evas_Coord w, Evas_Coord h, Evas *evas, Evas_Object **tmp, void (*cb)(Evas_Object *obj, void *data), void *data) { Evas_Object *r; - r = e_thumb_generate_begin(path, w, - h, evas, tmp, cb, - data); - + r = e_thumb_icon_add(evas); + e_thumb_icon_file_set(r, path, NULL); + e_thumb_icon_size_set(r, w, h); + e_thumb_icon_begin(r); return r; } diff --git a/src/bin/e_fileman_smart.c b/src/bin/e_fileman_smart.c index fd7d257c4..b0e5c2c27 100644 --- a/src/bin/e_fileman_smart.c +++ b/src/bin/e_fileman_smart.c @@ -501,7 +501,6 @@ e_fm_icon_destroy(Evas_Object *obj, void *data) E_Fm_Icon *icon; icon = data; - e_thumb_generate_end(icon->file->path); evas_object_del(icon->icon_obj); icon->state.visible = 0; } diff --git a/src/bin/e_icon.h b/src/bin/e_icon.h index 6afbbfea3..b45950816 100644 --- a/src/bin/e_icon.h +++ b/src/bin/e_icon.h @@ -10,7 +10,7 @@ EAPI Evas_Object *e_icon_add (Evas *evas); EAPI void e_icon_file_set (Evas_Object *obj, const char *file); EAPI void e_icon_file_key_set (Evas_Object *obj, const char *file, const char *key); EAPI void e_icon_file_edje_set (Evas_Object *obj, const char *file, const char *part); -EAPI void e_icon_object_set(Evas_Object *obj, Evas_Object *o); +EAPI void e_icon_object_set (Evas_Object *obj, Evas_Object *o); EAPI const char *e_icon_file_get (Evas_Object *obj); EAPI void e_icon_smooth_scale_set (Evas_Object *obj, int smooth); EAPI int e_icon_smooth_scale_get (Evas_Object *obj); diff --git a/src/bin/e_int_config_background.c b/src/bin/e_int_config_background.c index 473c83bb3..e8cd35adc 100644 --- a/src/bin/e_int_config_background.c +++ b/src/bin/e_int_config_background.c @@ -304,11 +304,12 @@ _load_bgs(E_Config_Dialog *cfd, Evas_Object *il) { Evas_Object *ic = NULL; - if (!e_thumb_exists(c)) - ic = e_thumb_generate_begin(c, 48, 48, cfd->dia->win->evas, &ic, NULL, NULL); - else - ic = e_thumb_evas_object_get(c, cfd->dia->win->evas, 48, 48, 1); - + ic = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(ic, f, "desktop/background"); + e_thumb_icon_size_set(ic, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(ic); e_widget_ilist_append(il, ic, _("Theme Wallpaper"), _ilist_cb_bg_selected, cfd, ""); if (!e_config->desktop_default_background) selnum = i; i++; @@ -370,11 +371,12 @@ _load_bgs(E_Config_Dialog *cfd, Evas_Object *il) if (ecore_file_is_dir(full_path)) continue; if (!e_util_edje_collection_exists(full_path, "desktop/background")) continue; - if (!e_thumb_exists(full_path)) - ic = e_thumb_generate_begin(full_path, 48, 48, evas, &ic, NULL, NULL); - else - ic = e_thumb_evas_object_get(full_path, evas, 48, 48, 1); - + ic = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(ic, full_path, "desktop/background"); + e_thumb_icon_size_set(ic, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(ic); e_widget_ilist_append(il, ic, ecore_file_strip_ext(bg_file), _ilist_cb_bg_selected, cfd, full_path); if ((e_config->desktop_default_background) && (!strcmp(e_config->desktop_default_background, full_path))) @@ -486,10 +488,12 @@ _bg_file_added(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, { if (e_util_edje_collection_exists((char *)path, "desktop/background")) { - if (!e_thumb_exists((char *)path)) - ic = e_thumb_generate_begin((char *)path, 48, 48, evas, &ic, NULL, NULL); - else - ic = e_thumb_evas_object_get((char *)path, evas, 48, 48, 1); + ic = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(ic, path, "desktop/background"); + e_thumb_icon_size_set(ic, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(ic); e_widget_ilist_append(il, ic, noext, _ilist_cb_bg_selected, cfd, (char *)path); } } diff --git a/src/bin/e_int_config_background_import.c b/src/bin/e_int_config_background_import.c index 2fd8d11ae..64b35011e 100644 --- a/src/bin/e_int_config_background_import.c +++ b/src/bin/e_int_config_background_import.c @@ -255,16 +255,18 @@ _bg_edj_gen(Evas *evas, char *filename, int method) int w, h; const char *file; char buff[4096], cmd[4096]; - char ipart[512]; + char ipart[4096]; char *imgdir = NULL; - static char tmpn[1024]; + static char tmpn[4096]; FILE *out = NULL; Ecore_Exe *x; if (!filename) return; file = ecore_file_get_file(filename); - snprintf(buff, sizeof(buff), "%s/.e/e/backgrounds/%s.edj", e_user_homedir_get(), ecore_file_strip_ext(file)); + snprintf(buff, sizeof(buff), "%s/.e/e/backgrounds/%s.edj", + e_user_homedir_get(), + ecore_file_strip_ext(file)); strcpy(tmpn, "/tmp/e_bgdlg_new.edc-tmp-XXXXXX"); fd = mkstemp(tmpn); if (fd < 0) @@ -309,7 +311,10 @@ _bg_edj_gen(Evas *evas, char *filename, int method) fclose(out); - snprintf(cmd, sizeof(cmd), "edje_cc -v %s %s %s", ipart, tmpn, buff); + snprintf(cmd, sizeof(cmd), "edje_cc -v %s %s %s", + ipart, + tmpn, + e_util_filename_escape(buff)); _edj_exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _edj_exe_exit_cb, NULL); x = ecore_exe_run(cmd, tmpn); diff --git a/src/bin/e_int_config_desklock.c b/src/bin/e_int_config_desklock.c index 07ca2d4cb..c9730232e 100644 --- a/src/bin/e_int_config_desklock.c +++ b/src/bin/e_int_config_desklock.c @@ -532,13 +532,12 @@ _load_bgs(E_Config_Dialog_Data *cfdata) e_widget_ilist_header_append(cfdata->gui.bg_list, NULL, _("Theme Backgrounds")); if (edje_object_file_set(o, f1, "desklock/background")) { - if (!e_thumb_exists(c)) - ic = e_thumb_generate_begin(c, BG_LIST_ICON_SIZE_W, BG_LIST_ICON_SIZE_H, - cfdata->evas, &ic, NULL, NULL); - else - ic = e_thumb_evas_object_get(c, cfdata->evas, BG_LIST_ICON_SIZE_W, - BG_LIST_ICON_SIZE_H, 1); - + ic = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(ic, (char *)f1, "desktop/background"); + e_thumb_icon_size_set(ic, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(ic); e_widget_ilist_append(cfdata->gui.bg_list, ic, _("Theme Desklock Background"), _ibg_list_cb_bg_selected, cfdata, DEF_DESKLOCK_BACKGROUND); } @@ -565,13 +564,12 @@ _load_bgs(E_Config_Dialog_Data *cfdata) ic = NULL; if (edje_object_file_set(o, f, "desktop/background")) { - if (!e_thumb_exists(c)) - ic = e_thumb_generate_begin(c, BG_LIST_ICON_SIZE_W, BG_LIST_ICON_SIZE_H, - cfdata->evas, &ic, NULL, NULL); - else - ic = e_thumb_evas_object_get(c, cfdata->evas, BG_LIST_ICON_SIZE_W, - BG_LIST_ICON_SIZE_H, 1); - + ic = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(ic, (char *)f, "desktop/background"); + e_thumb_icon_size_set(ic, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(ic); e_widget_ilist_append(cfdata->gui.bg_list, ic, _("Theme Background"), _ibg_list_cb_bg_selected, cfdata, DEF_THEME_BACKGROUND); } @@ -612,13 +610,12 @@ _load_bgs(E_Config_Dialog_Data *cfdata) if (ecore_file_is_dir(full_path)) continue; if (!e_util_edje_collection_exists(full_path, "desktop/background")) continue; - if (!e_thumb_exists(full_path)) - ic = e_thumb_generate_begin(full_path, BG_LIST_ICON_SIZE_W, BG_LIST_ICON_SIZE_H, - cfdata->evas, &ic, NULL, NULL); - else - ic = e_thumb_evas_object_get(full_path, cfdata->evas, BG_LIST_ICON_SIZE_W, - BG_LIST_ICON_SIZE_H, 1); - + ic = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(ic, full_path, "desktop/background"); + e_thumb_icon_size_set(ic, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(ic); e_widget_ilist_append(cfdata->gui.bg_list, ic, ecore_file_strip_ext(bg_file), _ibg_list_cb_bg_selected, cfdata, full_path); diff --git a/src/bin/e_int_config_startup.c b/src/bin/e_int_config_startup.c index 971ef8c4a..ba1e59895 100644 --- a/src/bin/e_int_config_startup.c +++ b/src/bin/e_int_config_startup.c @@ -195,11 +195,12 @@ _load_inits(E_Config_Dialog *cfd, Evas_Object *il) if (ecore_file_is_dir(full_path)) continue; if (!e_util_edje_collection_exists(full_path, "init/splash")) continue; - if (!e_thumb_exists(full_path)) - ic = e_thumb_generate_begin(full_path, 48, 48, cfd->dia->win->evas, &ic, NULL, NULL); - else - ic = e_thumb_evas_object_get(full_path, cfd->dia->win->evas, 48, 48, 1); - + ic = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(ic, full_path, "desktop/background"); + e_thumb_icon_size_set(ic, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(ic); e_widget_ilist_append(il, ic, ecore_file_strip_ext(init_file), _ilist_cb_init_selected, cfd, full_path); if ((e_config->init_default_theme) && diff --git a/src/bin/e_int_config_theme.c b/src/bin/e_int_config_theme.c index b1843f7b7..49c5fcd09 100644 --- a/src/bin/e_int_config_theme.c +++ b/src/bin/e_int_config_theme.c @@ -104,7 +104,6 @@ _e_config_theme_cb_standard(void *data) d = data; e_widget_preview_edje_set(d->cfd->data, d->file, "desktop/background"); -// e_widget_image_object_set(d->cfd->data, e_thumb_evas_object_get(d->file, d->cfd->dia->win->evas, 160, 120, 1)); cfdata = d->cfd->cfdata; if (cfdata->current_theme) @@ -199,10 +198,12 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf char *noext; E_Cfg_Theme_Data *cb_data; - if (!e_thumb_exists(fulltheme)) - o3 = e_thumb_generate_begin(fulltheme, 48, 48, cfd->dia->win->evas, &o3, NULL, NULL); - else - o3 = e_thumb_evas_object_get(fulltheme, cfd->dia->win->evas, 48, 48, 1); + o3 = e_thumb_icon_add(cfd->dia->win->evas); + e_thumb_icon_file_set(o3, fulltheme, "desktop/background"); + e_thumb_icon_size_set(o3, 64, + (64 * e_zone_current_get(cfd->dia->win->container)->h) / + e_zone_current_get(cfd->dia->win->container)->w); + e_thumb_icon_begin(o3); noext = ecore_file_strip_ext(themefile); @@ -221,8 +222,6 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf (320 * e_zone_current_get(cfd->dia->win->container)->h) / e_zone_current_get(cfd->dia->win->container)->w); e_widget_preview_edje_set(im, fulltheme, "desktop/background"); - // im = e_widget_image_add_from_object(evas, theme, 320, 240); - // e_widget_image_object_set(im, e_thumb_evas_object_get(fulltheme, evas, 320, 240, 1)); } free(noext); i++; @@ -245,9 +244,6 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf (320 * e_zone_current_get(cfd->dia->win->container)->h) / e_zone_current_get(cfd->dia->win->container)->w); e_widget_preview_edje_set(im, fulltheme, "desktop/background"); -// theme = e_thumb_generate_begin(fulltheme, 320, 240, evas, &theme, NULL, NULL); -// im = e_widget_image_add_from_object(evas, theme, 320, 240); -// e_widget_image_object_set(im, e_thumb_evas_object_get(fulltheme, evas, 320, 240, 1)); } cfd->data = im; diff --git a/src/bin/e_ipc.c b/src/bin/e_ipc.c index 7e676239b..836176855 100644 --- a/src/bin/e_ipc.c +++ b/src/bin/e_ipc.c @@ -116,6 +116,7 @@ _e_ipc_cb_client_del(void *data __UNUSED__, int type __UNUSED__, void *event) e = event; if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) return 1; /* delete client sruct */ + e_thumb_client_del(e); ecore_ipc_client_del(e->client); return 1; } @@ -127,11 +128,24 @@ _e_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event) e = event; if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) return 1; - switch (e->minor) + switch (e->major) { + case E_IPC_DOMAIN_SETUP: + case E_IPC_DOMAIN_REQUEST: + case E_IPC_DOMAIN_REPLY: + case E_IPC_DOMAIN_EVENT: + switch (e->minor) + { #define TYPE E_WM_IN -#include "e_ipc_handlers.h" +#include "e_ipc_handlers.h" #undef TYPE + default: + break; + } + break; + case E_IPC_DOMAIN_THUMB: + e_thumb_client_data(e); + break; default: break; } diff --git a/src/bin/e_ipc.h b/src/bin/e_ipc.h index 285ce6c5f..e88063466 100644 --- a/src/bin/e_ipc.h +++ b/src/bin/e_ipc.h @@ -13,6 +13,7 @@ typedef enum _E_Ipc_Domain E_IPC_DOMAIN_REQUEST, E_IPC_DOMAIN_REPLY, E_IPC_DOMAIN_EVENT, + E_IPC_DOMAIN_THUMB, E_IPC_DOMAIN_LAST } E_Ipc_Domain; diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index bfa482011..c8cc26fd5 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -1788,7 +1788,7 @@ _e_menu_submenu_activate(E_Menu_Item *mi) static void _e_menu_submenu_deactivate(E_Menu_Item *mi) { - if (mi->menu->active) return; + if (!mi->menu->active) return; if (mi->submenu_post_cb.func) mi->submenu_post_cb.func(mi->submenu_post_cb.data, mi->menu, mi); } diff --git a/src/bin/e_thumb.c b/src/bin/e_thumb.c index 5f247cbaf..79cda7e43 100644 --- a/src/bin/e_thumb.c +++ b/src/bin/e_thumb.c @@ -1,631 +1,317 @@ /* -* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 -*/ - + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ #include "e.h" -#ifdef EFM_DEBUG -# define D(x) do {printf(__FILE__ ":%d: ", __LINE__); printf x; fflush(stdout);} while (0) -#else -# define D(x) ((void) 0) -#endif +typedef struct _E_Thumb E_Thumb; -typedef struct _E_Thumb_Item E_Thumb_Item; - -static char *_e_thumb_file_id(char *file); -static void _e_thumb_generate(void); -static int _e_thumb_cb_exe_exit(void *data, int type, void *event); - -static char *thumb_path = NULL; -static Evas_List *thumb_files = NULL; -static Evas_List *event_handlers = NULL; -static pid_t pid = -1; - -struct _E_Thumb_Item +struct _E_Thumb { - char path[PATH_MAX]; - Evas_Object *obj; - Evas *evas; - Evas_Coord w, h; - void (*cb)(Evas_Object *obj, void *data); - void *data; + int objid; + int w, h; + char *file; + char *key; + unsigned char queued : 1; + unsigned char busy : 1; }; +/* local subsystem functions */ +static void _e_thumb_gen_begin(int objid, char *file, char *key, int w, int h); +static void _e_thumb_gen_end(int objid); +static void _e_thumb_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_thumb_hash_add(int objid, Evas_Object *obj); +static void _e_thumb_hash_del(int objid); +static Evas_Object *_e_thumb_hash_find(int objid); +static void _e_thumb_thumbnailers_kill(void); +static int _e_thumb_cb_exe_event_del(void *data, int type, void *event); + +/* local subsystem globals */ +static Evas_List *_thumbnailers = NULL; +static Evas_List *_thumbnailers_exe = NULL; +static Evas_List *_thumb_queue = NULL; +static int _objid = 0; +static Evas_Hash *_thumbs = NULL; +static int _pending = 0; +static int _num_thumbnailers = 2; +static Ecore_Event_Handler *_exe_del_handler = NULL; + +/* externally accessible functions */ EAPI int e_thumb_init(void) { - char *homedir; - char path[PATH_MAX]; - - homedir = e_user_homedir_get(); - if (homedir) - { - snprintf(path, sizeof(path), "%s/.e/e/fileman/thumbnails", homedir); - if (!ecore_file_exists(path)) - ecore_file_mkpath(path); - thumb_path = strdup(path); - free(homedir); - } - else return 0; - - event_handlers = - evas_list_append(event_handlers, - ecore_event_handler_add(ECORE_EXE_EVENT_DEL, - _e_thumb_cb_exe_exit, - NULL)); + _exe_del_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, + _e_thumb_cb_exe_event_del, + NULL); return 1; } EAPI int e_thumb_shutdown(void) { - E_FREE(thumb_path); - while (event_handlers) - { - ecore_event_handler_del(event_handlers->data); - event_handlers = evas_list_remove_list(event_handlers, event_handlers); - } - evas_list_free(thumb_files); - - if (pid != -1) - kill(pid, SIGTERM); - + ecore_event_handler_del(_exe_del_handler); + _exe_del_handler = NULL; return 1; } -/* return dir where thumbs are saved */ -EAPI const char * -e_thumb_dir_get(void) -{ - return thumb_path; -} - -/* queue an image for thumbnailing or return the thumb if it exists */ EAPI Evas_Object * -e_thumb_generate_begin(char *path, Evas_Coord w, Evas_Coord h, Evas *evas, Evas_Object **tmp, void (*cb)(Evas_Object *obj, void *data), void *data) +e_thumb_icon_add(Evas *evas) { - E_Thumb_Item *t; + Evas_Object *obj; + E_Thumb *eth; + char buf[32]; - if(!ecore_file_exists(path)) return *tmp; - if (e_thumb_exists(path)) - { - evas_object_del(*tmp); - *tmp = e_thumb_evas_object_get(path, evas, w, h, 1); - return *tmp; - } - - t = E_NEW(E_Thumb_Item, 1); - t->w = w; - t->h = h; - t->evas = evas; - t->cb = cb; - t->data = data; - *tmp = e_icon_add(evas); - t->obj = *tmp; - snprintf(t->path, sizeof(t->path), "%s", path); - thumb_files = evas_list_append(thumb_files, t); - if (pid == -1) _e_thumb_generate(); - - return *tmp; + obj = e_icon_add(evas); + _objid++; + eth = E_NEW(E_Thumb, 1); + eth->objid = _objid; + eth->w = 64; + eth->h = 64; + evas_object_data_set(obj, "e_thumbdata", eth); + evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE, + _e_thumb_del_hook, NULL); + _e_thumb_hash_add(eth->objid, obj); + return obj; } -/* delete an image from the thumb queue */ EAPI void -e_thumb_generate_end(char *path) +e_thumb_icon_file_set(Evas_Object *obj, char *file, char *key) +{ + E_Thumb *eth; + + eth = evas_object_data_get(obj, "e_thumbdata"); + if (!eth) return; + E_FREE(eth->file); + E_FREE(eth->key); + if (file) eth->file = strdup(file); + if (key) eth->key = strdup(key); +} + +EAPI void +e_thumb_icon_size_set(Evas_Object *obj, int w, int h) +{ + E_Thumb *eth; + + eth = evas_object_data_get(obj, "e_thumbdata"); + if (!eth) return; + if ((w < 1) || (h <1)) return; + eth->w = w; + eth->h = h; +} + +EAPI void +e_thumb_icon_begin(Evas_Object *obj) +{ + E_Thumb *eth, *eth2; + char buf[4096]; + + eth = evas_object_data_get(obj, "e_thumbdata"); + if (!eth) return; + if (!eth->file) return; + if (!_thumbnailers) + { + while (evas_list_count(_thumbnailers_exe) < _num_thumbnailers) + { + Ecore_Exe *exe; + + snprintf(buf, sizeof(buf), "%s/enlightenment_thumb", e_prefix_bin_get()); + exe = ecore_exe_run(buf, NULL); + _thumbnailers_exe = evas_list_append(_thumbnailers_exe, exe); + } + _thumb_queue = evas_list_append(_thumb_queue, eth); + eth->queued = 1; + return; + } + while (_thumb_queue) + { + eth2 = _thumb_queue->data; + _thumb_queue = evas_list_remove_list(_thumb_queue, _thumb_queue); + eth2->queued = 0; + eth2->busy = 1; + _pending++; + _e_thumb_gen_begin(eth2->objid, eth2->file, eth2->key, eth2->w, eth2->h); + } + eth->busy = 1; + _pending++; + _e_thumb_gen_begin(eth->objid, eth->file, eth->key, eth->w, eth->h); +} + +EAPI void +e_thumb_icon_end(Evas_Object *obj) +{ + E_Thumb *eth; + + eth = evas_object_data_get(obj, "e_thumbdata"); + if (!eth) return; + if (eth->queued) _thumb_queue = evas_list_remove(_thumb_queue, eth); + eth->queued = 0; + if (eth->busy) _e_thumb_gen_end(eth->objid); + eth->busy = 0; + _pending--; + if (_pending == 0) _e_thumb_thumbnailers_kill(); +} + +EAPI void +e_thumb_client_data(Ecore_Ipc_Event_Client_Data *e) +{ + int objid; + char *icon; + E_Thumb *eth; + Evas_Object *obj; + + if (!evas_list_find(_thumbnailers, e->client)) + _thumbnailers = evas_list_prepend(_thumbnailers, e->client); + if (e->minor == 2) + { + objid = e->ref; + icon = e->data; + if ((icon) && (e->size > 1) && (icon[e->size - 1] == 0)) + { + obj = _e_thumb_hash_find(objid); + if (obj) + { + eth = evas_object_data_get(obj, "e_thumbdata"); + if (eth) + { + eth->busy = 0; + _pending--; + if (_pending == 0) _e_thumb_thumbnailers_kill(); + e_icon_file_key_set(obj, icon, "/thumbnail/data"); + evas_object_smart_callback_call(obj, "e_thumb_gen", NULL); + } + } + } + } + if (e->minor == 1) + { + /* hello message */ + while (_thumb_queue) + { + eth = _thumb_queue->data; + _thumb_queue = evas_list_remove_list(_thumb_queue, _thumb_queue); + eth->queued = 0; + eth->busy = 1; + _pending++; + _e_thumb_gen_begin(eth->objid, eth->file, eth->key, eth->w, eth->h); + } + } +} + +EAPI void +e_thumb_client_del(Ecore_Ipc_Event_Client_Del *e) +{ + if (!evas_list_find(_thumbnailers, e->client)) return; + _thumbnailers = evas_list_remove(_thumbnailers, e->client); +} + +/* local subsystem functions */ +static void +_e_thumb_gen_begin(int objid, char *file, char *key, int w, int h) +{ + char *buf; + int l1, l2; + Ecore_Ipc_Client *cli; + + /* send thumb req */ + l1 = strlen(file); + l2 = 0; + if (key) l2 = strlen(key); + buf = alloca(l1 + 1 + l2 + 1); + strcpy(buf, file); + if (key) strcpy(buf + l1 + 1, key); + else buf[l1 + 1] = 0; + cli = _thumbnailers->data; + if (!cli) return; + _thumbnailers = evas_list_remove_list(_thumbnailers, _thumbnailers); + _thumbnailers = evas_list_append(_thumbnailers, cli); + ecore_ipc_client_send(cli, E_IPC_DOMAIN_THUMB, 1, objid, w, h, buf, l1 + 1 + l2 + 1); +} + +static void +_e_thumb_gen_end(int objid) { Evas_List *l; - E_Thumb_Item *t; + Ecore_Ipc_Client *cli; - for(l = thumb_files; l; l = l->next) + /* send thumb cancel */ + for (l = _thumbnailers; l; l = l->next) { - t = l->data; - if(!strcmp(path, t->path)) - { - thumb_files = evas_list_remove_list(thumb_files, l); - break; - } + cli = l->data; + ecore_ipc_client_send(cli, E_IPC_DOMAIN_THUMB, 2, objid, 0, 0, NULL, 0); } } -/* return hashed path of thumb */ -EAPI char * -e_thumb_file_get(char *file) -{ - char *id; - char thumb[PATH_MAX]; - - id = _e_thumb_file_id(file); - if (!id) return NULL; - snprintf(thumb, sizeof(thumb), "%s/%s", thumb_path, id); - free(id); - return strdup(thumb); -} - -/* return the width and height of a thumb, if from_eet is set, then we - * assume that the file being passed is the thumb's eet - */ -EAPI void -e_thumb_geometry_get(char *file, int *w, int *h, int from_eet) -{ - Eet_File *ef; - - if(!from_eet) - { - char *eet_file; - - eet_file = _e_thumb_file_id(file); - if(!eet_file) - { - if(w) *w = -1; - if(h) *h = -1; - return; - } - ef = eet_open(eet_file, EET_FILE_MODE_READ); - if (!ef) - { - eet_close(ef); - if(w) *w = -1; - if(h) *h = -1; - return; - } - } - else - { - ef = eet_open(file, EET_FILE_MODE_READ); - if (!ef) - { - eet_close(ef); - if(w) *w = -1; - if(h) *h = -1; - return; - } - } - if(!eet_data_image_header_read(ef, "/thumbnail/data", w, h, NULL, NULL, - NULL, NULL)) - { - eet_close(ef); - if(w) *w = -1; - if(h) *h = -1; - return; - } - eet_close(ef); -} - -/* return true if the saved thumb exists OR if its an eap */ -EAPI int -e_thumb_exists(char *file) -{ - char *thumb; - char *ext; - - ext = strrchr(file, '.'); - if ((ext) && (!strcasecmp(ext, ".eap"))) - return 1; - - thumb = e_thumb_file_get(file); - if ((thumb) && (ecore_file_exists(thumb))) - { - free(thumb); - return 1; - } - return 0; -} - -EAPI int * -_e_thumb_image_create(char *file, Evas_Coord w, Evas_Coord h, int *ww, int *hh, int *alpha, Evas_Object **im, Ecore_Evas **buf) -{ - Evas *evasbuf; - int iw, ih; - - *buf = ecore_evas_buffer_new(1, 1); - evasbuf = ecore_evas_get(*buf); - *im = evas_object_image_add(evasbuf); - evas_object_image_file_set(*im, file, NULL); - iw = 0; ih = 0; - evas_object_image_size_get(*im, &iw, &ih); - *alpha = evas_object_image_alpha_get(*im); - if ((iw > 0) && (ih > 0)) - { - *ww = w; - *hh = (w * ih) / iw; - if (*hh > h) - { - *hh = h; - *ww = (h * iw) / ih; - } - ecore_evas_resize(*buf, *ww, *hh); - evas_object_image_fill_set(*im, 0, 0, *ww, *hh); - evas_object_resize(*im, *ww, *hh); - evas_object_move(*im, 0, 0); - evas_object_show(*im); - - return (int *)ecore_evas_buffer_pixels_get(*buf); - } - return NULL; -} - -/* thumbnail an e17 background and return pixel data */ -const int * -_e_thumb_ebg_create(char *file, Evas_Coord w, Evas_Coord h, int *ww, int *hh, int *alpha, Evas_Object **im, Ecore_Evas **buf) -{ - Evas *evasbuf; - Evas_Object *wallpaper; - const int *pixels; - - *ww = 640; - *hh = 480; - *alpha = 0; - - w = 640; - h = 480; - - *buf = ecore_evas_buffer_new(w, h); - evasbuf = ecore_evas_get(*buf); - - wallpaper = edje_object_add(evasbuf); - - edje_object_file_set(wallpaper, file, "desktop/background"); - - /* wallpaper */ - evas_object_move(wallpaper, 0, 0); - evas_object_resize(wallpaper, w, h); - - evas_object_show(wallpaper); - - pixels = ecore_evas_buffer_pixels_get(*buf); - - evas_object_del(wallpaper); - return pixels; -} - -/* thumbnail an e17 theme and return pixel data */ -const int * -_e_thumb_etheme_create(char *file, Evas_Coord w, Evas_Coord h, int *ww, int *hh, int *alpha, Evas_Object **im, Ecore_Evas **buf) -{ - Evas *evasbuf; - Evas_Object *wallpaper, *window, *clock, *start, **pager, *init; - const int *pixels; - int is_init; - - *ww = 640; - *hh = 480; - *alpha = 0; - - w = 640; - h = 480; - - *buf = ecore_evas_buffer_new(w, h); - evasbuf = ecore_evas_get(*buf); - - is_init = e_util_edje_collection_exists(file, "init/splash"); - if (is_init) - { - init = edje_object_add(evasbuf); - edje_object_file_set(init, file, "init/splash"); - evas_object_move(init, 0, 0); - evas_object_resize(init, w, h); - evas_object_show(init); - pixels = ecore_evas_buffer_pixels_get(*buf); - evas_object_del(init); - } - else - { - wallpaper = edje_object_add(evasbuf); - window = edje_object_add(evasbuf); - clock = edje_object_add(evasbuf); - start = edje_object_add(evasbuf); - pager = E_NEW(Evas_Object*, 3); - pager[0] = edje_object_add(evasbuf); - pager[1] = edje_object_add(evasbuf); - pager[2] = edje_object_add(evasbuf); - - edje_object_file_set(wallpaper, file, "desktop/background"); - edje_object_file_set(window, file, "widgets/border/default/border"); - edje_object_file_set(clock, file, "modules/clock/main"); - edje_object_file_set(clock, file, "modules/clock/main"); - edje_object_file_set(start, file, "modules/start/main"); - edje_object_file_set(pager[0], file, "modules/pager/main"); - edje_object_file_set(pager[1], file, "modules/pager/desk"); - edje_object_file_set(pager[2], file, "modules/pager/window"); - edje_object_part_text_set(window, "title_text", file); - edje_object_part_swallow(pager[0], "items", pager[1]); - edje_object_part_swallow(pager[1], "items", pager[2]); - - /* wallpaper */ - evas_object_move(wallpaper, 0, 0); - evas_object_resize(wallpaper, w, h); - /* main window */ - evas_object_move(window, (w * 0.1), (h * 0.05)); - evas_object_resize(window, w * 0.8, h * 0.75); - /* clock */ - evas_object_move(clock, (w * 0.9), (h * 0.9)); - evas_object_resize(clock, w * 0.1, h * 0.1); - /* start */ - evas_object_move(start, 0.1, (h * 0.9)); - evas_object_resize(start, w * 0.1, h * 0.1); - /* pager */ - evas_object_move(pager[0], (w * 0.3), (h * 0.9)); - evas_object_resize(pager[0], w * 0.1, h * 0.1); - - evas_object_show(wallpaper); - evas_object_show(window); - evas_object_show(clock); - evas_object_show(start); - evas_object_show(pager[0]); - evas_object_show(pager[1]); - evas_object_show(pager[2]); - - pixels = ecore_evas_buffer_pixels_get(*buf); - - evas_object_del(wallpaper); - evas_object_del(window); - evas_object_del(clock); - evas_object_del(start); - evas_object_del(pager[0]); - evas_object_del(pager[1]); - evas_object_del(pager[2]); - free(pager); - } - - return pixels; -} - -/* create and save a thumb to disk */ -EAPI int -e_thumb_create(char *file, Evas_Coord w, Evas_Coord h) -{ - Eet_File *ef; - char *thumbpath, *ext; - Evas_Object *im = NULL; - const int *data; - int size, ww, hh; - Ecore_Evas *buf; - int alpha; - - ext = strrchr(file, '.'); - if ((ext) && (!strcasecmp(ext, ".eap"))) - return 1; - - thumbpath = e_thumb_file_get(file); - if (!thumbpath) - return -1; - - if (ext) - { - if (!strcasecmp(ext, ".edj")) - { - /* for now, this function does both the bg and theme previews */ - data = _e_thumb_etheme_create(file, w, h, &ww, &hh, &alpha, &im, &buf); - } - else - data = _e_thumb_image_create(file, w, h, &ww, &hh, &alpha, &im, &buf); - } - else - data = _e_thumb_image_create(file, w, h, &ww, &hh, &alpha, &im, &buf); - - if (data) - { - ef = eet_open(thumbpath, EET_FILE_MODE_WRITE); - if (!ef) - { - free(thumbpath); - if (im) evas_object_del(im); - ecore_evas_free(buf); - return -1; - } - free(thumbpath); - - eet_write(ef, "/thumbnail/orig_path", file, strlen(file), 1); - if ((size = eet_data_image_write(ef, "/thumbnail/data", - (void *)data, ww, hh, alpha, - 0, 91, 1)) <= 0) - { - if (im) evas_object_del(im); - ecore_evas_free(buf); - eet_close(ef); - return -1; - } - eet_close(ef); - } - if (im) evas_object_del(im); - ecore_evas_free(buf); - return 1; -} - -/* get evas object containing image of the thumb */ -EAPI Evas_Object * -e_thumb_evas_object_get(char *file, Evas *evas, Evas_Coord width, Evas_Coord height, int shrink) -{ - Eet_File *ef; - char *thumb, *ext; - Evas_Object *im = NULL; - -#define DEF_THUMB_RETURN im = evas_object_rectangle_add(evas); \ - evas_object_color_set(im, 255, 255, 255, 255); \ - evas_object_resize(im, width, height); \ - return im - - D(("e_thumb_evas_object_get: (%s)\n", file)); - - /* eap thumbnailer */ - ext = strrchr(file, '.'); - if (ext) - { - if (!strcasecmp(ext, ".eap")) - { - E_App *app; - - D(("e_thumb_evas_object_get: eap found\n")); - app = e_app_new(file, 0); - D(("e_thumb_evas_object_get: eap loaded\n")); - if (!app) - { - D(("e_thumb_evas_object_get: invalid eap\n")); - DEF_THUMB_RETURN; - } - else - { - D(("e_thumb_evas_object_get: creating eap thumb\n")); - im = e_icon_add(evas); - e_icon_file_edje_set(im, file, "icon"); - e_object_unref(E_OBJECT(app)); - D(("e_thumb_evas_object_get: returning eap thumb\n")); - return im; - } - } - } - - /* saved thumb */ - /* TODO: add ability to fetch thumbs from freedesktop dirs */ - if (!e_thumb_exists(file)) - { - if (!e_thumb_create(file, width, height)) - { - DEF_THUMB_RETURN; - } - } - - thumb = e_thumb_file_get(file); - if (!thumb) - { - DEF_THUMB_RETURN; - } - - ef = eet_open(thumb, EET_FILE_MODE_READ); - if (!ef) - { - eet_close(ef); - free(thumb); - DEF_THUMB_RETURN; - } - - im = e_icon_add(evas); - e_icon_file_key_set(im, thumb, "/thumbnail/data"); - if (shrink) - { - Evas_Coord sw, sh; - - e_icon_size_get(im, &sw, &sh); - evas_object_resize(im, sw, sh); - } - e_icon_fill_inside_set(im, 1); - free(thumb); - eet_close(ef); - return im; -} - -/* return hash for a file */ -static char * -_e_thumb_file_id(char *file) -{ - char s[256], *sp; - const char *chmap = - "0123456789abcdef" - "ghijklmnopqrstuv" - "wxyz`~!@#$%^&*()" - "[];',.{}<>?-=_+|"; - unsigned int id[4], i; - struct stat st; - - if (stat(file, &st) < 0) - return NULL; - - id[0] = st.st_ino; - id[1] = st.st_dev; - id[2] = (st.st_size & 0xffffffff); - id[3] = (st.st_mtime & 0xffffffff); - - sp = s; - for (i = 0; i < 4; i++) - { - unsigned int t, tt; - int j; - - t = id[i]; - j = 32; - while (j > 0) - { - tt = t & ((1 << 6) - 1); - *sp = chmap[tt]; - t >>= 6; - j -= 6; - sp++; - } - } - *sp = 0; - return strdup(s); -} - -/* generate a thumb from the list of queued thumbs */ static void -_e_thumb_generate(void) +_e_thumb_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info) { - E_Thumb_Item *t; + E_Thumb *eth; - if ((!thumb_files) || (pid != -1)) return; - pid = fork(); - if (pid == 0) + eth = evas_object_data_get(obj, "e_thumbdata"); + if (!eth) return; + evas_object_data_del(obj, "e_thumbdata"); + _e_thumb_hash_del(eth->objid); + if (eth->busy) { - /* reset signal handlers for the child */ - signal(SIGSEGV, SIG_DFL); - signal(SIGILL, SIG_DFL); - signal(SIGFPE, SIG_DFL); - signal(SIGBUS, SIG_DFL); - - t = thumb_files->data; - if (!e_thumb_exists(t->path)) - e_thumb_create(t->path, t->w, t->h); - eet_clearcache(); - exit(0); - } + _e_thumb_gen_end(eth->objid); + _pending--; + if (_pending == 0) _e_thumb_thumbnailers_kill(); + } + if (eth->queued) + _thumb_queue = evas_list_remove(_thumb_queue, eth); + E_FREE(eth->file); + E_FREE(eth->key); + free(eth); +} + +static void +_e_thumb_hash_add(int objid, Evas_Object *obj) +{ + char buf[32]; + + snprintf(buf, sizeof(buf), "%i", objid); + _thumbs = evas_hash_add(_thumbs, buf, obj); +} + +static void +_e_thumb_hash_del(int objid) +{ + char buf[32]; + + snprintf(buf, sizeof(buf), "%i", objid); + _thumbs = evas_hash_del(_thumbs, buf, NULL); +} + +static Evas_Object * +_e_thumb_hash_find(int objid) +{ + char buf[32]; + + snprintf(buf, sizeof(buf), "%i", objid); + return evas_hash_find(_thumbs, buf); +} + +static void +_e_thumb_thumbnailers_kill(void) +{ + Evas_List *l; + + for (l = _thumbnailers_exe; l; l = l->next) + ecore_exe_terminate(l->data); } -/* called when a thumb is generated */ static int -_e_thumb_cb_exe_exit(void *data, int type, void *event) +_e_thumb_cb_exe_event_del(void *data, int type, void *event) { Ecore_Exe_Event_Del *ev; - E_Thumb_Item *t; - char *ext; + Evas_List *l; ev = event; - if (ev->pid != pid) return 1; - if (!thumb_files) + for (l = _thumbnailers_exe; l; l = l->next) { - pid = -1; - return 1; - } - - t = thumb_files->data; - thumb_files = evas_list_remove_list(thumb_files, thumb_files); - - ext = strrchr(t->path, '.'); - if ((ext) && (strcasecmp(ext, ".eap"))) - ext = NULL; - - if ((ext) || (ecore_file_exists(t->path))) - { - Evas_Coord w, h; - Evas_Object *tmp; - void *data; - - tmp = e_thumb_evas_object_get(t->path, - t->evas, - t->w, - t->h, - 1); - if (tmp && t) + if (l->data == ev->exe) { - data = e_icon_data_get(tmp, &w, &h); - e_icon_data_set(t->obj, data, w, h); - evas_object_del(tmp); - if(t->cb) - t->cb(t->obj, t->data); - free(t); + _thumbnailers_exe = evas_list_remove_list(_thumbnailers_exe, l); + break; } } - - pid = -1; - _e_thumb_generate(); return 1; } diff --git a/src/bin/e_thumb.h b/src/bin/e_thumb.h index 49fd9683a..7624da085 100644 --- a/src/bin/e_thumb.h +++ b/src/bin/e_thumb.h @@ -10,14 +10,15 @@ EAPI int e_thumb_init(void); EAPI int e_thumb_shutdown(void); -EAPI const char *e_thumb_dir_get(void); -EAPI char *e_thumb_file_get(char *file); -EAPI void e_thumb_geometry_get(char *file, int *w, int *h, int from_eet); -EAPI int e_thumb_exists(char *file); -EAPI int e_thumb_create(char *file, Evas_Coord w, Evas_Coord h); -EAPI Evas_Object *e_thumb_evas_object_get(char *file, Evas *evas, Evas_Coord width, Evas_Coord height, int shrink); -EAPI Evas_Object *e_thumb_generate_begin(char *path, Evas_Coord w, Evas_Coord h, Evas *evas, Evas_Object **tmp, void (*cb)(Evas_Object *obj, void *data), void *data); -EAPI void e_thumb_generate_end(char *path); - + +EAPI Evas_Object *e_thumb_icon_add(Evas *evas); +EAPI void e_thumb_icon_file_set(Evas_Object *obj, char *file, char *key); +EAPI void e_thumb_icon_size_set(Evas_Object *obj, int w, int h); +EAPI void e_thumb_icon_begin(Evas_Object *obj); +EAPI void e_thumb_icon_end(Evas_Object *obj); + +EAPI void e_thumb_client_data(Ecore_Ipc_Event_Client_Data *e); +EAPI void e_thumb_client_del(Ecore_Ipc_Event_Client_Del *e); + #endif #endif diff --git a/src/bin/e_thumb_main.c b/src/bin/e_thumb_main.c new file mode 100644 index 000000000..ceadddce9 --- /dev/null +++ b/src/bin/e_thumb_main.c @@ -0,0 +1,388 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct _E_Thumb E_Thumb; + +struct _E_Thumb +{ + int objid; + int w, h; + char *file; + char *key; +}; + +/* local subsystem functions */ +static int _e_ipc_init(void); +static int _e_ipc_cb_server_add(void *data, int type, void *event); +static int _e_ipc_cb_server_del(void *data, int type, void *event); +static int _e_ipc_cb_server_data(void *data, int type, void *event); +static int _e_cb_timer(void *data); +static void _e_thumb_generate(E_Thumb *eth); +static char *_e_thumb_file_id(char *file, char *key); + +/* local subsystem globals */ +static Ecore_Ipc_Server *_e_ipc_server = NULL; +static Evas_List *_thumblist = NULL; +static Ecore_Timer *_timer = NULL; +static char _thumbdir[4096] = ""; + +/* externally accessible functions */ +int +main(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) + { + if ((!strcmp(argv[i], "-h")) || + (!strcmp(argv[i], "-help")) || + (!strcmp(argv[i], "--help"))) + { + printf( + "This is an internal tool for Enlightenment.\n" + "do not use it.\n" + ); + exit(0); + } + } + + ecore_init(); + ecore_app_args_set(argc, (const char **)argv); + eet_init(); + evas_init(); + ecore_evas_init(); + edje_init(); + ecore_file_init(); + ecore_ipc_init(); + + snprintf(_thumbdir, sizeof(_thumbdir), "%s/.e/e/fileman/thumbnails", + getenv("HOME")); + ecore_file_mkpath(_thumbdir); + + if (_e_ipc_init()) ecore_main_loop_begin(); + + if (_e_ipc_server) + { + ecore_ipc_server_del(_e_ipc_server); + _e_ipc_server = NULL; + } + ecore_ipc_shutdown(); + ecore_file_shutdown(); + ecore_evas_shutdown(); + edje_shutdown(); + evas_shutdown(); + eet_shutdown(); + ecore_shutdown(); + + return 0; +} + +/* local subsystem functions */ +static int +_e_ipc_init(void) +{ + char *sdir; + + sdir = getenv("E_IPC_SOCKET"); + if (!sdir) + { + printf("The E_IPC_SOCKET environment variable is not set. This is\n" + "exported by Enlightenment to all processes it launches.\n" + "This environment variable must be set and must point to\n" + "Enlightenment's IPC socket file (minus port number).\n"); + return 0; + } + _e_ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, sdir, 0, NULL); + if (!_e_ipc_server) return 0; + + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _e_ipc_cb_server_add, NULL); + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _e_ipc_cb_server_del, NULL); + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _e_ipc_cb_server_data, NULL); + + return 1; +} + +static int +_e_ipc_cb_server_add(void *data, int type, void *event) +{ + Ecore_Ipc_Event_Server_Add *e; + + e = event; + ecore_ipc_server_send(e->server, 5, 1, 0, 0, 0, NULL, 0); /* send hello */ + return 1; +} + +static int +_e_ipc_cb_server_del(void *data, int type, void *event) +{ + Ecore_Ipc_Event_Server_Del *e; + + e = event; + /* quit now */ + ecore_main_loop_quit(); + return 1; +} + +static int +_e_ipc_cb_server_data(void *data, int type, void *event) +{ + Ecore_Ipc_Event_Server_Data *e; + E_Thumb *eth; + Evas_List *l; + char *file = NULL; + char *key = NULL; + + e = event; + if (e->major != 5) return 1; + if (!e->data) return 1; + switch (e->minor) + { + case 1: + /* begin thumb */ + /* don't check stuff. since this connects TO e17 it is connecting */ + /* TO a trusted process that WILL send this message properly */ + /* formatted. if the thumbnailer dies anyway - it's not a big loss */ + /* but it is a sign of a bug in e formattign messages maybe */ + file = e->data; + key = file + strlen(file) + 1; + if (!key[0]) key = NULL; + eth = calloc(1, sizeof(E_Thumb)); + if (eth) + { + eth->objid = e->ref; + eth->w = e->ref_to; + eth->h = e->response; + eth->file = strdup(file); + if (key) eth->key = strdup(key); + _thumblist = evas_list_append(_thumblist, eth); + if (!_timer) _timer = ecore_timer_add(0.001, _e_cb_timer, NULL); + } + break; + case 2: + /* end thumb */ + for (l = _thumblist; l; l = l->next) + { + eth = l->data; + if (eth->objid == e->ref) + { + _thumblist = evas_list_remove_list(_thumblist, l); + if (eth->file) free(eth->file); + if (eth->key) free(eth->key); + free(eth); + break; + } + } + break; + case 3: + /* quit now */ + ecore_main_loop_quit(); + break; + default: + break; + } + return 1; +} + +static int +_e_cb_timer(void *data) +{ + E_Thumb *eth; + + /* take thumb at head of list */ + if (_thumblist) + { + eth = _thumblist->data; + _thumblist = evas_list_remove_list(_thumblist, _thumblist); + _e_thumb_generate(eth); + if (eth->file) free(eth->file); + if (eth->key) free(eth->key); + free(eth); + if (_thumblist) _timer = ecore_timer_add(0.001, _e_cb_timer, NULL); + else _timer = NULL; + } + else + _timer = NULL; + return 0; +} + +static void +_e_thumb_generate(E_Thumb *eth) +{ + char buf[4096], *id, *td, *ext = NULL; + Evas *evas = NULL, *evas_im = NULL; + Ecore_Evas *ee = NULL, *ee_im = NULL; + Evas_Object *im = NULL, *edje = NULL; + Eet_File *ef; + int iw, ih, alpha, ww, hh; + int *data = NULL; + time_t mtime_orig, mtime_thumb; + + id = _e_thumb_file_id(eth->file, eth->key); + if (!id) return; + + td = strdup(id); + if (!td) + { + free(id); + return; + } + td[3] = 0; + + snprintf(buf, sizeof(buf), "%s/%s", _thumbdir, td); + ecore_file_mkdir(buf); + + snprintf(buf, sizeof(buf), "%s/%s/%s.thm", _thumbdir, td, id + 3); + free(id); + free(td); + + mtime_orig = ecore_file_mod_time(eth->file); + mtime_thumb = ecore_file_mod_time(buf); + if (mtime_thumb <= mtime_orig) + { + edje_file_cache_set(0); + edje_collection_cache_set(0); + ee = ecore_evas_buffer_new(1, 1); + evas = ecore_evas_get(ee); + evas_image_cache_set(evas, 0); + evas_font_cache_set(evas, 0); + ww = 0; + hh = 0; + ext = strrchr(eth->file, '.'); + if ((ext) && (!strcasecmp(ext, ".edj")) && (eth->key)) + { + ww = eth->w; + hh = eth->h; + im = ecore_evas_object_image_new(ee); + ee_im = evas_object_data_get(im, "Ecore_Evas"); + evas_im = ecore_evas_get(ee_im); + evas_image_cache_set(evas_im, 0); + evas_font_cache_set(evas_im, 0); + evas_object_image_size_set(im, ww * 8, hh * 8); + evas_object_image_fill_set(im, 0, 0, ww, hh); + edje = edje_object_add(evas_im); + if (edje_object_file_set(edje, eth->file, eth->key)) + { + evas_object_move(edje, 0, 0); + evas_object_resize(edje, ww * 8, hh * 8); + evas_object_show(edje); + } + } + else + { + im = evas_object_image_add(evas); + evas_object_image_file_set(im, eth->file, NULL); + iw = 0; ih = 0; + evas_object_image_size_get(im, &iw, &ih); + alpha = evas_object_image_alpha_get(im); + if ((iw > 0) && (ih > 0)) + { + ww = eth->w; + hh = (eth->w * ih) / iw; + if (hh > eth->h) + { + hh = eth->h; + ww = (eth->h * iw) / ih; + } + evas_object_image_fill_set(im, 0, 0, ww, hh); + } + } + evas_object_move(im, 0, 0); + evas_object_resize(im, ww, hh); + ecore_evas_resize(ee, ww, hh); + evas_object_show(im); + if (ww > 0) + { + data = (int *)ecore_evas_buffer_pixels_get(ee); + if (data) + { + ef = eet_open(buf, EET_FILE_MODE_WRITE); + if (ef) + { + eet_write(ef, "/thumbnail/orig_file", + eth->file, strlen(eth->file), 1); + if (eth->key) + eet_write(ef, "/thumbnail/orig_key", + eth->key, strlen(eth->key), 1); + eet_data_image_write(ef, "/thumbnail/data", + (void *)data, ww, hh, alpha, + 0, 91, 1); + eet_close(ef); + } + } + } + /* will free all */ + if (edje) evas_object_del(edje); + if (ee_im) ecore_evas_free(ee_im); + else if (im) evas_object_del(im); + ecore_evas_free(ee); + eet_clearcache(); + } + /* send back path to thumb */ + ecore_ipc_server_send(_e_ipc_server, 5, 2, eth->objid, 0, 0, buf, strlen(buf) + 1); +} + +static char * +_e_thumb_file_id(char *file, char *key) +{ + char s[512], *sp; + const char *chmap = + "0123456789abcdef" + "ghijklmnopqrstuv"; + unsigned int id[8], i, t, tt; + int j; + + for (i = 0; i < 8; i++) id[i] = 0x55555555; + + j = 0; + sp = file; + while (*sp) + { + i = ((int)*sp) & 0x7; + id[i] ^= ((int)*sp) << j; + j++; + if (j == 25) j = 0; + sp++; + } + + sp = key; + if (sp) + { + while (*sp) + { + i = ((int)*sp) & 0x7; + id[i] ^= ((int)*sp) << j; + j++; + if (j == 25) j = 0; + sp++; + } + } + + sp = s; + for (i = 0; i < 8; i++) + { + t = id[i]; + j = 32; + while (j > 0) + { + tt = t & ((1 << 5) - 1); + *sp = chmap[tt]; + t >>= 5; + j -= 5; + sp++; + } + } + *sp = 0; + return strdup(s); +}