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