1 /*****************************************************************************
2 * plugins.c : Dynamic plugin management functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
26 #include <stdlib.h> /* free(), strtol() */
27 #include <stdio.h> /* sprintf() */
28 #include <string.h> /* strerror() */
29 #include <errno.h> /* ENOMEM */
30 #include <sys/types.h> /* open */
33 #include <unistd.h> /* close */
35 #if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */
36 #include <dlfcn.h> /* dlopen(), dlsym(), dlclose() */
38 #elif defined(HAVE_IMAGE_H) /* BeOS */
42 #error no dynamic plugins available on your system !
46 #include "beos_specific.h"
54 /* Local prototypes */
55 char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name );
56 int AllocatePlugin ( plugin_id_t plugin_id, plugin_bank_t * p_bank,
57 char * psz_filename );
59 plugin_bank_t * bank_Create( void )
61 plugin_bank_t *p_bank;
64 /* Allocate structure */
65 p_bank = malloc( sizeof( plugin_bank_t ) );
68 intf_ErrMsg("plugin bank error: %s\n", strerror( ENOMEM ) );
72 /* Initialize structure */
73 for( i = 0 ; i < MAX_PLUGIN_COUNT ; i++ )
75 p_bank->p_info[ i ] = NULL;
77 p_bank->i_plugin_count = MAX_PLUGIN_COUNT;
79 intf_Msg("Plugin bank initialized\n");
83 void bank_Init( plugin_bank_t * p_bank )
88 /* FIXME: we should browse all directories to get plugins */
89 #define SEEK_PLUGIN( name ) \
90 psz_filename = TestPlugin( &tmp, name ); \
91 if( psz_filename ) AllocatePlugin( tmp, p_bank, psz_filename );
94 SEEK_PLUGIN( "beos" );
99 SEEK_PLUGIN( "glide" );
100 SEEK_PLUGIN( "mga" );
102 /* High level Video */
103 SEEK_PLUGIN( "gnome" );
104 SEEK_PLUGIN( "ggi" );
105 SEEK_PLUGIN( "sdl" );
108 SEEK_PLUGIN( "yuvmmx" );
109 SEEK_PLUGIN( "yuv" );
112 SEEK_PLUGIN( "dsp" );
113 SEEK_PLUGIN( "esd" );
114 SEEK_PLUGIN( "alsa" );
117 SEEK_PLUGIN( "dummy" );
122 void bank_Destroy( plugin_bank_t * p_bank )
125 for( i = 0 ; i < p_bank->i_plugin_count ; i++ )
127 if( p_bank->p_info[ i ] != NULL )
129 free( p_bank->p_info[ i ]-> psz_filename );
137 * Following functions are local
140 char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name )
142 int i_count, i_length, i_fd;
144 char * psz_plugin_path[ ] =
147 "lib", /* this one should disappear */
152 i_length = strlen( psz_name );
154 for ( i_count = 0 ; psz_plugin_path[ i_count ] ; i_count++ )
157 char * psz_program_path;
159 psz_program_path = beos_GetProgramPath();
160 psz_plugin = malloc( strlen(psz_plugin_path[i_count]) +
161 strlen(psz_program_path) + i_length + 6 );
162 sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
163 psz_plugin_path[i_count], psz_name );
165 *p_plugin_id = load_add_on( psz_plugin );
167 psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 5 );
168 sprintf( psz_plugin, "%s/%s.so", psz_plugin_path[i_count], psz_name );
170 /* Try to open the plugin before dlopen()ing it. */
171 i_fd = open( psz_plugin, O_RDONLY );
179 *p_plugin_id = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
183 if( *p_plugin_id >= 0 )
185 if( *p_plugin_id != NULL )
188 /* plugin successfuly dlopened */
189 return( psz_plugin );
193 intf_WarnMsg( 1, "Plugin %s failed: %s\n", psz_plugin, dlerror() );
203 int AllocatePlugin( plugin_id_t plugin_id, plugin_bank_t * p_bank,
204 char * psz_filename )
206 typedef plugin_info_t * ( get_config_t ) ( void );
207 get_config_t * p_func;
210 for( i = 0 ; i < p_bank->i_plugin_count ; i++ )
212 if( p_bank->p_info[ i ] == NULL )
218 /* no room to store that plugin, quit */
219 if( i == p_bank->i_plugin_count )
221 intf_ErrMsg( "plugin bank error: reached max plugin count (%i), "
222 "increase MAX_PLUGIN_COUNT\n", p_bank->i_plugin_count );
226 /* system-specific dynamic symbol loading */
227 GET_PLUGIN( p_func, plugin_id, "GetConfig" );
229 /* if it failed, just quit */
235 /* run the plugin function to initialize the structure */
236 p_bank->p_info[ i ] = p_func( );
237 p_bank->p_info[ i ]->plugin_id = plugin_id;
238 p_bank->p_info[ i ]->psz_filename = strdup( psz_filename );
241 /* Tell the world we found it */
242 intf_Msg( "Plugin %i: %s %s [0x%x]\n", i,
243 p_bank->p_info[ i ]->psz_name,
244 p_bank->p_info[ i ]->psz_version,
245 p_bank->p_info[ i ]->i_score );
252 void TrashPlugin ( plugin_id_t plugin_id )
255 unload_add_on( plugin_id );
257 dlclose( plugin_id );