6 # define alloca __builtin_alloca
8 # define alloca __alloca
11 # define alloca _alloca
25 #include <Ecore_Evas.h>
26 #include <Ecore_Ipc.h>
27 #include <Ecore_File.h>
34 typedef struct _E_Thumb E_Thumb;
44 /* local subsystem functions */
45 static int _e_ipc_init(void);
46 static Eina_Bool _e_ipc_cb_server_add(void *data,
49 static Eina_Bool _e_ipc_cb_server_del(void *data,
52 static Eina_Bool _e_ipc_cb_server_data(void *data,
55 static Eina_Bool _e_cb_timer(void *data);
56 static void _e_thumb_generate(E_Thumb *eth);
57 static char *_e_thumb_file_id(char *file,
60 /* local subsystem globals */
61 static Ecore_Ipc_Server *_e_ipc_server = NULL;
62 static Eina_List *_thumblist = NULL;
63 static Ecore_Timer *_timer = NULL;
64 static char _thumbdir[4096] = "";
66 /* externally accessible functions */
73 for (i = 1; i < argc; i++)
75 if ((!strcmp(argv[i], "-h")) ||
76 (!strcmp(argv[i], "-help")) ||
77 (!strcmp(argv[i], "--help")))
80 "This is an internal tool for Enlightenment.\n"
85 else if (!strncmp(argv[i], "--nice=", 7))
92 ret = nice(atoi(val));
97 ecore_app_args_set(argc, (const char **)argv);
105 e_user_dir_concat_static(_thumbdir, "fileman/thumbnails");
106 ecore_file_mkpath(_thumbdir);
108 if (_e_ipc_init()) ecore_main_loop_begin();
112 ecore_ipc_server_del(_e_ipc_server);
113 _e_ipc_server = NULL;
116 ecore_ipc_shutdown();
117 ecore_file_shutdown();
118 ecore_evas_shutdown();
127 /* local subsystem functions */
133 sdir = getenv("E_IPC_SOCKET");
136 printf("The E_IPC_SOCKET environment variable is not set. This is\n"
137 "exported by Enlightenment to all processes it launches.\n"
138 "This environment variable must be set and must point to\n"
139 "Enlightenment's IPC socket file (minus port number).\n");
142 _e_ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, sdir, 0, NULL);
143 if (!_e_ipc_server) return 0;
145 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _e_ipc_cb_server_add, NULL);
146 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _e_ipc_cb_server_del, NULL);
147 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _e_ipc_cb_server_data, NULL);
153 _e_ipc_cb_server_add(void *data __UNUSED__,
157 Ecore_Ipc_Event_Server_Add *e;
160 ecore_ipc_server_send(e->server,
161 5 /*E_IPC_DOMAIN_THUMB*/,
163 0, 0, 0, NULL, 0); /* send hello */
164 return ECORE_CALLBACK_PASS_ON;
168 _e_ipc_cb_server_del(void *data __UNUSED__,
170 void *event __UNUSED__)
173 ecore_main_loop_quit();
174 return ECORE_CALLBACK_PASS_ON;
178 _e_ipc_cb_server_data(void *data __UNUSED__,
182 Ecore_Ipc_Event_Server_Data *e;
189 if (e->major != 5 /*E_IPC_DOMAIN_THUMB*/) return ECORE_CALLBACK_PASS_ON;
196 /* don't check stuff. since this connects TO e17 it is connecting */
197 /* TO a trusted process that WILL send this message properly */
198 /* formatted. if the thumbnailer dies anyway - it's not a big loss */
199 /* but it is a sign of a bug in e formattign messages maybe */
201 key = file + strlen(file) + 1;
202 if (!key[0]) key = NULL;
203 eth = calloc(1, sizeof(E_Thumb));
208 eth->h = e->response;
209 eth->file = strdup(file);
210 if (key) eth->key = strdup(key);
211 _thumblist = eina_list_append(_thumblist, eth);
212 if (!_timer) _timer = ecore_timer_add(0.001, _e_cb_timer, NULL);
219 EINA_LIST_FOREACH(_thumblist, l, eth)
221 if (eth->objid == e->ref)
223 _thumblist = eina_list_remove_list(_thumblist, l);
224 if (eth->file) free(eth->file);
225 if (eth->key) free(eth->key);
234 ecore_main_loop_quit();
240 return ECORE_CALLBACK_PASS_ON;
244 _e_cb_timer(void *data __UNUSED__)
248 Eina_List *del_list = NULL, *l;
251 /* take thumb at head of list */
254 eth = eina_list_data_get(_thumblist);
255 _thumblist = eina_list_remove_list(_thumblist, _thumblist);
256 _e_thumb_generate(eth);
257 if (eth->file) free(eth->file);
258 if (eth->key) free(eth->key);
261 if (_thumblist) _timer = ecore_timer_add(0.01, _e_cb_timer, NULL);
266 return ECORE_CALLBACK_CANCEL;
269 typedef struct _Color Color;
276 unsigned char r, g, b;
280 _e_thumb_generate(E_Thumb *eth)
282 char buf[4096], dbuf[4096], *id, *td, *ext = NULL;
283 Evas *evas = NULL, *evas_im = NULL;
284 Ecore_Evas *ee = NULL, *ee_im = NULL;
285 Evas_Object *im = NULL, *edje = NULL;
287 int iw, ih, alpha, ww, hh;
288 const unsigned int *data = NULL;
289 time_t mtime_orig, mtime_thumb;
291 id = _e_thumb_file_id(eth->file, eth->key);
302 snprintf(dbuf, sizeof(dbuf), "%s/%s", _thumbdir, td);
303 snprintf(buf, sizeof(buf), "%s/%s/%s-%ix%i.thm",
304 _thumbdir, td, id + 2, eth->w, eth->h);
308 mtime_orig = ecore_file_mod_time(eth->file);
309 mtime_thumb = ecore_file_mod_time(buf);
310 while (mtime_thumb <= mtime_orig)
314 ecore_file_mkdir(dbuf);
316 edje_file_cache_set(0);
317 edje_collection_cache_set(0);
318 ee = ecore_evas_buffer_new(1, 1);
319 evas = ecore_evas_get(ee);
320 evas_image_cache_set(evas, 0);
321 evas_font_cache_set(evas, 0);
325 ext = strrchr(eth->file, '.');
327 if ((ext) && (eth->key) &&
328 ((!strcasecmp(ext, ".edj")) ||
329 (!strcasecmp(ext, ".eap"))))
333 im = ecore_evas_object_image_new(ee);
334 ee_im = evas_object_data_get(im, "Ecore_Evas");
335 evas_im = ecore_evas_get(ee_im);
336 evas_image_cache_set(evas_im, 0);
337 evas_font_cache_set(evas_im, 0);
338 evas_object_image_size_set(im, ww * 4, hh * 4);
339 evas_object_image_fill_set(im, 0, 0, ww, hh);
340 edje = edje_object_add(evas_im);
342 ((!strcmp(eth->key, "e/desktop/background")) ||
343 (!strcmp(eth->key, "e/init/splash"))))
345 if (edje_object_file_set(edje, eth->file, eth->key))
347 evas_object_move(edje, 0, 0);
348 evas_object_resize(edje, ww * 4, hh * 4);
349 evas_object_show(edje);
352 else if (evas_object_image_extension_can_load_get(ext))
354 im = evas_object_image_add(evas);
355 evas_object_image_load_size_set(im, eth->w, eth->h);
356 evas_object_image_file_set(im, eth->file, NULL);
358 evas_object_image_size_get(im, &iw, &ih);
359 alpha = evas_object_image_alpha_get(im);
360 if ((iw > 0) && (ih > 0))
363 hh = (eth->w * ih) / iw;
367 ww = (eth->h * iw) / ih;
369 evas_object_image_fill_set(im, 0, 0, ww, hh);
374 ecore_evas_alpha_set(ee, alpha);
375 evas_object_move(im, 0, 0);
376 evas_object_resize(im, ww, hh);
377 ecore_evas_resize(ee, ww, hh);
378 evas_object_show(im);
379 if (ww <= 0) goto end;
380 data = ecore_evas_buffer_pixels_get(ee);
382 ef = eet_open(buf, EET_FILE_MODE_WRITE);
384 eet_write(ef, "/thumbnail/orig_file",
385 eth->file, strlen(eth->file), 1);
387 eet_write(ef, "/thumbnail/orig_key",
388 eth->key, strlen(eth->key), 1);
389 eet_data_image_write(ef, "/thumbnail/data",
390 (void *)data, ww, hh, alpha,
393 evas_object_image_fill_set(im, 0, 0, ww, hh);
394 evas_object_resize(im, ww, hh);
395 ecore_evas_resize(ee, ww, hh);
396 data = ecore_evas_buffer_pixels_get(ee);
399 data1 = malloc(ww * hh * sizeof(unsigned int));
400 memcpy(data1, data, ww * hh * sizeof(unsigned int));
402 evas_object_image_fill_set(im, 0, 0, ww, hh);
403 evas_object_resize(im, ww, hh);
404 ecore_evas_resize(ee, ww, hh);
405 data = ecore_evas_buffer_pixels_get(ee);
410 data2 = malloc(ww * hh * sizeof(unsigned int));
411 memcpy(data2, data, ww * hh * sizeof(unsigned int));
413 evas_object_image_fill_set(im, 0, 0, ww, hh);
414 evas_object_resize(im, ww, hh);
415 ecore_evas_resize(ee, ww, hh);
416 data = ecore_evas_buffer_pixels_get(ee);
420 unsigned char id2[(21 * 4) + 1];
436 data3 = malloc(ww * hh * sizeof(unsigned int));
437 memcpy(data3, data, ww * hh * sizeof(unsigned int));
440 #define A(v) (((v) >> 24) & 0xff)
441 #define R(v) (((v) >> 16) & 0xff)
442 #define G(v) (((v) >> 8) & 0xff)
443 #define B(v) (((v)) & 0xff)
445 evas_color_rgb_to_hsv(R(p), G(p), B(p), &h, &s, &v); \
446 hi = 20 * (h / 360.0); \
450 #define SAVEHSV(h, s, v) \
451 id2[n++] = 'a' + h; \
452 id2[n++] = 'a' + v; \
459 for (i = 0; i < 4; i++)
464 for (i = 0; i < 16; i++)
472 for (i = 0; i < 4; i++)
477 for (i = 0; i < 16; i++)
484 for (i = 0; i < 4; i++)
489 for (i = 0; i < 16; i++)
496 for (i = 0; i < 4; i++)
501 for (i = 0; i < 16; i++)
508 eet_write(ef, "/thumbnail/sort_id", id2, n, 1);
515 if (ef) eet_close(ef);
518 if (edje) evas_object_del(edje);
519 if (ee_im) ecore_evas_free(ee_im);
526 /* send back path to thumb */
527 ecore_ipc_server_send(_e_ipc_server, 5, 2, eth->objid, 0, 0, buf, strlen(buf) + 1);
531 _e_thumb_file_id(char *file,
535 const char *chmap = "0123456789abcdef";
536 unsigned char *buf, id[20];
550 strcpy((char *)buf, file);
551 if (key) strcpy((char *)(buf + lenf + 1), key);
553 e_sha1_sum(buf, len, id);
555 for (i = 0; i < 20; i++)
557 s[(i * 2) + 0] = chmap[(id[i] >> 4) & 0xf];
558 s[(i * 2) + 1] = chmap[(id[i]) & 0xf];