]> git.sesse.net Git - vlc/commitdiff
Use callback and opaque pointer for plugin descriptors
authorRémi Denis-Courmont <remi@remlab.net>
Tue, 16 Aug 2011 12:54:31 +0000 (15:54 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Tue, 16 Aug 2011 16:17:18 +0000 (19:17 +0300)
This is more flexible and extensible.

include/vlc_plugin.h
src/modules/bank.c
src/modules/entry.c
src/modules/modules.h

index e82256c570e150880d862a8a2bdd37657b57747e..e88702d684ff5879b6513a6bfbd4fd3363bd0f0e 100644 (file)
  * 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
 {
     VLC_MODULE_CREATE,
@@ -158,6 +153,12 @@ enum vlc_module_properties
 #   define EXTERN_SYMBOL
 #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
  * is looked at for the first time. We get the useful data from it, for
@@ -166,70 +167,65 @@ enum vlc_module_properties
  */
 #define vlc_module_begin() \
 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 \
-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_config_t *p_config = NULL; \
-    if (vlc_plugin_set (NULL, NULL, VLC_MODULE_CREATE, &module)) \
-        goto error; \
-    if (vlc_module_set (module, VLC_MODULE_NAME, (MODULE_STRING))) \
+    module_t *module; \
+    module_config_t *config = NULL; \
+    if (vlc_plugin_set (VLC_MODULE_CREATE, &module)) \
         goto error; \
-    p_submodule = module;
+    if (vlc_module_set (VLC_MODULE_NAME, (MODULE_STRING))) \
+        goto error;
 
 #define vlc_module_end() \
-    (void) p_config; \
-    return module; \
+    (void) config; \
+    return 0; \
 error: \
-    return NULL; \
+    return -1; \
 } \
 VLC_METADATA_EXPORTS
 
 #define add_submodule( ) \
-    if (vlc_plugin_set (module, NULL, VLC_MODULE_CREATE, &p_submodule)) \
+    if (vlc_plugin_set (VLC_MODULE_CREATE, &module)) \
         goto error;
 
 #define add_shortcut( ... ) \
 { \
     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)) \
         goto error; \
 }
 
 #define set_shortname( shortname ) \
-    if (vlc_module_set (p_submodule, VLC_MODULE_SHORTNAME, \
-                        (const char *)(shortname))) \
+    if (vlc_module_set (VLC_MODULE_SHORTNAME, (const char *)(shortname))) \
         goto error;
 
 #define set_description( desc ) \
-    if (vlc_module_set (p_submodule, VLC_MODULE_DESCRIPTION, \
-                        (const char *)(desc))) \
+    if (vlc_module_set (VLC_MODULE_DESCRIPTION, (const char *)(desc))) \
         goto error;
 
 #define set_help( help ) \
-    if (vlc_module_set (p_submodule, VLC_MODULE_HELP, \
-                        (const char *)(help))) \
+    if (vlc_module_set (VLC_MODULE_HELP, (const char *)(help))) \
         goto error;
 
 #define set_capability( cap, score ) \
-    if (vlc_module_set (p_submodule, VLC_MODULE_CAPABILITY, \
-                        (const char *)(cap)) \
-     || vlc_module_set (p_submodule, VLC_MODULE_SCORE, (int)(score))) \
+    if (vlc_module_set (VLC_MODULE_CAPABILITY, (const char *)(cap)) \
+     || vlc_module_set (VLC_MODULE_SCORE, (int)(score))) \
         goto error;
 
 #define set_callbacks( activate, deactivate ) \
-    if (vlc_module_set (p_submodule, VLC_MODULE_CB_OPEN, activate) \
-     || vlc_module_set (p_submodule, VLC_MODULE_CB_CLOSE, deactivate)) \
+    if (vlc_module_set (VLC_MODULE_CB_OPEN, activate) \
+     || vlc_module_set (VLC_MODULE_CB_CLOSE, deactivate)) \
         goto error;
 
 #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;
 
 #define set_text_domain( dom ) \
-    if (vlc_module_set (module, VLC_MODULE_TEXTDOMAIN, (dom))) \
+    if (vlc_plugin_set (VLC_MODULE_TEXTDOMAIN, (dom))) \
         goto error;
 
 /*****************************************************************************
@@ -246,38 +242,37 @@ VLC_METADATA_EXPORTS
  *****************************************************************************/
 
 #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 ) \
     add_type_inner( type ) \
-    vlc_config_set (p_config, VLC_CONFIG_DESC, \
+    vlc_config_set (VLC_CONFIG_DESC, \
                     (const char *)(text), (const char *)(longtext));
 
 #define add_typeadv_inner( type, text, longtext, advc ) \
     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 ) \
     add_typeadv_inner( type, text, longtext, advc ) \
-    vlc_config_set (p_config, VLC_CONFIG_NAME, \
-                    (const char *)(name));
+    vlc_config_set (VLC_CONFIG_NAME, (const char *)(name));
 
 #define add_string_inner( type, name, text, longtext, advc, v ) \
     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 ) \
     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 ) \
     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 ) \
     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 ) \
     add_typedesc_inner( CONFIG_SECTION, text, longtext )
@@ -321,12 +316,12 @@ VLC_METADATA_EXPORTS
 #define add_module( name, psz_caps, value, text, longtext, advc ) \
     add_string_inner( CONFIG_ITEM_MODULE, name, text, longtext, advc, \
                       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 ) \
     add_string_inner( CONFIG_ITEM_MODULE_LIST, name, text, longtext, advc, \
                       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__
 #define add_module_cat( name, i_subcategory, value, text, longtext, advc ) \
@@ -358,7 +353,7 @@ VLC_METADATA_EXPORTS
 
 #define add_float( name, v, 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 ) \
     add_float( name, value, text, longtext, advc ) \
@@ -366,14 +361,13 @@ VLC_METADATA_EXPORTS
 
 #define add_bool( name, v, 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 */
 #define add_obsolete_inner( name, type ) \
     add_type_inner( type ) \
-    vlc_config_set (p_config, VLC_CONFIG_NAME, \
-                    (const char *)(name)); \
-    vlc_config_set (p_config, VLC_CONFIG_REMOVED);
+    vlc_config_set (VLC_CONFIG_NAME, (const char *)(name)); \
+    vlc_config_set (VLC_CONFIG_REMOVED);
 
 #define add_obsolete_bool( name ) \
         add_obsolete_inner( name, CONFIG_ITEM_BOOL )
@@ -390,48 +384,46 @@ VLC_METADATA_EXPORTS
 /* Modifier macros for the config options (used for fine tuning) */
 
 #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 ) \
-    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 ) \
-    vlc_config_set (p_config, VLC_CONFIG_LIST, \
+    vlc_config_set (VLC_CONFIG_LIST, \
                     (size_t)(sizeof (list) / sizeof (char *)), \
                     (const char *const *)(list), \
                     (const char *const *)(list_text), \
                     (vlc_callback_t)(list_update_func));
 
 #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)), \
                     (const int *)(list), \
                     (const char *const *)(list_text), \
                     (vlc_callback_t)(NULL));
 
 #define change_integer_range( minv, maxv ) \
-    vlc_config_set (p_config, VLC_CONFIG_RANGE, \
-                    (int64_t)(minv), (int64_t)(maxv));
+    vlc_config_set (VLC_CONFIG_RANGE, (int64_t)(minv), (int64_t)(maxv));
 
 #define change_float_range( minv, maxv ) \
-    vlc_config_set (p_config, VLC_CONFIG_RANGE, \
-                    (double)(minv), (double)(maxv));
+    vlc_config_set (VLC_CONFIG_RANGE, (double)(minv), (double)(maxv));
 
 #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));
 
 /* For options that are saved but hidden from the preferences panel */
 #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 */
 #define change_volatile() \
     change_private() \
-    vlc_config_set (p_config, VLC_CONFIG_VOLATILE);
+    vlc_config_set (VLC_CONFIG_VOLATILE);
 
 #define change_safe() \
-    vlc_config_set (p_config, VLC_CONFIG_SAFE);
+    vlc_config_set (VLC_CONFIG_SAFE);
 
 /* Meta data plugin exports */
 #define VLC_META_EXPORT( name, value ) \
index db4e8d1fae0d1ac7e16dae999698e17fcbee968b..ce2350003c10d44840a9770296f567038e53629c 100644 (file)
@@ -56,8 +56,6 @@ static struct
     unsigned usage;
 } modules = { VLC_STATIC_MUTEX, NULL, 0 };
 
-module_t *vlc_entry__main (void);
-
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -467,7 +465,7 @@ static module_t *module_InitDynamic (vlc_object_t *obj,
     }
 
     /* We can now try to call the symbol */
-    module_t *module = entry ();
+    module_t *module = vlc_plugin_describe (entry);
     if (unlikely(module == NULL))
     {
         /* With a well-written module we shouldn't have to print an
@@ -497,8 +495,8 @@ error:
 static module_t *module_InitStatic (vlc_plugin_cb entry)
 {
     /* Initializes the module */
-    module_t *module = entry ();
-    if (unlikely (module == NULL))
+    module_t *module = vlc_plugin_describe (entry);
+    if (unlikely(module == NULL))
         return NULL;
 
     module->b_loaded = true;
index 687ca4a75619c10871c1b0a0a4612d08c7636287..6acfb31a3122c5aadabd8a874742d68cea8c9d43 100644 (file)
@@ -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;
     int ret = 0;
 
@@ -155,18 +161,20 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
     {
         case VLC_MODULE_CREATE:
         {
-            module_t **pp = va_arg (ap, module_t **);
+            module = *pprimary;
             module_t *submodule = vlc_module_create (module);
-
             if (unlikely(submodule == NULL))
             {
                 ret = -1;
                 break;
             }
 
-            *pp = submodule;
-            if (module == NULL)
+            *(va_arg (ap, module_t **)) = submodule;
+            if (*pprimary == NULL)
+            {
+                *pprimary = submodule;
                 break;
+            }
             /* Inheritance. Ugly!! */
             submodule->pp_shortcuts = xmalloc (sizeof (char **));
             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, ...)
         {
             int type = va_arg (ap, int);
             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;
+                break;
+            }
+            *pp = item;
             break;
         }
 
@@ -465,3 +478,19 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
     va_end (ap);
     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;
+}
index 90e5c86e259b95c1af893393b906b5dec24f8bf0..0356a121b064024adbed1672cd7baf598832ef81 100644 (file)
@@ -46,7 +46,11 @@ struct module_cache_t
 /** The module handle type */
 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
@@ -96,6 +100,7 @@ struct module_t
     char *              domain;                            /* gettext domain */
 };
 
+module_t *vlc_plugin_describe (vlc_plugin_cb);
 module_t *vlc_module_create (module_t *);
 void vlc_module_destroy (module_t *);