forked from enlightenment/efl
* emotion: Switch to Eina module.
TODO: Add configure option to build module statically. SVN revision: 44781
This commit is contained in:
parent
1c1663bd88
commit
65c4336b0b
|
@ -26,6 +26,10 @@
|
||||||
typedef enum _Emotion_Format Emotion_Format;
|
typedef enum _Emotion_Format Emotion_Format;
|
||||||
typedef struct _Emotion_Video_Module Emotion_Video_Module;
|
typedef struct _Emotion_Video_Module Emotion_Video_Module;
|
||||||
typedef struct _Emotion_Module_Options Emotion_Module_Options;
|
typedef struct _Emotion_Module_Options Emotion_Module_Options;
|
||||||
|
typedef struct _Eina_Emotion_Plugins Eina_Emotion_Plugins;
|
||||||
|
|
||||||
|
typedef Eina_Bool (*Emotion_Module_Open)(Evas_Object *, const Emotion_Video_Module **, void **, Emotion_Module_Options *);
|
||||||
|
typedef void (*Emotion_Module_Close)(Emotion_Video_Module *module, void *);
|
||||||
|
|
||||||
enum _Emotion_Format
|
enum _Emotion_Format
|
||||||
{
|
{
|
||||||
|
@ -38,8 +42,14 @@ enum _Emotion_Format
|
||||||
|
|
||||||
struct _Emotion_Module_Options
|
struct _Emotion_Module_Options
|
||||||
{
|
{
|
||||||
unsigned char no_video : 1;
|
Eina_Bool no_video : 1;
|
||||||
unsigned char no_audio : 1;
|
Eina_Bool no_audio : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Eina_Emotion_Plugins
|
||||||
|
{
|
||||||
|
Emotion_Module_Open open;
|
||||||
|
Emotion_Module_Close close;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Emotion_Video_Module
|
struct _Emotion_Video_Module
|
||||||
|
@ -101,8 +111,7 @@ struct _Emotion_Video_Module
|
||||||
int (*eject) (void *ef);
|
int (*eject) (void *ef);
|
||||||
const char * (*meta_get) (void *ef, int meta);
|
const char * (*meta_get) (void *ef, int meta);
|
||||||
|
|
||||||
Ecore_Plugin *plugin;
|
Eina_Emotion_Plugins *plugin;
|
||||||
Ecore_Path_Group *path_group;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EAPI void *_emotion_video_get(Evas_Object *obj);
|
EAPI void *_emotion_video_get(Evas_Object *obj);
|
||||||
|
@ -119,4 +128,7 @@ EAPI void _emotion_file_ref_set(Evas_Object *obj, const char *file, int num);
|
||||||
EAPI void _emotion_spu_button_num_set(Evas_Object *obj, int num);
|
EAPI void _emotion_spu_button_num_set(Evas_Object *obj, int num);
|
||||||
EAPI void _emotion_spu_button_set(Evas_Object *obj, int button);
|
EAPI void _emotion_spu_button_set(Evas_Object *obj, int button);
|
||||||
|
|
||||||
|
EAPI Eina_Bool _emotion_module_register(const char *name, Emotion_Module_Open open, Emotion_Module_Close close);
|
||||||
|
EAPI Eina_Bool _emotion_module_unregister(const char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,77 +85,78 @@ static void _smart_clip_unset(Evas_Object * obj);
|
||||||
/* Globals for the E Video Object */
|
/* Globals for the E Video Object */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
static Evas_Smart *smart = NULL;
|
static Evas_Smart *smart = NULL;
|
||||||
static Ecore_Path_Group *path_group = NULL;
|
static Eina_Hash *_backends = NULL;
|
||||||
|
static Eina_Array *_modules = NULL;
|
||||||
|
|
||||||
static unsigned char
|
EAPI Eina_Bool
|
||||||
|
_emotion_module_register(const char *name, Emotion_Module_Open open, Emotion_Module_Close close)
|
||||||
|
{
|
||||||
|
Eina_Emotion_Plugins *plugin;
|
||||||
|
|
||||||
|
fprintf(stderr, "registering: %s\n", name);
|
||||||
|
|
||||||
|
plugin = malloc(sizeof (Eina_Emotion_Plugins));
|
||||||
|
if (!plugin) return EINA_FALSE;
|
||||||
|
|
||||||
|
plugin->open = open;
|
||||||
|
plugin->close = close;
|
||||||
|
|
||||||
|
return eina_hash_add(_backends, name, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
_emotion_module_unregister(const char *name)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "unregistering: %s\n", name);
|
||||||
|
return eina_hash_del(_backends, name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
_emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module **mod, void **video)
|
_emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module **mod, void **video)
|
||||||
{
|
{
|
||||||
Ecore_Plugin *plugin;
|
Eina_Emotion_Plugins *plugin;
|
||||||
char *tmp = NULL;
|
|
||||||
Smart_Data *sd;
|
Smart_Data *sd;
|
||||||
|
|
||||||
E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
|
E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
|
||||||
if (!path_group)
|
if (!_backends)
|
||||||
path_group = ecore_path_group_new();
|
|
||||||
tmp = getenv("EMOTION_MODULES_DIR");
|
|
||||||
if (tmp)
|
|
||||||
ecore_path_group_add(path_group, tmp);
|
|
||||||
ecore_path_group_add(path_group, PACKAGE_LIB_DIR"/emotion/");
|
|
||||||
plugin = ecore_plugin_load(path_group, name, NULL);
|
|
||||||
if (plugin)
|
|
||||||
{
|
{
|
||||||
unsigned char (*func_module_open)(Evas_Object *, Emotion_Video_Module **, void **, Emotion_Module_Options *);
|
fprintf(stderr, "No backend loaded\n");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
func_module_open = ecore_plugin_symbol_get(plugin, "module_open");
|
/* FIXME: Always look for a working backend. */
|
||||||
if (func_module_open)
|
plugin = eina_hash_find(_backends, name);
|
||||||
|
if (!plugin)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No backend loaded\n");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin->open(obj, (const Emotion_Video_Module **) mod, video, &(sd->module_options)))
|
||||||
|
{
|
||||||
|
if (*mod)
|
||||||
{
|
{
|
||||||
if (func_module_open(obj, mod, video, &(sd->module_options)))
|
(*mod)->plugin = plugin;
|
||||||
{
|
return EINA_TRUE;
|
||||||
if (*mod)
|
|
||||||
{
|
|
||||||
(*mod)->plugin = plugin;
|
|
||||||
(*mod)->path_group = path_group;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ecore_plugin_unload(plugin);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fprintf (stderr, "Unable to load module %s\n", name);
|
|
||||||
|
|
||||||
if (path_group)
|
|
||||||
{
|
|
||||||
ecore_path_group_del(path_group);
|
|
||||||
path_group = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
fprintf (stderr, "Unable to load module %s\n", name);
|
||||||
|
|
||||||
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_emotion_module_close(Emotion_Video_Module *mod, void *video)
|
_emotion_module_close(Emotion_Video_Module *mod, void *video)
|
||||||
{
|
{
|
||||||
Ecore_Plugin *plugin;
|
|
||||||
void (*module_close) (Emotion_Video_Module *module, void *);
|
|
||||||
|
|
||||||
plugin = mod->plugin;
|
if (mod->plugin->close && video)
|
||||||
fprintf(stderr, "%p\n", plugin);
|
mod->plugin->close(mod, video);
|
||||||
module_close = ecore_plugin_symbol_get(mod->plugin, "module_close");
|
|
||||||
if ((module_close) && (video)) module_close(mod, video);
|
|
||||||
/* FIXME: we can't go dlclosing here as a thread still may be running from
|
/* FIXME: we can't go dlclosing here as a thread still may be running from
|
||||||
* the module - this in theory will leak- but it shouldnt be too bad and
|
* the module - this in theory will leak- but it shouldnt be too bad and
|
||||||
* mean that once a module is dlopened() it cant be closed - its refcount
|
* mean that once a module is dlopened() it cant be closed - its refcount
|
||||||
* will just keep going up
|
* will just keep going up
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
ecore_plugin_unload(plugin);
|
|
||||||
*/
|
|
||||||
if (path_group)
|
|
||||||
{
|
|
||||||
ecore_path_group_del(path_group);
|
|
||||||
path_group = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************/
|
/*******************************/
|
||||||
|
@ -180,11 +181,11 @@ emotion_object_module_option_set(Evas_Object *obj, const char *opt, const char *
|
||||||
if ((!opt) || (!val)) return;
|
if ((!opt) || (!val)) return;
|
||||||
if (!strcmp(opt, "video"))
|
if (!strcmp(opt, "video"))
|
||||||
{
|
{
|
||||||
if (!strcmp(val, "off")) sd->module_options.no_video = 1;
|
if (!strcmp(val, "off")) sd->module_options.no_video = EINA_TRUE;
|
||||||
}
|
}
|
||||||
else if (!strcmp(opt, "audio"))
|
else if (!strcmp(opt, "audio"))
|
||||||
{
|
{
|
||||||
if (!strcmp(val, "off")) sd->module_options.no_audio = 1;
|
if (!strcmp(val, "off")) sd->module_options.no_audio = EINA_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1181,11 +1182,60 @@ _pixels_get(void *data, Evas_Object *obj)
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
/* Internal smart object required routines */
|
/* Internal smart object required routines */
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
|
#ifdef EINA_STATIC_BUILD_XINE
|
||||||
|
Eina_Bool xine_module_init(void);
|
||||||
|
#endif
|
||||||
|
#ifdef EINA_STATIC_BUILD_VLC
|
||||||
|
Eina_Bool vlc_module_init(void);
|
||||||
|
#endif
|
||||||
|
#ifdef EINA_STATIC_BUILD_GSTREAMER
|
||||||
|
Eina_Bool gstreamer_module_init(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_smart_init(void)
|
_smart_init(void)
|
||||||
{
|
{
|
||||||
|
char *path;
|
||||||
|
|
||||||
if (smart) return;
|
if (smart) return;
|
||||||
{
|
{
|
||||||
|
eina_init();
|
||||||
|
|
||||||
|
_backends = eina_hash_string_small_new(free);
|
||||||
|
|
||||||
|
_modules = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/eina/mp/", 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)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No module found !\n");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
eina_module_list_load(_modules);
|
||||||
|
|
||||||
|
/* Init static module */
|
||||||
|
#ifdef EINA_STATIC_BUILD_XINE
|
||||||
|
xine_module_init();
|
||||||
|
#endif
|
||||||
|
#ifdef EINA_STATIC_BUILD_VLC
|
||||||
|
vlc_module_init();
|
||||||
|
#endif
|
||||||
|
#ifdef EINA_STATIC_BUILD_GSTREAMER
|
||||||
|
gstreamer_module_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
static const Evas_Smart_Class sc =
|
static const Evas_Smart_Class sc =
|
||||||
{
|
{
|
||||||
E_OBJ_NAME,
|
E_OBJ_NAME,
|
||||||
|
|
|
@ -1257,29 +1257,48 @@ em_meta_get(void *video, int meta)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI unsigned char
|
static Eina_Bool
|
||||||
module_open(Evas_Object *obj,
|
module_open(Evas_Object *obj,
|
||||||
Emotion_Video_Module **module,
|
const Emotion_Video_Module **module,
|
||||||
void **video,
|
void **video,
|
||||||
Emotion_Module_Options *opt)
|
Emotion_Module_Options *opt)
|
||||||
{
|
{
|
||||||
if (!module)
|
if (!module)
|
||||||
return 0;
|
return EINA_FALSE;
|
||||||
|
|
||||||
if (!em_module.init(obj, video, opt))
|
if (!em_module.init(obj, video, opt))
|
||||||
return 0;
|
return EINA_FALSE;
|
||||||
|
|
||||||
*module = &em_module;
|
*module = &em_module;
|
||||||
return 1;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
static void
|
||||||
module_close(Emotion_Video_Module *module,
|
module_close(Emotion_Video_Module *module,
|
||||||
void *video)
|
void *video)
|
||||||
{
|
{
|
||||||
em_module.shutdown(video);
|
em_module.shutdown(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
gstreamer_module_init(void)
|
||||||
|
{
|
||||||
|
return _emotion_module_register("gstreamer", module_open, module_close);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gstreamer_module_shutdown(void)
|
||||||
|
{
|
||||||
|
_emotion_module_unregister("gstreamer");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EINA_STATIC_BUILD_GSTREAMER
|
||||||
|
|
||||||
|
EINA_MODULE_INIT(gstreamer_module_init);
|
||||||
|
EINA_MODULE_SHUTDOWN(gstreamer_module_shutdown);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_for_each_tag(GstTagList const* list,
|
_for_each_tag(GstTagList const* list,
|
||||||
gchar const* tag,
|
gchar const* tag,
|
||||||
|
|
|
@ -95,12 +95,4 @@ struct _Emotion_Gstreamer_Video
|
||||||
unsigned char audio_mute : 1;
|
unsigned char audio_mute : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
EAPI unsigned char module_open(Evas_Object *obj,
|
|
||||||
Emotion_Video_Module **module,
|
|
||||||
void **video, Emotion_Module_Options *opt);
|
|
||||||
|
|
||||||
EAPI void module_close(Emotion_Video_Module *module,
|
|
||||||
void *video);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __EMOTION_GSTREAMER_H__ */
|
#endif /* __EMOTION_GSTREAMER_H__ */
|
||||||
|
|
|
@ -1201,25 +1201,46 @@ static Emotion_Video_Module em_module =
|
||||||
NULL /* handle */
|
NULL /* handle */
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
|
static Eina_Bool module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
|
||||||
{
|
{
|
||||||
if (!module) {
|
if (!module) {
|
||||||
return 0;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!em_module.init(obj, video, opt)) {
|
if (!em_module.init(obj, video, opt)) {
|
||||||
return 0;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*module = &em_module;
|
*module = &em_module;
|
||||||
|
|
||||||
return 1;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void module_close(Emotion_Video_Module *module, void *video)
|
static void module_close(Emotion_Video_Module *module, void *video)
|
||||||
{
|
{
|
||||||
em_module.shutdown(video);
|
em_module.shutdown(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
vlc_module_init(void)
|
||||||
|
{
|
||||||
|
return _emotion_module_register("vlc", module_open, module_close);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vlc_module_shutdown(void)
|
||||||
|
{
|
||||||
|
_emotion_module_unregister("vlc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EINA_STATIC_BUILD_VLC
|
||||||
|
|
||||||
|
EINA_MODULE_INIT(vlc_module_init);
|
||||||
|
EINA_MODULE_SHUTDOWN(vlc_module_shutdown);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* EMOTION_VLC_C */
|
#endif /* EMOTION_VLC_C */
|
||||||
|
|
||||||
|
|
|
@ -99,10 +99,6 @@ static double em_speed_get (void *ef);
|
||||||
static int em_eject (void *ef);
|
static int em_eject (void *ef);
|
||||||
static const char *em_meta_get (void *ef, int meta);
|
static const char *em_meta_get (void *ef, int meta);
|
||||||
|
|
||||||
/* entry points for module */
|
|
||||||
unsigned char module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt);
|
|
||||||
void module_close(Emotion_Video_Module *module, void *video);
|
|
||||||
|
|
||||||
typedef struct _vlc_event_t {
|
typedef struct _vlc_event_t {
|
||||||
libvlc_event_type_t type;
|
libvlc_event_type_t type;
|
||||||
int data_length;
|
int data_length;
|
||||||
|
@ -145,8 +141,8 @@ struct _Emotion_Vlc_Video
|
||||||
unsigned char video_mute : 1;
|
unsigned char video_mute : 1;
|
||||||
unsigned char audio_mute : 1;
|
unsigned char audio_mute : 1;
|
||||||
unsigned char spu_mute : 1;
|
unsigned char spu_mute : 1;
|
||||||
unsigned char opt_no_video : 1;
|
Eina_Bool opt_no_video : 1;
|
||||||
unsigned char opt_no_audio : 1;
|
Eina_Bool opt_no_audio : 1;
|
||||||
volatile unsigned char delete_me : 1;
|
volatile unsigned char delete_me : 1;
|
||||||
volatile unsigned char opening : 1;
|
volatile unsigned char opening : 1;
|
||||||
volatile unsigned char closing : 1;
|
volatile unsigned char closing : 1;
|
||||||
|
|
|
@ -1526,25 +1526,44 @@ static Emotion_Video_Module em_module =
|
||||||
NULL /* handle */
|
NULL /* handle */
|
||||||
};
|
};
|
||||||
|
|
||||||
EAPI unsigned char
|
static Eina_Bool
|
||||||
module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
|
module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
|
||||||
{
|
{
|
||||||
if (!module)
|
if (!module)
|
||||||
return 0;
|
return EINA_FALSE;
|
||||||
|
|
||||||
if (!em_module.init(obj, video, opt))
|
if (!em_module.init(obj, video, opt))
|
||||||
return 0;
|
return EINA_FALSE;
|
||||||
|
|
||||||
*module = &em_module;
|
*module = &em_module;
|
||||||
return 1;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
static void
|
||||||
module_close(Emotion_Video_Module *module, void *video)
|
module_close(Emotion_Video_Module *module, void *video)
|
||||||
{
|
{
|
||||||
em_module.shutdown(video);
|
em_module.shutdown(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
xine_module_init(void)
|
||||||
|
{
|
||||||
|
return _emotion_module_register("xine", module_open, module_close);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xine_module_shutdown(void)
|
||||||
|
{
|
||||||
|
_emotion_module_unregister("xine");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EINA_STATIC_BUILD_XINE
|
||||||
|
|
||||||
|
EINA_MODULE_INIT(xine_module_init);
|
||||||
|
EINA_MODULE_SHUTDOWN(xine_module_shutdown);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void
|
void
|
||||||
em_debug(Emotion_Xine_Video *ev)
|
em_debug(Emotion_Xine_Video *ev)
|
||||||
|
|
|
@ -43,8 +43,8 @@ struct _Emotion_Xine_Video
|
||||||
unsigned char video_mute : 1;
|
unsigned char video_mute : 1;
|
||||||
unsigned char audio_mute : 1;
|
unsigned char audio_mute : 1;
|
||||||
unsigned char spu_mute : 1;
|
unsigned char spu_mute : 1;
|
||||||
unsigned char opt_no_video : 1;
|
Eina_Bool opt_no_video : 1;
|
||||||
unsigned char opt_no_audio : 1;
|
Eina_Bool opt_no_audio : 1;
|
||||||
volatile unsigned char delete_me : 1;
|
volatile unsigned char delete_me : 1;
|
||||||
volatile unsigned char no_time : 1;
|
volatile unsigned char no_time : 1;
|
||||||
volatile unsigned char opening : 1;
|
volatile unsigned char opening : 1;
|
||||||
|
@ -85,7 +85,4 @@ struct _Emotion_Xine_Event
|
||||||
int mtype;
|
int mtype;
|
||||||
};
|
};
|
||||||
|
|
||||||
EAPI unsigned char module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt);
|
|
||||||
EAPI void module_close(Emotion_Video_Module *module, void *video);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue