]> git.sesse.net Git - vlc/blobdiff - src/misc/plugins.c
. autod�tection des plugins
[vlc] / src / misc / plugins.c
index ced56d186c491fb16e74188c40a3357e674d14a0..25c3cbe2d35ad4d2144dcaf001051db3e095caef 100644 (file)
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
+#include "defs.h"
+
+#include "config.h"
 
 #include <stdlib.h>                                      /* free(), strtol() */
 #include <stdio.h>                                              /* sprintf() */
+#include <string.h>                                            /* strerror() */
+#include <errno.h>                                                 /* ENOMEM */
 
-#if defined(SYS_LINUX) || defined(SYS_BSD) || defined(SYS_GNU)
+#if defined(HAVE_DLFCN_H)                                /* Linux, BSD, Hurd */
 #include <dlfcn.h>                           /* dlopen(), dlsym(), dlclose() */
+
+#elif defined(HAVE_IMAGE_H)                                          /* BeOS */
+#include <image.h>
+
+#else
+#error no dynamic plugins available on your system !
 #endif
 
 #ifdef SYS_BEOS
-#include <image.h>
+#include "beos_specific.h"
 #endif
 
+#include "common.h"
+
+#include "intf_msg.h"
 #include "plugins.h"
 
-#define PLUGIN_PATH_COUNT 5
+/* Local prototypes */
+char * TestPlugin     ( plugin_id_t *p_plugin_id, char * psz_name );
+int    AllocatePlugin ( plugin_id_t plugin_id, plugin_bank_t * p_bank,
+                        char * psz_filename );
+
+plugin_bank_t * bank_Create( void )
+{
+    plugin_bank_t *p_bank;
+    int i;
+
+    /* Allocate structure */
+    p_bank = malloc( sizeof( plugin_bank_t ) );
+    if( !p_bank )
+    {
+        intf_ErrMsg("plugin bank error: %s\n", strerror( ENOMEM ) );
+        return( NULL );
+    }
+
+    /* Initialize structure */
+    for( i = 0 ; i < MAX_PLUGIN_COUNT ; i++ )
+    {
+        p_bank->p_info[ i ] = NULL;
+    }
+    p_bank->i_plugin_count = MAX_PLUGIN_COUNT;
+
+    intf_Msg("Plugin bank initialized\n");
+    return( p_bank );
+}
+
+void bank_Init( plugin_bank_t * p_bank )
+{
+    plugin_id_t tmp;
+    char * psz_filename;
+
+    /* FIXME: we should browse all directories to get plugins */
+#define SEEK_PLUGIN( name ) \
+    psz_filename = TestPlugin( &tmp, name ); \
+    if( psz_filename ) AllocatePlugin( tmp, p_bank, psz_filename );
+
+    SEEK_PLUGIN( "beos" );
+    SEEK_PLUGIN( "x11" );
+    SEEK_PLUGIN( "dsp" );
+    SEEK_PLUGIN( "esd" );
+    SEEK_PLUGIN( "gnome" );
+    SEEK_PLUGIN( "ggi" );
+    SEEK_PLUGIN( "fb" );
+    SEEK_PLUGIN( "glide" );
+    SEEK_PLUGIN( "mga" );
+    SEEK_PLUGIN( "yuvmmx" );
+    SEEK_PLUGIN( "yuv" );
+    SEEK_PLUGIN( "dummy" );
+
+#undef SEEK_PLUGIN
+}
+
+void bank_Destroy( plugin_bank_t * p_bank )
+{
+    free( p_bank );
+}
+
+/*
+ * Following functions are local
+ */
 
-int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name )
+char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name )
 {
     int i_count, i_length;
     char * psz_plugin;
-    char * psz_plugin_path[ PLUGIN_PATH_COUNT ] =
+    char * psz_plugin_path[ ] =
     {
         ".",
+        "lib", /* this one should disappear */
         PLUGIN_PATH,
-        /* these ones should disappear */
-        "./audio_output",
-        "./video_output",
-        "./interface"
+        NULL
     };
 
-    i_length = strlen( psz_mask ) + strlen( psz_name );
+    i_length = strlen( psz_name );
 
-    for ( i_count = 0 ; i_count < PLUGIN_PATH_COUNT ; i_count++ )
+    for ( i_count = 0 ; psz_plugin_path[ i_count ] ; i_count++ )
     {
-        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 6 );
-        sprintf( psz_plugin, "%s/%s_%s.so", psz_plugin_path[i_count], psz_mask, psz_name );
 #ifdef SYS_BEOS
-        *p_plugin = load_addon_image( psz_plugin );
-#else  /* SYS_BEOS */
-        *p_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
-#endif /* SYS_BEOS */
-        free( psz_plugin );
+        char * psz_program_path;
+        
+        psz_program_path = beos_GetProgramPath();
+        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) +
+                             strlen(psz_program_path) + i_length + 5 );
+        sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
+                 psz_plugin_path[i_count], psz_name );        
+
+        *p_plugin_id = load_add_on( psz_plugin );
+#else
+        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 5 );
+        sprintf( psz_plugin, "%s/%s.so", psz_plugin_path[i_count], psz_name );
+
+        *p_plugin_id = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
+#endif
 
 #ifdef SYS_BEOS
-        if( *p_plugin >= 0 )
-            return( 0 );
+        if( *p_plugin_id >= 0 )
 #else
-        if( *p_plugin != NULL )
-            return( 0 );
+       if( *p_plugin_id != NULL )
+#endif
+        {
+            /* plugin successfuly dlopened */
+            return( psz_plugin );
+        }
+#ifndef SYS_BEOS
+        else
+        {
+            intf_DbgMsg( "%s\n", dlerror() );
+        }
 #endif
+
+        free( psz_plugin );
     }
 
-    return( -1 );
+    return( NULL );
 }
 
-void TrashPlugin ( plugin_id_t plugin )
+
+int AllocatePlugin( plugin_id_t plugin_id, plugin_bank_t * p_bank,
+                    char * psz_filename )
 {
-#ifdef SYS_BEOS
-    unload_add_on( plugin );
-#else
-    dlclose( plugin );
-#endif
+    typedef plugin_info_t * ( get_config_t ) ( void );
+    get_config_t * p_func;   
+    int i;
+
+    for( i = 0 ; i < p_bank->i_plugin_count ; i++ )
+    {
+        if( p_bank->p_info[ i ] == NULL )
+        {
+            break;
+        }
+    }
+
+    /* no room to store that plugin, quit */
+    if( i == p_bank->i_plugin_count )
+    {
+        intf_ErrMsg( "plugin bank error: reached max plugin count (%i), "
+                     "increase MAX_PLUGIN_COUNT\n", p_bank->i_plugin_count );
+        return( -1 );
+    }
+
+    /* system-specific dynamic symbol loading */
+    GET_PLUGIN( p_func, plugin_id, "GetConfig" );
+
+    /* if it failed, just quit */
+    if( !p_func )
+    {
+        return( -1 );
+    }
+
+    /* run the plugin function to initialize the structure */
+    p_bank->p_info[ i ]            = p_func( );
+    p_bank->p_info[ i ]->plugin_id = plugin_id;
+
+    /* Tell the world we found it */
+    intf_Msg( "Plugin %i: %s %s [0x%x]\n", i,
+              p_bank->p_info[ i ]->psz_name,
+              p_bank->p_info[ i ]->psz_version,
+              p_bank->p_info[ i ]->i_score );
+
+    /* return nicely */
+    return( 0 );
 }
 
-void * GetPluginFunction ( plugin_id_t plugin, char *psz_name )
+#if 0
+void TrashPlugin ( plugin_id_t plugin_id )
 {
 #ifdef SYS_BEOS
-    void * p_func;
-    
-    if( get_image_symbol( plugin, psz_name, B_SYMBOL_TYPE_TEXT, &p_func ) )
-        return( NULL );
-    else
-        return( p_func );    
+    unload_add_on( plugin_id );
 #else
-    return( dlsym(plugin, psz_name) );
+    dlclose( plugin_id );
 #endif
 }
+#endif