bfea18a02ee079142d1af0718ce611b294897487
[framework/uifw/e17.git] / src / bin / e_utils.c
1 #include "e.h"
2
3 EAPI E_Path *path_data = NULL;
4 EAPI E_Path *path_images = NULL;
5 EAPI E_Path *path_fonts = NULL;
6 EAPI E_Path *path_themes = NULL;
7 EAPI E_Path *path_icons = NULL;
8 EAPI E_Path *path_modules = NULL;
9 EAPI E_Path *path_backgrounds = NULL;
10 EAPI E_Path *path_messages = NULL;
11 EAPI int restart = 0;
12 EAPI int good = 0;
13 EAPI int evil = 0;
14 EAPI int starting = 1;
15 EAPI int stopping = 0;
16
17 typedef struct _E_Util_Fake_Mouse_Up_Info E_Util_Fake_Mouse_Up_Info;
18 typedef struct _E_Util_Image_Import_Settings E_Util_Image_Import_Settings;
19
20 struct _E_Util_Fake_Mouse_Up_Info
21 {
22    Evas *evas;
23    int button;
24 };
25
26 struct _E_Util_Image_Import_Settings
27 {
28    E_Dialog *dia;
29    struct
30      {
31         void (*func)(void *data, const char *path, Eina_Bool ok, Eina_Bool external, int quality, E_Image_Import_Mode mode);
32         void *data;
33      } cb;
34    const char *path;
35    int quality;
36    int external;
37    int mode;
38    Eina_Bool ok;
39 };
40
41 struct _E_Util_Image_Import_Handle
42 {
43    Ecore_Exe *exe;
44    Ecore_Event_Handler *handler;
45    struct
46      {
47         void (*func)(void *data, Eina_Bool ok, const char *image_path, const char *edje_path);
48         void *data;
49      } cb;
50    struct
51      {
52         const char *image, *edje, *temp;
53      } path;
54 };
55
56 /* local subsystem functions */
57 static Eina_Bool _e_util_cb_delayed_del(void *data);
58 static Eina_Bool _e_util_wakeup_cb(void *data);
59
60 static void _e_util_image_import_settings_do(void *data, E_Dialog *dia);
61 static void _e_util_image_import_settings_del(void *obj);
62
63 static Eina_Bool _e_util_image_import_exit(void *data, int type __UNUSED__, void *event);
64 static void _e_util_image_import_handle_free(E_Util_Image_Import_Handle *handle);
65 static Evas_Object *_e_util_icon_add(const char *path, Evas *evas, int size);
66
67 /* local subsystem globals */
68 static Ecore_Timer *_e_util_dummy_timer = NULL;
69
70 /* externally accessible functions */
71 EAPI void
72 e_util_wakeup(void)
73 {
74    if (_e_util_dummy_timer) return;
75    _e_util_dummy_timer = ecore_timer_add(0.0, _e_util_wakeup_cb, NULL);
76 }
77
78 EAPI void
79 e_util_env_set(const char *var, const char *val)
80 {
81    if (val)
82      {
83 #ifdef HAVE_SETENV
84         setenv(var, val, 1);
85 #else
86         char buf[8192];
87
88         snprintf(buf, sizeof(buf), "%s=%s", var, val);
89         if (getenv(var))
90           putenv(buf);
91         else
92           putenv(strdup(buf));
93 #endif
94      }
95    else
96      {
97 #ifdef HAVE_UNSETENV
98         unsetenv(var);
99 #else
100         if (getenv(var)) putenv(var);
101 #endif
102      }
103 }
104
105 EAPI E_Zone *
106 e_util_zone_current_get(E_Manager *man)
107 {
108    E_Container *con;
109
110    E_OBJECT_CHECK_RETURN(man, NULL);
111    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
112    con = e_container_current_get(man);
113    if (con)
114      {
115         E_Zone *zone;
116
117         zone = e_zone_current_get(con);
118         return zone;
119      }
120    return NULL;
121 }
122
123 EAPI int
124 e_util_glob_match(const char *str, const char *glob)
125 {
126    if ((!str) || (!glob)) return 0;
127    if (glob[0] == 0)
128      {
129         if (str[0] == 0) return 1;
130         return 0;
131      }
132    if (!strcmp(glob, "*")) return 1;
133    if (!fnmatch(glob, str, 0)) return 1;
134    return 0;
135 }
136
137 EAPI int
138 e_util_glob_case_match(const char *str, const char *glob)
139 {
140    const char *p;
141    char *tstr, *tglob, *tp;
142
143    if (glob[0] == 0)
144      {
145         if (str[0] == 0) return 1;
146         return 0;
147      }
148    if (!strcmp(glob, "*")) return 1;
149    tstr = alloca(strlen(str) + 1);
150    for (tp = tstr, p = str; *p != 0; p++, tp++) *tp = tolower(*p);
151    *tp = 0;
152    tglob = alloca(strlen(glob) + 1);
153    for (tp = tglob, p = glob; *p != 0; p++, tp++) *tp = tolower(*p);
154    *tp = 0;
155    if (!fnmatch(tglob, tstr, 0)) return 1;
156    return 0;
157 }
158
159 EAPI E_Container *
160 e_util_container_number_get(int num)
161 {
162    Eina_List *l;
163    E_Manager *man;
164
165    EINA_LIST_FOREACH(e_manager_list(), l, man)
166      {
167         E_Container *con;
168
169         con = e_container_number_get(man, num);
170         if (con) return con;
171      }
172    return NULL;
173 }
174
175 EAPI E_Zone *
176 e_util_container_zone_number_get(int con_num, int zone_num)
177 {
178    E_Container *con;
179
180    con = e_util_container_number_get(con_num);
181    if (!con) return NULL;
182    return e_container_zone_number_get(con, zone_num);
183 }
184
185 EAPI E_Zone *
186 e_util_container_zone_id_get(int con_num, int id)
187 {
188    E_Container *con;
189
190    con = e_util_container_number_get(con_num);
191    if (!con) return NULL;
192    return e_container_zone_id_get(con, id);
193 }
194
195 EAPI int
196 e_util_head_exec(int head, const char *cmd)
197 {
198    char *penv_display;
199    char *p1, *p2;
200    char buf[PATH_MAX], buf2[32];
201    int ok = 0;
202    Ecore_Exe *exe;
203
204    penv_display = getenv("DISPLAY");
205    if (!penv_display) return 0;
206    penv_display = strdup(penv_display);
207    /* set env vars */
208    p1 = strrchr(penv_display, ':');
209    p2 = strrchr(penv_display, '.');
210    if ((p1) && (p2) && (p2 > p1)) /* "blah:x.y" */
211      {
212         /* yes it could overflow... but who will overflow DISPLAY eh? why? to
213          * "exploit" your own applications running as you?
214          */
215         strcpy(buf, penv_display);
216         buf[p2 - penv_display + 1] = 0;
217         snprintf(buf2, sizeof(buf2), "%i", head);
218         strcat(buf, buf2);
219      }
220    else if (p1) /* "blah:x */
221      {
222         strcpy(buf, penv_display);
223         snprintf(buf2, sizeof(buf2), ".%i", head);
224         strcat(buf, buf2);
225      }
226    else
227      strcpy(buf, penv_display);
228
229    ok = 1;
230    e_util_library_path_strip();
231    exe = ecore_exe_run(cmd, NULL);
232    e_util_library_path_restore();
233    if (!exe)
234      {
235         e_util_dialog_show(_("Run Error"),
236                            _("Enlightenment was unable to fork a child process:<br>"
237                              "<br>"
238                              "%s<br>"),
239                            cmd);
240         ok = 0;
241      }
242
243    /* reset env vars */
244    if (penv_display)
245      {
246         e_util_env_set("DISPLAY", penv_display);
247         free(penv_display);
248      }
249    return ok;
250 }
251
252 EAPI int
253 e_util_strcmp(const char *s1, const char *s2)
254 {
255    if ((s1) && (s2))
256      return strcmp(s1, s2);
257    return 0x7fffffff;
258 }
259
260 EAPI int
261 e_util_both_str_empty(const char *s1, const char *s2)
262 {
263    int empty = 0;
264
265    if ((!s1) && (!s2)) return 1;
266    if ((!s1) || ((s1) && (s1[0] == 0))) empty++;
267    if ((!s2) || ((s2) && (s2[0] == 0))) empty++;
268    if (empty == 2) return 1;
269    return 0;
270 }
271
272 EAPI int
273 e_util_immortal_check(void)
274 {
275    Eina_List *wins;
276
277    wins = e_border_immortal_windows_get();
278    if (wins)
279      {
280         e_util_dialog_show(_("Cannot exit - immortal windows."),
281                            _("Some windows are left still around with the Lifespan lock enabled. This means<br>"
282                              "that Enlightenment will not allow itself to exit until these windows have<br>"
283                              "been closed or have the lifespan lock removed.<br>"));
284         /* FIXME: should really display a list of these lifespan locked */
285         /* windows in a dialog and let the user disable their locks in */
286         /* this dialog */
287         eina_list_free(wins);
288         return 1;
289      }
290    return 0;
291 }
292
293 EAPI int
294 e_util_edje_icon_list_check(const char *list)
295 {
296    char *buf;
297    const char *p;
298    const char *c;
299
300    if ((!list) || (!list[0])) return 0;
301    buf = alloca(strlen(list) + 1);
302    p = list;
303    while (p)
304      {
305         c = strchr(p, ',');
306         if (c)
307           {
308              strncpy(buf, p, c - p);
309              buf[c - p] = 0;
310              if (e_util_edje_icon_check(buf)) return 1;
311              p = c + 1;
312              if (!*p) return 0;
313           }
314         else
315           {
316              strcpy(buf, p);
317              if (e_util_edje_icon_check(buf)) return 1;
318              return 0;
319           }
320      }
321    return 0;
322 }
323
324 EAPI int
325 e_util_edje_icon_list_set(Evas_Object *obj, const char *list)
326 {
327    char *buf;
328    const char *p;
329    const char *c;
330
331    if ((!list) || (!list[0])) return 0;
332    buf = alloca(strlen(list) + 1);
333    p = list;
334    while (p)
335      {
336         c = strchr(p, ',');
337         if (c)
338           {
339              strncpy(buf, p, c - p);
340              buf[c - p] = 0;
341              if (e_util_edje_icon_set(obj, buf)) return 1;
342              p = c + 1;
343              if (!*p) return 0;
344           }
345         else
346           {
347              strcpy(buf, p);
348              if (e_util_edje_icon_set(obj, buf)) return 1;
349              return 0;
350           }
351      }
352    return 0;
353 }
354
355 EAPI int
356 e_util_menu_item_edje_icon_list_set(E_Menu_Item *mi, const char *list)
357 {
358    char *buf;
359    const char *p;
360    char *c;
361
362    if ((!list) || (!list[0])) return 0;
363    buf = alloca(strlen(list) + 1);
364    p = list;
365    while (p)
366      {
367         c = strchr(p, ',');
368         if (c)
369           {
370              strncpy(buf, p, c - p);
371              buf[c - p] = 0;
372              if (e_util_menu_item_theme_icon_set(mi, buf)) return 1;
373              p = c + 1;
374              if (!*p) return 0;
375           }
376         else
377           {
378              strcpy(buf, p);
379              if (e_util_menu_item_theme_icon_set(mi, buf)) return 1;
380              return 0;
381           }
382      }
383    return 0;
384 }
385
386 EAPI int
387 e_util_edje_icon_check(const char *name)
388 {
389    const char *file;
390    char buf[PATH_MAX];
391
392    if ((!name) || (!name[0])) return 0;
393    snprintf(buf, sizeof(buf), "e/icons/%s", name);
394    file = e_theme_edje_file_get("base/theme/icons", buf);
395    if (file[0]) return 1;
396    return 0;
397 }
398
399
400 /* WARNING This function is deprecated,. must be made static.
401  * You should use e_util_icon_theme_set instead
402  */
403 EAPI int
404 e_util_edje_icon_set(Evas_Object *obj, const char *name)
405 {
406    const char *file;
407    char buf[PATH_MAX];
408
409    if ((!name) || (!name[0])) return 0;
410    snprintf(buf, sizeof(buf), "e/icons/%s", name);
411    file = e_theme_edje_file_get("base/theme/icons", buf);
412    if (file[0])
413      {
414         edje_object_file_set(obj, file, buf);
415         return 1;
416      }
417    return 0;
418 }
419
420 static int
421 _e_util_icon_theme_set(Evas_Object *obj, const char *icon, Eina_Bool fallback)
422 {
423    const char *file;
424    char buf[PATH_MAX];
425
426    if ((!icon) || (!icon[0])) return 0;
427    snprintf(buf, sizeof(buf), "e/icons/%s", icon);
428
429    if (fallback)
430      file = e_theme_edje_icon_fallback_file_get(buf);
431    else
432      file = e_theme_edje_file_get("base/theme/icons", buf);
433
434    if (file[0])
435      {
436         e_icon_file_edje_set(obj, file, buf);
437         return 1;
438      }
439
440    return 0;
441 }
442
443 static int
444 _e_util_icon_fdo_set(Evas_Object *obj, const char *icon)
445 {
446    const char *path = NULL;
447    unsigned int size;
448    
449    if ((!icon) || (!icon[0])) return 0;
450    size = e_icon_scale_size_get(obj);
451    if (size < 16) size = 16;
452    size = e_util_icon_size_normalize(size * e_scale);
453
454    path = efreet_icon_path_find(e_config->icon_theme, icon, size);
455    if (!path) return 0;
456
457    e_icon_file_set(obj, path);
458    return 1;
459 }
460
461 /* use e_icon_size_scale_set(obj, size) to set the preferred icon size */
462 EAPI int
463 e_util_icon_theme_set(Evas_Object *obj, const char *icon)
464 {
465    if (e_config->icon_theme_overrides)
466      {
467         if (_e_util_icon_fdo_set(obj, icon))
468           return 1;
469         if (_e_util_icon_theme_set(obj, icon, EINA_FALSE))
470           return 1;
471         return _e_util_icon_theme_set(obj, icon, EINA_TRUE);
472      }
473    else
474      {
475         if (_e_util_icon_theme_set(obj, icon, EINA_FALSE))
476           return 1;
477         if (_e_util_icon_fdo_set(obj, icon))
478           return 1;
479         return _e_util_icon_theme_set(obj, icon, EINA_TRUE);
480      }
481 }
482
483 int
484 _e_util_menu_item_edje_icon_set(E_Menu_Item *mi, const char *name, Eina_Bool fallback)
485 {
486    const char *file;
487    char buf[PATH_MAX];
488
489    if ((!name) || (!name[0])) return 0;
490
491    if ((!fallback) && (name[0]=='/') && ecore_file_exists(name))
492      {
493         e_menu_item_icon_edje_set(mi, name, "icon");
494         return 1;
495      }
496    snprintf(buf, sizeof(buf), "e/icons/%s", name);
497
498    if (fallback)
499      file = e_theme_edje_icon_fallback_file_get(buf);
500    else
501      file = e_theme_edje_file_get("base/theme/icons", buf);
502
503    if (file[0])
504      {
505         e_menu_item_icon_edje_set(mi, file, buf);
506         return 1;
507      }
508    return 0;
509 }
510
511 EAPI unsigned int
512 e_util_icon_size_normalize(unsigned int desired)
513 {
514    const unsigned int *itr, known_sizes[] =
515      {
516         16, 22, 24, 32, 36, 48, 64, 72, 96, 128, 192, 256, -1
517      };
518
519    for (itr = known_sizes; *itr > 0; itr++)
520      if (*itr >= desired)
521        return *itr;
522
523    return 256; /* largest know size? */
524 }
525
526 static int
527 _e_util_menu_item_fdo_icon_set(E_Menu_Item *mi, const char *icon)
528 {
529    const char *path = NULL;
530    unsigned int size;
531
532    if ((!icon) || (!icon[0])) return 0;
533    size = e_util_icon_size_normalize(24 * e_scale);
534    path = efreet_icon_path_find(e_config->icon_theme, icon, size);
535    if (!path) return 0;
536    e_menu_item_icon_file_set(mi, path);
537    return 1;
538 }
539
540 EAPI int
541 e_util_menu_item_theme_icon_set(E_Menu_Item *mi, const char *icon)
542 {
543    if (e_config->icon_theme_overrides)
544      {
545         if (_e_util_menu_item_fdo_icon_set(mi, icon))
546           return 1;
547         if (_e_util_menu_item_edje_icon_set(mi, icon, EINA_FALSE))
548           return 1;
549         return _e_util_menu_item_edje_icon_set(mi, icon, EINA_TRUE);
550      }
551    else
552      {
553         if (_e_util_menu_item_edje_icon_set(mi, icon, EINA_FALSE))
554           return 1;
555         if (_e_util_menu_item_fdo_icon_set(mi, icon))
556           return 1;
557         return _e_util_menu_item_edje_icon_set(mi, icon, EINA_TRUE);
558      }
559 }
560
561 EAPI E_Container *
562 e_util_container_window_find(Ecore_X_Window win)
563 {
564    Eina_List *l, *ll;
565    E_Manager *man;
566    E_Container *con;
567
568    EINA_LIST_FOREACH(e_manager_list(), l, man)
569      {
570         EINA_LIST_FOREACH(man->containers, ll, con)
571           {
572              if ((con->win == win) || (con->bg_win == win) ||
573                  (con->event_win == win))
574                return con;
575           }
576      }
577    return NULL;
578 }
579
580 EAPI E_Zone *
581 e_util_zone_window_find(Ecore_X_Window win)
582 {
583    Eina_List *l, *ll, *lll;
584    E_Manager *man;
585    E_Container *con;
586    E_Zone *zone;
587
588    EINA_LIST_FOREACH(e_manager_list(), l, man)
589      EINA_LIST_FOREACH(man->containers, ll, con)
590        EINA_LIST_FOREACH(con->zones, lll, zone)
591          if (zone->black_win == win) return zone;
592
593    return NULL;
594 }
595
596 EAPI E_Border *
597 e_util_desk_border_above(E_Border *bd)
598 {
599    E_Border *bd2, *above = NULL;
600    Eina_List *l;
601    int pos, i;
602
603    E_OBJECT_CHECK_RETURN(bd, NULL);
604    E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
605
606    if (bd->layer == 0) pos = 0;
607    else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
608    else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
609    else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
610    else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
611    else pos = 5;
612
613    EINA_LIST_FOREACH(eina_list_data_find_list(bd->zone->container->layers[pos].clients, bd), l, bd2)
614      {
615         if(!eina_list_next(l) || above) break;
616         above = eina_list_data_get(eina_list_next(l));
617         if ((above->desk != bd->desk) && (!above->sticky))
618           above = NULL;
619      }
620    if (!above)
621      {
622         /* Need to check the layers above */
623         for (i = pos + 1; (i < 7) && (!above); i++)
624           {
625              EINA_LIST_FOREACH(bd->zone->container->layers[i].clients, l, bd2)
626                {
627                   if (above) break;
628                   above = bd2;
629                   if ((above->desk != bd->desk) && (!above->sticky))
630                     above = NULL;
631                }
632           }
633      }
634    return above;
635 }
636
637 EAPI E_Border *
638 e_util_desk_border_below(E_Border *bd)
639 {
640    E_Border *below = NULL, *bd2;
641    Eina_List *l;
642    int pos, i;
643
644    E_OBJECT_CHECK_RETURN(bd, NULL);
645    E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
646
647    if (bd->layer == 0) pos = 0;
648    else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
649    else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
650    else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
651    else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
652    else pos = 5;
653
654    for (l = eina_list_data_find_list(bd->zone->container->layers[pos].clients, bd); l; l = l->prev)
655      {
656         if (!eina_list_prev(l) || below) break;
657         below = eina_list_data_get(eina_list_prev(l));
658         if ((below->desk != bd->desk) && (!below->sticky))
659           below = NULL;
660      }
661    if (!below)
662      {
663         /* Need to check the layers below */
664         for (i = pos - 1; (i >= 0) && (!below); i--)
665           {
666              if (bd->zone->container->layers[i].clients)
667                {
668                   l = eina_list_data_find_list(bd->zone->container->layers[pos].clients, bd);
669                   for (; l && !below; l = l->prev)
670                     {
671                        bd2 = l->data;
672                        below = bd2;
673                        if ((below->desk != bd->desk) && (!below->sticky))
674                          below = NULL;
675                     }
676                }
677           }
678      }
679
680    return below;
681 }
682
683 EAPI int
684 e_util_edje_collection_exists(const char *file, const char *coll)
685 {
686    Eina_List *clist, *l;
687    char *str;
688
689    clist = edje_file_collection_list(file);
690    EINA_LIST_FOREACH(clist, l, str)
691      {
692         if (!strcmp(coll, str))
693           {
694              edje_file_collection_list_free(clist);
695              return 1;
696           }
697      }
698    edje_file_collection_list_free(clist);
699    return 0;
700 }
701
702 EAPI void
703 e_util_dialog_internal(const char *title, const char *txt)
704 {
705    E_Dialog *dia;
706
707    dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_error_dialog");
708    if (!dia) return;
709    e_dialog_title_set(dia, title);
710    e_dialog_text_set(dia, txt);
711    e_dialog_icon_set(dia, "dialog-error", 64);
712    e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
713    e_dialog_button_focus_num(dia, 0);
714    e_win_centered_set(dia->win, 1);
715    e_dialog_show(dia);
716 }
717
718 EAPI const char *
719 e_util_filename_escape(const char *filename)
720 {
721    const char *p;
722    char *q;
723    static char buf[PATH_MAX];
724
725    if (!filename) return NULL;
726    p = filename;
727    q = buf;
728    while (*p)
729      {
730         if ((q - buf) > 4090) return NULL;
731         if (
732             (*p == ' ') || (*p == '\t') || (*p == '\n') ||
733             (*p == '\\') || (*p == '\'') || (*p == '\"') ||
734             (*p == ';') || (*p == '!') || (*p == '#') ||
735             (*p == '$') || (*p == '%') || (*p == '&') ||
736             (*p == '*') || (*p == '(') || (*p == ')') ||
737             (*p == '[') || (*p == ']') || (*p == '{') ||
738             (*p == '}') || (*p == '|') || (*p == '<') ||
739             (*p == '>') || (*p == '?')
740             )
741           {
742              *q = '\\';
743              q++;
744           }
745         *q = *p;
746         q++;
747         p++;
748      }
749    *q = 0;
750    return buf;
751 }
752
753 EAPI int
754 e_util_icon_save(Ecore_X_Icon *icon, const char *filename)
755 {
756    Ecore_Evas *ee;
757    Evas *evas;
758    Evas_Object *im;
759    int ret;
760
761    ee = ecore_evas_buffer_new(icon->width, icon->height);
762    if (!ee) return 0;
763    evas = ecore_evas_get(ee);
764    evas_image_cache_set(evas, 0);
765    evas_font_cache_set(evas, 0);
766
767    im = evas_object_image_add(evas);
768    if (!im)
769      {
770         ecore_evas_free(ee);
771         return 0;
772      }
773    evas_object_move(im, 0, 0);
774    evas_object_resize(im, icon->width, icon->height);
775    evas_object_image_size_set(im, icon->width, icon->height);
776    evas_object_image_data_copy_set(im, icon->data);
777    evas_object_image_alpha_set(im, 1);
778    evas_object_show(im);
779    ret = evas_object_image_save(im, filename, NULL, NULL);
780    evas_object_del(im);
781    ecore_evas_free(ee);
782    return ret;
783 }
784
785 EAPI char *
786 e_util_shell_env_path_eval(const char *path)
787 {
788    /* evaluate things like:
789     * $HOME/bling -> /home/user/bling
790     * $HOME/bin/$HOSTNAME/blah -> /home/user/bin/localhost/blah
791     * etc. etc.
792     */
793    const char *p, *v2, *v1 = NULL;
794    char buf[PATH_MAX], *pd, *s, *vp;
795    char *v = NULL;
796    int esc = 0, invar = 0;
797
798    for (p = path, pd = buf; (pd < (buf + sizeof(buf) - 1)); p++)
799      {
800         if (invar)
801           {
802              if (!((isalnum(*p)) || (*p == '_')))
803                {
804                   v2 = p;
805                   invar = 0;
806                   if ((v2 - v1) > 1)
807                     {
808                        s = alloca(v2 - v1);
809                        strncpy(s, v1 + 1, v2 - v1 - 1);
810                        s[v2 - v1 - 1] = 0;
811                        if (strncmp(s, "XDG", 3))
812                          v = getenv(s);
813                        else
814                          {
815                             if (!strcmp(s, "XDG_CONFIG_HOME"))
816                               v = (char *)efreet_config_home_get();
817                             else if (!strcmp(s, "XDG_CACHE_HOME"))
818                               v = (char *)efreet_cache_home_get();
819                             else if (!strcmp(s, "XDG_DATA_HOME"))
820                               v = (char *)efreet_data_home_get();
821                          }
822
823                        if (v)
824                          {
825                             vp = v;
826                             while ((*vp) && (pd < (buf + sizeof(buf) - 1)))
827                               {
828                                  *pd = *vp;
829                                  vp++;
830                                  pd++;
831                               }
832                          }
833                     }
834                   if (pd < (buf + sizeof(buf) - 1))
835                     {
836                        *pd = *p;
837                        pd++;
838                     }
839                }
840           }
841         else
842           {
843              if (esc)
844                {
845                   *pd = *p;
846                   pd++;
847                }
848              else
849                {
850                   if (*p == '\\') esc = 1;
851                   else if (*p == '$')
852                     {
853                        invar = 1;
854                        v1 = p;
855                     }
856                   else
857                     {
858                        *pd = *p;
859                        pd++;
860                     }
861                }
862           }
863         if (*p == 0) break;
864      }
865    *pd = 0;
866    return strdup(buf);
867 }
868
869 EAPI char *
870 e_util_size_string_get(off_t size)
871 {
872    double dsize;
873    char buf[256];
874
875    dsize = (double)size;
876    if (dsize < 1024.0) snprintf(buf, sizeof(buf), _("%'.0f Bytes"), dsize);
877    else
878      {
879         dsize /= 1024.0;
880         if (dsize < 1024) snprintf(buf, sizeof(buf), _("%'.0f KB"), dsize);
881         else
882           {
883              dsize /= 1024.0;
884              if (dsize < 1024) snprintf(buf, sizeof(buf), _("%'.0f MB"), dsize);
885              else
886                {
887                   dsize /= 1024.0;
888                   snprintf(buf, sizeof(buf), _("%'.1f GB"), dsize);
889                }
890           }
891      }
892    return strdup(buf);
893 }
894
895 EAPI char *
896 e_util_file_time_get(time_t ftime)
897 {
898    time_t diff;
899    time_t ltime;
900    char buf[256];
901    char *s = NULL;
902
903    ltime = time(NULL);
904    diff = ltime - ftime;
905    buf[0] = 0;
906    if (ftime > ltime)
907      snprintf(buf, sizeof(buf), _("In the Future"));
908    else
909      {
910         if (diff <= 60)
911           snprintf(buf, sizeof(buf), _("In the last Minute"));
912         else if (diff >= 31526000)
913           snprintf(buf, sizeof(buf), _("%li Years ago"), (diff / 31526000));
914         else if (diff >= 2592000)
915           snprintf(buf, sizeof(buf), _("%li Months ago"), (diff / 2592000));
916         else if (diff >= 604800)
917           snprintf(buf, sizeof(buf), _("%li Weeks ago"), (diff / 604800));
918         else if (diff >= 86400)
919           snprintf(buf, sizeof(buf), _("%li Days ago"), (diff / 86400));
920         else if (diff >= 3600)
921           snprintf(buf, sizeof(buf), _("%li Hours ago"), (diff / 3600));
922         else if (diff > 60)
923           snprintf(buf, sizeof(buf), _("%li Minutes ago"), (diff / 60));
924      }
925
926    if (buf[0])
927      s = strdup(buf);
928    else
929      s = strdup(_("Unknown"));
930    return s;
931 }
932
933 static char *prev_ld_library_path = NULL;
934 static char *prev_path = NULL;
935
936 EAPI void
937 e_util_library_path_strip(void)
938 {
939    char *p, *p2;
940
941    p = getenv("LD_LIBRARY_PATH");
942    E_FREE(prev_ld_library_path);
943    if (p)
944      {
945         prev_ld_library_path = strdup(p);
946         p2 = strchr(p, ':');
947         if (p2) p2++;
948         e_util_env_set("LD_LIBRARY_PATH", p2);
949      }
950    p = getenv("PATH");
951    E_FREE(prev_path);
952    if (p)
953      {
954         prev_path = strdup(p);
955         p2 = strchr(p, ':');
956         if (p2) p2++;
957         e_util_env_set("PATH", p2);
958      }
959 }
960
961 EAPI void
962 e_util_library_path_restore(void)
963 {
964    if (prev_ld_library_path)
965      {
966         e_util_env_set("LD_LIBRARY_PATH", prev_ld_library_path);
967         E_FREE(prev_ld_library_path);
968      }
969    if (prev_path)
970      {
971         e_util_env_set("PATH", prev_path);
972         E_FREE(prev_path);
973      }
974 }
975
976 EAPI Evas_Object *
977 e_util_icon_add(const char *path, Evas *evas)
978 {
979    return _e_util_icon_add(path, evas, 64); 
980 }
981
982 EAPI Evas_Object *
983 e_util_desktop_icon_add(Efreet_Desktop *desktop, unsigned int size, Evas *evas)
984 {
985    if ((!desktop) || (!desktop->icon)) return NULL;
986    return e_util_icon_theme_icon_add(desktop->icon, size, evas);
987 }
988
989 EAPI Evas_Object *
990 e_util_icon_theme_icon_add(const char *icon_name, unsigned int size, Evas *evas)
991 {
992    if (!icon_name) return NULL;
993    if (icon_name[0] == '/') return e_util_icon_add(icon_name, evas);
994    else
995      {
996         Evas_Object *obj;
997         const char *path;
998
999         path = efreet_icon_path_find(e_config->icon_theme, icon_name, size);
1000         if (path)
1001           {
1002              obj = _e_util_icon_add(path, evas, size);
1003              return obj;
1004           }
1005      }
1006    return NULL;
1007 }
1008
1009 EAPI void
1010 e_util_desktop_menu_item_icon_add(Efreet_Desktop *desktop, unsigned int size, E_Menu_Item *mi)
1011 {
1012    const char *path = NULL;
1013
1014    if ((!desktop) || (!desktop->icon)) return;
1015
1016    if (desktop->icon[0] == '/') path = desktop->icon;
1017    else path = efreet_icon_path_find(e_config->icon_theme, desktop->icon, size);
1018
1019    if (path)
1020      {
1021         const char *ext;
1022
1023         ext = strrchr(path, '.');
1024         if (ext)
1025           {
1026              if (strcmp(ext, ".edj") == 0)
1027                e_menu_item_icon_edje_set(mi, path, "icon");
1028              else
1029                e_menu_item_icon_file_set(mi, path);
1030           }
1031         else
1032           e_menu_item_icon_file_set(mi, path);
1033      }
1034 }
1035
1036 EAPI int
1037 e_util_dir_check(const char *dir)
1038 {
1039    if (!ecore_file_exists(dir))
1040      {
1041         if (!ecore_file_mkpath(dir))
1042           {
1043              e_util_dialog_show("Error creating directory", "Failed to create directory: %s .<br>Check that you have correct permissions set.", dir);
1044              return 0;
1045           }
1046      }
1047    else
1048      {
1049         if (!ecore_file_is_dir(dir))
1050           {
1051              e_util_dialog_show("Error creating directory", "Failed to create directory: %s .<br>A file of that name already exists.", dir);
1052              return 0;
1053           }
1054      }
1055    return 1;
1056 }
1057
1058 EAPI void
1059 e_util_defer_object_del(E_Object *obj)
1060 {
1061    if (stopping)
1062      e_object_del(obj);
1063    else
1064      ecore_idle_enterer_before_add(_e_util_cb_delayed_del, obj);
1065 }
1066
1067 EAPI const char *
1068 e_util_winid_str_get(Ecore_X_Window win)
1069 {
1070    const char *vals = "qWeRtYuIoP5-$&<~";
1071    static char id[9];
1072    unsigned int val;
1073
1074    val = (unsigned int)win;
1075    id[0] = vals[(val >> 28) & 0xf];
1076    id[1] = vals[(val >> 24) & 0xf];
1077    id[2] = vals[(val >> 20) & 0xf];
1078    id[3] = vals[(val >> 16) & 0xf];
1079    id[4] = vals[(val >> 12) & 0xf];
1080    id[5] = vals[(val >>  8) & 0xf];
1081    id[6] = vals[(val >>  4) & 0xf];
1082    id[7] = vals[(val      ) & 0xf];
1083    id[8] = 0;
1084    return id;
1085 }
1086
1087 static int
1088 _win_auto_size_calc(int max, int min)
1089 {
1090    const float *itr, scales[] = {0.25, 0.3, 0.5, 0.75, 0.8, 0.9, 0.95, -1};
1091
1092    for (itr = scales; *itr > 0; itr++)
1093      {
1094         int value = *itr * max;
1095         if (value > min) /* not >=, try a bit larger */
1096           return value;
1097      }
1098
1099    return min;
1100 }
1101
1102 EAPI void
1103 e_util_win_auto_resize_fill(E_Win *win)
1104 {
1105    E_Zone *zone = NULL;
1106
1107    if (win->border)
1108      zone = win->border->zone;
1109    if ((!zone) && (win->container))
1110      zone = e_util_zone_current_get(win->container->manager);
1111
1112    if (zone)
1113      {
1114         int w, h;
1115
1116         e_zone_useful_geometry_get(zone, NULL, NULL, &w, &h);
1117
1118         w = _win_auto_size_calc(w, win->min_w);
1119         h = _win_auto_size_calc(h, win->min_h);
1120         e_win_resize(win, w, h);
1121      }
1122 }
1123
1124 /**
1125  * Creates a new dialog to query image import settings, report results.
1126  *
1127  * @param path may be used to display live preview (not used so far).
1128  * @param cb function to call before exit. Last parameter is mode of
1129  *        image filling.
1130  * @param data extra data to give to @a cb as first argument.
1131  *
1132  * @return newly allocated window on success, @c NULL on failure. If
1133  *         @c NULL is returned, then callback is never called!
1134  */
1135 EAPI E_Dialog *
1136 e_util_image_import_settings_new(const char *path, void (*cb)(void *data, const char *path, Eina_Bool ok, Eina_Bool external, int quality, E_Image_Import_Mode mode), const void *data)
1137 {
1138    Evas *evas;
1139    E_Util_Image_Import_Settings *ctxt;
1140    Evas_Object *vlist, *frame, *radio, *check, *slider;
1141    E_Radio_Group *rg;
1142    Evas_Coord w, h;
1143
1144    if (!path) return NULL;
1145    if (!cb) return NULL;
1146
1147    ctxt = E_NEW(E_Util_Image_Import_Settings, 1);
1148    if (!ctxt) return NULL;
1149
1150    ctxt->dia = e_dialog_new(NULL, "E", "_image_import_settings");
1151    if (!ctxt->dia)
1152      {
1153         E_FREE(ctxt);
1154         return NULL;
1155      }
1156
1157    ctxt->dia->data = ctxt;
1158
1159    e_object_del_attach_func_set
1160      (E_OBJECT(ctxt->dia), _e_util_image_import_settings_del);
1161    e_dialog_title_set(ctxt->dia, _("Image Import Settings"));
1162    e_dialog_border_icon_set(ctxt->dia, "dialog-ask");
1163
1164    e_dialog_button_add
1165      (ctxt->dia, _("Import"), NULL, _e_util_image_import_settings_do, ctxt);
1166    e_dialog_button_add
1167      (ctxt->dia, _("Cancel"), NULL, NULL, ctxt);
1168    e_dialog_button_focus_num(ctxt->dia, 0);
1169
1170    ctxt->cb.func = cb;
1171    ctxt->cb.data = (void *)data;
1172    ctxt->path = eina_stringshare_add(path);
1173    ctxt->quality = 90;
1174    ctxt->ok = EINA_FALSE;
1175    ctxt->external = EINA_FALSE;
1176    ctxt->mode = E_IMAGE_IMPORT_STRETCH;
1177
1178    evas = e_win_evas_get(ctxt->dia->win);
1179
1180    vlist = e_widget_list_add(evas, 0, 0);
1181
1182    frame = e_widget_frametable_add(evas, _("Fill and Stretch Options"), 1);
1183    rg = e_widget_radio_group_new(&ctxt->mode);
1184
1185 #define RD(lbl, icon, val, col, row)                                    \
1186    radio = e_widget_radio_icon_add                                      \
1187      (evas, lbl, "enlightenment/wallpaper_"icon, 24, 24, val, rg);      \
1188    e_widget_frametable_object_append(frame, radio, col, row, 1, 1, 1, 1, 0, 0)
1189
1190    RD(_("Stretch"), "stretch", E_IMAGE_IMPORT_STRETCH, 0, 0);
1191    RD(_("Center"), "center", E_IMAGE_IMPORT_CENTER, 1, 0);
1192    RD(_("Title"), "tile", E_IMAGE_IMPORT_TILE, 2, 0);
1193    RD(_("Within"), "scale_aspect_in", E_IMAGE_IMPORT_SCALE_ASPECT_IN, 3, 0);
1194    RD(_("Fill"), "scale_aspect_out", E_IMAGE_IMPORT_SCALE_ASPECT_OUT, 4, 0);
1195 #undef RD
1196
1197    e_widget_list_object_append(vlist, frame, 1, 1, 0.5);
1198
1199    frame = e_widget_frametable_add(evas, _("File Quality"), 0);
1200
1201    check = e_widget_check_add(evas, _("Use original file"), &ctxt->external);
1202    e_widget_frametable_object_append(frame, check, 0, 0, 1, 1, 1, 0, 1, 0);
1203
1204    slider = e_widget_slider_add
1205      (evas, 1, 0, _("%3.0f%%"), 0.0, 100.0, 1.0, 0, NULL, &ctxt->quality, 150);
1206    e_widget_frametable_object_append(frame, slider, 0, 1, 1, 1, 1, 0, 1, 0);
1207
1208    e_widget_list_object_append(vlist, frame, 1, 1, 0.5);
1209
1210    e_widget_size_min_get(vlist, &w, &h);
1211    w += 50;
1212    e_dialog_content_set(ctxt->dia, vlist, w, h);
1213
1214    e_win_centered_set(ctxt->dia->win, 1);
1215
1216    return ctxt->dia;
1217 }
1218
1219 /**
1220  * Request given image to be imported as an edje file.
1221  *
1222  * This is useful to convert images to icons and background.
1223  *
1224  * @param image_path path to source image to use.
1225  * @param edje_path path to destination edje to generate.
1226  * @param external if @c EINA_TRUE, then it will not embed image into edje,
1227  *        but reference the original @a image_path.
1228  * @param quality quality value from 0-100.
1229  * @param mode how to resize image with edje.
1230  * @param cb function to callback when process finishes.
1231  * @param data extra context to give to callback.
1232  *
1233  * @return handle so one can cancel the operation. This handle will be
1234  *         invalid after @a cb is called!
1235  */
1236 EAPI E_Util_Image_Import_Handle *
1237 e_util_image_import(const char *image_path, const char *edje_path, const char *edje_group, Eina_Bool external, int quality, E_Image_Import_Mode mode, void (*cb)(void *data, Eina_Bool ok, const char *image_path, const char *edje_path), const void *data)
1238 {
1239    static const char *tmpdir = NULL;
1240    E_Util_Image_Import_Handle *handle;
1241    Ecore_Evas *ee;
1242    Evas_Object *img;
1243    int fd, w, h;
1244    const char *escaped_file;
1245    char cmd[PATH_MAX * 2], tmpn[PATH_MAX];
1246    FILE *f;
1247
1248    if (!image_path) return NULL;
1249    if (!edje_path) return NULL;
1250    if (!edje_group) return NULL;
1251    if (!cb) return NULL;
1252    ee = ecore_evas_buffer_new(1, 1);
1253    img = evas_object_image_add(ecore_evas_get(ee));
1254    evas_object_image_file_set(img, image_path, NULL);
1255    if (evas_object_image_load_error_get(img) != EVAS_LOAD_ERROR_NONE)
1256      {
1257         ecore_evas_free(ee);
1258         printf("Error loading image '%s'\n", image_path);
1259         return NULL;
1260      }
1261    evas_object_image_size_get(img, &w, &h);
1262    ecore_evas_free(ee);
1263
1264    if (!tmpdir)
1265      {
1266         tmpdir = getenv("TMPDIR");
1267         if (!tmpdir) tmpdir = "/tmp";
1268      }
1269    snprintf(tmpn, sizeof(tmpn), "%s/e_util_image_import-XXXXXX", tmpdir);
1270    fd = mkstemp(tmpn);
1271    if (fd < 0)
1272      {
1273         printf("Error Creating tmp file: %s\n", strerror(errno));
1274         return NULL;
1275      }
1276
1277    f = fdopen(fd, "wb");
1278    if (!f)
1279      {
1280         printf("Cannot open %s for writing\n", tmpn);
1281         close(fd);
1282         return NULL;
1283      }
1284
1285    escaped_file = e_util_filename_escape(image_path); // watch out ret buffer!
1286
1287    fprintf(f, "images.image: \"%s\" ", escaped_file);
1288    if (external)
1289      fputs("USER", f);
1290    else if (quality >= 100)
1291      fputs("COMP", f);
1292    else
1293      fprintf(f, "LOSSY %d", (quality > 1) ? quality : 90);
1294
1295    fprintf(f,
1296            ";\n"
1297            "collections {\n"
1298            "   group {\n"
1299            "      name: \"%s\";\n"
1300            "      data.item: \"style\" \"%d\";\n"
1301            "      max: %d %d;\n"
1302            "      parts {\n",
1303            edje_group, mode, w, h);
1304
1305    if ((mode == E_IMAGE_IMPORT_CENTER) ||
1306        (mode == E_IMAGE_IMPORT_SCALE_ASPECT_IN))
1307      {
1308         fputs("         part {\n"
1309               "            type: RECT;\n"
1310               "            name: \"col\";\n"
1311               "            mouse_events: 0;\n"
1312               "            description {\n"
1313               "               state: \"default\" 0.0;\n"
1314               "               color: 255 255 255 255;\n"
1315               "            }\n"
1316               "         }\n",
1317               f);
1318      }
1319
1320    fprintf(f,
1321            "         part {\n"
1322            "            type: IMAGE;\n"
1323            "            name: \"image\";\n"
1324            "            mouse_events: 0;\n"
1325            "            description {\n"
1326            "               state: \"default\" 0.0;\n"
1327            "               image {\n"
1328            "                  normal: \"%s\";\n"
1329            "                  scale_hint: STATIC;\n"
1330            "               }\n",
1331            escaped_file);
1332
1333    if (mode == E_IMAGE_IMPORT_TILE)
1334      {
1335         fprintf(f,
1336                 "               fill {\n"
1337                 "                  size {\n"
1338                 "                     relative: 0.0 0.0;\n"
1339                 "                     offset: %d %d;\n"
1340                 "                  }\n"
1341                 "               }\n",
1342                 w, h);
1343      }
1344    else if (mode == E_IMAGE_IMPORT_CENTER)
1345      {
1346         fprintf(f,
1347                 "               min: %d %d;\n"
1348                 "               max: %d %d;\n",
1349                 w, h, w, h);
1350
1351      }
1352    else if ((mode == E_IMAGE_IMPORT_SCALE_ASPECT_IN) ||
1353             (mode == E_IMAGE_IMPORT_SCALE_ASPECT_OUT))
1354      {
1355         const char *locale = e_intl_language_get();
1356         double aspect = (double)w / (double)h;
1357         setlocale(LC_NUMERIC, "C");
1358         fprintf(f,
1359                 "               aspect: %1.9f %1.9f;\n"
1360                 "               aspect_preference: %s;\n",
1361                 aspect, aspect,
1362                 (mode == E_IMAGE_IMPORT_SCALE_ASPECT_IN) ? "BOTH" : "NONE");
1363         setlocale(LC_NUMERIC, locale);
1364      }
1365
1366    fputs("            }\n" // description
1367          "         }\n"    // part
1368          "      }\n"       // parts
1369          "   }\n"          // group
1370          "}\n",            // collections
1371          f);
1372
1373    fclose(f); // fd gets closed here
1374
1375    snprintf(cmd, sizeof(cmd), "edje_cc %s %s",
1376             tmpn, e_util_filename_escape(edje_path));
1377
1378    handle = E_NEW(E_Util_Image_Import_Handle, 1);
1379    if (!handle)
1380      {
1381         unlink(tmpn);
1382         return NULL;
1383      }
1384
1385    handle->cb.func = cb;
1386    handle->cb.data = (void *)data;
1387    handle->path.image = eina_stringshare_add(image_path);
1388    handle->path.edje = eina_stringshare_add(edje_path);
1389    handle->path.temp = eina_stringshare_add(tmpn);
1390    handle->handler = ecore_event_handler_add
1391      (ECORE_EXE_EVENT_DEL, _e_util_image_import_exit, handle);
1392    handle->exe = ecore_exe_run(cmd, NULL);
1393    if (!handle->exe)
1394      {
1395         _e_util_image_import_handle_free(handle);
1396         return NULL;
1397      }
1398
1399    return handle;
1400 }
1401
1402 EAPI void
1403 e_util_image_import_cancel(E_Util_Image_Import_Handle *handle)
1404 {
1405    if (!handle) return;
1406    ecore_exe_kill(handle->exe);
1407 }
1408
1409 EAPI int
1410 e_util_container_desk_count_get(E_Container *con)
1411 {
1412    Eina_List *zl;
1413    E_Zone *zone;
1414    int count = 0;
1415
1416    E_OBJECT_CHECK_RETURN(con, 0);
1417    E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, 0);
1418    EINA_LIST_FOREACH(con->zones, zl, zone)
1419      {
1420         int x, y;
1421         int cx = 0, cy = 0;
1422
1423         e_zone_desk_count_get(zone, &cx, &cy);
1424         for (x = 0; x < cx; x++)
1425           {
1426              for (y = 0; y < cy; y++)
1427                count += 1;
1428           }
1429      }
1430    return count;
1431 }
1432
1433 /* local subsystem functions */
1434
1435 static Evas_Object *
1436 _e_util_icon_add(const char *path, Evas *evas, int size)
1437 {
1438    Evas_Object *o = NULL;
1439    const char *ext;
1440
1441    if (!path) return NULL;
1442    if (!ecore_file_exists(path)) return NULL;
1443
1444    o = e_icon_add(evas);
1445    e_icon_scale_size_set(o, size); 
1446    e_icon_preload_set(o, 1);
1447    ext = strrchr(path, '.');
1448    if (ext)
1449      {
1450         if (!strcmp(ext, ".edj"))
1451           e_icon_file_edje_set(o, path, "icon");
1452         else
1453           e_icon_file_set(o, path);
1454      }
1455    else
1456      e_icon_file_set(o, path);
1457    e_icon_fill_inside_set(o, 1);
1458
1459    return o;
1460 }
1461
1462 static Eina_Bool
1463 _e_util_cb_delayed_del(void *data)
1464 {
1465    e_object_del(E_OBJECT(data));
1466    return ECORE_CALLBACK_CANCEL;
1467 }
1468
1469 static Eina_Bool
1470 _e_util_wakeup_cb(void *data __UNUSED__)
1471 {
1472    _e_util_dummy_timer = NULL;
1473    return ECORE_CALLBACK_CANCEL;
1474 }
1475
1476 static void
1477 _e_util_image_import_settings_do(void *data, E_Dialog *dia)
1478 {
1479    E_Util_Image_Import_Settings *ctxt = data;
1480
1481    ctxt->ok = EINA_TRUE;
1482    e_util_defer_object_del(E_OBJECT(dia));
1483 }
1484
1485 static void
1486 _e_util_image_import_settings_del(void *obj)
1487 {
1488    E_Dialog *dia = obj;
1489    E_Util_Image_Import_Settings *ctxt = dia->data;
1490
1491    ctxt->cb.func(ctxt->cb.data, ctxt->path,
1492                  ctxt->ok, ctxt->external, ctxt->quality, ctxt->mode);
1493
1494    eina_stringshare_del(ctxt->path);
1495    E_FREE(ctxt);
1496 }
1497
1498 static Eina_Bool
1499 _e_util_image_import_exit(void *data, int type __UNUSED__, void *event)
1500 {
1501    E_Util_Image_Import_Handle *handle = data;
1502    Ecore_Exe_Event_Del *ev = event;
1503    Eina_Bool ok;
1504
1505    if (ev->exe != handle->exe) return ECORE_CALLBACK_PASS_ON;
1506
1507    ok = (ev->exit_code == 0);
1508
1509    if (!ok) unlink(handle->path.edje);
1510    handle->cb.func(handle->cb.data, ok, handle->path.image, handle->path.edje);
1511
1512    _e_util_image_import_handle_free(handle);
1513
1514    return ECORE_CALLBACK_CANCEL;
1515 }
1516
1517 static void
1518 _e_util_image_import_handle_free(E_Util_Image_Import_Handle *handle)
1519 {
1520    unlink(handle->path.temp);
1521    eina_stringshare_del(handle->path.image);
1522    eina_stringshare_del(handle->path.edje);
1523    eina_stringshare_del(handle->path.temp);
1524    if (handle->handler) ecore_event_handler_del(handle->handler);
1525    E_FREE(handle);
1526 }
1527
1528 static Eina_Bool
1529 _e_util_conf_timer_old(void *data)
1530 {
1531    char *module_name = data;
1532    char buf[PATH_MAX];
1533    char *msg =
1534      _("Configuration data needed "
1535        "upgrading. Your old configuration<br> has been"
1536        " wiped and a new set of defaults initialized. "
1537        "This<br>will happen regularly during "
1538        "development, so don't report a<br>bug. "
1539        "This simply means the module needs "
1540        "new configuration<br>data by default for "
1541        "usable functionality that your old<br>"
1542        "configuration simply lacks. This new set of "
1543        "defaults will fix<br>that by adding it in. "
1544        "You can re-configure things now to your<br>"
1545        "liking. Sorry for the inconvenience.<br>");
1546
1547    snprintf(buf, sizeof(buf),N_("%s Configuration Updated"), module_name);
1548    e_util_dialog_internal(buf, msg);
1549    E_FREE(module_name);
1550
1551    return ECORE_CALLBACK_CANCEL;
1552 }
1553
1554 static Eina_Bool
1555 _e_util_conf_timer_new(void *data)
1556 {
1557    char *module_name = data;
1558    char buf[4096];
1559    char *msg =
1560      _("Your module configuration is NEWER "
1561        "than the module version. This is "
1562        "very<br>strange. This should not happen unless"
1563        " you downgraded<br>the module or "
1564        "copied the configuration from a place where"
1565        "<br>a newer version of the module "
1566        "was running. This is bad and<br>as a "
1567        "precaution your configuration has been now "
1568        "restored to<br>defaults. Sorry for the "
1569        "inconvenience.<br>");
1570
1571    snprintf(buf, sizeof(buf),N_("%s Configuration Updated"), module_name);
1572    e_util_dialog_internal(buf, msg);
1573    E_FREE(module_name);
1574
1575    return ECORE_CALLBACK_CANCEL;
1576 }
1577
1578 EAPI Eina_Bool
1579 e_util_module_config_check(const char *module_name, int conf, int epoch, int version)
1580 {
1581    if ((conf >> 16) < epoch)
1582      {
1583         ecore_timer_add(1.0, _e_util_conf_timer_old, strdup(module_name));
1584         return EINA_FALSE;
1585      }
1586    else if (conf > version)
1587      {
1588         ecore_timer_add(1.0, _e_util_conf_timer_new, strdup(module_name));
1589         return EINA_FALSE;
1590      }
1591
1592    return EINA_TRUE;
1593 }
1594
1595 /**
1596  * Checks whenever the current manager/container/zone have fullscreen windows.
1597  */
1598 EAPI Eina_Bool
1599 e_util_fullscreen_curreny_any(void)
1600 {
1601    E_Manager *man = e_manager_current_get();
1602    E_Container *con = e_container_current_get(man);
1603    E_Zone *zone = e_zone_current_get(con);
1604    E_Desk *desk;
1605
1606    if ((zone) && (zone->fullscreen > 0)) return EINA_TRUE;
1607    desk = e_desk_current_get(zone);
1608    if ((desk) && (desk->fullscreen_borders > 0)) return EINA_TRUE;
1609    return EINA_FALSE;
1610 }
1611
1612 /**
1613  * Checks whenever any manager/container/zone have fullscreen windows.
1614  */
1615 EAPI Eina_Bool
1616 e_util_fullscreen_any(void)
1617 {
1618    E_Zone *zone;
1619    Eina_List *lm, *lc, *lz;
1620    E_Container *con;
1621    E_Manager *man;
1622    E_Desk *desk;
1623    int x, y;
1624
1625    EINA_LIST_FOREACH(e_manager_list(), lm, man)
1626      {
1627         EINA_LIST_FOREACH(man->containers, lc, con)
1628           {
1629              EINA_LIST_FOREACH(con->zones, lz, zone)
1630                {
1631                   if (zone->fullscreen > 0) return EINA_TRUE;
1632
1633                   for (x = 0; x < zone->desk_x_count; x++)
1634                     for (y = 0; y < zone->desk_y_count; y++)
1635                       {
1636                          desk = e_desk_at_xy_get(zone, x, y);
1637                          if ((desk) && (desk->fullscreen_borders > 0))
1638                            return EINA_TRUE;
1639                       }
1640                }
1641           }
1642      }
1643    return EINA_FALSE;
1644 }