* 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 */
+#include <sys/types.h> /* open */
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h> /* close */
-#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 );
-int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name )
+plugin_bank_t * bank_Create( void )
{
- int i_count, i_length;
+ 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 );
+
+ /* Arch plugins */
+ SEEK_PLUGIN( "beos" );
+
+ /* Low level Video */
+ SEEK_PLUGIN( "x11" );
+ SEEK_PLUGIN( "fb" );
+ SEEK_PLUGIN( "glide" );
+ SEEK_PLUGIN( "mga" );
+
+ /* High level Video */
+ SEEK_PLUGIN( "gnome" );
+ SEEK_PLUGIN( "ggi" );
+ SEEK_PLUGIN( "sdl" );
+
+ /* Video calculus */
+ SEEK_PLUGIN( "yuvmmx" );
+ SEEK_PLUGIN( "yuv" );
+
+ /* Audio pluins */
+ SEEK_PLUGIN( "dsp" );
+ SEEK_PLUGIN( "esd" );
+ SEEK_PLUGIN( "alsa" );
+
+ /* Dummy plugin */
+ SEEK_PLUGIN( "dummy" );
+
+#undef SEEK_PLUGIN
+}
+
+void bank_Destroy( plugin_bank_t * p_bank )
+{
+ int i;
+ for( i = 0 ; i < p_bank->i_plugin_count ; i++ )
+ {
+ if( p_bank->p_info[ i ] != NULL )
+ {
+ free( p_bank->p_info[ i ]-> psz_filename );
+ }
+ }
+
+ free( p_bank );
+}
+
+/*
+ * Following functions are local
+ */
+
+char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name )
+{
+ int i_count, i_length, i_fd;
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 + 6 );
+ 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 );
+
+ /* Try to open the plugin before dlopen()ing it. */
+ i_fd = open( psz_plugin, O_RDONLY );
+ if( i_fd == -1 )
+ {
+ free( psz_plugin );
+ continue;
+ }
+ close( i_fd );
+
+ *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
+ intf_WarnMsg( 1, "Plugin %s failed: %s\n", psz_plugin, 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;
+ p_bank->p_info[ i ]->psz_filename = strdup( psz_filename );
+
+
+ /* 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