elementary: Add ecore_cocoa backend to elementary
[framework/uifw/elementary.git] / src / lib / elm_main.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #ifdef HAVE_FORK
6 #include <dlfcn.h> /* dlopen,dlclose,etc */
7 #endif
8
9 #ifdef HAVE_CRT_EXTERNS_H
10 # include <crt_externs.h>
11 #endif
12
13 #ifdef HAVE_EVIL
14 # include <Evil.h>
15 #endif
16
17 #include <Elementary.h>
18 #include "elm_priv.h"
19
20 #define SEMI_BROKEN_QUICKLAUNCH 1
21
22 static Elm_Version _version = { VMAJ, VMIN, VMIC, VREV };
23 EAPI Elm_Version *elm_version = &_version;
24
25 Eina_Bool
26 _elm_dangerous_call_check(const char *call)
27 {
28    char buf[256];
29    const char *eval;
30
31    snprintf(buf, sizeof(buf), "%i.%i.%i.%i", VMAJ, VMIN, VMIC, VREV);
32    eval = getenv("ELM_NO_FINGER_WAGGLING");
33    if ((eval) && (!strcmp(eval, buf)))
34      return 0;
35    printf("ELEMENTARY FINGER WAGGLE!!!!!!!!!!\n"
36           "\n"
37           "  %s() used.\n"
38           "PLEASE see the API documentation for this function. This call\n"
39           "should almost never be used. Only in very special cases.\n"
40           "\n"
41           "To remove this warning please set the environment variable:\n"
42           "  ELM_NO_FINGER_WAGGLING\n"
43           "To the value of the Elementary version + revision number. e.g.:\n"
44           "  1.2.5.40295\n"
45           "\n"
46           ,
47           call);
48    return 1;
49 }
50
51 static Eina_Bool _elm_signal_exit(void *data,
52                                   int   ev_type,
53                                   void *ev);
54
55 static Eina_Prefix *pfx = NULL;
56 char *_elm_appname = NULL;
57 const char *_elm_data_dir = NULL;
58 const char *_elm_lib_dir = NULL;
59 int _elm_log_dom = -1;
60
61 EAPI int ELM_EVENT_POLICY_CHANGED = 0;
62
63 static int _elm_init_count = 0;
64 static int _elm_sub_init_count = 0;
65 static int _elm_ql_init_count = 0;
66 static int _elm_policies[ELM_POLICY_LAST];
67 static Ecore_Event_Handler *_elm_exit_handler = NULL;
68 static Eina_Bool quicklaunch_on = 0;
69
70 static Eina_Bool
71 _elm_signal_exit(void *data  __UNUSED__,
72                  int ev_type __UNUSED__,
73                  void *ev    __UNUSED__)
74 {
75    elm_exit();
76    return ECORE_CALLBACK_PASS_ON;
77 }
78
79 void
80 _elm_rescale(void)
81 {
82    edje_scale_set(_elm_config->scale);
83    _elm_win_rescale(NULL, EINA_FALSE);
84    _elm_ews_wm_rescale(NULL, EINA_FALSE);
85 }
86
87 static void *app_mainfunc = NULL;
88 static const char *app_domain = NULL;
89 static const char *app_checkfile = NULL;
90
91 static const char *app_compile_bin_dir = NULL;
92 static const char *app_compile_lib_dir = NULL;
93 static const char *app_compile_data_dir = NULL;
94 static const char *app_compile_locale_dir = NULL;
95 static const char *app_prefix_dir = NULL;
96 static const char *app_bin_dir = NULL;
97 static const char *app_lib_dir = NULL;
98 static const char *app_data_dir = NULL;
99 static const char *app_locale_dir = NULL;
100
101 static Eina_Prefix *app_pfx = NULL;
102
103 static void
104 _prefix_check(void)
105 {
106    int argc = 0;
107    char **argv = NULL;
108    const char *dirs[4] = { NULL, NULL, NULL, NULL };
109    char *caps = NULL, *p1, *p2;
110
111    if (app_pfx) return;
112    if (!app_domain) return;
113
114    ecore_app_args_get(&argc, &argv);
115    if (argc < 1) return;
116
117    dirs[0] = app_compile_bin_dir;
118    dirs[1] = app_compile_lib_dir;
119    dirs[2] = app_compile_data_dir;
120    dirs[3] = app_compile_locale_dir;
121
122    if (!dirs[1]) dirs[1] = dirs[0];
123    if (!dirs[0]) dirs[0] = dirs[1];
124    if (!dirs[3]) dirs[3] = dirs[2];
125    if (!dirs[2]) dirs[2] = dirs[3];
126
127    if (app_domain)
128      {
129         caps = alloca(strlen(app_domain) + 1);
130         for (p1 = (char *)app_domain, p2 = caps; *p1; p1++, p2++)
131            *p2 = toupper(*p1);
132         *p2 = 0;
133      }
134    app_pfx = eina_prefix_new(argv[0], app_mainfunc, caps, app_domain,
135                              app_checkfile, dirs[0], dirs[1], dirs[2], dirs[3]);
136 }
137
138 static void
139 _prefix_shutdown(void)
140 {
141    if (app_pfx) eina_prefix_free(app_pfx);
142    if (app_domain) eina_stringshare_del(app_domain);
143    if (app_checkfile) eina_stringshare_del(app_checkfile);
144    if (app_compile_bin_dir) eina_stringshare_del(app_compile_bin_dir);
145    if (app_compile_lib_dir) eina_stringshare_del(app_compile_lib_dir);
146    if (app_compile_data_dir) eina_stringshare_del(app_compile_data_dir);
147    if (app_compile_locale_dir) eina_stringshare_del(app_compile_locale_dir);
148    if (app_prefix_dir) eina_stringshare_del(app_prefix_dir);
149    if (app_bin_dir) eina_stringshare_del(app_bin_dir);
150    if (app_lib_dir) eina_stringshare_del(app_lib_dir);
151    if (app_data_dir) eina_stringshare_del(app_data_dir);
152    if (app_locale_dir) eina_stringshare_del(app_locale_dir);
153    app_mainfunc = NULL;
154    app_domain = NULL;
155    app_checkfile = NULL;
156    app_compile_bin_dir = NULL;
157    app_compile_lib_dir = NULL;
158    app_compile_data_dir = NULL;
159    app_compile_locale_dir = NULL;
160    app_prefix_dir = NULL;
161    app_bin_dir = NULL;
162    app_lib_dir = NULL;
163    app_data_dir = NULL;
164    app_locale_dir = NULL;
165    app_pfx = NULL;
166 }
167
168 EAPI int
169 elm_init(int    argc,
170          char **argv)
171 {
172    _elm_init_count++;
173    if (_elm_init_count > 1) return _elm_init_count;
174    elm_quicklaunch_init(argc, argv);
175    elm_quicklaunch_sub_init(argc, argv);
176    _prefix_shutdown();
177    return _elm_init_count;
178 }
179
180 EAPI int
181 elm_shutdown(void)
182 {
183    _elm_init_count--;
184    if (_elm_init_count > 0) return _elm_init_count;
185    _elm_win_shutdown();
186    while (_elm_win_deferred_free) ecore_main_loop_iterate();
187 // wrningz :(
188 //   _prefix_shutdown();
189    elm_quicklaunch_sub_shutdown();
190    elm_quicklaunch_shutdown();
191    return _elm_init_count;
192 }
193
194 EAPI void
195 elm_app_info_set(void *mainfunc, const char *dom, const char *checkfile)
196 {
197    app_mainfunc = mainfunc;
198    eina_stringshare_replace(&app_domain, dom);
199    eina_stringshare_replace(&app_checkfile, checkfile);
200 }
201
202 EAPI void
203 elm_app_compile_bin_dir_set(const char *dir)
204 {
205    eina_stringshare_replace(&app_compile_bin_dir, dir);
206 }
207
208 EAPI void
209 elm_app_compile_lib_dir_set(const char *dir)
210 {
211    eina_stringshare_replace(&app_compile_lib_dir, dir);
212 }
213
214 EAPI void
215 elm_app_compile_data_dir_set(const char *dir)
216 {
217    eina_stringshare_replace(&app_compile_data_dir, dir);
218 }
219
220 EAPI void
221 elm_app_compile_locale_set(const char *dir)
222 {
223    eina_stringshare_replace(&app_compile_locale_dir, dir);
224 }
225
226 EAPI const char *
227 elm_app_prefix_dir_get(void)
228 {
229    if (app_prefix_dir) return app_prefix_dir;
230    _prefix_check();
231   if (!app_pfx) return "";
232    app_prefix_dir = eina_prefix_get(app_pfx);
233    return app_prefix_dir;
234 }
235
236 EAPI const char *
237 elm_app_bin_dir_get(void)
238 {
239    if (app_bin_dir) return app_bin_dir;
240    _prefix_check();
241    if (!app_pfx) return "";
242    app_bin_dir = eina_prefix_bin_get(app_pfx);
243    return app_bin_dir;
244 }
245
246 EAPI const char *
247 elm_app_lib_dir_get(void)
248 {
249    if (app_lib_dir) return app_lib_dir;
250    _prefix_check();
251    if (!app_pfx) return "";
252    app_lib_dir = eina_prefix_lib_get(app_pfx);
253    return app_lib_dir;
254 }
255
256 EAPI const char *
257 elm_app_data_dir_get(void)
258 {
259    if (app_data_dir) return app_data_dir;
260    _prefix_check();
261    if (!app_pfx) return "";
262    app_data_dir = eina_prefix_data_get(app_pfx);
263    return app_data_dir;
264 }
265
266 EAPI const char *
267 elm_app_locale_dir_get(void)
268 {
269    if (app_locale_dir) return app_locale_dir;
270    _prefix_check();
271    if (!app_pfx) return "";
272    app_locale_dir = eina_prefix_locale_get(app_pfx);
273    return app_locale_dir;
274 }
275
276 #ifdef ELM_EDBUS
277 static int _elm_need_e_dbus = 0;
278 #endif
279 EAPI Eina_Bool
280 elm_need_e_dbus(void)
281 {
282 #ifdef ELM_EDBUS
283    if (_elm_need_e_dbus++) return EINA_TRUE;
284    e_dbus_init();
285    return EINA_TRUE;
286 #else
287    return EINA_FALSE;
288 #endif
289 }
290
291 static void
292 _elm_unneed_e_dbus(void)
293 {
294 #ifdef ELM_EDBUS
295    if (--_elm_need_e_dbus) return;
296
297    _elm_need_e_dbus = 0;
298    e_dbus_shutdown();
299 #endif
300 }
301
302 #ifdef ELM_EFREET
303 static int _elm_need_efreet = 0;
304 #endif
305 EAPI Eina_Bool
306 elm_need_efreet(void)
307 {
308 #ifdef ELM_EFREET
309    if (_elm_need_efreet++) return EINA_TRUE;
310    efreet_init();
311    efreet_mime_init();
312    efreet_trash_init();
313     /*
314      {
315         Eina_List **list;
316
317         list = efreet_icon_extra_list_get();
318         if (list)
319           {
320              e_user_dir_concat_static(buf, "icons");
321              *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
322              e_prefix_data_concat_static(buf, "data/icons");
323              *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
324           }
325      }
326    */
327    return EINA_TRUE;
328 #else
329    return EINA_FALSE;
330 #endif
331 }
332
333 static void
334 _elm_unneed_efreet(void)
335 {
336 #ifdef ELM_EFREET
337    if (--_elm_need_efreet) return;
338
339    _elm_need_efreet = 0;
340    efreet_trash_shutdown();
341    efreet_mime_shutdown();
342    efreet_shutdown();
343 #endif
344 }
345
346 EAPI void
347 elm_quicklaunch_mode_set(Eina_Bool ql_on)
348 {
349    quicklaunch_on = ql_on;
350 }
351
352 EAPI Eina_Bool
353 elm_quicklaunch_mode_get(void)
354 {
355    return quicklaunch_on;
356 }
357
358 EAPI int
359 elm_quicklaunch_init(int    argc,
360                      char **argv)
361 {
362    _elm_ql_init_count++;
363    if (_elm_ql_init_count > 1) return _elm_ql_init_count;
364    eina_init();
365    _elm_log_dom = eina_log_domain_register("elementary", EINA_COLOR_LIGHTBLUE);
366    if (!_elm_log_dom)
367      {
368         EINA_LOG_ERR("could not register elementary log domain.");
369         _elm_log_dom = EINA_LOG_DOMAIN_GLOBAL;
370      }
371
372    eet_init();
373    ecore_init();
374
375 #ifdef HAVE_ELEMENTARY_EMAP
376    emap_init();
377 #endif
378    ecore_app_args_set(argc, (const char **)argv);
379
380    memset(_elm_policies, 0, sizeof(_elm_policies));
381    if (!ELM_EVENT_POLICY_CHANGED)
382      ELM_EVENT_POLICY_CHANGED = ecore_event_type_new();
383
384    ecore_file_init();
385
386    _elm_exit_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, NULL);
387
388    if (argv) _elm_appname = strdup(ecore_file_file_get(argv[0]));
389
390    pfx = eina_prefix_new(argv[0], elm_quicklaunch_init,
391                          "ELM", "elementary", "config/profile.cfg",
392                          PACKAGE_LIB_DIR, /* don't have a bin dir currently */
393                          PACKAGE_LIB_DIR,
394                          PACKAGE_DATA_DIR,
395                          LOCALE_DIR);
396    if (pfx)
397      {
398         _elm_data_dir = eina_stringshare_add(eina_prefix_data_get(pfx));
399         _elm_lib_dir = eina_stringshare_add(eina_prefix_lib_get(pfx));
400      }
401    if (!_elm_data_dir) _elm_data_dir = eina_stringshare_add("/");
402    if (!_elm_lib_dir) _elm_lib_dir = eina_stringshare_add("/");
403
404    _elm_config_init();
405    return _elm_ql_init_count;
406 }
407
408 EAPI int
409 elm_quicklaunch_sub_init(int    argc,
410                          char **argv)
411 {
412    _elm_sub_init_count++;
413    if (_elm_sub_init_count > 1) return _elm_sub_init_count;
414    if (quicklaunch_on)
415      {
416 #ifdef SEMI_BROKEN_QUICKLAUNCH
417         return _elm_sub_init_count;
418 #endif
419      }
420    if (!quicklaunch_on)
421      {
422         ecore_app_args_set(argc, (const char **)argv);
423         evas_init();
424         edje_init();
425         _elm_module_init();
426         _elm_config_sub_init();
427         ecore_evas_init(); // FIXME: check errors
428         ecore_imf_init();
429         ecore_con_init();
430         ecore_con_url_init();
431         _elm_ews_wm_init();
432      }
433    return _elm_sub_init_count;
434 }
435
436 EAPI int
437 elm_quicklaunch_sub_shutdown(void)
438 {
439    _elm_sub_init_count--;
440    if (_elm_sub_init_count > 0) return _elm_sub_init_count;
441    if (quicklaunch_on)
442      {
443 #ifdef SEMI_BROKEN_QUICKLAUNCH
444         return _elm_sub_init_count;
445 #endif
446      }
447    if (!quicklaunch_on)
448      {
449         _elm_win_shutdown();
450         _elm_module_shutdown();
451         _elm_ews_wm_shutdown();
452         ecore_con_url_shutdown();
453         ecore_con_shutdown();
454         ecore_imf_shutdown();
455         ecore_evas_shutdown();
456         _elm_config_sub_shutdown();
457 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
458         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
459             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
460             ENGINE_COMPARE(ELM_XRENDER_X11) ||
461             ENGINE_COMPARE(ELM_OPENGL_X11) ||
462             ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
463             ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
464             ENGINE_COMPARE(ELM_OPENGL_SDL) ||
465             ENGINE_COMPARE(ELM_OPENGL_COCOA) ||
466             ENGINE_COMPARE(ELM_SOFTWARE_WIN32) ||
467             ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE) ||
468             ENGINE_COMPARE(ELM_EWS))
469 #undef ENGINE_COMPARE
470           evas_cserve_disconnect();
471         edje_shutdown();
472         evas_shutdown();
473      }
474    return _elm_sub_init_count;
475 }
476
477 EAPI int
478 elm_quicklaunch_shutdown(void)
479 {
480    _elm_ql_init_count--;
481    if (_elm_ql_init_count > 0) return _elm_ql_init_count;
482    if (pfx) eina_prefix_free(pfx);
483    pfx = NULL;
484    eina_stringshare_del(_elm_data_dir);
485    _elm_data_dir = NULL;
486    eina_stringshare_del(_elm_lib_dir);
487    _elm_lib_dir = NULL;
488
489    free(_elm_appname);
490    _elm_appname = NULL;
491
492    _elm_config_shutdown();
493
494    ecore_event_handler_del(_elm_exit_handler);
495    _elm_exit_handler = NULL;
496
497    _elm_theme_shutdown();
498    _elm_unneed_efreet();
499    _elm_unneed_e_dbus();
500    _elm_unneed_ethumb();
501    _elm_unneed_web();
502    ecore_file_shutdown();
503
504 #ifdef HAVE_ELEMENTARY_EMAP
505    emap_shutdown();
506 #endif
507
508    ecore_shutdown();
509    eet_shutdown();
510
511    if ((_elm_log_dom > -1) && (_elm_log_dom != EINA_LOG_DOMAIN_GLOBAL))
512      {
513         eina_log_domain_unregister(_elm_log_dom);
514         _elm_log_dom = -1;
515      }
516
517    _elm_widget_type_clear();
518
519    eina_shutdown();
520    return _elm_ql_init_count;
521 }
522
523 EAPI void
524 elm_quicklaunch_seed(void)
525 {
526 #ifndef SEMI_BROKEN_QUICKLAUNCH
527    if (quicklaunch_on)
528      {
529         Evas_Object *win, *bg, *bt;
530
531         win = elm_win_add(NULL, "seed", ELM_WIN_BASIC);
532         bg = elm_bg_add(win);
533         elm_win_resize_object_add(win, bg);
534         evas_object_show(bg);
535         bt = elm_button_add(win);
536         elm_button_label_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?");
537         elm_win_resize_object_add(win, bt);
538         ecore_main_loop_iterate();
539         evas_object_del(win);
540         ecore_main_loop_iterate();
541 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
542         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
543             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
544             ENGINE_COMPARE(ELM_XRENDER_X11) ||
545             ENGINE_COMPARE(ELM_OPENGL_X11))
546 #undef ENGINE_COMPARE
547           {
548 # ifdef HAVE_ELEMENTARY_X
549              ecore_x_sync();
550 # endif
551           }
552         ecore_main_loop_iterate();
553      }
554 #endif
555 }
556
557 #ifdef HAVE_FORK
558 static void *qr_handle = NULL;
559 #endif
560 static int (*qr_main)(int    argc,
561                       char **argv) = NULL;
562
563 EAPI Eina_Bool
564 elm_quicklaunch_prepare(int argc __UNUSED__,
565                         char   **argv)
566 {
567 #ifdef HAVE_FORK
568    char *exe = elm_quicklaunch_exe_path_get(argv[0]);
569    if (!exe)
570      {
571         ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
572         return EINA_FALSE;
573      }
574    else
575      {
576         char *exe2, *p;
577         char *exename;
578
579         exe2 = malloc(strlen(exe) + 1 + 10);
580         strcpy(exe2, exe);
581         p = strrchr(exe2, '/');
582         if (p) p++;
583         else p = exe2;
584         exename = alloca(strlen(p) + 1);
585         strcpy(exename, p);
586         *p = 0;
587         strcat(p, "../lib/");
588         strcat(p, exename);
589         strcat(p, ".so");
590         if (!access(exe2, R_OK | X_OK))
591           {
592              free(exe);
593              exe = exe2;
594           }
595         else
596           free(exe2);
597      }
598    qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
599    if (!qr_handle)
600      {
601         fprintf(stderr, "dlerr: %s\n", dlerror());
602         WRN("dlopen('%s') failed: %s", exe, dlerror());
603         free(exe);
604         return EINA_FALSE;
605      }
606    INF("dlopen('%s') = %p", exe, qr_handle);
607    qr_main = dlsym(qr_handle, "elm_main");
608    INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
609    if (!qr_main)
610      {
611         WRN("not quicklauncher capable: no elm_main in '%s'", exe);
612         dlclose(qr_handle);
613         qr_handle = NULL;
614         free(exe);
615         return EINA_FALSE;
616      }
617    free(exe);
618    return EINA_TRUE;
619 #else
620    return EINA_FALSE;
621    (void)argv;
622 #endif
623 }
624
625 #ifdef HAVE_FORK
626 static void
627 save_env(void)
628 {
629    int i, size;
630    extern char **environ;
631    char **oldenv, **p;
632
633    oldenv = environ;
634
635    for (i = 0, size = 0; environ[i]; i++)
636      size += strlen(environ[i]) + 1;
637
638    p = malloc((i + 1) * sizeof(char *));
639    if (!p) return;
640
641    environ = p;
642
643    for (i = 0; oldenv[i]; i++)
644      environ[i] = strdup(oldenv[i]);
645    environ[i] = NULL;
646 }
647
648 #endif
649
650 EAPI Eina_Bool
651 elm_quicklaunch_fork(int    argc,
652                      char **argv,
653                      char  *cwd,
654                      void (postfork_func) (void *data),
655                      void  *postfork_data)
656 {
657 #ifdef HAVE_FORK
658    pid_t child;
659    int ret;
660    int real_argc;
661    char **real_argv;
662
663    // FIXME:
664    // need to accept current environment from elementary_run
665    if (!qr_main)
666      {
667         int i;
668         char **args;
669
670         child = fork();
671         if (child > 0) return EINA_TRUE;
672         else if (child < 0)
673           {
674              perror("could not fork");
675              return EINA_FALSE;
676           }
677         setsid();
678         if (chdir(cwd) != 0)
679           perror("could not chdir");
680         args = alloca((argc + 1) * sizeof(char *));
681         for (i = 0; i < argc; i++) args[i] = argv[i];
682         args[argc] = NULL;
683         WRN("%s not quicklaunch capable, fallback...", argv[0]);
684         execvp(argv[0], args);
685         ERR("failed to execute '%s': %s", argv[0], strerror(errno));
686         exit(-1);
687      }
688    child = fork();
689    if (child > 0) return EINA_TRUE;
690    else if (child < 0)
691      {
692         perror("could not fork");
693         return EINA_FALSE;
694      }
695    if (postfork_func) postfork_func(postfork_data);
696
697    if (quicklaunch_on)
698      {
699 #ifdef SEMI_BROKEN_QUICKLAUNCH
700         ecore_app_args_set(argc, (const char **)argv);
701         evas_init();
702         edje_init();
703         _elm_config_sub_init();
704 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
705         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
706             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
707             ENGINE_COMPARE(ELM_XRENDER_X11) ||
708             ENGINE_COMPARE(ELM_OPENGL_X11))
709 #undef ENGINE_COMPARE
710           {
711 # ifdef HAVE_ELEMENTARY_X
712              ecore_x_init(NULL);
713 # endif
714           }
715         ecore_evas_init(); // FIXME: check errors
716         ecore_imf_init();
717         _elm_module_init();
718 #endif
719      }
720
721    setsid();
722    if (chdir(cwd) != 0)
723      perror("could not chdir");
724    // FIXME: this is very linux specific. it changes argv[0] of the process
725    // so ps etc. report what you'd expect. for other unixes and os's this
726    // may just not work
727    save_env();
728    if (argv)
729      {
730         char *lastarg, *p;
731
732         ecore_app_args_get(&real_argc, &real_argv);
733         lastarg = real_argv[real_argc - 1] + strlen(real_argv[real_argc - 1]);
734         for (p = real_argv[0]; p < lastarg; p++) *p = 0;
735         strcpy(real_argv[0], argv[0]);
736      }
737    ecore_app_args_set(argc, (const char **)argv);
738    ret = qr_main(argc, argv);
739    exit(ret);
740    return EINA_TRUE;
741 #else
742    return EINA_FALSE;
743    (void)argc;
744    (void)argv;
745    (void)cwd;
746    (void)postfork_func;
747    (void)postfork_data;
748 #endif
749 }
750
751 EAPI void
752 elm_quicklaunch_cleanup(void)
753 {
754 #ifdef HAVE_FORK
755    if (qr_handle)
756      {
757         dlclose(qr_handle);
758         qr_handle = NULL;
759         qr_main = NULL;
760      }
761 #endif
762 }
763
764 EAPI int
765 elm_quicklaunch_fallback(int    argc,
766                          char **argv)
767 {
768    int ret;
769    elm_quicklaunch_init(argc, argv);
770    elm_quicklaunch_sub_init(argc, argv);
771    elm_quicklaunch_prepare(argc, argv);
772    ret = qr_main(argc, argv);
773    exit(ret);
774    return ret;
775 }
776
777 EAPI char *
778 elm_quicklaunch_exe_path_get(const char *exe)
779 {
780    static char *path = NULL;
781    static Eina_List *pathlist = NULL;
782    const char *pathitr;
783    const Eina_List *l;
784    char buf[PATH_MAX];
785    if (exe[0] == '/') return strdup(exe);
786    if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe);
787    if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe);
788    if (!path)
789      {
790         const char *p, *pp;
791         char *buf2;
792         path = getenv("PATH");
793         buf2 = alloca(strlen(path) + 1);
794         p = path;
795         pp = p;
796         for (;; )
797           {
798              if ((*p == ':') || (!*p))
799                {
800                   int len;
801
802                   len = p - pp;
803                   strncpy(buf2, pp, len);
804                   buf2[len] = 0;
805                   pathlist = eina_list_append(pathlist, eina_stringshare_add(buf2));
806                   if (!*p) break;
807                   p++;
808                   pp = p;
809                }
810              else
811                {
812                   if (!*p) break;
813                   p++;
814                }
815           }
816      }
817    EINA_LIST_FOREACH(pathlist, l, pathitr)
818      {
819         snprintf(buf, sizeof(buf), "%s/%s", pathitr, exe);
820         if (!access(buf, R_OK | X_OK)) return strdup(buf);
821      }
822    return NULL;
823 }
824
825 EAPI void
826 elm_run(void)
827 {
828    ecore_main_loop_begin();
829 }
830
831 EAPI void
832 elm_exit(void)
833 {
834    ecore_main_loop_quit();
835 }
836
837 EAPI Eina_Bool
838 elm_policy_set(unsigned int policy,
839                int          value)
840 {
841    Elm_Event_Policy_Changed *ev;
842
843    if (policy >= ELM_POLICY_LAST)
844      return EINA_FALSE;
845
846    if (value == _elm_policies[policy])
847      return EINA_TRUE;
848
849    /* TODO: validade policy? */
850
851    ev = malloc(sizeof(*ev));
852    ev->policy = policy;
853    ev->new_value = value;
854    ev->old_value = _elm_policies[policy];
855
856    _elm_policies[policy] = value;
857
858    ecore_event_add(ELM_EVENT_POLICY_CHANGED, ev, NULL, NULL);
859
860    return EINA_TRUE;
861 }
862
863 EAPI int
864 elm_policy_get(unsigned int policy)
865 {
866    if (policy >= ELM_POLICY_LAST)
867      return 0;
868    return _elm_policies[policy];
869 }
870
871 EAPI void
872 elm_language_set(const char *lang)
873 {
874    setlocale(LC_ALL, lang);
875    _elm_win_translate();
876 }
877
878 EAPI Eina_Bool
879 elm_object_mirrored_get(const Evas_Object *obj)
880 {
881    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
882    return elm_widget_mirrored_get(obj);
883 }
884
885 EAPI void
886 elm_object_mirrored_set(Evas_Object *obj, Eina_Bool mirrored)
887 {
888    EINA_SAFETY_ON_NULL_RETURN(obj);
889    elm_widget_mirrored_set(obj, mirrored);
890 }
891
892 EAPI Eina_Bool
893 elm_object_mirrored_automatic_get(const Evas_Object *obj)
894 {
895    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
896    return elm_widget_mirrored_automatic_get(obj);
897 }
898
899 EAPI void
900 elm_object_mirrored_automatic_set(Evas_Object *obj, Eina_Bool automatic)
901 {
902    EINA_SAFETY_ON_NULL_RETURN(obj);
903    elm_widget_mirrored_automatic_set(obj, automatic);
904 }
905
906 /**
907  * @}
908  */
909
910 EAPI void
911 elm_object_scale_set(Evas_Object *obj,
912                      double       scale)
913 {
914    EINA_SAFETY_ON_NULL_RETURN(obj);
915    elm_widget_scale_set(obj, scale);
916 }
917
918 EAPI double
919 elm_object_scale_get(const Evas_Object *obj)
920 {
921    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0.0);
922    return elm_widget_scale_get(obj);
923 }
924
925 EAPI void
926 elm_object_text_part_set(Evas_Object *obj, const char *part, const char *label)
927 {
928    EINA_SAFETY_ON_NULL_RETURN(obj);
929    elm_widget_text_part_set(obj, part, label);
930 }
931
932 EAPI const char *
933 elm_object_text_part_get(const Evas_Object *obj, const char *part)
934 {
935    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
936    return elm_widget_text_part_get(obj, part);
937 }
938
939 EAPI void
940 elm_object_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *text)
941 {
942    EINA_SAFETY_ON_NULL_RETURN(obj);
943    elm_widget_domain_translatable_text_part_set(obj, part, domain, text);
944 }
945
946 EAPI const char *
947 elm_object_translatable_text_part_get(const Evas_Object *obj, const char *part)
948 {
949    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
950    return elm_widget_translatable_text_part_get(obj, part);
951 }
952
953 EAPI void
954 elm_object_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
955 {
956    EINA_SAFETY_ON_NULL_RETURN(obj);
957    elm_widget_content_part_set(obj, part, content);
958 }
959
960 EAPI Evas_Object *
961 elm_object_content_part_get(const Evas_Object *obj, const char *part)
962 {
963    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
964    return elm_widget_content_part_get(obj, part);
965 }
966
967 EAPI Evas_Object *
968 elm_object_content_part_unset(Evas_Object *obj, const char *part)
969 {
970    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
971    return elm_widget_content_part_unset(obj, part);
972 }
973
974 EAPI double
975 elm_scale_get(void)
976 {
977    return _elm_config->scale;
978 }
979
980 EAPI void
981 elm_scale_set(double scale)
982 {
983    if (_elm_config->scale == scale) return;
984    _elm_config->scale = scale;
985    _elm_rescale();
986 }
987
988 EAPI void
989 elm_scale_all_set(double scale)
990 {
991    elm_scale_set(scale);
992    _elm_config_all_update();
993 }
994
995 EAPI Eina_Bool
996 elm_password_show_last_get(void)
997 {
998    return _elm_config->password_show_last;
999 }
1000
1001 EAPI void
1002 elm_password_show_last_set(Eina_Bool password_show_last)
1003 {
1004    if (_elm_config->password_show_last == password_show_last) return;
1005    _elm_config->password_show_last = password_show_last;
1006    edje_password_show_last_set(_elm_config->password_show_last);
1007 }
1008
1009 EAPI double
1010 elm_password_show_last_timeout_get(void)
1011 {
1012    return _elm_config->password_show_last_timeout;
1013 }
1014
1015 EAPI void
1016 elm_password_show_last_timeout_set(double password_show_last_timeout)
1017 {
1018    if (_elm_config->password_show_last_timeout == password_show_last_timeout) return;
1019    _elm_config->password_show_last_timeout = password_show_last_timeout;
1020    edje_password_show_last_timeout_set(_elm_config->password_show_last_timeout);
1021 }
1022
1023 EAPI void
1024 elm_object_style_set(Evas_Object *obj,
1025                      const char  *style)
1026 {
1027    EINA_SAFETY_ON_NULL_RETURN(obj);
1028    elm_widget_style_set(obj, style);
1029 }
1030
1031 EAPI const char *
1032 elm_object_style_get(const Evas_Object *obj)
1033 {
1034    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1035    return elm_widget_style_get(obj);
1036 }
1037
1038 EAPI void
1039 elm_object_disabled_set(Evas_Object *obj,
1040                         Eina_Bool    disabled)
1041 {
1042    EINA_SAFETY_ON_NULL_RETURN(obj);
1043    elm_widget_disabled_set(obj, disabled);
1044 }
1045
1046 EAPI Eina_Bool
1047 elm_object_disabled_get(const Evas_Object *obj)
1048 {
1049    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1050    return elm_widget_disabled_get(obj);
1051 }
1052
1053 EAPI Eina_Bool
1054 elm_config_save(void)
1055 {
1056    return _elm_config_save();
1057 }
1058
1059 EAPI void
1060 elm_config_reload(void)
1061 {
1062    _elm_config_reload();
1063 }
1064
1065 EAPI const char *
1066 elm_profile_current_get(void)
1067 {
1068    return _elm_config_current_profile_get();
1069 }
1070
1071 EAPI const char *
1072 elm_profile_dir_get(const char *profile,
1073                     Eina_Bool   is_user)
1074 {
1075    return _elm_config_profile_dir_get(profile, is_user);
1076 }
1077
1078 EAPI void
1079 elm_profile_dir_free(const char *p_dir)
1080 {
1081    free((void *)p_dir);
1082 }
1083
1084 EAPI Eina_List *
1085 elm_profile_list_get(void)
1086 {
1087    return _elm_config_profiles_list();
1088 }
1089
1090 EAPI void
1091 elm_profile_list_free(Eina_List *l)
1092 {
1093    const char *dir;
1094
1095    EINA_LIST_FREE(l, dir)
1096      eina_stringshare_del(dir);
1097 }
1098
1099 EAPI void
1100 elm_profile_set(const char *profile)
1101 {
1102    EINA_SAFETY_ON_NULL_RETURN(profile);
1103    _elm_config_profile_set(profile);
1104 }
1105
1106 EAPI void
1107 elm_profile_all_set(const char *profile)
1108 {
1109    _elm_config_profile_set(profile);
1110    _elm_config_all_update();
1111 }
1112
1113 EAPI const char *
1114 elm_engine_current_get(void)
1115 {
1116    return _elm_config->engine;
1117 }
1118
1119 EAPI void
1120 elm_engine_set(const char *engine)
1121 {
1122    EINA_SAFETY_ON_NULL_RETURN(engine);
1123
1124    _elm_config_engine_set(engine);
1125 }
1126
1127 EAPI const Eina_List *
1128 elm_text_classes_list_get(void)
1129 {
1130    return _elm_config_text_classes_get();
1131 }
1132
1133 EAPI void
1134 elm_text_classes_list_free(const Eina_List *list)
1135 {
1136    _elm_config_text_classes_free((Eina_List *)list);
1137 }
1138
1139 EAPI const Eina_List *
1140 elm_font_overlay_list_get(void)
1141 {
1142    return _elm_config_font_overlays_list();
1143 }
1144
1145 EAPI void
1146 elm_font_overlay_set(const char    *text_class,
1147                      const char    *font,
1148                      Evas_Font_Size size)
1149 {
1150    _elm_config_font_overlay_set(text_class, font, size);
1151 }
1152
1153 EAPI void
1154 elm_font_overlay_unset(const char *text_class)
1155 {
1156    _elm_config_font_overlay_remove(text_class);
1157 }
1158
1159 EAPI void
1160 elm_font_overlay_apply(void)
1161 {
1162    _elm_config_font_overlay_apply();
1163 }
1164
1165 EAPI void
1166 elm_font_overlay_all_apply(void)
1167 {
1168    elm_font_overlay_apply();
1169    _elm_config_all_update();
1170 }
1171
1172 EAPI Elm_Font_Properties *
1173 elm_font_properties_get(const char *font)
1174 {
1175    EINA_SAFETY_ON_NULL_RETURN_VAL(font, NULL);
1176    return _elm_font_properties_get(NULL, font);
1177 }
1178
1179 EAPI void
1180 elm_font_properties_free(Elm_Font_Properties *efp)
1181 {
1182    const char *str;
1183
1184    EINA_SAFETY_ON_NULL_RETURN(efp);
1185    EINA_LIST_FREE(efp->styles, str)
1186      if (str) eina_stringshare_del(str);
1187    if (efp->name) eina_stringshare_del(efp->name);
1188    free(efp);
1189 }
1190
1191 EAPI const char *
1192 elm_font_fontconfig_name_get(const char *name,
1193                              const char *style)
1194 {
1195    char buf[256];
1196
1197    EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
1198    if (!style || style[0] == 0) return eina_stringshare_add(name);
1199    snprintf(buf, 256, "%s" ELM_FONT_TOKEN_STYLE "%s", name, style);
1200    return eina_stringshare_add(buf);
1201 }
1202
1203 EAPI void
1204 elm_font_fontconfig_name_free(const char *name)
1205 {
1206    eina_stringshare_del(name);
1207 }
1208
1209 EAPI Eina_Hash *
1210 elm_font_available_hash_add(Eina_List *list)
1211 {
1212    Eina_Hash *font_hash;
1213    Eina_List *l;
1214    void *key;
1215
1216    font_hash = NULL;
1217
1218    /* populate with default font families */
1219    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Regular");
1220    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold");
1221    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Oblique");
1222    font_hash = _elm_font_available_hash_add(font_hash,
1223                                             "Sans:style=Bold Oblique");
1224
1225    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Regular");
1226    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold");
1227    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Oblique");
1228    font_hash = _elm_font_available_hash_add(font_hash,
1229                                             "Serif:style=Bold Oblique");
1230
1231    font_hash = _elm_font_available_hash_add(font_hash,
1232                                             "Monospace:style=Regular");
1233    font_hash = _elm_font_available_hash_add(font_hash,
1234                                             "Monospace:style=Bold");
1235    font_hash = _elm_font_available_hash_add(font_hash,
1236                                             "Monospace:style=Oblique");
1237    font_hash = _elm_font_available_hash_add(font_hash,
1238                                             "Monospace:style=Bold Oblique");
1239
1240    EINA_LIST_FOREACH(list, l, key)
1241      font_hash = _elm_font_available_hash_add(font_hash, key);
1242
1243    return font_hash;
1244 }
1245
1246 EAPI void
1247 elm_font_available_hash_del(Eina_Hash *hash)
1248 {
1249    _elm_font_available_hash_del(hash);
1250 }
1251
1252 EAPI Evas_Coord
1253 elm_finger_size_get(void)
1254 {
1255    return _elm_config->finger_size;
1256 }
1257
1258 EAPI void
1259 elm_finger_size_set(Evas_Coord size)
1260 {
1261    if (_elm_config->finger_size == size) return;
1262    _elm_config->finger_size = size;
1263    _elm_rescale();
1264 }
1265
1266 EAPI void
1267 elm_finger_size_all_set(Evas_Coord size)
1268 {
1269    elm_finger_size_set(size);
1270    _elm_config_all_update();
1271 }
1272
1273 EAPI void
1274 elm_coords_finger_size_adjust(int         times_w,
1275                               Evas_Coord *w,
1276                               int         times_h,
1277                               Evas_Coord *h)
1278 {
1279    if ((w) && (*w < (_elm_config->finger_size * times_w)))
1280      *w = _elm_config->finger_size * times_w;
1281    if ((h) && (*h < (_elm_config->finger_size * times_h)))
1282      *h = _elm_config->finger_size * times_h;
1283 }
1284
1285 EAPI void
1286 elm_all_flush(void)
1287 {
1288    const Eina_List *l;
1289    Evas_Object *obj;
1290
1291    edje_file_cache_flush();
1292    edje_collection_cache_flush();
1293    eet_clearcache();
1294    EINA_LIST_FOREACH(_elm_win_list, l, obj)
1295      {
1296         Evas *e = evas_object_evas_get(obj);
1297         evas_image_cache_flush(e);
1298         evas_font_cache_flush(e);
1299         evas_render_dump(e);
1300      }
1301 }
1302
1303 EAPI int
1304 elm_cache_flush_interval_get(void)
1305 {
1306    return _elm_config->cache_flush_poll_interval;
1307 }
1308
1309 EAPI void
1310 elm_cache_flush_interval_set(int size)
1311 {
1312    if (_elm_config->cache_flush_poll_interval == size) return;
1313    _elm_config->cache_flush_poll_interval = size;
1314
1315    _elm_recache();
1316 }
1317
1318 EAPI void
1319 elm_cache_flush_interval_all_set(int size)
1320 {
1321    elm_cache_flush_interval_set(size);
1322    _elm_config_all_update();
1323 }
1324
1325 EAPI Eina_Bool
1326 elm_cache_flush_enabled_get(void)
1327 {
1328    return _elm_config->cache_flush_enable;
1329 }
1330
1331 EAPI void
1332 elm_cache_flush_enabled_set(Eina_Bool enabled)
1333 {
1334    enabled = !!enabled;
1335    if (_elm_config->cache_flush_enable == enabled) return;
1336    _elm_config->cache_flush_enable = enabled;
1337
1338    _elm_recache();
1339 }
1340
1341 EAPI void
1342 elm_cache_flush_enabled_all_set(Eina_Bool enabled)
1343 {
1344    elm_cache_flush_enabled_set(enabled);
1345    _elm_config_all_update();
1346 }
1347
1348 EAPI int
1349 elm_font_cache_get(void)
1350 {
1351    return _elm_config->font_cache;
1352 }
1353
1354 EAPI void
1355 elm_font_cache_set(int size)
1356 {
1357    if (_elm_config->font_cache == size) return;
1358    _elm_config->font_cache = size;
1359
1360    _elm_recache();
1361 }
1362
1363 EAPI void
1364 elm_font_cache_all_set(int size)
1365 {
1366    elm_font_cache_set(size);
1367    _elm_config_all_update();
1368 }
1369
1370 EAPI int
1371 elm_image_cache_get(void)
1372 {
1373    return _elm_config->image_cache;
1374 }
1375
1376 EAPI void
1377 elm_image_cache_set(int size)
1378 {
1379    if (_elm_config->image_cache == size) return;
1380    _elm_config->image_cache = size;
1381
1382    _elm_recache();
1383 }
1384
1385 EAPI void
1386 elm_image_cache_all_set(int size)
1387 {
1388    elm_image_cache_set(size);
1389    _elm_config_all_update();
1390 }
1391
1392 EAPI int
1393 elm_edje_file_cache_get(void)
1394 {
1395    return _elm_config->edje_cache;
1396 }
1397
1398 EAPI void
1399 elm_edje_file_cache_set(int size)
1400 {
1401    if (_elm_config->edje_cache == size) return;
1402    _elm_config->edje_cache = size;
1403
1404    _elm_recache();
1405 }
1406
1407 EAPI void
1408 elm_edje_file_cache_all_set(int size)
1409 {
1410    elm_edje_file_cache_set(size);
1411    _elm_config_all_update();
1412 }
1413
1414 EAPI int
1415 elm_edje_collection_cache_get(void)
1416 {
1417    return _elm_config->edje_collection_cache;
1418 }
1419
1420 EAPI void
1421 elm_edje_collection_cache_set(int size)
1422 {
1423    if (_elm_config->edje_collection_cache == size) return;
1424    _elm_config->edje_collection_cache = size;
1425
1426    _elm_recache();
1427 }
1428
1429 EAPI void
1430 elm_edje_collection_cache_all_set(int size)
1431 {
1432    elm_edje_collection_cache_set(size);
1433    _elm_config_all_update();
1434 }
1435
1436 EAPI Eina_Bool
1437 elm_object_focus_get(const Evas_Object *obj)
1438 {
1439    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1440    return elm_widget_focus_get(obj);
1441 }
1442
1443 EAPI void
1444 elm_object_focus_set(Evas_Object *obj,
1445                      Eina_Bool    focus)
1446 {
1447    EINA_SAFETY_ON_NULL_RETURN(obj);
1448    if (focus)
1449      {
1450         if (elm_widget_focus_get(obj)) return;
1451         elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
1452      }
1453    else
1454      {
1455         if (!elm_widget_can_focus_get(obj)) return;
1456         elm_widget_focused_object_clear(obj);
1457      }
1458 }
1459
1460 EAPI void
1461 elm_object_focus(Evas_Object *obj)
1462 {
1463    EINA_SAFETY_ON_NULL_RETURN(obj);
1464    elm_object_focus_set(obj, EINA_TRUE);
1465 }
1466
1467 EAPI void
1468 elm_object_unfocus(Evas_Object *obj)
1469 {
1470    EINA_SAFETY_ON_NULL_RETURN(obj);
1471    elm_object_focus_set(obj, EINA_FALSE);
1472 }
1473
1474 EAPI void
1475 elm_object_focus_allow_set(Evas_Object *obj,
1476                            Eina_Bool    enable)
1477 {
1478    EINA_SAFETY_ON_NULL_RETURN(obj);
1479    elm_widget_can_focus_set(obj, enable);
1480 }
1481
1482 EAPI Eina_Bool
1483 elm_object_focus_allow_get(const Evas_Object *obj)
1484 {
1485    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1486    return (elm_widget_can_focus_get(obj)) || (elm_widget_child_can_focus_get(obj));
1487 }
1488
1489 EAPI void
1490 elm_object_focus_custom_chain_set(Evas_Object *obj,
1491                                   Eina_List   *objs)
1492 {
1493    EINA_SAFETY_ON_NULL_RETURN(obj);
1494    elm_widget_focus_custom_chain_set(obj, objs);
1495 }
1496
1497 EAPI void
1498 elm_object_focus_custom_chain_unset(Evas_Object *obj)
1499 {
1500    EINA_SAFETY_ON_NULL_RETURN(obj);
1501    elm_widget_focus_custom_chain_unset(obj);
1502 }
1503
1504 EAPI const Eina_List *
1505 elm_object_focus_custom_chain_get(const Evas_Object *obj)
1506 {
1507    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1508    return elm_widget_focus_custom_chain_get(obj);
1509 }
1510
1511 EAPI void
1512 elm_object_focus_custom_chain_append(Evas_Object *obj,
1513                                      Evas_Object *child,
1514                                      Evas_Object *relative_child)
1515 {
1516    EINA_SAFETY_ON_NULL_RETURN(obj);
1517    EINA_SAFETY_ON_NULL_RETURN(child);
1518    elm_widget_focus_custom_chain_append(obj, child, relative_child);
1519 }
1520
1521 EAPI void
1522 elm_object_focus_custom_chain_prepend(Evas_Object *obj,
1523                                       Evas_Object *child,
1524                                       Evas_Object *relative_child)
1525 {
1526    EINA_SAFETY_ON_NULL_RETURN(obj);
1527    EINA_SAFETY_ON_NULL_RETURN(child);
1528    elm_widget_focus_custom_chain_prepend(obj, child, relative_child);
1529 }
1530
1531 EAPI void
1532 elm_object_focus_cycle(Evas_Object        *obj,
1533                        Elm_Focus_Direction dir)
1534 {
1535    EINA_SAFETY_ON_NULL_RETURN(obj);
1536    elm_widget_focus_cycle(obj, dir);
1537 }
1538
1539 EAPI void
1540 elm_object_focus_direction_go(Evas_Object *obj,
1541                               int          x,
1542                               int          y)
1543 {
1544    EINA_SAFETY_ON_NULL_RETURN(obj);
1545    elm_widget_focus_direction_go(obj, x, y);
1546 }
1547
1548 EAPI void
1549 elm_object_tree_unfocusable_set(Evas_Object *obj,
1550                                 Eina_Bool    tree_unfocusable)
1551 {
1552    EINA_SAFETY_ON_NULL_RETURN(obj);
1553    elm_widget_tree_unfocusable_set(obj, tree_unfocusable);
1554 }
1555
1556 EAPI Eina_Bool
1557 elm_object_tree_unfocusable_get(const Evas_Object *obj)
1558 {
1559    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1560    return elm_widget_tree_unfocusable_get(obj);
1561 }
1562
1563 EAPI Eina_Bool
1564 elm_focus_highlight_enabled_get(void)
1565 {
1566    return _elm_config->focus_highlight_enable;
1567 }
1568
1569 EAPI void
1570 elm_focus_highlight_enabled_set(Eina_Bool enable)
1571 {
1572    _elm_config->focus_highlight_enable = !!enable;
1573 }
1574
1575 EAPI Eina_Bool
1576 elm_focus_highlight_animate_get(void)
1577 {
1578    return _elm_config->focus_highlight_animate;
1579 }
1580
1581 EAPI void
1582 elm_focus_highlight_animate_set(Eina_Bool animate)
1583 {
1584    _elm_config->focus_highlight_animate = !!animate;
1585 }
1586
1587 EAPI Eina_Bool
1588 elm_scroll_bounce_enabled_get(void)
1589 {
1590    return _elm_config->thumbscroll_bounce_enable;
1591 }
1592
1593 EAPI void
1594 elm_scroll_bounce_enabled_set(Eina_Bool enabled)
1595 {
1596    _elm_config->thumbscroll_bounce_enable = enabled;
1597 }
1598
1599 EAPI void
1600 elm_scroll_bounce_enabled_all_set(Eina_Bool enabled)
1601 {
1602    elm_scroll_bounce_enabled_set(enabled);
1603    _elm_config_all_update();
1604 }
1605
1606 EAPI double
1607 elm_scroll_bounce_friction_get(void)
1608 {
1609    return _elm_config->thumbscroll_bounce_friction;
1610 }
1611
1612 EAPI void
1613 elm_scroll_bounce_friction_set(double friction)
1614 {
1615    _elm_config->thumbscroll_bounce_friction = friction;
1616 }
1617
1618 EAPI void
1619 elm_scroll_bounce_friction_all_set(double friction)
1620 {
1621    elm_scroll_bounce_friction_set(friction);
1622    _elm_config_all_update();
1623 }
1624
1625 EAPI double
1626 elm_scroll_page_scroll_friction_get(void)
1627 {
1628    return _elm_config->page_scroll_friction;
1629 }
1630
1631 EAPI void
1632 elm_scroll_page_scroll_friction_set(double friction)
1633 {
1634    _elm_config->page_scroll_friction = friction;
1635 }
1636
1637 EAPI void
1638 elm_scroll_page_scroll_friction_all_set(double friction)
1639 {
1640    elm_scroll_page_scroll_friction_set(friction);
1641    _elm_config_all_update();
1642 }
1643
1644 EAPI double
1645 elm_scroll_bring_in_scroll_friction_get(void)
1646 {
1647    return _elm_config->bring_in_scroll_friction;
1648 }
1649
1650 EAPI void
1651 elm_scroll_bring_in_scroll_friction_set(double friction)
1652 {
1653    _elm_config->bring_in_scroll_friction = friction;
1654 }
1655
1656 EAPI void
1657 elm_scroll_bring_in_scroll_friction_all_set(double friction)
1658 {
1659    elm_scroll_bring_in_scroll_friction_set(friction);
1660    _elm_config_all_update();
1661 }
1662
1663 EAPI double
1664 elm_scroll_zoom_friction_get(void)
1665 {
1666    return _elm_config->zoom_friction;
1667 }
1668
1669 EAPI void
1670 elm_scroll_zoom_friction_set(double friction)
1671 {
1672    _elm_config->zoom_friction = friction;
1673 }
1674
1675 EAPI void
1676 elm_scroll_zoom_friction_all_set(double friction)
1677 {
1678    elm_scroll_zoom_friction_set(friction);
1679    _elm_config_all_update();
1680 }
1681
1682 EAPI Eina_Bool
1683 elm_scroll_thumbscroll_enabled_get(void)
1684 {
1685    return _elm_config->thumbscroll_enable;
1686 }
1687
1688 EAPI void
1689 elm_scroll_thumbscroll_enabled_set(Eina_Bool enabled)
1690 {
1691    _elm_config->thumbscroll_enable = enabled;
1692 }
1693
1694 EAPI void
1695 elm_scroll_thumbscroll_enabled_all_set(Eina_Bool enabled)
1696 {
1697    elm_scroll_thumbscroll_enabled_set(enabled);
1698    _elm_config_all_update();
1699 }
1700
1701 EAPI unsigned int
1702 elm_scroll_thumbscroll_threshold_get(void)
1703 {
1704    return _elm_config->thumbscroll_threshold;
1705 }
1706
1707 EAPI void
1708 elm_scroll_thumbscroll_threshold_set(unsigned int threshold)
1709 {
1710    _elm_config->thumbscroll_threshold = threshold;
1711 }
1712
1713 EAPI void
1714 elm_scroll_thumbscroll_threshold_all_set(unsigned int threshold)
1715 {
1716    elm_scroll_thumbscroll_threshold_set(threshold);
1717    _elm_config_all_update();
1718 }
1719
1720 EAPI double
1721 elm_scroll_thumbscroll_momentum_threshold_get(void)
1722 {
1723    return _elm_config->thumbscroll_momentum_threshold;
1724 }
1725
1726 EAPI void
1727 elm_scroll_thumbscroll_momentum_threshold_set(double threshold)
1728 {
1729    _elm_config->thumbscroll_momentum_threshold = threshold;
1730 }
1731
1732 EAPI void
1733 elm_scroll_thumbscroll_momentum_threshold_all_set(double threshold)
1734 {
1735    elm_scroll_thumbscroll_momentum_threshold_set(threshold);
1736    _elm_config_all_update();
1737 }
1738
1739 EAPI double
1740 elm_scroll_thumbscroll_friction_get(void)
1741 {
1742    return _elm_config->thumbscroll_friction;
1743 }
1744
1745 EAPI void
1746 elm_scroll_thumbscroll_friction_set(double friction)
1747 {
1748    _elm_config->thumbscroll_friction = friction;
1749 }
1750
1751 EAPI void
1752 elm_scroll_thumbscroll_friction_all_set(double friction)
1753 {
1754    elm_scroll_thumbscroll_friction_set(friction);
1755    _elm_config_all_update();
1756 }
1757
1758 EAPI double
1759 elm_scroll_thumbscroll_border_friction_get(void)
1760 {
1761    return _elm_config->thumbscroll_border_friction;
1762 }
1763
1764 EAPI void
1765 elm_scroll_thumbscroll_border_friction_set(double friction)
1766 {
1767    if (friction < 0.0) friction = 0.0;
1768    if (friction > 1.0) friction = 1.0;
1769    _elm_config->thumbscroll_friction = friction;
1770 }
1771
1772 EAPI void
1773 elm_scroll_thumbscroll_border_friction_all_set(double friction)
1774 {
1775    elm_scroll_thumbscroll_border_friction_set(friction);
1776    _elm_config_all_update();
1777 }
1778
1779 EAPI double
1780 elm_scroll_thumbscroll_sensitivity_friction_get(void)
1781 {
1782    return _elm_config->thumbscroll_sensitivity_friction;
1783 }
1784
1785 EAPI void
1786 elm_scroll_thumbscroll_sensitivity_friction_set(double friction)
1787 {
1788    if (friction < 0.1) friction = 0.1;
1789    if (friction > 1.0) friction = 1.0;
1790    _elm_config->thumbscroll_friction = friction;
1791 }
1792
1793 EAPI void
1794 elm_scroll_thumbscroll_sensitivity_friction_all_set(double friction)
1795 {
1796    elm_scroll_thumbscroll_sensitivity_friction_set(friction);
1797    _elm_config_all_update();
1798 }
1799
1800 EAPI void
1801 elm_object_scroll_hold_push(Evas_Object *obj)
1802 {
1803    EINA_SAFETY_ON_NULL_RETURN(obj);
1804    elm_widget_scroll_hold_push(obj);
1805 }
1806
1807 EAPI void
1808 elm_object_scroll_hold_pop(Evas_Object *obj)
1809 {
1810    EINA_SAFETY_ON_NULL_RETURN(obj);
1811    elm_widget_scroll_hold_pop(obj);
1812 }
1813
1814 EAPI void
1815 elm_object_scroll_freeze_push(Evas_Object *obj)
1816 {
1817    EINA_SAFETY_ON_NULL_RETURN(obj);
1818    elm_widget_scroll_freeze_push(obj);
1819 }
1820
1821 EAPI void
1822 elm_object_scroll_lock_x_set(Evas_Object *obj,
1823                              Eina_Bool    lock)
1824 {
1825    EINA_SAFETY_ON_NULL_RETURN(obj);
1826    elm_widget_drag_lock_x_set(obj, lock);
1827 }
1828
1829 EAPI void
1830 elm_object_scroll_lock_y_set(Evas_Object *obj,
1831                              Eina_Bool    lock)
1832 {
1833    EINA_SAFETY_ON_NULL_RETURN(obj);
1834    elm_widget_drag_lock_y_set(obj, lock);
1835 }
1836
1837 EAPI Eina_Bool
1838 elm_object_scroll_lock_x_get(const Evas_Object *obj)
1839 {
1840    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1841    return elm_widget_drag_lock_x_get(obj);
1842 }
1843
1844 EAPI Eina_Bool
1845 elm_object_scroll_lock_y_get(const Evas_Object *obj)
1846 {
1847    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1848    return elm_widget_drag_lock_y_get(obj);
1849 }
1850
1851 EAPI void
1852 elm_object_scroll_freeze_pop(Evas_Object *obj)
1853 {
1854    EINA_SAFETY_ON_NULL_RETURN(obj);
1855    elm_widget_scroll_freeze_pop(obj);
1856 }
1857
1858 EAPI Eina_Bool
1859 elm_object_widget_check(const Evas_Object *obj)
1860 {
1861    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1862    return elm_widget_is(obj);
1863 }
1864
1865 EAPI Evas_Object *
1866 elm_object_parent_widget_get(const Evas_Object *obj)
1867 {
1868    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1869    return elm_widget_parent_widget_get(obj);
1870 }
1871
1872 EAPI Evas_Object *
1873 elm_object_top_widget_get(const Evas_Object *obj)
1874 {
1875    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1876    return elm_widget_top_get(obj);
1877 }
1878
1879 EAPI const char *
1880 elm_object_widget_type_get(const Evas_Object *obj)
1881 {
1882    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1883    return elm_widget_type_get(obj);
1884 }
1885
1886 EAPI void
1887 elm_object_signal_emit(Evas_Object *obj,
1888                        const char  *emission,
1889                        const char  *source)
1890 {
1891    EINA_SAFETY_ON_NULL_RETURN(obj);
1892    elm_widget_signal_emit(obj, emission, source);
1893 }
1894
1895 EAPI void
1896 elm_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
1897 {
1898     EINA_SAFETY_ON_NULL_RETURN(obj);
1899     EINA_SAFETY_ON_NULL_RETURN(func);
1900     elm_widget_signal_callback_add(obj, emission, source, func, data);
1901 }
1902
1903 EAPI void *
1904 elm_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func)
1905 {
1906     EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1907     EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
1908     return elm_widget_signal_callback_del(obj, emission, source, func);
1909 }
1910
1911 EAPI void
1912 elm_object_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data)
1913 {
1914    EINA_SAFETY_ON_NULL_RETURN(obj);
1915    EINA_SAFETY_ON_NULL_RETURN(func);
1916    elm_widget_event_callback_add(obj, func, data);
1917 }
1918
1919 EAPI void *
1920 elm_object_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data)
1921 {
1922    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1923    EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
1924    return elm_widget_event_callback_del(obj, func, data);
1925 }
1926
1927 EAPI void
1928 elm_object_tree_dump(const Evas_Object *top)
1929 {
1930 #ifdef ELM_DEBUG
1931    elm_widget_tree_dump(top);
1932 #else
1933    return;
1934    (void)top;
1935 #endif
1936 }
1937
1938 EAPI void
1939 elm_object_tree_dot_dump(const Evas_Object *top,
1940                          const char        *file)
1941 {
1942 #ifdef ELM_DEBUG
1943    FILE *f = fopen(file, "wb");
1944    elm_widget_tree_dot_dump(top, f);
1945    fclose(f);
1946 #else
1947    return;
1948    (void)top;
1949    (void)file;
1950 #endif
1951 }
1952
1953 EAPI void
1954 elm_longpress_timeout_set(double longpress_timeout)
1955 {
1956    _elm_config->longpress_timeout = longpress_timeout;
1957 }
1958
1959 EAPI double
1960 elm_longpress_timeout_get(void)
1961 {
1962    return _elm_config->longpress_timeout;
1963 }
1964
1965 EAPI Evas_Object *
1966 elm_object_item_object_get(const Elm_Object_Item *it)
1967 {
1968    return ((Elm_Widget_Item *) it)->widget;
1969 }
1970
1971 EAPI void
1972 elm_object_item_content_part_set(Elm_Object_Item *it,
1973                                  const char *part,
1974                                  Evas_Object *content)
1975 {
1976    _elm_widget_item_content_part_set((Elm_Widget_Item *) it, part, content);
1977 }
1978
1979 EAPI Evas_Object *
1980 elm_object_item_content_part_get(const Elm_Object_Item *it,
1981                                  const char *part)
1982 {
1983    return _elm_widget_item_content_part_get((Elm_Widget_Item *) it, part);
1984 }
1985
1986 EAPI Evas_Object *
1987 elm_object_item_content_part_unset(Elm_Object_Item *it, const char *part)
1988 {
1989    return _elm_widget_item_content_part_unset((Elm_Widget_Item *) it, part);
1990 }
1991
1992 EAPI void
1993 elm_object_item_text_part_set(Elm_Object_Item *it,
1994                               const char *part,
1995                               const char *label)
1996 {
1997    _elm_widget_item_text_part_set((Elm_Widget_Item *) it, part, label);
1998 }
1999
2000 EAPI const char *
2001 elm_object_item_text_part_get(const Elm_Object_Item *it, const char *part)
2002 {
2003    return _elm_widget_item_text_part_get((Elm_Widget_Item *) it, part);
2004 }
2005
2006 EAPI void
2007 elm_object_access_info_set(Evas_Object *obj, const char *txt)
2008 {
2009    elm_widget_access_info_set(obj, txt);
2010 }
2011
2012 EAPI void
2013 elm_object_item_access_info_set(Elm_Object_Item *it, const char *txt)
2014 {
2015    _elm_widget_item_access_info_set((Elm_Widget_Item *) it, txt);
2016 }
2017
2018 EAPI void *
2019 elm_object_item_data_get(const Elm_Object_Item *it)
2020 {
2021    return elm_widget_item_data_get(it);
2022 }
2023
2024 EAPI void
2025 elm_object_item_data_set(Elm_Object_Item *it, void *data)
2026 {
2027    elm_widget_item_data_set(it, data);
2028 }
2029
2030 EAPI void
2031 elm_object_item_signal_emit(Elm_Object_Item *it, const char *emission, const char *source)
2032 {
2033    _elm_widget_item_signal_emit((Elm_Widget_Item *) it, emission, source);
2034 }