#ifdef HAVE_CONFIG_H # include "elementary_config.h" #endif #ifndef _WIN32 # include /* dlopen,dlclose,etc */ #endif #ifdef HAVE_CRT_EXTERNS_H # include #endif #ifdef _WIN32 # include /* getcwd */ # include /* dlopen,dlclose,etc */ #endif #include #include #include "eina_internal.h" #include "ecore_internal.h" #include "elm_priv.h" #include "elm_interface_scrollable.h" #include "elm_pan_eo.h" //we need those for legacy compatible code #include "elm_genlist_eo.h" #include "elm_gengrid_eo.h" #include "elm_widget_gengrid.h" #define SEMI_BROKEN_QUICKLAUNCH 1 #ifdef __CYGWIN__ # define LIBEXT ".dll" #else # define LIBEXT ".so" #endif Eina_Bool _use_build_config; static Elm_Version _version = { VMAJ, VMIN, VMIC, VREV }; EAPI Elm_Version *elm_version = &_version; Eina_FreeQ *postponed_fq = NULL; static void _focus_ev_redirect_cb(void *data, const Efl_Event *ev EINA_UNUSED) { Eina_Rect rect = efl_ui_focus_object_focus_geometry_get(data); efl_event_callback_call(data, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_GEOMETRY_CHANGED, &rect); } void _efl_ui_focus_event_redirector(Efl_Ui_Focus_Object *obj, Efl_Ui_Focus_Object *goal) { efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _focus_ev_redirect_cb, goal); efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _focus_ev_redirect_cb, goal); } void _efl_ui_focus_manager_redirect_events_del(Efl_Ui_Focus_Manager *manager, Eo *obj) { efl_event_callback_forwarder_del(manager, EFL_UI_FOCUS_MANAGER_EVENT_FLUSH_PRE, obj); efl_event_callback_forwarder_del(manager, EFL_UI_FOCUS_MANAGER_EVENT_REDIRECT_CHANGED, obj); efl_event_callback_forwarder_del(manager, EFL_UI_FOCUS_MANAGER_EVENT_MANAGER_FOCUS_CHANGED , obj); efl_event_callback_forwarder_del(manager, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, obj); efl_event_callback_forwarder_del(manager, EFL_UI_FOCUS_MANAGER_EVENT_DIRTY_LOGIC_FREEZE_CHANGED, obj); } void _efl_ui_focus_manager_redirect_events_add(Efl_Ui_Focus_Manager *manager, Eo *obj) { efl_event_callback_forwarder_add(manager, EFL_UI_FOCUS_MANAGER_EVENT_FLUSH_PRE, obj); efl_event_callback_forwarder_add(manager, EFL_UI_FOCUS_MANAGER_EVENT_REDIRECT_CHANGED, obj); efl_event_callback_forwarder_add(manager, EFL_UI_FOCUS_MANAGER_EVENT_MANAGER_FOCUS_CHANGED , obj); efl_event_callback_forwarder_add(manager, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, obj); efl_event_callback_forwarder_add(manager, EFL_UI_FOCUS_MANAGER_EVENT_DIRTY_LOGIC_FREEZE_CHANGED, obj); } Eina_Bool _elm_dangerous_call_check(const char *call) { char buf[256]; const char *eval; snprintf(buf, sizeof(buf), "%i.%i.%i.%i", VMAJ, VMIN, VMIC, VREV); eval = getenv("ELM_NO_FINGER_WAGGLING"); if ((eval) && (!strcmp(eval, buf))) return 0; ERR("ELEMENTARY FINGER WAGGLE!!!!!!!!!!\n" "\n" " %s() used.\n" "PLEASE see the API documentation for this function. This call\n" "should almost never be used. Only in very special cases.\n" "\n" "To remove this warning please set the environment variable:\n" " ELM_NO_FINGER_WAGGLING\n" "To the value of the Elementary version + revision number. e.g.:\n" " 1.2.5.40295\n" "\n" , call); return 1; } static Eina_Bool _elm_signal_exit(void *data, int ev_type, void *ev); static Eina_Prefix *pfx = NULL; char *_elm_appname = NULL; const char *_elm_data_dir = NULL; const char *_elm_lib_dir = NULL; int _elm_log_dom = -1; EAPI int ELM_EVENT_POLICY_CHANGED = 0; EAPI int ELM_EVENT_PROCESS_BACKGROUND = 0; EAPI int ELM_EVENT_PROCESS_FOREGROUND = 0; static int _elm_init_count = 0; static int _elm_sub_init_count = 0; static int _elm_ql_init_count = 0; static Eina_Bool _elm_prefs_initted = EINA_FALSE; static int _elm_policies[ELM_POLICY_LAST]; static Ecore_Event_Handler *_elm_exit_handler = NULL; static Eina_Bool quicklaunch_on = 0; static Eina_Bool _elm_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED) { elm_exit(); return ECORE_CALLBACK_PASS_ON; } void _elm_rescale(void) { edje_scale_set(_elm_config->scale); _elm_win_rescale(NULL, EINA_FALSE); _elm_ews_wm_rescale(NULL, EINA_FALSE); } static void *app_mainfunc = NULL; static const char *app_name = NULL; static const char *app_desktop_entry = NULL; static const char *app_domain = NULL; static const char *app_checkfile = NULL; static const char *app_compile_bin_dir = NULL; static const char *app_compile_lib_dir = NULL; static const char *app_compile_data_dir = NULL; static const char *app_compile_locale_dir = NULL; static const char *app_prefix_dir = NULL; static const char *app_bin_dir = NULL; static const char *app_lib_dir = NULL; static const char *app_data_dir = NULL; static const char *app_locale_dir = NULL; static double app_base_scale = 1.0; static Eina_Prefix *app_pfx = NULL; static Ecore_Event_Handler *system_handlers[2] = { NULL, NULL }; static void _prefix_check(void) { int argc = 0; char **argv = NULL; const char *dirs[4] = { NULL, NULL, NULL, NULL }; char *caps = NULL, *p1, *p2; char buf[PATH_MAX]; if (app_pfx) return; if (!app_domain) return; ecore_app_args_get(&argc, &argv); if (argc < 1) return; dirs[0] = app_compile_bin_dir; dirs[1] = app_compile_lib_dir; dirs[2] = app_compile_data_dir; dirs[3] = app_compile_locale_dir; if (!dirs[0]) dirs[0] = "/usr/local/bin"; if (!dirs[1]) dirs[1] = "/usr/local/lib"; if (!dirs[2]) { snprintf(buf, sizeof(buf), "/usr/local/share/%s", app_domain); dirs[2] = buf; } if (!dirs[3]) dirs[3] = dirs[2]; if (app_domain) { caps = alloca(eina_stringshare_strlen(app_domain) + 1); for (p1 = (char *)app_domain, p2 = caps; *p1; p1++, p2++) *p2 = toupper(*p1); *p2 = 0; } app_pfx = eina_prefix_new(argv[0], app_mainfunc, caps, app_domain, app_checkfile, dirs[0], dirs[1], dirs[2], dirs[3]); eina_vpath_interface_app_set(app_domain, app_pfx); } static void _prefix_shutdown(void) { if (app_pfx) eina_prefix_free(app_pfx); ELM_SAFE_FREE(app_domain, eina_stringshare_del); ELM_SAFE_FREE(app_checkfile, eina_stringshare_del); ELM_SAFE_FREE(app_compile_bin_dir, eina_stringshare_del); ELM_SAFE_FREE(app_compile_lib_dir, eina_stringshare_del); ELM_SAFE_FREE(app_compile_data_dir, eina_stringshare_del); ELM_SAFE_FREE(app_compile_locale_dir, eina_stringshare_del); app_mainfunc = NULL; app_prefix_dir = NULL; app_bin_dir = NULL; app_lib_dir = NULL; app_data_dir = NULL; app_locale_dir = NULL; app_pfx = NULL; } static struct { Eina_Module *handle; void (*init)(void); void (*shutdown)(void); Eina_Bool (*app_connect)(const char *appname); Eina_Bool is_init; } _clouseau_old_info; static struct { Eina_Module *handle; Eina_Bool (*init)(void); Eina_Bool (*shutdown)(void); Eina_Bool is_init; } _clouseau_info; #define _CLOUSEAU_OLD_LOAD_SYMBOL(cls_struct, sym) \ do \ { \ if ((cls_struct).handle) \ (cls_struct).sym = eina_module_symbol_get((cls_struct).handle, "clouseau_" #sym); \ if (!(cls_struct).sym) \ { \ WRN("Failed loading symbol '%s' from the clouseau library.", "clouseau_" #sym); \ if ((cls_struct).handle) eina_module_free((cls_struct).handle); \ (cls_struct).handle = NULL; \ } \ } \ while (0) #define _CLOUSEAU_LOAD_SYMBOL(cls_struct, sym) \ do \ { \ if ((cls_struct).handle) \ (cls_struct).sym = eina_module_symbol_get((cls_struct).handle, "clouseau_debug_" #sym); \ if (!(cls_struct).sym) \ { \ WRN("Failed loading symbol '%s' from the clouseau library.", "clouseau_debug_" #sym); \ if ((cls_struct).handle) eina_module_free((cls_struct).handle); \ (cls_struct).handle = NULL; \ return EINA_FALSE; \ } \ } \ while (0) static void _elm_old_clouseau_unload() { if (_clouseau_old_info.is_init) { if (_clouseau_old_info.shutdown) { _clouseau_old_info.shutdown(); } if (_clouseau_old_info.handle) { eina_module_free(_clouseau_old_info.handle); _clouseau_old_info.handle = NULL; } _clouseau_old_info.is_init = EINA_FALSE; } } static void _elm_clouseau_unload() { if (_clouseau_info.is_init) { if (_clouseau_info.shutdown) { _clouseau_info.shutdown(); } if (_clouseau_info.handle) { eina_module_free(_clouseau_info.handle); _clouseau_info.handle = NULL; } _clouseau_info.is_init = EINA_FALSE; } } Eina_Bool _elm_old_clouseau_reload() { if (!_elm_config->clouseau_enable) { _elm_old_clouseau_unload(); return EINA_TRUE; } if (!_clouseau_old_info.is_init) { _clouseau_old_info.handle = eina_module_new( PACKAGE_LIB_DIR "/libclouseau" LIBEXT); if (!_clouseau_old_info.handle || !eina_module_load(_clouseau_old_info.handle)) { WRN("Failed loading the clouseau_old library."); if (_clouseau_old_info.handle) eina_module_free(_clouseau_old_info.handle); _clouseau_old_info.handle = NULL; } _CLOUSEAU_OLD_LOAD_SYMBOL(_clouseau_old_info, init); _CLOUSEAU_OLD_LOAD_SYMBOL(_clouseau_old_info, shutdown); _CLOUSEAU_OLD_LOAD_SYMBOL(_clouseau_old_info, app_connect); if (_clouseau_old_info.handle) { _clouseau_old_info.init(); if (!_clouseau_old_info.app_connect(elm_app_name_get())) { ERR("Failed connecting to the clouseau server."); } _clouseau_old_info.is_init = EINA_TRUE; } } return EINA_TRUE; } static Eina_Bool _elm_clouseau_load() { if (getenv("EFL_RUN_IN_TREE")) return EINA_FALSE; if (!_clouseau_info.is_init) { _clouseau_info.handle = eina_module_new( PACKAGE_LIB_DIR "/libclouseau_debug" LIBEXT); if (!_clouseau_info.handle || !eina_module_load(_clouseau_info.handle)) { WRN("Failed loading the clouseau library."); if (_clouseau_info.handle) eina_module_free(_clouseau_info.handle); _clouseau_info.handle = NULL; return EINA_FALSE; } _CLOUSEAU_LOAD_SYMBOL(_clouseau_info, init); _CLOUSEAU_LOAD_SYMBOL(_clouseau_info, shutdown); if (_clouseau_info.handle) { _clouseau_info.init(); _clouseau_info.is_init = EINA_TRUE; } } return EINA_TRUE; } static Eina_Bool _sys_memory_changed(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) { Ecore_Memory_State state = ecore_memory_state_get(); if (state != ECORE_MEMORY_STATE_LOW) return ECORE_CALLBACK_PASS_ON; elm_cache_all_flush(); return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _sys_lang_changed(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) { char *lang; lang = getenv("LANG"); if (!lang) lang = getenv("LC_MESSAGES"); if (!lang) lang = getenv("LC_ALL"); if (lang) elm_language_set(lang); else ERR("Language not set in environment"); return ECORE_CALLBACK_PASS_ON; } EAPI Eina_Error EFL_UI_THEME_APPLY_ERROR_NONE = 0; EAPI Eina_Error EFL_UI_THEME_APPLY_ERROR_DEFAULT = 0; EAPI Eina_Error EFL_UI_THEME_APPLY_ERROR_GENERIC = 0; static void _efl_ui_theme_apply_error_init(void) { if (EFL_UI_THEME_APPLY_ERROR_DEFAULT) return; /* NONE should always be 0 */ EFL_UI_THEME_APPLY_ERROR_DEFAULT = eina_error_msg_static_register("Fallback to default style was enabled for this widget"); EFL_UI_THEME_APPLY_ERROR_GENERIC = eina_error_msg_static_register("An error occurred and no theme could be set for this widget"); } // This is necessary to keep backward compatibility static const char *bcargv[] = { "exe" }; EAPI int elm_init(int argc, char **argv) { _elm_init_count++; if (_elm_init_count > 1) return _elm_init_count; EINA_SAFETY_ON_FALSE_RETURN_VAL(elm_quicklaunch_init(argc, argv ? argv : (char**) bcargv), --_elm_init_count); EINA_SAFETY_ON_FALSE_GOTO(elm_quicklaunch_sub_init(argc, argv ? argv : (char**) bcargv), shutdown_ql); _prefix_shutdown(); /* this is fine if it fails */ _elm_clouseau_load(); system_handlers[0] = ecore_event_handler_add(ECORE_EVENT_MEMORY_STATE, _sys_memory_changed, NULL); system_handlers[1] = ecore_event_handler_add(ECORE_EVENT_LOCALE_CHANGED, _sys_lang_changed, NULL); ELM_CNP_EVENT_SELECTION_CHANGED = ecore_event_type_new(); if (_elm_config->atspi_mode != ELM_ATSPI_MODE_OFF) _elm_atspi_bridge_init(); if (!_elm_config->web_backend) _elm_config->web_backend = eina_stringshare_add("none"); if (!_elm_web_init(_elm_config->web_backend)) _elm_config->web_backend = eina_stringshare_add("none"); _elm_code_parse_setup(); // For backward compability, EFL startup time and ELM startup time are made // identical. It is fine to do it here as we are finishing initialisation // and the startup time should have been accounted earlier. if (_elm_startup_time >= 0) if (_efl_startup_time <= 0) _efl_startup_time = _elm_startup_time; _elm_startup_time = _efl_startup_time; _efl_ui_theme_apply_error_init(); return _elm_init_count; shutdown_ql: elm_quicklaunch_shutdown(); return --_elm_init_count; } EAPI int elm_shutdown(void) { if (_elm_init_count <= 0) return 0; _elm_init_count--; if (_elm_init_count > 0) return _elm_init_count; ecore_event_handler_del(system_handlers[0]); ecore_event_handler_del(system_handlers[1]); _elm_win_shutdown(); _elm_atspi_bridge_shutdown(); while (_elm_win_deferred_free) ecore_main_loop_iterate(); _elm_clouseau_unload(); _elm_old_clouseau_unload(); // wrningz :( // _prefix_shutdown(); ELM_SAFE_FREE(app_name, eina_stringshare_del); ELM_SAFE_FREE(app_desktop_entry, eina_stringshare_del); elm_quicklaunch_sub_shutdown(); elm_quicklaunch_shutdown(); return _elm_init_count; } EAPI void elm_app_info_set(void *mainfunc, const char *dom, const char *checkfile) { app_mainfunc = mainfunc; eina_stringshare_replace(&app_domain, dom); eina_stringshare_replace(&app_checkfile, checkfile); } EAPI void elm_app_name_set(const char *name) { eina_stringshare_replace(&app_name, name); } EAPI void elm_app_desktop_entry_set(const char *path) { eina_stringshare_replace(&app_desktop_entry, path); } EAPI void elm_app_compile_bin_dir_set(const char *dir) { eina_stringshare_replace(&app_compile_bin_dir, dir); } EAPI void elm_app_compile_lib_dir_set(const char *dir) { eina_stringshare_replace(&app_compile_lib_dir, dir); } EAPI void elm_app_compile_data_dir_set(const char *dir) { eina_stringshare_replace(&app_compile_data_dir, dir); } EAPI void elm_app_compile_locale_set(const char *dir) { eina_stringshare_replace(&app_compile_locale_dir, dir); } EAPI const char * elm_app_name_get(void) { if (app_name) return app_name; return ""; } EAPI const char * elm_app_desktop_entry_get(void) { if (app_desktop_entry) return app_desktop_entry; return ""; } EAPI const char * elm_app_prefix_dir_get(void) { if (app_prefix_dir) return app_prefix_dir; _prefix_check(); if (!app_pfx) return ""; app_prefix_dir = eina_prefix_get(app_pfx); return app_prefix_dir; } EAPI const char * elm_app_bin_dir_get(void) { if (app_bin_dir) return app_bin_dir; _prefix_check(); if (!app_pfx) return ""; app_bin_dir = eina_prefix_bin_get(app_pfx); return app_bin_dir; } EAPI const char * elm_app_lib_dir_get(void) { if (app_lib_dir) return app_lib_dir; _prefix_check(); if (!app_pfx) return ""; app_lib_dir = eina_prefix_lib_get(app_pfx); return app_lib_dir; } EAPI const char * elm_app_data_dir_get(void) { if (app_data_dir) return app_data_dir; _prefix_check(); if (!app_pfx) return ""; /* only used to run inside efl src tree */ if (getenv("EFL_RUN_IN_TREE")) { /* "/some/path/to/repo/build/src" */ const char *path = elm_app_prefix_dir_get(); /* "/some/path/to/repo/build/" */ const char *last_sep = strrchr(path, '/'); Eina_Strbuf *buf = eina_strbuf_new(); eina_strbuf_append_length(buf, path, last_sep - path + 1); eina_strbuf_append(buf, "data/elementary"); app_data_dir = eina_strbuf_string_steal(buf); eina_strbuf_free(buf); /* yes this leaks app_data_dir but it's a one time allocation who cares */ } else app_data_dir = eina_prefix_data_get(app_pfx); return app_data_dir; } EAPI const char * elm_app_locale_dir_get(void) { if (app_locale_dir) return app_locale_dir; _prefix_check(); if (!app_pfx) return ""; app_locale_dir = eina_prefix_locale_get(app_pfx); return app_locale_dir; } EAPI void elm_app_base_scale_set(double base_scale) { if (base_scale < 0.0) return; if (fabs(base_scale) < DBL_EPSILON) return; app_base_scale = base_scale; } EAPI double elm_app_base_scale_get(void) { if (app_base_scale > 0.0) return app_base_scale; return 1.0; } static Eina_Bool _elm_need_e_dbus = EINA_FALSE; static void *e_dbus_handle = NULL; EAPI Eina_Bool elm_need_e_dbus(void) { int (*init_func)(void) = NULL; if (_elm_need_e_dbus) return EINA_TRUE; /* We use RTLD_NOLOAD when available, so we are sure to use the 'libeldbus' that was linked to the binary */ #ifndef RTLD_NOLOAD # define RTLD_NOLOAD RTLD_GLOBAL #endif if (!e_dbus_handle) e_dbus_handle = dlopen("libedbus.so", RTLD_LAZY | RTLD_NOLOAD); if (!e_dbus_handle) e_dbus_handle = dlopen("libedbus.so.1", RTLD_LAZY | RTLD_NOLOAD); if (!e_dbus_handle) return EINA_FALSE; init_func = dlsym(e_dbus_handle, "e_dbus_init"); if (!init_func) return EINA_FALSE; _elm_need_e_dbus = EINA_TRUE; init_func(); return EINA_TRUE; } static void _elm_unneed_e_dbus(void) { int (*shutdown_func)(void) = NULL; if (!_elm_need_e_dbus) return; shutdown_func = dlsym(e_dbus_handle, "e_dbus_shutdown"); if (!shutdown_func) return; _elm_need_e_dbus = EINA_FALSE; shutdown_func(); dlclose(e_dbus_handle); e_dbus_handle = NULL; } static Eina_Bool _elm_need_eldbus = EINA_FALSE; EAPI Eina_Bool elm_need_eldbus(void) { if (_elm_need_eldbus) return EINA_TRUE; _elm_need_eldbus = EINA_TRUE; eldbus_init(); return EINA_TRUE; } static void _elm_unneed_eldbus(void) { if (!_elm_need_eldbus) return; _elm_need_eldbus = EINA_FALSE; eldbus_shutdown(); } #ifdef ELM_ELOCATION static Eina_Bool _elm_need_elocation = EINA_FALSE; #endif EAPI Eina_Bool elm_need_elocation(void) { #ifdef ELM_ELOCATION if (_elm_need_elocation) return EINA_TRUE; _elm_need_elocation = EINA_TRUE; elocation_init(); return EINA_TRUE; #else return EINA_FALSE; #endif } static void _elm_unneed_elocation(void) { #ifdef ELM_ELOCATION if (!_elm_need_elocation) return; _elm_need_elocation = EINA_FALSE; elocation_shutdown(); #endif } static Eina_Bool _elm_need_efreet = EINA_FALSE; EAPI Eina_Bool elm_need_efreet(void) { if (_elm_need_efreet) return EINA_TRUE; if (!efreet_init()) return EINA_FALSE; if (!efreet_mime_init()) { efreet_shutdown(); return EINA_FALSE; } if (!efreet_trash_init()) { efreet_mime_shutdown(); efreet_shutdown(); return EINA_FALSE; } _elm_need_efreet = EINA_TRUE; /* { Eina_List **list; list = efreet_icon_extra_list_get(); if (list) { e_user_dir_concat_static(buf, "icons"); *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf)); e_prefix_data_concat_static(buf, "data/icons"); *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf)); } } */ return EINA_TRUE; } static void _elm_unneed_efreet(void) { if (!_elm_need_efreet) return; _elm_need_efreet = EINA_FALSE; efreet_trash_shutdown(); efreet_mime_shutdown(); efreet_shutdown(); } EAPI void elm_quicklaunch_mode_set(Eina_Bool ql_on) { quicklaunch_on = ql_on; } EAPI Eina_Bool elm_quicklaunch_mode_get(void) { return quicklaunch_on; } static void _postpone_cb(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) { eina_freeq_clear(postponed_fq); } EAPI int elm_quicklaunch_init(int argc EINA_UNUSED, char **argv) { _elm_ql_init_count++; if (_elm_ql_init_count > 1) return _elm_ql_init_count; _use_build_config = !!getenv("EFL_RUN_IN_TREE"); EINA_SAFETY_ON_FALSE_GOTO(eina_init(), fail_eina); _elm_log_dom = eina_log_domain_register("elementary", EINA_COLOR_LIGHTBLUE); EINA_SAFETY_ON_TRUE_GOTO(_elm_log_dom < 0, fail_eina_log); postponed_fq = eina_freeq_new(EINA_FREEQ_POSTPONED); EINA_SAFETY_ON_FALSE_GOTO(eet_init(), fail_eet); EINA_SAFETY_ON_FALSE_GOTO(ecore_init(), fail_ecore); EINA_SAFETY_ON_FALSE_GOTO(ecore_event_init(), fail_ecore_event); EINA_SAFETY_ON_FALSE_GOTO(edje_init(), fail_edje); EINA_SAFETY_ON_FALSE_GOTO(eio_init(), fail_eio); #ifdef HAVE_ELEMENTARY_EMAP EINA_SAFETY_ON_FALSE_GOTO(emap_init(), fail_emap); #endif memset(_elm_policies, 0, sizeof(_elm_policies)); ELM_EVENT_POLICY_CHANGED = ecore_event_type_new(); ELM_EVENT_PROCESS_BACKGROUND = ecore_event_type_new(); ELM_EVENT_PROCESS_FOREGROUND = ecore_event_type_new(); EINA_SAFETY_ON_FALSE_GOTO(ecore_file_init(), fail_ecore_file); _elm_theme_init(); _elm_exit_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, NULL); if (argv) { _elm_appname = strdup(ecore_file_file_get(argv[0])); elm_app_name_set(_elm_appname); } pfx = eina_prefix_new(argv ? argv[0] : NULL, elm_quicklaunch_init, "ELM", "elementary", "config/profile.cfg", PACKAGE_LIB_DIR, /* don't have a bin dir currently */ PACKAGE_LIB_DIR, PACKAGE_DATA_DIR, LOCALE_DIR); if (pfx) { if (_use_build_config) _elm_data_dir = eina_stringshare_add(PACKAGE_BUILD_DIR "/data/elementary"); else _elm_data_dir = eina_stringshare_add(eina_prefix_data_get(pfx)); _elm_lib_dir = eina_stringshare_add(eina_prefix_lib_get(pfx)); } if (!_elm_data_dir) _elm_data_dir = eina_stringshare_add("/"); if (!_elm_lib_dir) _elm_lib_dir = eina_stringshare_add("/"); if (!_property_style_ss) _property_style_ss = eina_stringshare_add("style"); efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_IDLE_EXIT, _postpone_cb, NULL); eina_log_timing(_elm_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT); if (quicklaunch_on) _elm_init_count++; return _elm_ql_init_count; fail_ecore_file: #ifdef HAVE_ELEMENTARY_EMAP emap_shutdown(); fail_emap: #endif eio_shutdown(); fail_eio: edje_shutdown(); fail_edje: ecore_event_shutdown(); fail_ecore_event: ecore_shutdown(); fail_ecore: eet_shutdown(); fail_eet: eina_log_domain_unregister(_elm_log_dom); _elm_log_dom = -1; fail_eina_log: eina_shutdown(); fail_eina: return --_elm_ql_init_count; } EAPI int elm_quicklaunch_sub_init(int argc, char **argv) { _elm_sub_init_count++; if (_elm_sub_init_count > 1) return _elm_sub_init_count; _elm_config_init(); if (!quicklaunch_on) { EINA_SAFETY_ON_FALSE_GOTO(ecore_init_ex(argc, argv), ql_sub_ecore); EINA_SAFETY_ON_FALSE_GOTO(ecore_evas_init(), ql_sub_ee); elm_color_class_init(); _elm_module_init(); _elm_config_sub_init(); EINA_SAFETY_ON_FALSE_GOTO(ecore_imf_init(), ql_sub_imf); EINA_SAFETY_ON_FALSE_GOTO(ecore_con_init(), ql_sub_ecore_con); EINA_SAFETY_ON_FALSE_GOTO(ecore_con_url_init(), ql_sub_ecore_con_url); _elm_prefs_initted = _elm_prefs_init(); EINA_SAFETY_ON_FALSE_GOTO(_elm_ews_wm_init(), ql_sub_ews);; } return _elm_sub_init_count; ql_sub_ews: if (_elm_prefs_initted) _elm_prefs_shutdown(); ecore_con_url_shutdown(); ql_sub_ecore_con_url: ecore_con_shutdown(); ql_sub_ecore_con: ecore_imf_shutdown(); ql_sub_imf: ecore_evas_shutdown(); _elm_module_shutdown(); _elm_config_sub_shutdown(); ql_sub_ee: ecore_shutdown_ex(); ql_sub_ecore: _elm_config_shutdown(); return --_elm_sub_init_count; } EAPI int elm_quicklaunch_sub_shutdown(void) { _elm_sub_init_count--; if (_elm_sub_init_count > 0) return _elm_sub_init_count; if (!quicklaunch_on) { ecore_shutdown_ex(); _elm_win_shutdown(); _elm_ews_wm_shutdown(); ecore_con_url_shutdown(); ecore_con_shutdown(); ecore_imf_shutdown(); edje_shutdown(); ecore_evas_shutdown(); _elm_config_sub_shutdown(); _elm_module_shutdown(); if (_elm_prefs_initted) _elm_prefs_shutdown(); _efl_ui_dnd_shutdown(); elm_color_class_shutdown(); } ecore_main_loop_iterate(); _elm_config_shutdown(); return _elm_sub_init_count; } EAPI int elm_quicklaunch_shutdown(void) { _elm_ql_init_count--; if (_elm_ql_init_count > 0) return _elm_ql_init_count; eina_log_timing(_elm_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_SHUTDOWN); ecore_event_type_flush(ELM_EVENT_POLICY_CHANGED, ELM_EVENT_PROCESS_BACKGROUND, ELM_EVENT_PROCESS_FOREGROUND); if (pfx) eina_prefix_free(pfx); pfx = NULL; ELM_SAFE_FREE(_elm_data_dir, eina_stringshare_del); ELM_SAFE_FREE(_elm_lib_dir, eina_stringshare_del); ELM_SAFE_FREE(_property_style_ss, eina_stringshare_del); ELM_SAFE_FREE(_elm_appname, free); ELM_SAFE_FREE(_elm_exit_handler, ecore_event_handler_del); _elm_theme_shutdown(); _elm_unneed_systray(); _elm_unneed_sys_notify(); _elm_unneed_efreet(); _elm_unneed_e_dbus(); _elm_unneed_eldbus(); _elm_unneed_elocation(); _elm_unneed_ethumb(); _elm_unneed_web(); #ifdef HAVE_ELEMENTARY_EMAP emap_shutdown(); #endif efl_event_callback_del(efl_main_loop_get(), EFL_LOOP_EVENT_IDLE_EXIT, _postpone_cb, NULL); eina_freeq_free(postponed_fq); postponed_fq = NULL; ecore_file_shutdown(); eio_shutdown(); ecore_event_shutdown(); ecore_shutdown(); eet_shutdown(); if (_elm_log_dom > -1) { eina_log_domain_unregister(_elm_log_dom); _elm_log_dom = -1; } eina_shutdown(); return _elm_ql_init_count; } EAPI void elm_quicklaunch_seed(void) { #ifndef SEMI_BROKEN_QUICKLAUNCH if (quicklaunch_on) { Evas_Object *win, *bg, *bt; win = elm_win_add(NULL, "seed", ELM_WIN_BASIC); bg = elm_bg_add(win); elm_win_resize_object_add(win, bg); evas_object_show(bg); bt = elm_button_add(win); elm_object_text_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?"); elm_win_resize_object_add(win, bt); ecore_main_loop_iterate(); evas_object_del(win); ecore_main_loop_iterate(); # ifdef HAVE_ELEMENTARY_X if (ecore_x_display_get()) ecore_x_sync(); # endif ecore_main_loop_iterate(); } #endif } #ifdef HAVE_FORK static void *qr_handle = NULL; #endif static int (*qr_main)(int argc, char **argv) = NULL; static void (*qre_main)(void *data, const Efl_Event *ev) = NULL; static void (*qre_pause)(void *data, const Efl_Event *ev) = NULL; static void (*qre_resume)(void *data, const Efl_Event *ev) = NULL; static void (*qre_terminate)(void *data, const Efl_Event *ev) = NULL; EFL_CALLBACKS_ARRAY_DEFINE(_qre_main_ex, { EFL_LOOP_EVENT_ARGUMENTS, qre_main }, { EFL_APP_EVENT_PAUSE, qre_pause }, { EFL_APP_EVENT_RESUME, qre_resume }, { EFL_EVENT_DEL, qre_terminate }); EAPI Eina_Bool elm_quicklaunch_prepare(int argc, char **argv, const char *cwd) { #ifdef HAVE_FORK char *exe, *exe2, *p; char *exename; if (argc <= 0 || argv == NULL) return EINA_FALSE; exe = elm_quicklaunch_exe_path_get(argv[0], cwd); if (!exe) { ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]); return EINA_FALSE; } exe2 = malloc(strlen(exe) + 1 + 7 + strlen(LIBEXT)); strcpy(exe2, exe); p = strrchr(exe2, '/'); if (p) p++; else p = exe2; exename = alloca(strlen(p) + 1); strcpy(exename, p); *p = 0; strcat(p, "../lib/"); strcat(p, exename); strcat(p, LIBEXT); if (access(exe2, R_OK | X_OK) != 0) ELM_SAFE_FREE(exe2, free); /* Try linking to executable first. Works with PIE files. */ qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL); if (qr_handle) { INF("dlopen('%s') = %p", exe, qr_handle); qr_main = dlsym(qr_handle, "elm_main"); if (qr_main) { INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main); free(exe2); free(exe); return EINA_TRUE; } dlclose(qr_handle); qr_handle = NULL; } if (!exe2) { WRN("not quicklauncher capable: '%s'", exe); free(exe); return EINA_FALSE; } free(exe); /* Open companion .so file. * Support for legacy quicklaunch apps with separate library. */ qr_handle = dlopen(exe2, RTLD_NOW | RTLD_GLOBAL); if (!qr_handle) { WRN("dlopen('%s') failed: %s", exe2, dlerror()); free(exe2); return EINA_FALSE; } INF("dlopen('%s') = %p", exe2, qr_handle); qr_main = dlsym(qr_handle, "elm_main"); INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main); if (!qr_main) { WRN("not quicklauncher capable: no elm_main in '%s'", exe2); dlclose(qr_handle); qr_handle = NULL; free(exe2); return EINA_FALSE; } free(exe2); return EINA_TRUE; #else (void)argc; (void)argv; (void)cwd; return EINA_FALSE; #endif } EAPI Eina_Bool efl_quicklaunch_prepare(int argc, char **argv, const char *cwd) { #ifdef HAVE_FORK char *exe, *exe2; if (argc <= 0 || argv == NULL) return EINA_FALSE; exe = elm_quicklaunch_exe_path_get(argv[0], cwd); if (!exe) { ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]); return EINA_FALSE; } exe2 = eina_file_path_sanitize(exe); ELM_SAFE_FREE(exe, free); /* Try linking to executable first. Works with PIE files. */ qr_handle = dlopen(exe2, RTLD_NOW | RTLD_GLOBAL); if (!qr_handle) { ERR("dlopen('%s') failed: %s", exe2, dlerror()); free(exe2); return EINA_FALSE; } INF("dlopen('%s') = %p", exe2, qr_handle); qre_main = dlsym(qr_handle, "efl_main"); INF("dlsym(%p, 'efl_main') = %p", qr_handle, qre_main); qre_pause = dlsym(qr_handle, "efl_pause"); qre_resume = dlsym(qr_handle, "efl_resume"); qre_terminate = dlsym(qr_handle, "efl_terminate"); if (qre_main) { free(exe2); return EINA_TRUE; } WRN("not quicklauncher capable: no efl_main in '%s'", exe2); dlclose(qr_handle); qr_handle = NULL; free(exe2); return EINA_FALSE; #else (void)argc; (void)argv; (void)cwd; return EINA_FALSE; #endif } EAPI int elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (*postfork_func) (void *data), void *postfork_data) { #ifdef HAVE_FORK pid_t child; int ret; if (!qr_main && !qre_main) { int i; char **args; WRN("No main function found."); child = fork(); if (child > 0) return child; else if (child < 0) { perror("could not fork"); return 0; } setsid(); if (chdir(cwd) != 0) perror("could not chdir"); args = alloca((argc + 1) * sizeof(char *)); for (i = 0; i < argc; i++) args[i] = argv[i]; args[argc] = NULL; WRN("%s not quicklaunch capable, fallback...", argv[0]); execvp(argv[0], args); ERR("failed to execute '%s': %s", argv[0], strerror(errno)); exit(-1); } INF("Main function found (legacy: %p, efl: %p)", qr_main, qre_main); child = fork(); if (child > 0) return child; else if (child < 0) { perror("could not fork"); return 0; } ecore_app_args_set(argc, (const char**)argv); if (postfork_func) postfork_func(postfork_data); eina_main_loop_define(); ecore_fork_reset(); if (quicklaunch_on) { ELM_SAFE_FREE(_elm_appname, free); if ((argv) && (argv[0])) _elm_appname = strdup(ecore_file_file_get(argv[0])); #ifdef SEMI_BROKEN_QUICKLAUNCH evas_init(); _elm_module_init(); _elm_config_sub_init(); ecore_evas_init(); // FIXME: check errors ecore_imf_init(); #endif } if (setsid() < 0) perror("could not setsid"); if (chdir(cwd) != 0) perror("could not chdir"); if (_elm_config->atspi_mode != ELM_ATSPI_MODE_OFF) _elm_atspi_bridge_init(); if (qre_main) { if (qre_pause && qre_resume && qre_terminate) { efl_event_callback_array_add(efl_main_loop_get(), _qre_main_ex(), NULL); } else { efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, qre_main, NULL); } ecore_init_ex(argc, argv); ret = efl_loop_exit_code_process(efl_loop_begin(efl_main_loop_get())); ecore_shutdown_ex(); elm_shutdown(); exit(ret); } else { ecore_init_ex(argc, argv); ret = qr_main(argc, argv); ecore_shutdown_ex(); exit(ret); } return 1; #else return 0; (void)argc; (void)argv; (void)cwd; (void)postfork_func; (void)postfork_data; #endif } EAPI void elm_quicklaunch_cleanup(void) { #ifdef HAVE_FORK if (qr_handle) { dlclose(qr_handle); qr_handle = NULL; qr_main = NULL; } #endif } EAPI int elm_quicklaunch_fallback(int argc, char **argv) { int ret; char cwd[PATH_MAX]; /* return nonzero on failure */ EINA_SAFETY_ON_FALSE_RETURN_VAL(elm_quicklaunch_init(argc, argv), 1); EINA_SAFETY_ON_FALSE_GOTO(elm_quicklaunch_sub_init(argc, argv), fallback_ql); elm_quicklaunch_prepare(argc, argv, getcwd(cwd, sizeof(cwd))); ret = qr_main(argc, argv); exit(ret); return ret; fallback_ql: elm_quicklaunch_shutdown(); return 1; } EAPI char * elm_quicklaunch_exe_path_get(const char *exe, const char *cwd) { static char *path = NULL; static Eina_List *pathlist = NULL; const char *pathitr; const Eina_List *l; char buf[PATH_MAX]; if (exe[0] == '/') return strdup(exe); if (cwd) pathlist = eina_list_append(pathlist, eina_stringshare_add(cwd)); else { if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe); if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe); } if (!path) { const char *p, *pp; char *buf2; path = getenv("PATH"); buf2 = alloca(strlen(path) + 1); p = path; pp = p; for (;; ) { if ((*p == ':') || (!*p)) { int len; len = p - pp; strncpy(buf2, pp, len); buf2[len] = 0; pathlist = eina_list_append(pathlist, eina_stringshare_add(buf2)); if (!*p) break; p++; pp = p; } else { if (!*p) break; p++; } } } EINA_LIST_FOREACH(pathlist, l, pathitr) { snprintf(buf, sizeof(buf), "%s/%s", pathitr, exe); if (!access(buf, R_OK | X_OK)) return strdup(buf); } return NULL; } EAPI void elm_run(void) { ecore_main_loop_begin(); } static void _on_terminate(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) { Eina_List *l, *l_next; Evas_Object *win; EINA_LIST_FOREACH_SAFE(_elm_win_list, l, l_next, win) evas_object_del(win); } EAPI void elm_exit(void) { efl_exit(0); } //FIXME: Use Elm_Policy Parameter when 2.0 is released. EAPI Eina_Bool elm_policy_set(unsigned int policy, int value) { Elm_Event_Policy_Changed *ev; if (policy >= ELM_POLICY_LAST) return EINA_FALSE; if (value == _elm_policies[policy]) return EINA_TRUE; if (policy == ELM_POLICY_EXIT) { if (value == ELM_POLICY_EXIT_WINDOWS_DEL) { efl_event_callback_add(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE, _on_terminate, NULL); } else { efl_event_callback_del(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE, _on_terminate, NULL); } } /* TODO: validate policy? */ ev = malloc(sizeof(*ev)); ev->policy = policy; ev->new_value = value; ev->old_value = _elm_policies[policy]; _elm_policies[policy] = value; ecore_event_add(ELM_EVENT_POLICY_CHANGED, ev, NULL, NULL); return EINA_TRUE; } //FIXME: Use Elm_Policy Parameter when 2.0 is released. EAPI int elm_policy_get(unsigned int policy) { if (policy >= ELM_POLICY_LAST) return 0; return _elm_policies[policy]; } EAPI void elm_language_set(const char *lang) { setlocale(LC_ALL, lang); evas_language_reinit(); _elm_win_translate(); edje_language_set(lang); } EAPI Eina_Bool elm_object_mirrored_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return efl_ui_mirrored_get(obj); } EAPI void elm_object_mirrored_set(Evas_Object *obj, Eina_Bool mirrored) { EINA_SAFETY_ON_NULL_RETURN(obj); efl_ui_mirrored_set(obj, mirrored); } EAPI Eina_Bool elm_object_mirrored_automatic_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return efl_ui_mirrored_automatic_get(obj); } EAPI void elm_object_mirrored_automatic_set(Evas_Object *obj, Eina_Bool automatic) { EINA_SAFETY_ON_NULL_RETURN(obj); efl_ui_mirrored_automatic_set(obj, automatic); } /** * @} */ EAPI void elm_object_scale_set(Evas_Object *obj, double scale) { EINA_SAFETY_ON_NULL_RETURN(obj); efl_gfx_entity_scale_set(obj, scale); } EAPI double elm_object_scale_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0.0); return efl_gfx_entity_scale_get(obj); } EAPI void elm_object_part_text_set(Evas_Object *obj, const char *part, const char *label) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_part_text_set(obj, part, label); } EAPI const char * elm_object_part_text_get(const Evas_Object *obj, const char *part) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_widget_part_text_get(obj, part); } EAPI void elm_object_domain_translatable_part_text_set(Evas_Object *obj, const char *part, const char *domain, const char *text) { EINA_SAFETY_ON_NULL_RETURN(obj); if (elm_widget_is_legacy(obj)) { if (!part) part = efl_ui_widget_default_text_part_get(obj); else if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) _elm_layout_part_aliasing_eval(obj, &part, EINA_TRUE); elm_widget_part_translatable_text_set(obj, part, text, domain); } else { if (!part) efl_ui_l10n_text_set(obj, text, domain); else efl_ui_l10n_text_set(efl_part(obj, part), text, domain); } } EAPI const char * elm_object_translatable_part_text_get(const Evas_Object *obj, const char *part) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); if (elm_widget_is_legacy(obj)) { if (!part) part = efl_ui_widget_default_text_part_get(obj); else if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) _elm_layout_part_aliasing_eval(obj, &part, EINA_TRUE); return elm_widget_part_translatable_text_get(obj, part, NULL); } else { if (!part) return efl_ui_l10n_text_get(obj, NULL); else return efl_ui_l10n_text_get(efl_part(obj, part), NULL); } } EAPI void elm_object_domain_part_text_translatable_set(Evas_Object *obj, const char *part, const char *domain, Eina_Bool translatable) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_domain_part_text_translatable_set(obj, part, domain, translatable); } EINA_DEPRECATED EAPI void elm_object_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *text) { elm_object_domain_translatable_part_text_set(obj, part, domain, text); } EINA_DEPRECATED EAPI const char * elm_object_translatable_text_part_get(const Evas_Object *obj, const char *part) { return elm_object_translatable_part_text_get(obj, part); } EAPI void elm_object_part_content_set(Evas_Object *obj, const char *part, Evas_Object *content) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_content_part_set(obj, part, content); } EAPI Evas_Object * elm_object_part_content_get(const Evas_Object *obj, const char *part) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_widget_content_part_get(obj, part); } EAPI Evas_Object * elm_object_part_content_unset(Evas_Object *obj, const char *part) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_widget_content_part_unset(obj, part); } EAPI Eina_Bool elm_object_style_set(Evas_Object *obj, const char *style) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return elm_widget_style_set(obj, style) == EFL_UI_THEME_APPLY_ERROR_NONE; } EAPI Eina_Bool elm_object_focus_highlight_style_set(Evas_Object *obj, const char *style) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return elm_win_focus_highlight_style_set(elm_widget_top_get(obj), style); } EAPI const char * elm_object_focus_highlight_style_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_win_focus_highlight_style_get(elm_widget_top_get(obj)); } EAPI const char * elm_object_style_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_widget_style_get(obj); } EAPI void elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled) { EINA_SAFETY_ON_NULL_RETURN(obj); ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd); ELM_WIDGET_DATA_GET_OR_RETURN(efl_ui_widget_parent_get(obj), ppd); if (disabled) { //we aim here for the disabled count of parent + 1 if (pd->disabled == ppd->disabled + 1) return; pd->disabled = ppd->disabled; } else { //we aim for the same disabled count as the parent here if (pd->disabled == ppd->disabled) return; pd->disabled = ppd->disabled + 1; } elm_widget_disabled_set(obj, disabled); } EAPI Eina_Bool elm_object_disabled_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return elm_widget_disabled_get(obj); } EAPI void elm_cache_all_flush(void) { const Eina_List *l; Evas_Object *obj; edje_file_cache_flush(); edje_collection_cache_flush(); eet_clearcache(); EINA_LIST_FOREACH(_elm_win_list, l, obj) { Evas *e = evas_object_evas_get(obj); evas_image_cache_flush(e); evas_font_cache_flush(e); // this is up for debate if we should dump as well // evas_render_dump(e); } } EAPI void elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_can_focus_set(obj, enable); } EAPI Eina_Bool elm_object_focus_allow_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return (elm_widget_can_focus_get(obj)) || (elm_widget_child_can_focus_get(obj)); } EAPI void elm_object_tree_focus_allow_set(Evas_Object *obj, Eina_Bool tree_focusable) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_tree_unfocusable_set(obj, !tree_focusable); } EAPI Eina_Bool elm_object_tree_focus_allow_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return !elm_widget_tree_unfocusable_get(obj); } EAPI void elm_object_focus_move_policy_set(Evas_Object *obj, Elm_Focus_Move_Policy policy) { EINA_SAFETY_ON_NULL_RETURN(obj); efl_ui_widget_focus_move_policy_set(obj, policy); } EAPI Elm_Focus_Move_Policy elm_object_focus_move_policy_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return efl_ui_widget_focus_move_policy_get(obj); } EAPI Eina_Bool elm_object_focus_move_policy_automatic_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return efl_ui_widget_focus_move_policy_automatic_get(obj); } EAPI void elm_object_focus_move_policy_automatic_set(Evas_Object *obj, Eina_Bool automatic) { EINA_SAFETY_ON_NULL_RETURN(obj); return efl_ui_widget_focus_move_policy_automatic_set(obj, automatic); } EAPI void elm_object_scroll_hold_push(Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_scroll_hold_push(obj); } EAPI void elm_object_scroll_hold_pop(Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_scroll_hold_pop(obj); } EAPI int elm_object_scroll_hold_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0); return elm_widget_scroll_hold_get(obj); } EAPI void elm_object_scroll_freeze_push(Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_scroll_freeze_push(obj); } EAPI void elm_object_scroll_freeze_pop(Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_scroll_freeze_pop(obj); } EAPI int elm_object_scroll_freeze_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0); return elm_widget_scroll_freeze_get(obj); } EAPI void elm_object_scroll_lock_x_set(Evas_Object *obj, Eina_Bool lock) { Efl_Ui_Scroll_Block block; EINA_SAFETY_ON_NULL_RETURN(obj); block = elm_widget_scroll_lock_get(obj); if (lock) block |= EFL_UI_SCROLL_BLOCK_HORIZONTAL; else block &= ~EFL_UI_SCROLL_BLOCK_HORIZONTAL; elm_widget_scroll_lock_set(obj, block); } EAPI void elm_object_scroll_lock_y_set(Evas_Object *obj, Eina_Bool lock) { Efl_Ui_Scroll_Block block; EINA_SAFETY_ON_NULL_RETURN(obj); block = elm_widget_scroll_lock_get(obj); if (lock) block |= EFL_UI_SCROLL_BLOCK_VERTICAL; else block &= ~EFL_UI_SCROLL_BLOCK_VERTICAL; elm_widget_scroll_lock_set(obj, block); } EAPI Eina_Bool elm_object_scroll_lock_x_get(const Evas_Object *obj) { Efl_Ui_Scroll_Block block; EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); block = elm_widget_scroll_lock_get(obj); return !!(block & EFL_UI_SCROLL_BLOCK_HORIZONTAL); } EAPI Eina_Bool elm_object_scroll_lock_y_get(const Evas_Object *obj) { Efl_Ui_Scroll_Block block; EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); block = elm_widget_scroll_lock_get(obj); return !!(block & EFL_UI_SCROLL_BLOCK_VERTICAL); } EAPI void elm_object_scroll_item_loop_enabled_set(Evas_Object *obj, Eina_Bool enable) { EINA_SAFETY_ON_NULL_RETURN(obj); if (!efl_isa(obj, ELM_INTERFACE_SCROLLABLE_MIXIN)) return; elm_interface_scrollable_item_loop_enabled_set(obj, enable); } EAPI Eina_Bool elm_object_scroll_item_loop_enabled_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); if (!efl_isa(obj, ELM_INTERFACE_SCROLLABLE_MIXIN)) return EINA_FALSE; return elm_interface_scrollable_item_loop_enabled_get(obj); } EAPI Eina_Bool elm_object_widget_check(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); return elm_widget_is(obj); } EAPI Evas_Object * elm_object_parent_widget_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_widget_parent_widget_get(obj); } EAPI Evas_Object * elm_object_top_widget_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_widget_top_get(obj); } EAPI const char * elm_object_widget_type_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); return elm_widget_type_get(obj); } EAPI void elm_object_signal_emit(Evas_Object *obj, const char *emission, const char *source) { EINA_SAFETY_ON_NULL_RETURN(obj); elm_widget_signal_emit(obj, emission, source); } EAPI void elm_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data) { EINA_SAFETY_ON_NULL_RETURN(obj); EINA_SAFETY_ON_NULL_RETURN(func); elm_widget_signal_callback_add(obj, emission, source, func, data); } EAPI void * elm_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL); return elm_widget_signal_callback_del(obj, emission, source, func); } EAPI void elm_object_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data) { EINA_SAFETY_ON_NULL_RETURN(obj); EINA_SAFETY_ON_NULL_RETURN(func); elm_widget_event_callback_add(obj, func, data); } EAPI void * elm_object_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL); return elm_widget_event_callback_del(obj, func, data); } EAPI void elm_object_tree_dump(const Evas_Object *top) { #ifdef ELM_DEBUG elm_widget_tree_dump(top); #else (void)top; return; #endif } EAPI void elm_object_tree_dot_dump(const Evas_Object *top, const char *file) { #ifdef ELM_DEBUG FILE *f = fopen(file, "wb"); elm_widget_tree_dot_dump(top, f); fclose(f); #else (void)top; (void)file; return; #endif } EAPI void elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h) { if ((w) && (*w < (elm_config_finger_size_get() * times_w))) *w = elm_config_finger_size_get() * times_w; if ((h) && (*h < (elm_config_finger_size_get() * times_h))) *h = elm_config_finger_size_get() * times_h; } EAPI void elm_object_access_info_set(Evas_Object *obj, const char *txt) { elm_widget_access_info_set(obj, txt); } EAPI const char * elm_object_access_info_get(Evas_Object *obj) { return elm_widget_access_info_get(obj); } EAPI Evas_Object * elm_object_name_find(const Evas_Object *obj, const char *name, int recurse) { return elm_widget_name_find(obj, name, recurse); } EAPI void elm_object_orientation_mode_disabled_set(Evas_Object *obj, Eina_Bool disabled) { if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) { efl_ui_layout_automatic_theme_rotation_set(obj, disabled); } else { //legacy behaviour efl_key_data_set(obj, "__orientation_mode_disabled", (void*) (intptr_t) disabled); } } EAPI Eina_Bool elm_object_orientation_mode_disabled_get(const Evas_Object *obj) { if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) { return efl_ui_layout_automatic_theme_rotation_get(obj); } else { if (efl_key_data_get(obj, "__orientation_mode_disabled")) return EINA_TRUE; } return EINA_FALSE; } EAPI Elm_Object_Item * elm_object_focused_item_get(const Evas_Object *obj) { EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); if (!efl_isa(obj, ELM_WIDGET_ITEM_CONTAINER_INTERFACE)) return NULL; return elm_widget_item_container_focused_item_get(obj); } EAPI void elm_object_focus_region_show_mode_set(Evas_Object *obj, Elm_Focus_Region_Show_Mode mode) { if (efl_isa(obj, ELM_GENGRID_CLASS)) { Elm_Gengrid_Data *pd = efl_data_scope_get(obj, ELM_GENGRID_CLASS); pd->mode = mode; } } EAPI Elm_Focus_Region_Show_Mode elm_object_focus_region_show_mode_get(const Evas_Object *obj) { if (efl_isa(obj, ELM_GENGRID_CLASS)) { Elm_Gengrid_Data *pd = efl_data_scope_get(obj, ELM_GENGRID_CLASS); return pd->mode; } return ELM_FOCUS_REGION_SHOW_WIDGET; } static void _item_noref(void *data EINA_UNUSED, const Efl_Event *ev) { if (!efl_parent_get(ev->object)) return ; efl_del(ev->object); } EAPI void elm_object_item_del(Eo *obj) { Elm_Widget_Item_Data *item; if (efl_ref_count(obj) == 1) { // Noref already, die little item ! efl_del(obj); return ; } item = efl_data_scope_safe_get(obj, ELM_WIDGET_ITEM_CLASS); if (!item) return ; efl_event_callback_add(obj, EFL_EVENT_NOREF, _item_noref, NULL); item->on_deletion = EINA_TRUE; } EAPI Eina_Bool elm_object_cursor_set(Eo *obj, const char *cursor) { return efl_ui_widget_cursor_set(obj, cursor); } EAPI const char * elm_object_cursor_get(const Eo *obj) { return efl_ui_widget_cursor_get(obj); } EAPI Eina_Bool elm_object_cursor_style_set(Eo *obj, const char *style) { return efl_ui_widget_cursor_style_set(obj, style); } EAPI const char * elm_object_cursor_style_get(const Eo *obj) { return efl_ui_widget_cursor_style_get(obj); } EAPI Eina_Bool elm_object_cursor_theme_search_enabled_set(Eo *obj, Eina_Bool allow) { return efl_ui_widget_cursor_theme_search_enabled_set(obj, allow); } EAPI Eina_Bool elm_object_cursor_theme_search_enabled_get(const Eo *obj) { return efl_ui_widget_cursor_theme_search_enabled_get(obj); }