1 #include "e.h"
2
3 E_API E_Path * path_data = NULL;
4 E_API E_Path * path_images = NULL;
5 E_API E_Path * path_fonts = NULL;
6 E_API E_Path * path_icons = NULL;
7 E_API E_Path * path_modules = NULL;
8 E_API E_Path * path_backgrounds = NULL;
9 E_API E_Path * path_messages = NULL;
10
11 /* local subsystem functions */
12 static Eina_Bool _e_util_cb_delayed_del(void *data);
13 static Eina_Bool _e_util_wakeup_cb(void *data);
14
15 static Evas_Object *_e_util_icon_add(const char *path, Evas *evas, int size);
16
17 static void _e_util_cb_delayed_cancel(void *data, void *obj);
18
19 /* local subsystem globals */
20 static Ecore_Timer *_e_util_dummy_timer = NULL;
21
22 /* externally accessible functions */
23 E_API void
e_util_wakeup(void)24 e_util_wakeup(void)
25 {
26 if (_e_util_dummy_timer) return;
27 _e_util_dummy_timer = ecore_timer_loop_add(0.0, _e_util_wakeup_cb, NULL);
28 }
29
30 E_API void
e_util_env_set(const char * var,const char * val)31 e_util_env_set(const char *var, const char *val)
32 {
33 if (val)
34 {
35 #ifdef HAVE_SETENV
36 setenv(var, val, 1);
37 #else
38 char buf[8192];
39
40 snprintf(buf, sizeof(buf), "%s=%s", var, val);
41 putenv(strdup(buf));
42 #endif
43 }
44 else
45 {
46 #ifdef HAVE_UNSETENV
47 unsetenv(var);
48 #else
49 if (getenv(var)) putenv(var);
50 #endif
51 }
52 }
53
54 E_API int
e_util_glob_match(const char * str,const char * pattern)55 e_util_glob_match(const char *str, const char *pattern)
56 {
57 if ((!str) || (!pattern)) return 0;
58 if (pattern[0] == 0)
59 {
60 if (str[0] == 0) return 1;
61 return 0;
62 }
63 if (str == pattern) return 1;
64 if (!strcmp(pattern, "*")) return 1;
65 if (!fnmatch(pattern, str, 0)) return 1;
66 return 0;
67 }
68
69 E_API int
e_util_glob_case_match(const char * str,const char * pattern)70 e_util_glob_case_match(const char *str, const char *pattern)
71 {
72 const char *p;
73 char *tstr, *tglob, *tp;
74
75 if (str == pattern) return 1;
76 if (pattern[0] == 0)
77 {
78 if (str[0] == 0) return 1;
79 return 0;
80 }
81 if (!strcmp(pattern, "*")) return 1;
82 tstr = alloca(strlen(str) + 1);
83 for (tp = tstr, p = str; *p != 0; p++, tp++)
84 *tp = tolower(*p);
85 *tp = 0;
86 tglob = alloca(strlen(pattern) + 1);
87 for (tp = tglob, p = pattern; *p != 0; p++, tp++)
88 *tp = tolower(*p);
89 *tp = 0;
90 if (!fnmatch(tglob, tstr, 0)) return 1;
91 return 0;
92 }
93
94 E_API int
e_util_strcmp(const char * s1,const char * s2)95 e_util_strcmp(const char *s1, const char *s2)
96 {
97 if ((s1) && (s2))
98 {
99 if (s1 == s2) return 0;
100 return strcmp(s1, s2);
101 }
102 return 0x7fffffff;
103 }
104
105 E_API int
e_util_strcasecmp(const char * s1,const char * s2)106 e_util_strcasecmp(const char *s1, const char *s2)
107 {
108 if ((!s1) && (!s2)) return 0;
109 if (!s1) return -1;
110 if (!s2) return 1;
111 return strcasecmp(s1, s2);
112 }
113
114 E_API int
e_util_both_str_empty(const char * s1,const char * s2)115 e_util_both_str_empty(const char *s1, const char *s2)
116 {
117 int empty = 0;
118
119 if ((!s1) && (!s2)) return 1;
120 if ((!s1) || ((s1) && (s1[0] == 0))) empty++;
121 if ((!s2) || ((s2) && (s2[0] == 0))) empty++;
122 if (empty == 2) return 1;
123 return 0;
124 }
125
126 E_API int
e_util_immortal_check(void)127 e_util_immortal_check(void)
128 {
129 Eina_List *wins;
130
131 wins = e_clients_immortal_list();
132 if (wins)
133 {
134 e_util_dialog_show(_("Cannot exit - immortal windows."),
135 _("Some windows are left still around with the Lifespan lock enabled. This means<ps/>"
136 "that Enlightenment will not allow itself to exit until these windows have<ps/>"
137 "been closed or have the lifespan lock removed.<ps/>"));
138 /* FIXME: should really display a list of these lifespan locked */
139 /* windows in a dialog and let the user disable their locks in */
140 /* this dialog */
141 eina_list_free(wins);
142 return 1;
143 }
144 return 0;
145 }
146
147 E_API int
e_util_edje_icon_check(const char * name)148 e_util_edje_icon_check(const char *name)
149 {
150 const char *file;
151 char buf[4096];
152
153 if ((!name) || (!name[0])) return 0;
154 snprintf(buf, sizeof(buf), "e/icons/%s", name);
155 file = e_theme_edje_file_get("base/theme/icons", buf);
156 if (file[0]) return 1;
157 return 0;
158 }
159
160 /* WARNING This function is deprecated,. must be made static.
161 * You should use e_util_icon_theme_set instead
162 */
163 E_API int
e_util_edje_icon_set(Evas_Object * obj,const char * name)164 e_util_edje_icon_set(Evas_Object *obj, const char *name)
165 {
166 const char *file;
167 char buf[4096];
168
169 if ((!name) || (!name[0])) return 0;
170 snprintf(buf, sizeof(buf), "e/icons/%s", name);
171 file = e_theme_edje_file_get("base/theme/icons", buf);
172 if (file[0])
173 {
174 edje_object_file_set(obj, file, buf);
175 return 1;
176 }
177 return 0;
178 }
179
180 static int
_e_util_icon_theme_set(Evas_Object * obj,const char * icon,Eina_Bool fallback)181 _e_util_icon_theme_set(Evas_Object *obj, const char *icon, Eina_Bool fallback)
182 {
183 const char *file;
184 char buf[4096];
185
186 if ((!icon) || (!icon[0])) return 0;
187 snprintf(buf, sizeof(buf), "e/icons/%s", icon);
188
189 if (fallback)
190 file = e_theme_edje_icon_fallback_file_get(buf);
191 else
192 file = e_theme_edje_file_get("base/theme/icons", buf);
193
194 if (file[0])
195 {
196 e_icon_file_edje_set(obj, file, buf);
197 return 1;
198 }
199
200 return 0;
201 }
202
203 static int
_e_util_icon_fdo_set(Evas_Object * obj,const char * icon)204 _e_util_icon_fdo_set(Evas_Object *obj, const char *icon)
205 {
206 const char *path = NULL;
207 unsigned int size;
208
209 if ((!icon) || (!icon[0])) return 0;
210 size = e_icon_scale_size_get(obj);
211 if (size < 16) size = 16;
212 size = e_util_icon_size_normalize(size * e_scale);
213
214 path = efreet_icon_path_find(e_config->icon_theme, icon, size);
215 if (!path) return 0;
216
217 e_icon_file_set(obj, path);
218 return 1;
219 }
220
221 /* use e_icon_size_scale_set(obj, size) to set the preferred icon size */
222 E_API int
e_util_icon_theme_set(Evas_Object * obj,const char * icon)223 e_util_icon_theme_set(Evas_Object *obj, const char *icon)
224 {
225 if (icon && (icon[0] == '/'))
226 {
227 e_icon_file_set(obj, icon);
228 return 1;
229 }
230 if (e_config->icon_theme_overrides)
231 {
232 if (_e_util_icon_fdo_set(obj, icon))
233 return 1;
234 if (_e_util_icon_theme_set(obj, icon, EINA_FALSE))
235 return 1;
236 return _e_util_icon_theme_set(obj, icon, EINA_TRUE);
237 }
238 else
239 {
240 if (_e_util_icon_theme_set(obj, icon, EINA_FALSE))
241 return 1;
242 if (_e_util_icon_fdo_set(obj, icon))
243 return 1;
244 return _e_util_icon_theme_set(obj, icon, EINA_TRUE);
245 }
246 }
247
248 int
_e_util_menu_item_edje_icon_set(E_Menu_Item * mi,const char * name,Eina_Bool fallback)249 _e_util_menu_item_edje_icon_set(E_Menu_Item *mi, const char *name, Eina_Bool fallback)
250 {
251 const char *file;
252 char buf[4096];
253
254 if ((!name) || (!name[0])) return 0;
255
256 if ((!fallback) && (name[0] == '/') && ecore_file_exists(name))
257 {
258 e_menu_item_icon_edje_set(mi, name, "icon");
259 return 1;
260 }
261 snprintf(buf, sizeof(buf), "e/icons/%s", name);
262
263 if (fallback)
264 file = e_theme_edje_icon_fallback_file_get(buf);
265 else
266 file = e_theme_edje_file_get("base/theme/icons", buf);
267
268 if (file[0])
269 {
270 e_menu_item_icon_edje_set(mi, file, buf);
271 return 1;
272 }
273 return 0;
274 }
275
276 E_API unsigned int
e_util_icon_size_normalize(unsigned int desired)277 e_util_icon_size_normalize(unsigned int desired)
278 {
279 const unsigned int *itr, known_sizes[] =
280 {
281 16, 22, 24, 32, 36, 48, 64, 72, 96, 128, 192, 256, 0
282 };
283
284 for (itr = known_sizes; *itr > 0; itr++)
285 if (*itr >= desired)
286 return *itr;
287
288 return 256; /* largest know size? */
289 }
290
291 static int
_e_util_menu_item_fdo_icon_set(E_Menu_Item * mi,const char * icon)292 _e_util_menu_item_fdo_icon_set(E_Menu_Item *mi, const char *icon)
293 {
294 const char *path = NULL;
295 unsigned int size;
296
297 if ((!icon) || (!icon[0])) return 0;
298 size = e_util_icon_size_normalize(96 * e_scale);
299 path = efreet_icon_path_find(e_config->icon_theme, icon, size);
300 if (!path) return 0;
301 e_menu_item_icon_file_set(mi, path);
302 return 1;
303 }
304
305 E_API int
e_util_menu_item_theme_icon_set(E_Menu_Item * mi,const char * icon)306 e_util_menu_item_theme_icon_set(E_Menu_Item *mi, const char *icon)
307 {
308 if (e_config->icon_theme_overrides)
309 {
310 if (_e_util_menu_item_fdo_icon_set(mi, icon))
311 return 1;
312 if (_e_util_menu_item_edje_icon_set(mi, icon, EINA_FALSE))
313 return 1;
314 return _e_util_menu_item_edje_icon_set(mi, icon, EINA_TRUE);
315 }
316 else
317 {
318 if (_e_util_menu_item_edje_icon_set(mi, icon, EINA_FALSE))
319 return 1;
320 if (_e_util_menu_item_fdo_icon_set(mi, icon))
321 return 1;
322 return _e_util_menu_item_edje_icon_set(mi, icon, EINA_TRUE);
323 }
324 }
325
326 E_API const char *
e_util_mime_icon_get(const char * mime,unsigned int size)327 e_util_mime_icon_get(const char *mime, unsigned int size)
328 {
329 char buf[1024];
330 const char *file = NULL;
331
332 if (e_config->icon_theme_overrides)
333 file = efreet_mime_type_icon_get(mime, e_config->icon_theme, e_util_icon_size_normalize(size));
334 if (file) return file;
335
336 if (snprintf(buf, sizeof(buf), "e/icons/fileman/mime/%s", mime) >= (int)sizeof(buf))
337 return NULL;
338
339 file = e_theme_edje_file_get("base/theme/icons", buf);
340 if (file && file[0]) return file;
341 return efreet_mime_type_icon_get(mime, e_config->icon_theme, e_util_icon_size_normalize(size));
342 }
343
344 E_API E_Client *
e_util_desk_client_above(E_Client * ec)345 e_util_desk_client_above(E_Client *ec)
346 {
347 E_Client *ec2;
348
349 E_OBJECT_CHECK_RETURN(ec, NULL);
350 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, NULL);
351
352 for (ec2 = e_client_above_get(ec); ec2; ec2 = e_client_above_get(ec2))
353 {
354 if ((ec2->desk == ec->desk) || (ec2->sticky)) return ec2;
355 }
356 return NULL;
357 }
358
359 E_API E_Client *
e_util_desk_client_below(E_Client * ec)360 e_util_desk_client_below(E_Client *ec)
361 {
362 E_Client *ec2;
363
364 E_OBJECT_CHECK_RETURN(ec, NULL);
365 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, NULL);
366
367 for (ec2 = e_client_below_get(ec); ec2; ec2 = e_client_below_get(ec2))
368 {
369 if ((ec2->desk == ec->desk) || (ec2->sticky)) return ec2;
370 }
371 return NULL;
372 }
373
374 E_API int
e_util_edje_collection_exists(const char * file,const char * coll)375 e_util_edje_collection_exists(const char *file, const char *coll)
376 {
377 Eina_List *clist;
378 Eina_Stringshare *str;
379 Eina_Bool ret = EINA_FALSE;
380
381 clist = edje_file_collection_list(file);
382 EINA_LIST_FREE(clist, str)
383 {
384 if ((!ret) && (!strcmp(coll, str)))
385 ret = EINA_TRUE;
386 eina_stringshare_del(str);
387 }
388 return ret;
389 }
390
391 E_API E_Dialog *
e_util_dialog_internal(const char * title,const char * txt)392 e_util_dialog_internal(const char *title, const char *txt)
393 {
394 E_Dialog *dia;
395
396 dia = e_dialog_new(NULL, "E", "_error_dialog");
397 if (!dia) return NULL;
398 e_dialog_title_set(dia, title);
399 e_dialog_text_set(dia, txt);
400 e_dialog_icon_set(dia, "dialog-error", 64);
401 e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
402 e_dialog_button_focus_num(dia, 0);
403 elm_win_center(dia->win, 1, 1);
404 e_dialog_show(dia);
405 return dia;
406 }
407
408 E_API const char *
e_util_filename_escape(const char * filename)409 e_util_filename_escape(const char *filename)
410 {
411 const char *p;
412 char *q;
413 static char buf[PATH_MAX];
414
415 if (!filename) return NULL;
416 p = filename;
417 q = buf;
418 while (*p)
419 {
420 if ((q - buf) > 4090) return NULL;
421 if (
422 (*p == ' ') || (*p == '\t') || (*p == '\n') ||
423 (*p == '\\') || (*p == '\'') || (*p == '\"') ||
424 (*p == ';') || (*p == '!') || (*p == '#') ||
425 (*p == '$') || (*p == '%') || (*p == '&') ||
426 (*p == '*') || (*p == '(') || (*p == ')') ||
427 (*p == '[') || (*p == ']') || (*p == '{') ||
428 (*p == '}') || (*p == '|') || (*p == '<') ||
429 (*p == '>') || (*p == '?')
430 )
431 {
432 *q = '\\';
433 q++;
434 }
435 *q = *p;
436 q++;
437 p++;
438 }
439 *q = 0;
440 return buf;
441 }
442
443
444 E_API char *
e_util_shell_env_path_eval(const char * path)445 e_util_shell_env_path_eval(const char *path)
446 {
447 /* evaluate things like:
448 * $HOME/bling -> /home/user/bling
449 * $HOME/bin/$HOSTNAME/blah -> /home/user/bin/localhost/blah
450 * etc. etc.
451 */
452 const char *p, *v2, *v1 = NULL;
453 char buf[PATH_MAX], *pd, *s, *vp;
454 char *v = NULL;
455 int esc = 0, invar = 0;
456
457 for (p = path, pd = buf; (pd < (buf + sizeof(buf) - 1)); p++)
458 {
459 if (invar)
460 {
461 if (!((isalnum(*p)) || (*p == '_')))
462 {
463 v2 = p;
464 invar = 0;
465 if ((v2 - v1) > 1)
466 {
467 s = alloca(v2 - v1);
468 strncpy(s, v1 + 1, v2 - v1 - 1);
469 s[v2 - v1 - 1] = 0;
470 if (strncmp(s, "XDG", 3))
471 v = getenv(s);
472 else
473 {
474 if (!strcmp(s, "XDG_CONFIG_HOME"))
475 v = (char *)efreet_config_home_get();
476 else if (!strcmp(s, "XDG_CACHE_HOME"))
477 v = (char *)efreet_cache_home_get();
478 else if (!strcmp(s, "XDG_DATA_HOME"))
479 v = (char *)efreet_data_home_get();
480 else if (!strcmp(s, "XDG_DESKTOP_DIR"))
481 v = (char *)efreet_desktop_dir_get();
482 else if (!strcmp(s, "XDG_DOWNLOAD_DIR"))
483 v = (char *)efreet_download_dir_get();
484 else if (!strcmp(s, "XDG_TEMPLATES_DIR"))
485 v = (char *)efreet_templates_dir_get();
486 else if (!strcmp(s, "XDG_PUBLICSHARE_DIR"))
487 v = (char *)efreet_public_share_dir_get();
488 else if (!strcmp(s, "XDG_DOCUMENTS_DIR"))
489 v = (char *)efreet_documents_dir_get();
490 else if (!strcmp(s, "XDG_MUSIC_DIR"))
491 v = (char *)efreet_music_dir_get();
492 else if (!strcmp(s, "XDG_PICTURES_DIR"))
493 v = (char *)efreet_pictures_dir_get();
494 else if (!strcmp(s, "XDG_VIDEOS_DIR"))
495 v = (char *)efreet_videos_dir_get();
496 else if (!strcmp(s, "XDG_RUNTIME_DIR"))
497 v = (char *)efreet_runtime_dir_get();
498 }
499
500 if (v)
501 {
502 vp = v;
503 while ((*vp) && (pd < (buf + sizeof(buf) - 1)))
504 {
505 *pd = *vp;
506 vp++;
507 pd++;
508 }
509 }
510 }
511 if (pd < (buf + sizeof(buf) - 1))
512 {
513 *pd = *p;
514 pd++;
515 }
516 }
517 }
518 else
519 {
520 if (esc)
521 {
522 *pd = *p;
523 pd++;
524 }
525 else
526 {
527 if (*p == '\\') esc = 1;
528 else if (*p == '$')
529 {
530 invar = 1;
531 v1 = p;
532 }
533 else
534 {
535 *pd = *p;
536 pd++;
537 }
538 }
539 }
540 if (*p == 0) break;
541 }
542 *pd = 0;
543 return strdup(buf);
544 }
545
546 E_API char *
e_util_size_string_get(off_t size)547 e_util_size_string_get(off_t size)
548 {
549 double dsize;
550 char buf[256];
551
552 dsize = (double)size;
553 if (dsize < 1024.0) snprintf(buf, sizeof(buf), _("%'.0f bytes"), dsize);
554 else
555 {
556 dsize /= 1024.0;
557 if (dsize < 1024) snprintf(buf, sizeof(buf), _("%'.0f KiB"), dsize);
558 else
559 {
560 dsize /= 1024.0;
561 if (dsize < 1024) snprintf(buf, sizeof(buf), _("%'.1f MiB"), dsize);
562 else
563 {
564 dsize /= 1024.0;
565 if (dsize < 1024) snprintf(buf, sizeof(buf), _("%'.1f GiB"), dsize);
566 else
567 {
568 dsize /= 1024.0;
569 snprintf(buf, sizeof(buf), _("%'.1f TiB"), dsize);
570 }
571 }
572 }
573 }
574 return strdup(buf);
575 }
576
577 E_API char *
e_util_file_time_get(time_t ftime)578 e_util_file_time_get(time_t ftime)
579 {
580 time_t diff, ltime;
581 char buf[256];
582 char *s = NULL;
583 long test;
584 ltime = time(NULL);
585 diff = ltime - ftime;
586 buf[0] = 0;
587 if (ftime > ltime)
588 snprintf(buf, sizeof(buf), _("In the future"));
589 else
590 {
591 if (diff <= 60)
592 snprintf(buf, sizeof(buf), _("In the last minute"));
593 else if (diff >= 31526000)
594 {
595 test = diff / 31526000;
596 snprintf(buf, sizeof(buf), P_("Last year", "%li Years ago", test), test);
597 }
598 else if (diff >= 2592000)
599 {
600 test = diff / 2592000;
601 snprintf(buf, sizeof(buf), P_("Last month", "%li Months ago", test), test);
602 }
603 else if (diff >= 604800)
604 {
605 test = diff / 604800;
606 snprintf(buf, sizeof(buf), P_("Last week", "%li Weeks ago", test), test);
607 }
608 else if (diff >= 86400)
609 {
610 test = diff / 86400;
611 snprintf(buf, sizeof(buf), P_("Yesterday", "%li Days ago", test), test);
612 }
613 else if (diff >= 3600)
614 {
615 test = diff / 3600;
616 snprintf(buf, sizeof(buf), P_("An hour ago", "%li Hours ago", test), test);
617 }
618 else if (diff > 60)
619 {
620 test = diff / 60;
621 snprintf(buf, sizeof(buf), P_("A minute ago", "%li Minutes ago", test), test);
622 }
623 }
624
625 if (buf[0])
626 s = strdup(buf);
627 else
628 s = strdup(_("Unknown"));
629 return s;
630 }
631
632 E_API Evas_Object *
e_util_icon_add(const char * path,Evas * evas)633 e_util_icon_add(const char *path, Evas *evas)
634 {
635 return _e_util_icon_add(path, evas, 64);
636 }
637
638 E_API Evas_Object *
e_util_desktop_icon_add(Efreet_Desktop * desktop,unsigned int size,Evas * evas)639 e_util_desktop_icon_add(Efreet_Desktop *desktop, unsigned int size, Evas *evas)
640 {
641 if ((!desktop) || (!desktop->icon)) return NULL;
642 return e_util_icon_theme_icon_add(desktop->icon, size, evas);
643 }
644
645 E_API Evas_Object *
e_util_icon_theme_icon_add(const char * icon_name,unsigned int size,Evas * evas)646 e_util_icon_theme_icon_add(const char *icon_name, unsigned int size, Evas *evas)
647 {
648 if (!icon_name) return NULL;
649 if (icon_name[0] == '/') return _e_util_icon_add(icon_name, evas, size);
650 else
651 {
652 Evas_Object *obj;
653 const char *path;
654
655 path = efreet_icon_path_find(e_config->icon_theme, icon_name, size);
656 if (path)
657 {
658 obj = _e_util_icon_add(path, evas, size);
659 return obj;
660 }
661 }
662 return NULL;
663 }
664
665 E_API void
e_util_desktop_menu_item_icon_add(Efreet_Desktop * desktop,unsigned int size,E_Menu_Item * mi)666 e_util_desktop_menu_item_icon_add(Efreet_Desktop *desktop, unsigned int size, E_Menu_Item *mi)
667 {
668 const char *path = NULL;
669
670 if ((!desktop) || (!desktop->icon)) return;
671
672 if (desktop->icon[0] == '/') path = desktop->icon;
673 else path = efreet_icon_path_find(e_config->icon_theme, desktop->icon, size);
674
675 if (path)
676 {
677 const char *ext;
678
679 ext = strrchr(path, '.');
680 if (ext)
681 {
682 if (strcmp(ext, ".edj") == 0)
683 e_menu_item_icon_edje_set(mi, path, "icon");
684 else
685 e_menu_item_icon_file_set(mi, path);
686 }
687 else
688 e_menu_item_icon_file_set(mi, path);
689 }
690 }
691
692 E_API int
e_util_dir_check(const char * dir)693 e_util_dir_check(const char *dir)
694 {
695 if (!ecore_file_exists(dir))
696 {
697 if (!ecore_file_mkpath(dir))
698 {
699 e_util_dialog_show(_("Error creating directory"), _("Failed to create directory: %s .<ps/>Check that you have correct permissions set."), dir);
700 return 0;
701 }
702 }
703 else
704 {
705 if (!ecore_file_is_dir(dir))
706 {
707 e_util_dialog_show(_("Error creating directory"), _("Failed to create directory: %s .<ps/>A file of that name already exists."), dir);
708 return 0;
709 }
710 }
711 return 1;
712 }
713
714 static Eina_Array *_delay_del_array = NULL;
715 static Ecore_Idle_Enterer *_delay_del_idler = NULL;
716
717 static Eina_Bool
_e_util_cb_delayed_del(void * data EINA_UNUSED)718 _e_util_cb_delayed_del(void *data EINA_UNUSED)
719 {
720 while (_delay_del_array)
721 {
722 Eina_Array *arr = _delay_del_array;
723 Eina_Iterator *itr = eina_array_iterator_new(arr);
724 void *ptr;
725
726 _delay_del_array = NULL;
727 while (eina_iterator_next(itr, &ptr))
728 {
729 if (ptr) e_object_del(E_OBJECT(ptr));
730 }
731 eina_array_free(arr);
732 }
733 _delay_del_idler = NULL;
734 return ECORE_CALLBACK_CANCEL;
735 }
736
737 static void
_e_util_cb_delayed_cancel(void * data,void * obj EINA_UNUSED)738 _e_util_cb_delayed_cancel(void *data, void *obj EINA_UNUSED)
739 {
740 unsigned long c = (unsigned long)data;
741 if (_delay_del_array) eina_array_data_set(_delay_del_array, c, NULL);
742 }
743
744 E_API void
e_util_defer_object_del(E_Object * obj)745 e_util_defer_object_del(E_Object *obj)
746 {
747 if (stopping)
748 e_object_del(obj);
749 else
750 {
751 if (!_delay_del_array)
752 {
753 _delay_del_array = eina_array_new(8);
754 if (!_delay_del_idler)
755 _delay_del_idler = ecore_idle_enterer_before_add
756 (_e_util_cb_delayed_del, NULL);
757 }
758 if (_delay_del_array)
759 {
760 if (eina_array_push(_delay_del_array, obj))
761 {
762 unsigned long c = eina_array_count_get(_delay_del_array);
763 e_object_delfn_add(obj, _e_util_cb_delayed_cancel, (void *)c);
764 }
765 }
766 }
767 }
768
769 E_API const char *
e_util_winid_str_get(Ecore_X_Window win)770 e_util_winid_str_get(Ecore_X_Window win)
771 {
772 const char *vals = "qWeRtYuIoP5-$&<~";
773 static char id[9];
774 unsigned int val;
775
776 val = (unsigned int)win;
777 id[0] = vals[(val >> 28) & 0xf];
778 id[1] = vals[(val >> 24) & 0xf];
779 id[2] = vals[(val >> 20) & 0xf];
780 id[3] = vals[(val >> 16) & 0xf];
781 id[4] = vals[(val >> 12) & 0xf];
782 id[5] = vals[(val >> 8) & 0xf];
783 id[6] = vals[(val >> 4) & 0xf];
784 id[7] = vals[(val) & 0xf];
785 id[8] = 0;
786 return id;
787 }
788
789 static int
_win_auto_size_calc(int max,int min)790 _win_auto_size_calc(int max, int min)
791 {
792 const float *itr, scales[] = {0.25, 0.3, 0.5, 0.75, 0.8, 0.9, 0.95, -1};
793
794 for (itr = scales; *itr > 0; itr++)
795 {
796 int value = *itr * max;
797 if (value > min) /* not >=, try a bit larger */
798 {
799 if (min > 10)
800 value = E_CLAMP(value, min, min * 1.5);
801 return value;
802 }
803 }
804
805 return min;
806 }
807
808 E_API void
e_util_win_auto_resize_fill(Evas_Object * win)809 e_util_win_auto_resize_fill(Evas_Object *win)
810 {
811 E_Zone *zone = NULL;
812 E_Client *ec;
813
814 ec = e_win_client_get(win);
815 if (ec)
816 zone = ec->zone;
817 if (!zone)
818 zone = e_zone_current_get();
819
820 if (zone)
821 {
822 int w, h, mw, mh;
823
824 e_zone_useful_geometry_get(zone, NULL, NULL, &w, &h);
825
826 evas_object_size_hint_min_get(win, &mw, &mh);
827 w = _win_auto_size_calc(w, mw);
828 h = _win_auto_size_calc(h, mh);
829 evas_object_resize(win, w, h);
830 }
831 }
832
833 /* local subsystem functions */
834
835 static Evas_Object *
_e_util_icon_add(const char * path,Evas * evas,int size)836 _e_util_icon_add(const char *path, Evas *evas, int size)
837 {
838 Evas_Object *o = NULL;
839 const char *ext;
840
841 if (!path) return NULL;
842 if (!ecore_file_exists(path)) return NULL;
843
844 o = e_icon_add(evas);
845 e_icon_scale_size_set(o, size);
846 e_icon_preload_set(o, 1);
847 ext = strrchr(path, '.');
848 if (ext)
849 {
850 if (!strcmp(ext, ".edj"))
851 e_icon_file_edje_set(o, path, "icon");
852 else
853 e_icon_file_set(o, path);
854 }
855 else
856 e_icon_file_set(o, path);
857 e_icon_fill_inside_set(o, 1);
858
859 return o;
860 }
861
862 static Eina_Bool
_e_util_wakeup_cb(void * data EINA_UNUSED)863 _e_util_wakeup_cb(void *data EINA_UNUSED)
864 {
865 _e_util_dummy_timer = NULL;
866 return ECORE_CALLBACK_CANCEL;
867 }
868
869 static Eina_Bool
_e_util_conf_timer_old(void * data)870 _e_util_conf_timer_old(void *data)
871 {
872 char *module_name = data;
873 char buf[4096];
874 char *msg = _("Configuration data needed upgrading. Your old configuration<ps/>"
875 "has been wiped and a new set of defaults initialized. This<ps/>"
876 "will happen regularly during development, so don't report a<ps/>"
877 "bug. This means the module needs new configuration<ps/>"
878 "data by default for usable functionality that your old<ps/>"
879 "configuration lacked. This new set of defaults will fix<ps/>"
880 "that by adding it in. You can re-configure things now to your<ps/>"
881 "liking. Sorry for the hiccup in your configuration.<ps/>");
882
883 snprintf(buf, sizeof(buf), N_("%s Configuration Updated"), module_name);
884 e_util_dialog_internal(buf, msg);
885 E_FREE(module_name);
886
887 return ECORE_CALLBACK_CANCEL;
888 }
889
890 static Eina_Bool
_e_util_conf_timer_new(void * data)891 _e_util_conf_timer_new(void *data)
892 {
893 char *module_name = data;
894 char buf[4096];
895 char *msg =
896 _("Your module configuration is NEWER "
897 "than the module version. This is "
898 "very<ps/>strange. This should not happen unless"
899 " you downgraded<ps/>the module or "
900 "copied the configuration from a place where"
901 "<ps/>a newer version of the module "
902 "was running. This is bad and<ps/>as a "
903 "precaution your configuration has been now "
904 "restored to<ps/>defaults. Sorry for the "
905 "inconvenience.<ps/>");
906
907 snprintf(buf, sizeof(buf), _("%s Configuration Updated"), module_name);
908 e_util_dialog_internal(buf, msg);
909 E_FREE(module_name);
910
911 return ECORE_CALLBACK_CANCEL;
912 }
913
914 E_API Eina_Bool
e_util_module_config_check(const char * module_name,int loaded,int current)915 e_util_module_config_check(const char *module_name, int loaded, int current)
916 {
917 if (loaded > current)
918 {
919 ecore_timer_loop_add(1.0, _e_util_conf_timer_new, strdup(module_name));
920 return EINA_FALSE;
921 }
922 loaded -= loaded % 1000000, current -= current % 1000000;
923 if (loaded < current)
924 {
925 ecore_timer_loop_add(1.0, _e_util_conf_timer_old, strdup(module_name));
926 return EINA_FALSE;
927 }
928
929 return EINA_TRUE;
930 }
931
932 /**
933 * Checks whenever the current manager/comp/zone have fullscreen windows.
934 */
935 E_API Eina_Bool
e_util_fullscreen_current_any(void)936 e_util_fullscreen_current_any(void)
937 {
938 E_Zone *zone = e_zone_current_get();
939 E_Desk *desk;
940
941 if ((zone) && (zone->fullscreen > 0)) return EINA_TRUE;
942 desk = e_desk_current_get(zone);
943 if ((desk) && (desk->fullscreen_clients)) return EINA_TRUE;
944 return EINA_FALSE;
945 }
946
947 /**
948 * Checks whenever any manager/comp/zone have fullscreen windows.
949 */
950 E_API Eina_Bool
e_util_fullscreen_any(void)951 e_util_fullscreen_any(void)
952 {
953 E_Zone *zone;
954 const Eina_List *lz;
955 E_Desk *desk;
956 int x, y;
957
958 EINA_LIST_FOREACH(e_comp->zones, lz, zone)
959 {
960 if (zone->fullscreen > 0) return EINA_TRUE;
961
962 for (x = 0; x < zone->desk_x_count; x++)
963 for (y = 0; y < zone->desk_y_count; y++)
964 {
965 desk = e_desk_at_xy_get(zone, x, y);
966 if ((desk) && (desk->fullscreen_clients))
967 return EINA_TRUE;
968 }
969 }
970 return EINA_FALSE;
971 }
972
973 E_API const char *
e_util_time_str_get(long int seconds)974 e_util_time_str_get(long int seconds)
975 {
976 static char buf[1024];
977 long int test;
978
979 if (seconds < 0)
980 snprintf(buf, sizeof(buf), _("Never"));
981 else
982 {
983 if (seconds <= 60)
984 snprintf(buf, sizeof(buf), P_("A second", "%li Seconds", seconds), seconds);
985 else if (seconds >= 31526000)
986 {
987 test = seconds / 31526000;
988 snprintf(buf, sizeof(buf), P_("One year", "%li Years", test), test);
989 }
990 else if (seconds >= 2592000)
991 {
992 test = seconds / 2592000;
993 snprintf(buf, sizeof(buf), P_("One month", "%li Months", test), test);
994 }
995 else if (seconds >= 604800)
996 {
997 test = seconds / 604800;
998 snprintf(buf, sizeof(buf), P_("One week", "%li Weeks", test), test);
999 }
1000 else if (seconds >= 86400)
1001 {
1002 test = seconds / 86400;
1003 snprintf(buf, sizeof(buf), P_("One day", "%li Days", test), test);
1004 }
1005 else if (seconds >= 3600)
1006 {
1007 test = seconds / 3600;
1008 snprintf(buf, sizeof(buf), P_("An hour", "%li Hours", test), test);
1009 }
1010 else if (seconds > 60)
1011 {
1012 test = seconds / 60;
1013 snprintf(buf, sizeof(buf), P_("A minute", "%li Minutes", test), test);
1014 }
1015 }
1016 return buf;
1017 }
1018
1019 static void
_e_util_size_debug_free(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1020 _e_util_size_debug_free(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1021 {
1022 int x, y, w, h;
1023 const char *name;
1024
1025 evas_object_geometry_get(obj, &x, &y, &w, &h);
1026 name = evas_object_name_get(obj);
1027 fprintf(stderr, "FREE %s %d OBJ[%s%s%p]: (%d,%d) - %dx%d\n", evas_object_visible_get(obj) ? "VIS" : "HID", evas_object_layer_get(obj), name ?: "", name ? "|" : "", obj, x, y, w, h);
1028 }
1029
1030 static void
_e_util_size_debug_del(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1031 _e_util_size_debug_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1032 {
1033 int x, y, w, h;
1034 const char *name;
1035
1036 evas_object_geometry_get(obj, &x, &y, &w, &h);
1037 name = evas_object_name_get(obj);
1038 fprintf(stderr, "DEL %s %d OBJ[%s%s%p]: (%d,%d) - %dx%d\n", evas_object_visible_get(obj) ? "VIS" : "HID", evas_object_layer_get(obj), name ?: "", name ? "|" : "", obj, x, y, w, h);
1039 }
1040
1041 static void
_e_util_size_debug_stack(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1042 _e_util_size_debug_stack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1043 {
1044 int x, y, w, h;
1045 const char *name;
1046
1047 evas_object_geometry_get(obj, &x, &y, &w, &h);
1048 name = evas_object_name_get(obj);
1049 fprintf(stderr, "RESTACK %s %d OBJ[%s%s%p]: (%d,%d) - %dx%d\n", evas_object_visible_get(obj) ? "VIS" : "HID", evas_object_layer_get(obj), name ?: "", name ? "|" : "", obj, x, y, w, h);
1050 }
1051
1052 E_API void
e_util_size_debug(Evas_Object * obj)1053 e_util_size_debug(Evas_Object *obj)
1054 {
1055 int x, y, w, h;
1056 const char *name;
1057
1058 evas_object_geometry_get(obj, &x, &y, &w, &h);
1059 name = evas_object_name_get(obj);
1060 fprintf(stderr, "%s %d OBJ[%s%s%p]: (%d,%d) - %dx%d\n", evas_object_visible_get(obj) ? "VIS" : "HID", evas_object_layer_get(obj), name ?: evas_object_type_get(obj), "|", obj, x, y, w, h);
1061 }
1062
1063 static void
_e_util_size_debug(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1064 _e_util_size_debug(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1065 {
1066 e_util_size_debug(obj);
1067 }
1068
1069 E_API void
e_util_size_debug_set(Evas_Object * obj,Eina_Bool enable)1070 e_util_size_debug_set(Evas_Object *obj, Eina_Bool enable)
1071 {
1072 if (enable)
1073 {
1074 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
1075 _e_util_size_debug, NULL);
1076 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
1077 _e_util_size_debug, NULL);
1078 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW,
1079 _e_util_size_debug, NULL);
1080 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
1081 _e_util_size_debug, NULL);
1082 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESTACK,
1083 _e_util_size_debug_stack, NULL);
1084 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
1085 _e_util_size_debug_del, NULL);
1086 evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
1087 _e_util_size_debug_free, NULL);
1088 }
1089 else
1090 {
1091 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
1092 _e_util_size_debug, NULL);
1093 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
1094 _e_util_size_debug, NULL);
1095 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_SHOW,
1096 _e_util_size_debug, NULL);
1097 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE,
1098 _e_util_size_debug, NULL);
1099 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
1100 _e_util_size_debug_del, NULL);
1101 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_FREE,
1102 _e_util_size_debug_free, NULL);
1103 }
1104 }
1105
1106 E_API void
e_util_string_list_free(Eina_List * l)1107 e_util_string_list_free(Eina_List *l)
1108 {
1109 char *s;
1110
1111 EINA_LIST_FREE(l, s)
1112 free(s);
1113 }
1114
1115 static Efreet_Desktop *
_e_util_default_terminal_get(const char * defaults_list)1116 _e_util_default_terminal_get(const char *defaults_list)
1117 {
1118 Efreet_Desktop *tdesktop = NULL;
1119 Efreet_Ini *ini;
1120 const char *s;
1121
1122 ini = efreet_ini_new(defaults_list);
1123 if ((ini) && (ini->data) &&
1124 (efreet_ini_section_set(ini, "Default Applications")) &&
1125 (ini->section))
1126 {
1127 s = efreet_ini_string_get(ini, "x-scheme-handler/terminal");
1128 if (s) tdesktop = efreet_util_desktop_file_id_find(s);
1129 }
1130 if (ini) efreet_ini_free(ini);
1131 return tdesktop;
1132 }
1133
1134 E_API Efreet_Desktop *
e_util_terminal_desktop_get(void)1135 e_util_terminal_desktop_get(void)
1136 {
1137 const char *terms[] =
1138 {
1139 "terminology.desktop",
1140 "rxvt.desktop",
1141 "gnome-terminal.desktop",
1142 "konsole.desktop",
1143 NULL
1144 };
1145 const char *s;
1146 char buf[PATH_MAX];
1147 Efreet_Desktop *tdesktop = NULL, *td;
1148 Eina_List *l;
1149 int i;
1150
1151 s = efreet_data_home_get();
1152 if (s)
1153 {
1154 snprintf(buf, sizeof(buf), "%s/mimeapps.list",
1155 efreet_config_home_get());
1156 tdesktop = _e_util_default_terminal_get(buf);
1157 }
1158 if (tdesktop) return tdesktop;
1159 EINA_LIST_FOREACH(efreet_data_dirs_get(), l, s)
1160 {
1161 snprintf(buf, sizeof(buf), "%s/applications/defaults.list", s);
1162 tdesktop = _e_util_default_terminal_get(buf);
1163 if (tdesktop) return tdesktop;
1164 }
1165
1166 for (i = 0; terms[i]; i++)
1167 {
1168 tdesktop = efreet_util_desktop_file_id_find(terms[i]);
1169 if (tdesktop) return tdesktop;
1170 }
1171 if (!tdesktop)
1172 {
1173 l = efreet_util_desktop_category_list("TerminalEmulator");
1174 if (l)
1175 {
1176 // just take first one since above list doesn't work.
1177 tdesktop = l->data;
1178 EINA_LIST_FREE(l, td)
1179 {
1180 // free/unref the desktops we are not going to use
1181 if (td != tdesktop) efreet_desktop_free(td);
1182 }
1183 }
1184 }
1185 return tdesktop;
1186 }
1187
1188 E_API E_Config_Binding_Key *
e_util_binding_match(const Eina_List * bindlist,Ecore_Event_Key * ev,unsigned int * num,const E_Config_Binding_Key * skip)1189 e_util_binding_match(const Eina_List *bindlist, Ecore_Event_Key *ev, unsigned int *num, const E_Config_Binding_Key *skip)
1190 {
1191 E_Config_Binding_Key *bi;
1192 const Eina_List *l;
1193 unsigned int mod = E_BINDING_MODIFIER_NONE;
1194
1195 if (num) *num = 0;
1196
1197 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
1198 mod |= E_BINDING_MODIFIER_SHIFT;
1199 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
1200 mod |= E_BINDING_MODIFIER_CTRL;
1201 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
1202 mod |= E_BINDING_MODIFIER_ALT;
1203 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
1204 mod |= E_BINDING_MODIFIER_WIN;
1205 /* see comment in e_bindings on numlock
1206 if (ev->modifiers & ECORE_X_LOCK_NUM)
1207 mod |= ECORE_X_LOCK_NUM;
1208 */
1209 EINA_LIST_FOREACH(bindlist ? : e_bindings->key_bindings, l, bi)
1210 {
1211 if (bi != skip)
1212 {
1213 if ((bi->modifiers == mod) && eina_streq(bi->key, ev->key))
1214 return bi;
1215 }
1216 if (num) (*num)++;
1217 }
1218 if (num) *num = 0;
1219 return NULL;
1220 }
1221
1222 E_API void
e_util_gadcon_orient_icon_set(E_Gadcon_Orient orient,Evas_Object * obj)1223 e_util_gadcon_orient_icon_set(E_Gadcon_Orient orient, Evas_Object *obj)
1224 {
1225 switch (orient)
1226 {
1227 case E_GADCON_ORIENT_LEFT:
1228 e_util_icon_theme_set(obj, "preferences-position-left");
1229 break;
1230
1231 case E_GADCON_ORIENT_RIGHT:
1232 e_util_icon_theme_set(obj, "preferences-position-right");
1233 break;
1234
1235 case E_GADCON_ORIENT_TOP:
1236 e_util_icon_theme_set(obj, "preferences-position-top");
1237 break;
1238
1239 case E_GADCON_ORIENT_BOTTOM:
1240 e_util_icon_theme_set(obj, "preferences-position-bottom");
1241 break;
1242
1243 case E_GADCON_ORIENT_CORNER_TL:
1244 e_util_icon_theme_set(obj, "preferences-position-top-left");
1245 break;
1246
1247 case E_GADCON_ORIENT_CORNER_TR:
1248 e_util_icon_theme_set(obj, "preferences-position-top-right");
1249 break;
1250
1251 case E_GADCON_ORIENT_CORNER_BL:
1252 e_util_icon_theme_set(obj, "preferences-position-bottom-left");
1253 break;
1254
1255 case E_GADCON_ORIENT_CORNER_BR:
1256 e_util_icon_theme_set(obj, "preferences-position-bottom-right");
1257 break;
1258
1259 case E_GADCON_ORIENT_CORNER_LT:
1260 e_util_icon_theme_set(obj, "preferences-position-left-top");
1261 break;
1262
1263 case E_GADCON_ORIENT_CORNER_RT:
1264 e_util_icon_theme_set(obj, "preferences-position-right-top");
1265 break;
1266
1267 case E_GADCON_ORIENT_CORNER_LB:
1268 e_util_icon_theme_set(obj, "preferences-position-left-bottom");
1269 break;
1270
1271 case E_GADCON_ORIENT_CORNER_RB:
1272 e_util_icon_theme_set(obj, "preferences-position-right-bottom");
1273 break;
1274
1275 default:
1276 e_util_icon_theme_set(obj, "enlightenment");
1277 break;
1278 }
1279 }
1280
1281 E_API void
e_util_gadcon_orient_menu_item_icon_set(E_Gadcon_Orient orient,E_Menu_Item * mi)1282 e_util_gadcon_orient_menu_item_icon_set(E_Gadcon_Orient orient, E_Menu_Item *mi)
1283 {
1284 switch (orient)
1285 {
1286 case E_GADCON_ORIENT_LEFT:
1287 e_util_menu_item_theme_icon_set(mi, "preferences-position-left");
1288 break;
1289
1290 case E_GADCON_ORIENT_RIGHT:
1291 e_util_menu_item_theme_icon_set(mi, "preferences-position-right");
1292 break;
1293
1294 case E_GADCON_ORIENT_TOP:
1295 e_util_menu_item_theme_icon_set(mi, "preferences-position-top");
1296 break;
1297
1298 case E_GADCON_ORIENT_BOTTOM:
1299 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom");
1300 break;
1301
1302 case E_GADCON_ORIENT_CORNER_TL:
1303 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-left");
1304 break;
1305
1306 case E_GADCON_ORIENT_CORNER_TR:
1307 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-right");
1308 break;
1309
1310 case E_GADCON_ORIENT_CORNER_BL:
1311 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-left");
1312 break;
1313
1314 case E_GADCON_ORIENT_CORNER_BR:
1315 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-right");
1316 break;
1317
1318 case E_GADCON_ORIENT_CORNER_LT:
1319 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-top");
1320 break;
1321
1322 case E_GADCON_ORIENT_CORNER_RT:
1323 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-top");
1324 break;
1325
1326 case E_GADCON_ORIENT_CORNER_LB:
1327 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-bottom");
1328 break;
1329
1330 case E_GADCON_ORIENT_CORNER_RB:
1331 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-bottom");
1332 break;
1333
1334 default:
1335 e_util_menu_item_theme_icon_set(mi, "enlightenment");
1336 break;
1337 }
1338 }
1339
1340 E_API char *
e_util_string_append_char(char * str,size_t * size,size_t * len,char c)1341 e_util_string_append_char(char *str, size_t *size, size_t *len, char c)
1342 {
1343 if (!str)
1344 {
1345 str = malloc(4096);
1346 if (!str) return NULL;
1347 str[0] = 0;
1348 *size = 4096;
1349 *len = 0;
1350 }
1351
1352 if (*len >= *size - 1)
1353 {
1354 char *str2;
1355
1356 *size += 1024;
1357 str2 = realloc(str, *size);
1358 if (!str2)
1359 {
1360 *size = 0;
1361 free(str);
1362 return NULL;
1363 }
1364 str = str2;
1365 }
1366
1367 str[(*len)++] = c;
1368 str[*len] = 0;
1369
1370 return str;
1371 }
1372
1373 E_API char *
e_util_string_append_quoted(char * str,size_t * size,size_t * len,const char * src)1374 e_util_string_append_quoted(char *str, size_t *size, size_t *len, const char *src)
1375 {
1376 str = e_util_string_append_char(str, size, len, '\'');
1377 if (!str) return NULL;
1378
1379 while (*src)
1380 {
1381 if (*src == '\'')
1382 {
1383 str = e_util_string_append_char(str, size, len, '\'');
1384 if (!str) return NULL;
1385 str = e_util_string_append_char(str, size, len, '\\');
1386 if (!str) return NULL;
1387 str = e_util_string_append_char(str, size, len, '\'');
1388 if (!str) return NULL;
1389 str = e_util_string_append_char(str, size, len, '\'');
1390 if (!str) return NULL;
1391 }
1392 else
1393 {
1394 str = e_util_string_append_char(str, size, len, *src);
1395 if (!str) return NULL;
1396 }
1397
1398 src++;
1399 }
1400
1401 str = e_util_string_append_char(str, size, len, '\'');
1402 if (!str) return NULL;
1403
1404 return str;
1405 }
1406
1407 E_API void
e_util_evas_objects_above_print(Evas_Object * o)1408 e_util_evas_objects_above_print(Evas_Object *o)
1409 {
1410 Evas_Object *a, *oo;
1411
1412 EINA_SAFETY_ON_NULL_RETURN(o);
1413 a = o;
1414 while ((a = evas_object_above_get(a)))
1415 {
1416 const Eina_List *l, *ll;
1417
1418 l = evas_object_clipees_get(a);
1419 if (l)
1420 {
1421 fprintf(stderr, "[%p] - %s(%s) %s :: CLIPPEES: ", a, evas_object_type_get(a), evas_object_name_get(a), evas_object_visible_get(a) ? "VISIBLE" : "HIDDEN");
1422 EINA_LIST_FOREACH(l, ll, oo)
1423 fprintf(stderr, "[%p] - %s(%s) %s", oo, evas_object_type_get(oo), evas_object_name_get(oo), ll->next ? "| " : "");
1424 }
1425 else
1426 fprintf(stderr, "[%p] - %s(%s) %s\n", a, evas_object_type_get(a), evas_object_name_get(a), evas_object_visible_get(a) ? "VISIBLE" : "HIDDEN");
1427 }
1428 }
1429
1430 E_API void
e_util_evas_objects_above_print_smart(Evas_Object * o)1431 e_util_evas_objects_above_print_smart(Evas_Object *o)
1432 {
1433 Evas_Object *a, *oo;
1434
1435 EINA_SAFETY_ON_NULL_RETURN(o);
1436 a = o;
1437 while ((a = evas_object_above_get(a)))
1438 {
1439 const Eina_List *l, *ll;
1440
1441 l = evas_object_clipees_get(a);
1442 if (l)
1443 {
1444 fprintf(stderr, "[%p] - %s(%s) %s :: CLIPPEES: ", a, evas_object_type_get(a), evas_object_name_get(a), evas_object_visible_get(a) ? "VISIBLE" : "HIDDEN");
1445 EINA_LIST_FOREACH(l, ll, oo)
1446 fprintf(stderr, "[%p] - %s(%s) %s", oo, evas_object_type_get(oo), evas_object_name_get(oo), ll->next ? "| " : "");
1447 fprintf(stderr, "\n");
1448 }
1449 else if (evas_object_smart_data_get(a))
1450 {
1451 fprintf(stderr, "[%p] - %s(%s) %s :: SMART MEMBERS: ", a, evas_object_type_get(a), evas_object_name_get(a), evas_object_visible_get(a) ? "VISIBLE" : "HIDDEN");
1452 EINA_LIST_FOREACH(evas_object_smart_members_get(a), l, oo)
1453 fprintf(stderr, "[%p] - %s(%s) %s", oo, evas_object_type_get(oo), evas_object_name_get(oo), l->next ? "| " : "");
1454 fprintf(stderr, "\n");
1455 }
1456 else
1457 fprintf(stderr, "[%p] - %s(%s) %s\n", a, evas_object_type_get(a), evas_object_name_get(a), evas_object_visible_get(a) ? "VISIBLE" : "HIDDEN");
1458 }
1459 }
1460
1461 #if defined(HAVE_MEMSET_S)
1462 #elif defined(HAVE_EXPLICIT_BZERO)
1463 #elif defined(HAVE_EXPLICIT_MEMSET)
1464 #else
1465 void *(* const volatile __memset_ptr)(void *, int, size_t) = memset;
1466 #endif
1467
1468 E_API void
e_util_memclear(void * s,size_t n)1469 e_util_memclear(void *s, size_t n)
1470 {
1471 if (n == 0) return;
1472 #if defined(HAVE_MEMSET_S)
1473 memset_s(s, n, 0, n);
1474 #elif defined(HAVE_EXPLICIT_BZERO)
1475 explicit_bzero(s, n);
1476 #elif defined(HAVE_EXPLICIT_MEMSET)
1477 explicit_memset(s, 0, n);
1478 #else
1479 __memset_ptr(s, 0, n);
1480 __asm__ __volatile__("": :"r"(s) : "memory");
1481 #endif
1482 }
1483
1484 E_API Ecore_Exe *
e_util_open(const char * exe,void * data)1485 e_util_open(const char *exe, void *data)
1486 {
1487 char *sb;
1488 size_t size = 65536, len;
1489 Ecore_Exe *ret;
1490
1491 sb = malloc(size);
1492 snprintf(sb, size, "%s/enlightenment_open ", e_prefix_bin_get());
1493 len = strlen(sb);
1494 sb = e_util_string_append_quoted(sb, &size, &len, exe);
1495 ret = e_util_exe_safe_run(sb, data);
1496 free(sb);
1497 return ret;
1498 }
1499
1500 E_API Ecore_Exe *
e_util_exe_safe_run(const char * cmd,void * data)1501 e_util_exe_safe_run(const char *cmd, void *data)
1502 {
1503 Ecore_Exe_Flags flags = ECORE_EXE_NONE;
1504
1505 #if (ECORE_VERSION_MAJOR >= 1) && (ECORE_VERSION_MINOR >= 21)
1506 flags |= ECORE_EXE_ISOLATE_IO;
1507 #else
1508 flags |= 1024; // isolate_io is bit 10 .... it will be ignored if
1509 // efl doesn't do it, so harmless
1510 #endif
1511 return ecore_exe_pipe_run(cmd, flags, data);
1512 }
1513
1514 static Eina_Bool
str_matches_one(const char * instr,const char ** strset)1515 str_matches_one(const char *instr, const char **strset)
1516 {
1517 int i;
1518
1519 if ((!instr) || (!strset)) return EINA_FALSE;
1520 for (i = 0; strset[i]; i++)
1521 {
1522 if (!strcmp(strset[i], instr)) return EINA_TRUE;
1523 }
1524 return EINA_FALSE;
1525 }
1526
1527 E_API E_Util_Action
e_util_key_geometry_action_get(const char * key,int * x,int * y,int dx,int dy)1528 e_util_key_geometry_action_get(const char *key, int *x, int *y, int dx, int dy)
1529 {
1530 const char *k_up[] = { "Up", "KP_Up", "k", "K", "w", "W", NULL };
1531 const char *k_down[] = { "Down", "KP_Down", "j", "J", "s", "S", NULL };
1532 const char *k_left[] = { "Left", "KP_Left", "h", "H", "a", "A", NULL };
1533 const char *k_right[] = { "Right", "KP_Right", "l", "L", "d", "D", NULL };
1534 const char *k_done[] = { "Return", "KP_Enter", "space", NULL };
1535 const char *k_abort[] = { "Escape", "BackSpace", "Delete", "x", "X", NULL };
1536
1537 if (str_matches_one(key, k_up)) *y -= dy;
1538 else if (str_matches_one(key, k_down)) *y += dy;
1539 else if (str_matches_one(key, k_left)) *x -= dx;
1540 else if (str_matches_one(key, k_right)) *x += dx;
1541 else if (str_matches_one(key, k_done)) return E_UTIL_ACTION_DONE;
1542 else if (str_matches_one(key, k_abort)) return E_UTIL_ACTION_ABORT;
1543 else return E_UTIL_ACTION_NONE;
1544
1545 return E_UTIL_ACTION_DO;
1546 }
1547