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