From 517471190f87e473e3bc38584c23ae28fb772c7c Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Thu, 10 Jan 2013 05:48:55 +0000 Subject: [PATCH] efl/emotion: refactor init/shutdown, load modules from eina_prefix. * emotion_init() and emotion_shutdown() now exist, let's do our initialization from there. * smart_add/smart_free will call init/shutdown for legacy apps. * use eina_prefix to determine runtime location. * use eina_module_arch_list_get() SVN revision: 82509 --- src/lib/emotion/emotion_main.c | 221 +++++++++++++++++++++++++++--- src/lib/emotion/emotion_private.h | 10 ++ src/lib/emotion/emotion_smart.c | 125 +++++------------ 3 files changed, 244 insertions(+), 112 deletions(-) diff --git a/src/lib/emotion/emotion_main.c b/src/lib/emotion/emotion_main.c index 4e0aa5b75b..906cc7776d 100644 --- a/src/lib/emotion/emotion_main.c +++ b/src/lib/emotion/emotion_main.c @@ -30,10 +30,28 @@ #include "Emotion.h" #include "emotion_private.h" +#ifdef EMOTION_STATIC_BUILD_XINE +Eina_Bool xine_module_init(void); +void xine_module_shutdown(void); +#endif +#ifdef EMOTION_STATIC_BUILD_GSTREAMER +Eina_Bool gstreamer_module_init(void); +void gstreamer_module_shutdown(void); +#endif +#ifdef EMOTION_STATIC_BUILD_GENERIC +Eina_Bool generic_module_init(void); +void generic_module_shutdown(void); +#endif + static Emotion_Version _version = { VMAJ, VMIN, VMIC, VREV }; static int emotion_pending_objects = 0; EAPI Emotion_Version *emotion_version = &_version; +static Eina_Prefix *pfx = NULL; +Eina_Hash *_emotion_backends = NULL; +Eina_Array *_emotion_modules = NULL; +int _emotion_log_domain = -1; + EAPI int EMOTION_WEBCAM_UPDATE = 0; struct ext_match_s @@ -120,7 +138,7 @@ _emotion_object_extension_can_play_generic_get(const void *data EINA_UNUSED, con EAPI Eina_Bool emotion_object_extension_may_play_fast_get(const char *file) { - if (!file) return EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); return _emotion_object_extension_can_play_generic_get(NULL, file); } @@ -130,7 +148,7 @@ emotion_object_extension_may_play_get(const char *file) const char *tmp; Eina_Bool result; - if (!file) return EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); tmp = eina_stringshare_add(file); result = emotion_object_extension_may_play_fast_get(tmp); eina_stringshare_del(tmp); @@ -158,7 +176,7 @@ struct _Emotion_Webcam const char *filename; }; -static int _emotion_webcams_count = 0; +static int _emotion_init_count = 0; static Eet_Data_Descriptor *_webcam_edd; static Eet_Data_Descriptor *_webcams_edd; @@ -319,33 +337,131 @@ _emotion_eeze_events(const char *syspath, #endif +static void +_emotion_modules_init(void) +{ + char buf[PATH_MAX]; + char *path; + + if (getenv("EFL_RUN_IN_TREE")) + { + struct stat st; + snprintf(buf, sizeof(buf), "%s/src/modules/emotion", + PACKAGE_BUILD_DIR); + if (stat(buf, &st) == 0) + { + const char *built_modules[] = { +#ifdef EMOTION_BUILD_GSTREAMER + "gstreamer", +#endif +#ifdef EMOTION_BUILD_XINE + "xine", +#endif + NULL + }; + const char **itr; + for (itr = built_modules; *itr != NULL; itr++) + { + snprintf(buf, sizeof(buf), + "%s/src/modules/emotion/%s/.libs", + PACKAGE_BUILD_DIR, *itr); + _emotion_modules = eina_module_list_get(_emotion_modules, buf, + EINA_FALSE, NULL, NULL); + } + + return; + } + } + + path = eina_module_environment_path_get("EMOTION_MODULES_DIR", + "/emotion/modules"); + if (path) + { + _emotion_modules = eina_module_arch_list_get(_emotion_modules, path, MODULE_ARCH); + free(path); + } + + path = eina_module_environment_path_get("HOME", "/.emotion"); + if (path) + { + _emotion_modules = eina_module_arch_list_get(_emotion_modules, path, MODULE_ARCH); + free(path); + } + + snprintf(buf, sizeof(buf), "%s/emotion/modules", eina_prefix_lib_get(pfx)); + _emotion_modules = eina_module_arch_list_get(_emotion_modules, buf, MODULE_ARCH); +} + EAPI Eina_Bool emotion_init(void) { char buffer[PATH_MAX]; + int static_modules = 0; - if (_emotion_webcams_count++) return EINA_TRUE; + if (_emotion_init_count > 0) + { + _emotion_init_count++; + return EINA_TRUE; + } + + eina_init(); + + _emotion_log_domain = eina_log_domain_register("emotion", EINA_COLOR_LIGHTCYAN); + if (_emotion_log_domain < 0) + { + EINA_LOG_CRIT("Could not register log domain 'emotion'"); + eina_shutdown(); + return EINA_FALSE; + } + + pfx = eina_prefix_new(NULL, emotion_init, + "EMOTION", "emotion", "checkme", + PACKAGE_BIN_DIR, PACKAGE_LIB_DIR, + PACKAGE_DATA_DIR, PACKAGE_DATA_DIR); + EINA_SAFETY_ON_NULL_GOTO(pfx, error); + + _emotion_backends = eina_hash_string_small_new(free); + EINA_SAFETY_ON_NULL_GOTO(_emotion_backends, error_hash); + + _emotion_modules_init(); + + /* Init static module */ +#ifdef EMOTION_STATIC_BUILD_XINE + static_modules += xine_module_init(); +#endif +#ifdef EMOTION_STATIC_BUILD_GSTREAMER + static_modules += gstreamer_module_init(); +#endif +#ifdef EMOTION_STATIC_BUILD_GENERIC + static_modules += generic_module_init(); +#endif + + if ((!_emotion_modules) && (!static_modules)) + WRN("No emotion modules found!"); + else if (_emotion_modules) + eina_module_list_load(_emotion_modules); ecore_init(); + eet_init(); - snprintf(buffer, sizeof(buffer), "%s/emotion.cfg", PACKAGE_DATA_DIR); + snprintf(buffer, sizeof(buffer), "%s/emotion.cfg", eina_prefix_data_get(pfx)); _emotion_webcams_file = eet_open(buffer, EET_FILE_MODE_READ); if (_emotion_webcams_file) { - Eet_Data_Descriptor *edd; - - edd = _emotion_webcams_data(); + Eet_Data_Descriptor *edd = _emotion_webcams_data(); _emotion_webcams = eet_data_read(_emotion_webcams_file, edd, "config"); + INF("Loaded config %p from eet: %s", _emotion_webcams_file, buffer); eet_data_descriptor_free(_webcams_edd); _webcams_edd = NULL; eet_data_descriptor_free(_webcam_edd); _webcam_edd = NULL; } if (!_emotion_webcams) { + DBG("No config at %s, create empty", buffer); _emotion_webcams = calloc(1, sizeof (Emotion_Webcams)); - if (!_emotion_webcams) return EINA_FALSE; + EINA_SAFETY_ON_NULL_GOTO(_emotion_webcams, error_webcams_alloc); } #ifdef HAVE_EEZE @@ -360,7 +476,41 @@ emotion_init(void) _emotion_eeze_events, NULL); #endif + _emotion_init_count = 1; return EINA_TRUE; + + error_webcams_alloc: + +#ifdef EMOTION_STATIC_BUILD_XINE + xine_module_shutdown(); +#endif +#ifdef EMOTION_STATIC_BUILD_GSTREAMER + gstreamer_module_shutdown(); +#endif +#ifdef EMOTION_STATIC_BUILD_GENERIC + generic_module_shutdown(); +#endif + + if (_emotion_modules) + { + eina_module_list_free(_emotion_modules); + eina_array_free(_emotion_modules); + _emotion_modules = NULL; + } + + eina_hash_free(_emotion_backends); + _emotion_backends = NULL; + + error_hash: + eina_prefix_free(pfx); + pfx = NULL; + + error: + eina_log_domain_unregister(_emotion_log_domain); + _emotion_log_domain = -1; + + eina_shutdown(); + return EINA_FALSE; } EAPI Eina_Bool @@ -369,12 +519,12 @@ emotion_shutdown(void) Emotion_Webcam *ew; double start; - if (_emotion_webcams_count <= 0) + if (_emotion_init_count <= 0) { - EINA_LOG_ERR("Init count not greater than 0 in shutdown."); + EINA_LOG_ERR("Init count not greater than 0 in emotion shutdown."); return EINA_FALSE; } - if (--_emotion_webcams_count) return EINA_TRUE; + if (--_emotion_init_count) return EINA_TRUE; EINA_LIST_FREE(_emotion_webcams->webcams, ew) { @@ -408,30 +558,58 @@ emotion_shutdown(void) EINA_LOG_ERR("There is still %i Emotion pipeline running", emotion_pending_objects); } + eet_shutdown(); ecore_shutdown(); +#ifdef EMOTION_STATIC_BUILD_XINE + xine_module_shutdown(); +#endif +#ifdef EMOTION_STATIC_BUILD_GSTREAMER + gstreamer_module_shutdown(); +#endif +#ifdef EMOTION_STATIC_BUILD_GENERIC + generic_module_shutdown(); +#endif + + if (_emotion_modules) + { + eina_module_list_free(_emotion_modules); + eina_array_free(_emotion_modules); + _emotion_modules = NULL; + } + + eina_hash_free(_emotion_backends); + _emotion_backends = NULL; + + eina_prefix_free(pfx); + pfx = NULL; + + eina_log_domain_unregister(_emotion_log_domain); + _emotion_log_domain = -1; + + eina_shutdown(); + return EINA_TRUE; } EAPI const Eina_List * emotion_webcams_get(void) { + EINA_SAFETY_ON_NULL_RETURN_VAL(_emotion_webcams, NULL); return _emotion_webcams->webcams; } EAPI const char * emotion_webcam_name_get(const Emotion_Webcam *ew) { - if (!ew) return NULL; - + EINA_SAFETY_ON_NULL_RETURN_VAL(ew, NULL); return ew->name; } EAPI const char * emotion_webcam_device_get(const Emotion_Webcam *ew) { - if (!ew) return NULL; - + EINA_SAFETY_ON_NULL_RETURN_VAL(ew, NULL); return ew->device; } @@ -441,12 +619,11 @@ emotion_webcam_custom_get(const char *device) const Emotion_Webcam *ew; const Eina_List *l; - if (_emotion_webcams) - { - EINA_LIST_FOREACH(_emotion_webcams->webcams, l, ew) - if (ew->device && strcmp(device, ew->device) == 0) - return ew->custom; - } + EINA_SAFETY_ON_NULL_RETURN_VAL(_emotion_webcams, NULL); + + EINA_LIST_FOREACH(_emotion_webcams->webcams, l, ew) + if (ew->device && strcmp(device, ew->device) == 0) + return ew->custom; return NULL; } diff --git a/src/lib/emotion/emotion_private.h b/src/lib/emotion/emotion_private.h index 73a1b7ddf0..125e52c36e 100644 --- a/src/lib/emotion/emotion_private.h +++ b/src/lib/emotion/emotion_private.h @@ -134,4 +134,14 @@ EAPI const char *emotion_webcam_custom_get(const char *device); EAPI void _emotion_pending_object_ref(void); EAPI void _emotion_pending_object_unref(void); +extern Eina_Hash *_emotion_backends; +extern Eina_Array *_emotion_modules; +extern int _emotion_log_domain; + +#define DBG(...) EINA_LOG_DOM_DBG(_emotion_log_domain, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_emotion_log_domain, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_emotion_log_domain, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_emotion_log_domain, __VA_ARGS__) +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_emotion_log_domain, __VA_ARGS__) + #endif diff --git a/src/lib/emotion/emotion_smart.c b/src/lib/emotion/emotion_smart.c index 709414459c..2b0c59dfc2 100644 --- a/src/lib/emotion/emotion_smart.c +++ b/src/lib/emotion/emotion_smart.c @@ -43,12 +43,6 @@ if (strcmp(_e_smart_str, type)) return ret; \ } -#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__) -#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__) -#define WRN(...) EINA_LOG_DOM_WARN(_log_domain, __VA_ARGS__) -#define ERR(...) EINA_LOG_DOM_ERR(_log_domain, __VA_ARGS__) -#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_domain, __VA_ARGS__) - #define E_OBJ_NAME "emotion_object" typedef struct _Smart_Data Smart_Data; @@ -141,9 +135,6 @@ static void _smart_clip_unset(Evas_Object * obj); /* Globals for the E Video Object */ /**********************************/ static Evas_Smart *smart = NULL; -static Eina_Hash *_backends = NULL; -static Eina_Array *_modules = NULL; -static int _log_domain = -1; static const char *_backend_priority[] = { "gstreamer", @@ -242,7 +233,8 @@ _smart_data_free(Smart_Data *sd) free(sd->ref.file); free(sd); - ecore_shutdown(); + /* TODO: remove legacy: emotion used to have no shutdown, call automatically */ + emotion_shutdown(); } EAPI Eina_Bool @@ -251,18 +243,20 @@ _emotion_module_register(const char *name, Emotion_Module_Open mod_open, Emotion Eina_Emotion_Plugins *plugin; plugin = malloc(sizeof (Eina_Emotion_Plugins)); - if (!plugin) return EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(plugin, EINA_FALSE); plugin->open = mod_open; plugin->close = mod_close; - return eina_hash_add(_backends, name, plugin); + INF("register module=%s, open=%p, close=%p", name, mod_open, mod_close); + return eina_hash_add(_emotion_backends, name, plugin); } EAPI Eina_Bool _emotion_module_unregister(const char *name) { - return eina_hash_del(_backends, name, NULL); + INF("unregister module=%s", name); + return eina_hash_del_by_key(_emotion_backends, name); } static const char * @@ -273,21 +267,25 @@ _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module ** unsigned int i = 0; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!_backends) + if (!_emotion_backends) { ERR("No backend loaded"); - return NULL; + return NULL; } if (!name && getenv("EMOTION_ENGINE")) - name = getenv("EMOTION_ENGINE"); + { + name = getenv("EMOTION_ENGINE"); + DBG("using EMOTION_ENGINE=%s", name); + } /* FIXME: Always look for a working backend. */ retry: if (!name || i > 0) name = _backend_priority[i++]; - plugin = eina_hash_find(_backends, name); + plugin = eina_hash_find(_emotion_backends, name); + DBG("try engine=%s, plugin=%p", name, plugin); if (!plugin) { if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*))) @@ -299,6 +297,7 @@ _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module ** if (plugin->open(obj, (const Emotion_Video_Module **) mod, video, &(sd->module_options))) { + INF("opened %s, mod=%p, video=%p", name, mod, video); if (*mod) { (*mod)->plugin = plugin; @@ -1909,85 +1908,29 @@ _pixels_get(void *data, Evas_Object *obj) /*******************************************/ /* Internal smart object required routines */ /*******************************************/ -#ifdef EMOTION_STATIC_BUILD_XINE -Eina_Bool xine_module_init(void); -#endif -#ifdef EMOTION_STATIC_BUILD_GSTREAMER -Eina_Bool gstreamer_module_init(void); -#endif -#ifdef EMOTION_STATIC_BUILD_GENERIC -Eina_Bool generic_module_init(void); -#endif static void _smart_init(void) { - char *path; + static Evas_Smart_Class sc = + EVAS_SMART_CLASS_INIT_NAME_VERSION(E_OBJ_NAME); if (smart) return; + + if (!sc.add) { - eina_init(); - - _log_domain = eina_log_domain_register("emotion", EINA_COLOR_LIGHTCYAN); - if (_log_domain < 0) - { - EINA_LOG_CRIT("Could not register log domain 'emotion'"); - eina_shutdown(); - return; - } - - _backends = eina_hash_string_small_new(free); - - _modules = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/emotion/", 0, NULL, NULL); - - path = eina_module_environment_path_get("HOME", "/.emotion/"); - _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); - if (path) free(path); - - path = eina_module_environment_path_get("EMOTION_MODULES_DIR", "/emotion/"); - _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); - if (path) free(path); - - path = eina_module_symbol_path_get(emotion_object_add, "/emotion/"); - _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); - if (path) free(path); - - if (!_modules) - { - ERR("No module found!"); - return; - } - - eina_module_list_load(_modules); - - /* Init static module */ -#ifdef EMOTION_STATIC_BUILD_XINE - xine_module_init(); -#endif -#ifdef EMOTION_STATIC_BUILD_GSTREAMER - gstreamer_module_init(); -#endif -#ifdef EMOTION_STATIC_BUILD_GENERIC - generic_module_init(); -#endif - - static Evas_Smart_Class sc = - EVAS_SMART_CLASS_INIT_NAME_VERSION(E_OBJ_NAME); - if (!sc.add) - { - sc.add = _smart_add; - sc.del = _smart_del; - sc.move = _smart_move; - sc.resize = _smart_resize; - sc.show = _smart_show; - sc.hide = _smart_hide; - sc.color_set = _smart_color_set; - sc.clip_set = _smart_clip_set; - sc.clip_unset = _smart_clip_unset; - sc.callbacks = _smart_callbacks; - } - smart = evas_smart_class_new(&sc); + sc.add = _smart_add; + sc.del = _smart_del; + sc.move = _smart_move; + sc.resize = _smart_resize; + sc.show = _smart_show; + sc.hide = _smart_hide; + sc.color_set = _smart_color_set; + sc.clip_set = _smart_clip_set; + sc.clip_unset = _smart_clip_unset; + sc.callbacks = _smart_callbacks; } + smart = evas_smart_class_new(&sc); } static void @@ -1998,6 +1941,10 @@ _smart_add(Evas_Object * obj) sd = calloc(1, sizeof(Smart_Data)); if (!sd) return; + + /* TODO: remove legacy: emotion used to have no init, call automatically */ + emotion_init(); + EINA_REFCOUNT_INIT(sd); sd->state = EMOTION_WAKEUP; sd->obj = evas_object_image_add(evas_object_evas_get(obj)); @@ -2021,8 +1968,6 @@ _smart_add(Evas_Object * obj) evas_object_image_data_set(obj, pixel); } evas_object_smart_data_set(obj, sd); - - ecore_init(); } static void