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 if (mtime_thumb <= mtime_orig)
312 ecore_file_mkdir(dbuf);
314 edje_file_cache_set(0);
315 edje_collection_cache_set(0);
316 ee = ecore_evas_buffer_new(1, 1);
317 evas = ecore_evas_get(ee);
318 evas_image_cache_set(evas, 0);
319 evas_font_cache_set(evas, 0);
323 ext = strrchr(eth->file, '.');
325 if ((ext) && (eth->key) &&
326 ((!strcasecmp(ext, ".edj")) ||
327 (!strcasecmp(ext, ".eap"))))
331 im = ecore_evas_object_image_new(ee);
332 ee_im = evas_object_data_get(im, "Ecore_Evas");
333 evas_im = ecore_evas_get(ee_im);
334 evas_image_cache_set(evas_im, 0);
335 evas_font_cache_set(evas_im, 0);
336 evas_object_image_size_set(im, ww * 4, hh * 4);
337 evas_object_image_fill_set(im, 0, 0, ww, hh);
338 edje = edje_object_add(evas_im);
340 ((!strcmp(eth->key, "e/desktop/background")) ||
341 (!strcmp(eth->key, "e/init/splash"))))
343 if (edje_object_file_set(edje, eth->file, eth->key))
345 evas_object_move(edje, 0, 0);
346 evas_object_resize(edje, ww * 4, hh * 4);
347 evas_object_show(edje);
352 im = evas_object_image_add(evas);
353 evas_object_image_load_size_set(im, eth->w, eth->h);
354 evas_object_image_file_set(im, eth->file, NULL);
356 evas_object_image_size_get(im, &iw, &ih);
357 alpha = evas_object_image_alpha_get(im);
358 if ((iw > 0) && (ih > 0))
361 hh = (eth->w * ih) / iw;
365 ww = (eth->h * iw) / ih;
367 evas_object_image_fill_set(im, 0, 0, ww, hh);
370 evas_object_move(im, 0, 0);
371 evas_object_resize(im, ww, hh);
372 ecore_evas_resize(ee, ww, hh);
373 evas_object_show(im);
376 data = ecore_evas_buffer_pixels_get(ee);
379 ef = eet_open(buf, EET_FILE_MODE_WRITE);
382 eet_write(ef, "/thumbnail/orig_file",
383 eth->file, strlen(eth->file), 1);
385 eet_write(ef, "/thumbnail/orig_key",
386 eth->key, strlen(eth->key), 1);
387 eet_data_image_write(ef, "/thumbnail/data",
388 (void *)data, ww, hh, alpha,
391 evas_object_image_fill_set(im, 0, 0, ww, hh);
392 evas_object_resize(im, ww, hh);
393 ecore_evas_resize(ee, ww, hh);
394 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 id[(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) \
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", id, n, 1);
521 if (edje) evas_object_del(edje);
522 if (ee_im) ecore_evas_free(ee_im);
528 /* send back path to thumb */
529 ecore_ipc_server_send(_e_ipc_server, 5, 2, eth->objid, 0, 0, buf, strlen(buf) + 1);
533 _e_thumb_file_id(char *file,
537 const char *chmap = "0123456789abcdef";
538 unsigned char *buf, id[20];
552 strcpy((char *)buf, file);
553 if (key) strcpy((char *)(buf + lenf + 1), key);
555 e_sha1_sum(buf, len, id);
557 for (i = 0; i < 20; i++)
559 s[(i * 2) + 0] = chmap[(id[i] >> 4) & 0xf];
560 s[(i * 2) + 1] = chmap[(id[i]) & 0xf];