192b53ddd081f62642e83fd84d56a5c29c561576
[vlc.git] / src / misc / modules_plugin.h.in
1 /*****************************************************************************
2  * modules_plugin.h : Plugin management functions used by the core application.
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: modules_plugin.h.in,v 1.8 2002/12/06 10:10:39 sam Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Inline functions for handling dynamic modules
26  *****************************************************************************/
27
28 /*****************************************************************************
29  * module_load: load a dynamic library
30  *****************************************************************************
31  * This function loads a dynamically linked library using a system dependant
32  * method, and returns a non-zero value on error, zero otherwise.
33  *****************************************************************************/
34 static int module_load( const MYCHAR * psz_filename, module_handle_t * handle )
35 {
36 #ifdef SYS_BEOS
37     *handle = load_add_on( psz_filename );
38     return( *handle < 0 );
39
40 #elif defined(WIN32) || defined(UNDER_CE)
41     *handle = LoadLibrary( psz_filename );
42     return( *handle == NULL );
43
44 #elif defined(RTLD_NOW)
45 #   if defined(SYS_LINUX)
46     /* We should NOT open modules with RTLD_GLOBAL, or we are going to get
47      * namespace collisions when two modules have common public symbols,
48      * but ALSA is being a pest here. */
49     if( strstr( psz_filename, "alsa" ) )
50     {
51         *handle = dlopen( psz_filename, RTLD_NOW | RTLD_GLOBAL );
52         return( *handle == NULL );
53     }
54 #   endif
55     *handle = dlopen( psz_filename, RTLD_NOW );
56     return( *handle == NULL );
57
58 #else
59     *handle = dlopen( psz_filename, DL_LAZY );
60     return( *handle == NULL );
61
62 #endif
63 }
64
65 /*****************************************************************************
66  * module_unload: unload a dynamic library
67  *****************************************************************************
68  * This function unloads a previously opened dynamically linked library
69  * using a system dependant method. No return value is taken in consideration,
70  * since some libraries sometimes refuse to close properly.
71  *****************************************************************************/
72 static void module_unload( module_handle_t handle )
73 {
74 #ifdef SYS_BEOS
75     unload_add_on( handle );
76
77 #elif defined(WIN32) || defined(UNDER_CE)
78     FreeLibrary( handle );
79
80 #else
81     dlclose( handle );
82
83 #endif
84     return;
85 }
86
87 /*****************************************************************************
88  * module_getsymbol: get a symbol from a dynamic library
89  *****************************************************************************
90  * This function queries a loaded library for a symbol specified in a
91  * string, and returns a pointer to it. We don't check for dlerror() or
92  * similar functions, since we want a non-NULL symbol anyway.
93  *****************************************************************************/
94 static void * _module_getsymbol( module_handle_t handle,
95                                  const char * psz_function )
96 {
97 #ifdef SYS_BEOS
98     void * p_symbol;
99     if( B_OK == get_image_symbol( handle, psz_function,
100                                   B_SYMBOL_TYPE_TEXT, &p_symbol ) )
101     {
102         return p_symbol;
103     }
104     else
105     {
106         return NULL;
107     }
108
109 #elif defined( UNDER_CE )
110     wchar_t psz_real[256];
111     MultiByteToWideChar( CP_ACP, 0, psz_function, -1, psz_real, 256 );
112
113     return (void *)GetProcAddress( handle, psz_real );
114
115 #elif defined( WIN32 )
116     return (void *)GetProcAddress( handle, (MYCHAR*)psz_function );
117
118 #else
119     return dlsym( handle, psz_function );
120
121 #endif
122 }
123
124 static void * module_getsymbol( module_handle_t handle,
125                                 const char * psz_function )
126 {
127     void * p_symbol = _module_getsymbol( handle, psz_function );
128
129     /* MacOS X dl library expects symbols to begin with "_". So do
130      * some other operating systems. That's really lame, but hey, what
131      * can we do ? */
132     if( p_symbol == NULL )
133     {
134         char *psz_call = malloc( strlen( psz_function ) + 2 );
135
136         strcpy( psz_call + 1, psz_function );
137         psz_call[ 0 ] = '_';
138         p_symbol = _module_getsymbol( handle, psz_call );
139         free( psz_call );
140     }
141
142     return p_symbol;
143 }
144
145 /*****************************************************************************
146  * module_error: wrapper for dlerror()
147  *****************************************************************************
148  * This function returns the error message of the last module operation. It
149  * returns the string "failed" on systems which do not have a dlerror() like
150  * function. psz_buffer can be used to store temporary data, it is guaranteed
151  * to be kept intact until the return value of module_error has been used.
152  *****************************************************************************/
153 static const char * module_error( char *psz_buffer )
154 {
155 #if defined(SYS_BEOS)
156     return "failed";
157
158 #elif defined(UNDER_CE)
159     wchar_t psz_tmp[256];
160
161     int i, i_error = GetLastError();
162
163     FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
164                    NULL, i_error, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
165                    (LPTSTR) psz_tmp, 256, NULL );
166
167     /* Go to the end of the string */
168     for( i = 0;
169          psz_tmp[i] && psz_tmp[i] != L'\r' && psz_tmp[i] != L'\n';
170          i++ ) {};
171
172     if( psz_tmp[i] )
173     {
174         swprintf( psz_tmp + i, L" (error %i)", i_error );
175         psz_tmp[ 255 ] = L'\0';
176     }
177
178     WideCharToMultiByte( CP_ACP, WC_DEFAULTCHAR, psz_tmp, -1,
179                          psz_buffer, 256, NULL, NULL );
180
181     return psz_buffer;
182
183 #elif defined(WIN32)
184     int i, i_error = GetLastError();
185
186     FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
187                    NULL, i_error, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
188                    (LPTSTR) psz_buffer, 256, NULL );
189
190     /* Go to the end of the string */
191     for( i = 0;
192          psz_buffer[i] && psz_buffer[i] != '\r' && psz_buffer[i] != '\n';
193          i++ ) {};
194
195     if( psz_buffer[i] )
196     {
197         snprintf( psz_buffer + i, 256 - i, " (error %i)", i_error );
198         psz_buffer[ 255 ] = '\0';
199     }
200
201     return psz_buffer;
202
203 #else
204     return dlerror();
205
206 #endif
207 }
208
209 /*****************************************************************************
210  * STORE_SYMBOLS: store known symbols into p_symbols for plugin access.
211  *****************************************************************************/