Commit ab7c7713 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Use callback and opaque pointer for plugin descriptors

This is more flexible and extensible.
parent cf52eed6
...@@ -29,11 +29,6 @@ ...@@ -29,11 +29,6 @@
* This file implements plugin (module) macros used to define a vlc module. * This file implements plugin (module) macros used to define a vlc module.
*/ */
VLC_API int vlc_plugin_set(module_t *, module_config_t *, int, ...);
#define vlc_module_set( mod, ... ) vlc_plugin_set ((mod), NULL, __VA_ARGS__)
#define vlc_config_set( cfg, ... ) vlc_plugin_set (NULL, (cfg), __VA_ARGS__)
enum vlc_module_properties enum vlc_module_properties
{ {
VLC_MODULE_CREATE, VLC_MODULE_CREATE,
...@@ -158,6 +153,12 @@ enum vlc_module_properties ...@@ -158,6 +153,12 @@ enum vlc_module_properties
# define EXTERN_SYMBOL # define EXTERN_SYMBOL
#endif #endif
typedef int (*vlc_set_cb) (void *, void *, int, ...);
#define vlc_plugin_set(...) vlc_set (opaque, NULL, __VA_ARGS__)
#define vlc_module_set(...) vlc_set (opaque, module, __VA_ARGS__)
#define vlc_config_set(...) vlc_set (opaque, config, __VA_ARGS__)
/* /*
* InitModule: this function is called once and only once, when the module * InitModule: this function is called once and only once, when the module
* is looked at for the first time. We get the useful data from it, for * is looked at for the first time. We get the useful data from it, for
...@@ -166,70 +167,65 @@ enum vlc_module_properties ...@@ -166,70 +167,65 @@ enum vlc_module_properties
*/ */
#define vlc_module_begin() \ #define vlc_module_begin() \
EXTERN_SYMBOL DLL_SYMBOL \ EXTERN_SYMBOL DLL_SYMBOL \
module_t *CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (void); \ int CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (vlc_set_cb, void *); \
EXTERN_SYMBOL DLL_SYMBOL \ EXTERN_SYMBOL DLL_SYMBOL \
module_t *CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (void) \ int CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (vlc_set_cb vlc_set, void *opaque) \
{ \ { \
module_t *module, *p_submodule; \ module_t *module; \
module_config_t *p_config = NULL; \ module_config_t *config = NULL; \
if (vlc_plugin_set (NULL, NULL, VLC_MODULE_CREATE, &module)) \ if (vlc_plugin_set (VLC_MODULE_CREATE, &module)) \
goto error; \
if (vlc_module_set (module, VLC_MODULE_NAME, (MODULE_STRING))) \
goto error; \ goto error; \
p_submodule = module; if (vlc_module_set (VLC_MODULE_NAME, (MODULE_STRING))) \
goto error;
#define vlc_module_end() \ #define vlc_module_end() \
(void) p_config; \ (void) config; \
return module; \ return 0; \
error: \ error: \
return NULL; \ return -1; \
} \ } \
VLC_METADATA_EXPORTS VLC_METADATA_EXPORTS
#define add_submodule( ) \ #define add_submodule( ) \
if (vlc_plugin_set (module, NULL, VLC_MODULE_CREATE, &p_submodule)) \ if (vlc_plugin_set (VLC_MODULE_CREATE, &module)) \
goto error; goto error;
#define add_shortcut( ... ) \ #define add_shortcut( ... ) \
{ \ { \
const char *shortcuts[] = { __VA_ARGS__ }; \ const char *shortcuts[] = { __VA_ARGS__ }; \
if (vlc_module_set (p_submodule, VLC_MODULE_SHORTCUT, \ if (vlc_module_set (VLC_MODULE_SHORTCUT, \
sizeof(shortcuts)/sizeof(shortcuts[0]), shortcuts)) \ sizeof(shortcuts)/sizeof(shortcuts[0]), shortcuts)) \
goto error; \ goto error; \
} }
#define set_shortname( shortname ) \ #define set_shortname( shortname ) \
if (vlc_module_set (p_submodule, VLC_MODULE_SHORTNAME, \ if (vlc_module_set (VLC_MODULE_SHORTNAME, (const char *)(shortname))) \
(const char *)(shortname))) \
goto error; goto error;
#define set_description( desc ) \ #define set_description( desc ) \
if (vlc_module_set (p_submodule, VLC_MODULE_DESCRIPTION, \ if (vlc_module_set (VLC_MODULE_DESCRIPTION, (const char *)(desc))) \
(const char *)(desc))) \
goto error; goto error;
#define set_help( help ) \ #define set_help( help ) \
if (vlc_module_set (p_submodule, VLC_MODULE_HELP, \ if (vlc_module_set (VLC_MODULE_HELP, (const char *)(help))) \
(const char *)(help))) \
goto error; goto error;
#define set_capability( cap, score ) \ #define set_capability( cap, score ) \
if (vlc_module_set (p_submodule, VLC_MODULE_CAPABILITY, \ if (vlc_module_set (VLC_MODULE_CAPABILITY, (const char *)(cap)) \
(const char *)(cap)) \ || vlc_module_set (VLC_MODULE_SCORE, (int)(score))) \
|| vlc_module_set (p_submodule, VLC_MODULE_SCORE, (int)(score))) \
goto error; goto error;
#define set_callbacks( activate, deactivate ) \ #define set_callbacks( activate, deactivate ) \
if (vlc_module_set (p_submodule, VLC_MODULE_CB_OPEN, activate) \ if (vlc_module_set (VLC_MODULE_CB_OPEN, activate) \
|| vlc_module_set (p_submodule, VLC_MODULE_CB_CLOSE, deactivate)) \ || vlc_module_set (VLC_MODULE_CB_CLOSE, deactivate)) \
goto error; goto error;
#define cannot_unload_broken_library( ) \ #define cannot_unload_broken_library( ) \
if (vlc_module_set (p_submodule, VLC_MODULE_NO_UNLOAD)) \ if (vlc_module_set (VLC_MODULE_NO_UNLOAD)) \
goto error; goto error;
#define set_text_domain( dom ) \ #define set_text_domain( dom ) \
if (vlc_module_set (module, VLC_MODULE_TEXTDOMAIN, (dom))) \ if (vlc_plugin_set (VLC_MODULE_TEXTDOMAIN, (dom))) \
goto error; goto error;
/***************************************************************************** /*****************************************************************************
...@@ -246,38 +242,37 @@ VLC_METADATA_EXPORTS ...@@ -246,38 +242,37 @@ VLC_METADATA_EXPORTS
*****************************************************************************/ *****************************************************************************/
#define add_type_inner( type ) \ #define add_type_inner( type ) \
vlc_plugin_set (module, NULL, VLC_CONFIG_CREATE, (type), &p_config); vlc_plugin_set (VLC_CONFIG_CREATE, (type), &config);
#define add_typedesc_inner( type, text, longtext ) \ #define add_typedesc_inner( type, text, longtext ) \
add_type_inner( type ) \ add_type_inner( type ) \
vlc_config_set (p_config, VLC_CONFIG_DESC, \ vlc_config_set (VLC_CONFIG_DESC, \
(const char *)(text), (const char *)(longtext)); (const char *)(text), (const char *)(longtext));
#define add_typeadv_inner( type, text, longtext, advc ) \ #define add_typeadv_inner( type, text, longtext, advc ) \
add_typedesc_inner( type, text, longtext ) \ add_typedesc_inner( type, text, longtext ) \
if (advc) vlc_config_set (p_config, VLC_CONFIG_ADVANCED); if (advc) vlc_config_set (VLC_CONFIG_ADVANCED);
#define add_typename_inner( type, name, text, longtext, advc ) \ #define add_typename_inner( type, name, text, longtext, advc ) \
add_typeadv_inner( type, text, longtext, advc ) \ add_typeadv_inner( type, text, longtext, advc ) \
vlc_config_set (p_config, VLC_CONFIG_NAME, \ vlc_config_set (VLC_CONFIG_NAME, (const char *)(name));
(const char *)(name));
#define add_string_inner( type, name, text, longtext, advc, v ) \ #define add_string_inner( type, name, text, longtext, advc, v ) \
add_typename_inner( type, name, text, longtext, advc ) \ add_typename_inner( type, name, text, longtext, advc ) \
vlc_config_set (p_config, VLC_CONFIG_VALUE, (const char *)(v)); vlc_config_set (VLC_CONFIG_VALUE, (const char *)(v));
#define add_int_inner( type, name, text, longtext, advc, v ) \ #define add_int_inner( type, name, text, longtext, advc, v ) \
add_typename_inner( type, name, text, longtext, advc ) \ add_typename_inner( type, name, text, longtext, advc ) \
vlc_config_set (p_config, VLC_CONFIG_VALUE, (int64_t)(v)); vlc_config_set (VLC_CONFIG_VALUE, (int64_t)(v));
#define set_category( i_id ) \ #define set_category( i_id ) \
add_type_inner( CONFIG_CATEGORY ) \ add_type_inner( CONFIG_CATEGORY ) \
vlc_config_set (p_config, VLC_CONFIG_VALUE, (int64_t)(i_id)); vlc_config_set (VLC_CONFIG_VALUE, (int64_t)(i_id));
#define set_subcategory( i_id ) \ #define set_subcategory( i_id ) \
add_type_inner( CONFIG_SUBCATEGORY ) \ add_type_inner( CONFIG_SUBCATEGORY ) \
vlc_config_set (p_config, VLC_CONFIG_VALUE, (int64_t)(i_id)); vlc_config_set (VLC_CONFIG_VALUE, (int64_t)(i_id));
#define set_section( text, longtext ) \ #define set_section( text, longtext ) \
add_typedesc_inner( CONFIG_SECTION, text, longtext ) add_typedesc_inner( CONFIG_SECTION, text, longtext )
...@@ -321,12 +316,12 @@ VLC_METADATA_EXPORTS ...@@ -321,12 +316,12 @@ VLC_METADATA_EXPORTS
#define add_module( name, psz_caps, value, text, longtext, advc ) \ #define add_module( name, psz_caps, value, text, longtext, advc ) \
add_string_inner( CONFIG_ITEM_MODULE, name, text, longtext, advc, \ add_string_inner( CONFIG_ITEM_MODULE, name, text, longtext, advc, \
value ) \ value ) \
vlc_config_set (p_config, VLC_CONFIG_CAPABILITY, (const char *)(psz_caps)); vlc_config_set (VLC_CONFIG_CAPABILITY, (const char *)(psz_caps));
#define add_module_list( name, psz_caps, value, text, longtext, advc ) \ #define add_module_list( name, psz_caps, value, text, longtext, advc ) \
add_string_inner( CONFIG_ITEM_MODULE_LIST, name, text, longtext, advc, \ add_string_inner( CONFIG_ITEM_MODULE_LIST, name, text, longtext, advc, \
value ) \ value ) \
vlc_config_set (p_config, VLC_CONFIG_CAPABILITY, (const char *)(psz_caps)); vlc_config_set (VLC_CONFIG_CAPABILITY, (const char *)(psz_caps));
#ifndef __PLUGIN__ #ifndef __PLUGIN__
#define add_module_cat( name, i_subcategory, value, text, longtext, advc ) \ #define add_module_cat( name, i_subcategory, value, text, longtext, advc ) \
...@@ -358,7 +353,7 @@ VLC_METADATA_EXPORTS ...@@ -358,7 +353,7 @@ VLC_METADATA_EXPORTS
#define add_float( name, v, text, longtext, advc ) \ #define add_float( name, v, text, longtext, advc ) \
add_typename_inner( CONFIG_ITEM_FLOAT, name, text, longtext, advc ) \ add_typename_inner( CONFIG_ITEM_FLOAT, name, text, longtext, advc ) \
vlc_config_set (p_config, VLC_CONFIG_VALUE, (double)(v)); vlc_config_set (VLC_CONFIG_VALUE, (double)(v));
#define add_float_with_range( name, value, f_min, f_max, text, longtext, advc ) \ #define add_float_with_range( name, value, f_min, f_max, text, longtext, advc ) \
add_float( name, value, text, longtext, advc ) \ add_float( name, value, text, longtext, advc ) \
...@@ -366,14 +361,13 @@ VLC_METADATA_EXPORTS ...@@ -366,14 +361,13 @@ VLC_METADATA_EXPORTS
#define add_bool( name, v, text, longtext, advc ) \ #define add_bool( name, v, text, longtext, advc ) \
add_typename_inner( CONFIG_ITEM_BOOL, name, text, longtext, advc ) \ add_typename_inner( CONFIG_ITEM_BOOL, name, text, longtext, advc ) \
if (v) vlc_config_set (p_config, VLC_CONFIG_VALUE, (int64_t)true); if (v) vlc_config_set (VLC_CONFIG_VALUE, (int64_t)true);
/* For removed option */ /* For removed option */
#define add_obsolete_inner( name, type ) \ #define add_obsolete_inner( name, type ) \
add_type_inner( type ) \ add_type_inner( type ) \
vlc_config_set (p_config, VLC_CONFIG_NAME, \ vlc_config_set (VLC_CONFIG_NAME, (const char *)(name)); \
(const char *)(name)); \ vlc_config_set (VLC_CONFIG_REMOVED);
vlc_config_set (p_config, VLC_CONFIG_REMOVED);
#define add_obsolete_bool( name ) \ #define add_obsolete_bool( name ) \
add_obsolete_inner( name, CONFIG_ITEM_BOOL ) add_obsolete_inner( name, CONFIG_ITEM_BOOL )
...@@ -390,48 +384,46 @@ VLC_METADATA_EXPORTS ...@@ -390,48 +384,46 @@ VLC_METADATA_EXPORTS
/* Modifier macros for the config options (used for fine tuning) */ /* Modifier macros for the config options (used for fine tuning) */
#define add_deprecated_alias( name ) \ #define add_deprecated_alias( name ) \
vlc_config_set (p_config, VLC_CONFIG_OLDNAME, (const char *)(name)); vlc_config_set (VLC_CONFIG_OLDNAME, (const char *)(name));
#define change_short( ch ) \ #define change_short( ch ) \
vlc_config_set (p_config, VLC_CONFIG_SHORTCUT, (int)(ch)); vlc_config_set (VLC_CONFIG_SHORTCUT, (int)(ch));
#define change_string_list( list, list_text, list_update_func ) \ #define change_string_list( list, list_text, list_update_func ) \
vlc_config_set (p_config, VLC_CONFIG_LIST, \ vlc_config_set (VLC_CONFIG_LIST, \
(size_t)(sizeof (list) / sizeof (char *)), \ (size_t)(sizeof (list) / sizeof (char *)), \
(const char *const *)(list), \ (const char *const *)(list), \
(const char *const *)(list_text), \ (const char *const *)(list_text), \
(vlc_callback_t)(list_update_func)); (vlc_callback_t)(list_update_func));
#define change_integer_list( list, list_text ) \ #define change_integer_list( list, list_text ) \
vlc_config_set (p_config, VLC_CONFIG_LIST, \ vlc_config_set (VLC_CONFIG_LIST, \
(size_t)(sizeof (list) / sizeof (int)), \ (size_t)(sizeof (list) / sizeof (int)), \
(const int *)(list), \ (const int *)(list), \
(const char *const *)(list_text), \ (const char *const *)(list_text), \
(vlc_callback_t)(NULL)); (vlc_callback_t)(NULL));
#define change_integer_range( minv, maxv ) \ #define change_integer_range( minv, maxv ) \
vlc_config_set (p_config, VLC_CONFIG_RANGE, \ vlc_config_set (VLC_CONFIG_RANGE, (int64_t)(minv), (int64_t)(maxv));
(int64_t)(minv), (int64_t)(maxv));
#define change_float_range( minv, maxv ) \ #define change_float_range( minv, maxv ) \
vlc_config_set (p_config, VLC_CONFIG_RANGE, \ vlc_config_set (VLC_CONFIG_RANGE, (double)(minv), (double)(maxv));
(double)(minv), (double)(maxv));
#define change_action_add( pf_action, text ) \ #define change_action_add( pf_action, text ) \
vlc_config_set (p_config, VLC_CONFIG_ADD_ACTION, \ vlc_config_set (VLC_CONFIG_ADD_ACTION, \
(vlc_callback_t)(pf_action), (const char *)(text)); (vlc_callback_t)(pf_action), (const char *)(text));
/* For options that are saved but hidden from the preferences panel */ /* For options that are saved but hidden from the preferences panel */
#define change_private() \ #define change_private() \
vlc_config_set (p_config, VLC_CONFIG_PRIVATE); vlc_config_set (VLC_CONFIG_PRIVATE);
/* For options that cannot be saved in the configuration */ /* For options that cannot be saved in the configuration */
#define change_volatile() \ #define change_volatile() \
change_private() \ change_private() \
vlc_config_set (p_config, VLC_CONFIG_VOLATILE); vlc_config_set (VLC_CONFIG_VOLATILE);
#define change_safe() \ #define change_safe() \
vlc_config_set (p_config, VLC_CONFIG_SAFE); vlc_config_set (VLC_CONFIG_SAFE);
/* Meta data plugin exports */ /* Meta data plugin exports */
#define VLC_META_EXPORT( name, value ) \ #define VLC_META_EXPORT( name, value ) \
......
...@@ -56,8 +56,6 @@ static struct ...@@ -56,8 +56,6 @@ static struct
unsigned usage; unsigned usage;
} modules = { VLC_STATIC_MUTEX, NULL, 0 }; } modules = { VLC_STATIC_MUTEX, NULL, 0 };
module_t *vlc_entry__main (void);
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -467,7 +465,7 @@ static module_t *module_InitDynamic (vlc_object_t *obj, ...@@ -467,7 +465,7 @@ static module_t *module_InitDynamic (vlc_object_t *obj,
} }
/* We can now try to call the symbol */ /* We can now try to call the symbol */
module_t *module = entry (); module_t *module = vlc_plugin_describe (entry);
if (unlikely(module == NULL)) if (unlikely(module == NULL))
{ {
/* With a well-written module we shouldn't have to print an /* With a well-written module we shouldn't have to print an
...@@ -497,8 +495,8 @@ error: ...@@ -497,8 +495,8 @@ error:
static module_t *module_InitStatic (vlc_plugin_cb entry) static module_t *module_InitStatic (vlc_plugin_cb entry)
{ {
/* Initializes the module */ /* Initializes the module */
module_t *module = entry (); module_t *module = vlc_plugin_describe (entry);
if (unlikely (module == NULL)) if (unlikely(module == NULL))
return NULL; return NULL;
module->b_loaded = true; module->b_loaded = true;
......
...@@ -145,8 +145,14 @@ static module_config_t *vlc_config_create (module_t *module, int type) ...@@ -145,8 +145,14 @@ static module_config_t *vlc_config_create (module_t *module, int type)
} }
int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) /**
* Callback for the plugin descriptor functions.
*/
static int vlc_plugin_setter (void *plugin, void *tgt, int propid, ...)
{ {
module_t **pprimary = plugin;
module_t *module = tgt;
module_config_t *item = tgt;
va_list ap; va_list ap;
int ret = 0; int ret = 0;
...@@ -155,18 +161,20 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) ...@@ -155,18 +161,20 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
{ {
case VLC_MODULE_CREATE: case VLC_MODULE_CREATE:
{ {
module_t **pp = va_arg (ap, module_t **); module = *pprimary;
module_t *submodule = vlc_module_create (module); module_t *submodule = vlc_module_create (module);
if (unlikely(submodule == NULL)) if (unlikely(submodule == NULL))
{ {
ret = -1; ret = -1;
break; break;
} }
*pp = submodule; *(va_arg (ap, module_t **)) = submodule;
if (module == NULL) if (*pprimary == NULL)
{
*pprimary = submodule;
break; break;
}
/* Inheritance. Ugly!! */ /* Inheritance. Ugly!! */
submodule->pp_shortcuts = xmalloc (sizeof (char **)); submodule->pp_shortcuts = xmalloc (sizeof (char **));
submodule->pp_shortcuts[0] = strdup_null (module->pp_shortcuts[0]); submodule->pp_shortcuts[0] = strdup_null (module->pp_shortcuts[0]);
...@@ -182,9 +190,14 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) ...@@ -182,9 +190,14 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
{ {
int type = va_arg (ap, int); int type = va_arg (ap, int);
module_config_t **pp = va_arg (ap, module_config_t **); module_config_t **pp = va_arg (ap, module_config_t **);
*pp = vlc_config_create (module, type);
if (*pp == NULL) item = vlc_config_create (*pprimary, type);
if (unlikely(item == NULL))
{
ret = -1; ret = -1;
break;
}
*pp = item;
break; break;
} }
...@@ -465,3 +478,19 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) ...@@ -465,3 +478,19 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
va_end (ap); va_end (ap);
return ret; return ret;
} }
/**
* Runs a plug-in descriptor. This loads the plug-in meta-data in memory.
*/
module_t *vlc_plugin_describe (vlc_plugin_cb entry)
{
module_t *module = NULL;
if (entry (vlc_plugin_setter, &module) != 0)
{
if (module != NULL) /* partially initialized plug-in... */
vlc_module_destroy (module);
module = NULL;
}
return module;
}
...@@ -46,7 +46,11 @@ struct module_cache_t ...@@ -46,7 +46,11 @@ struct module_cache_t
/** The module handle type */ /** The module handle type */
typedef void *module_handle_t; typedef void *module_handle_t;
typedef module_t *(*vlc_plugin_cb) (void); /** Plugin entry point prototype */
typedef int (*vlc_plugin_cb) (int (*)(void *, void *, int, ...), void *);
/** Main module */
int vlc_entry__main (int (*)(void *, void *, int, ...), void *);
/** /**
* Internal module descriptor * Internal module descriptor
...@@ -96,6 +100,7 @@ struct module_t ...@@ -96,6 +100,7 @@ struct module_t
char * domain; /* gettext domain */ char * domain; /* gettext domain */
}; };
module_t *vlc_plugin_describe (vlc_plugin_cb);
module_t *vlc_module_create (module_t *); module_t *vlc_module_create (module_t *);
void vlc_module_destroy (module_t *); void vlc_module_destroy (module_t *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment