]> git.saurik.com Git - wxWidgets.git/blob - src/common/dynlib.cpp
New virtual key defines (NUMPAD_XXX).
[wxWidgets.git] / src / common / dynlib.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        dynlib.cpp
3 // Purpose:     Dynamic library management
4 // Author:      Guilhem Lavaux
5 // Modified by:
6 // Created:     20/07/98
7 // RCS-ID:      $Id$
8 // Copyright:   (c) Guilhem Lavaux
9 // Licence:     wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21     #pragma implementation "dynlib.h"
22 #endif
23
24 #include  "wx/wxprec.h"
25
26 #ifdef    __BORLANDC__
27   #pragma hdrstop
28 #endif  //__BORLANDC__
29
30 #if wxUSE_DYNLIB_CLASS
31
32 #include "wx/dynlib.h"
33 #include "wx/filefn.h"
34 #include "wx/intl.h"
35 #include "wx/log.h"
36 #include "wx/tokenzr.h"
37
38 // ----------------------------------------------------------------------------
39 // conditional compilation
40 // ----------------------------------------------------------------------------
41
42 #if defined(HAVE_DLOPEN)
43     #define wxDllOpen(lib)                dlopen(lib.fn_str(), RTLD_LAZY)
44     #define wxDllGetSymbol(handle, name)  dlsym(handle, name.mb_str())
45     #define wxDllClose                    dlclose
46 #elif defined(HAVE_SHL_LOAD)
47     #define wxDllOpen(lib)                shl_load(lib.fn_str(), BIND_DEFERRED, 0)
48     #define wxDllClose      shl_unload
49
50     static inline void *wxDllGetSymbol(shl_t handle, const wxString& name)
51     {
52         void *sym;
53         if ( shl_findsym(&handle, name.mb_str(), TYPE_UNDEFINED, &sym) == 0 )
54             return sym;
55         else
56             return (void *)0;
57     }
58 #elif defined(__WINDOWS__)
59     #include <windows.h>
60
61     // using LoadLibraryEx under Win32 to avoid name clash with LoadLibrary
62     #ifdef __WIN32__
63         #define wxDllOpen(lib)                  ::LoadLibraryEx(lib, 0, 0)
64     #else   // Win16
65         #define wxDllOpen(lib)                  ::LoadLibrary(lib)
66     #endif  // Win32/16
67     #define wxDllGetSymbol(handle, name)    ::GetProcAddress(handle, name)
68     #define wxDllClose                      ::FreeLibrary
69 #else
70     #error "Don't know how to load shared libraries on this platform."
71 #endif // OS
72
73 // ---------------------------------------------------------------------------
74 // Global variables
75 // ---------------------------------------------------------------------------
76
77 wxLibraries wxTheLibraries;
78
79 // ----------------------------------------------------------------------------
80 // private functions
81 // ----------------------------------------------------------------------------
82
83 // construct the full name from the base shared object name: adds a .dll
84 // suffix under Windows or .so under Unix
85 static wxString ConstructLibraryName(const wxString& basename)
86 {
87     wxString fullname(basename);
88
89 #if defined(__UNIX__)
90     #if defined(__HPUX__)
91         fullname << ".sl";
92     #else       //__HPUX__
93         fullname << ".so";
94     #endif      //__HPUX__
95 #elif defined(__WINDOWS__)
96     fullname << ".dll";
97 #endif
98
99     return fullname;
100 }
101
102 // ============================================================================
103 // implementation
104 // ============================================================================
105
106 // ---------------------------------------------------------------------------
107 // wxLibrary (one instance per dynamic library)
108 // ---------------------------------------------------------------------------
109
110 wxLibrary::wxLibrary(wxDllType handle)
111 {
112     typedef wxClassInfo *(*t_get_first)(void);
113     t_get_first get_first;
114
115     m_handle = handle;
116
117     // Some system may use a local heap for library.
118     get_first = (t_get_first)GetSymbol("wxGetClassFirst");
119     // It is a wxWindows DLL.
120     if (get_first)
121         PrepareClasses(get_first());
122 }
123
124 wxLibrary::~wxLibrary()
125 {
126     if ( m_handle )
127     {
128         wxDllClose(m_handle);
129     }
130 }
131
132 wxObject *wxLibrary::CreateObject(const wxString& name)
133 {
134     wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
135
136     if (!info)
137         return NULL;
138
139     return info->CreateObject();
140 }
141
142 void wxLibrary::PrepareClasses(wxClassInfo *first)
143 {
144     // Index all class infos by their class name
145     wxClassInfo *info = first;
146     while (info)
147     {
148         if (info->m_className)
149             classTable.Put(info->m_className, (wxObject *)info);
150         info = info->GetNext();
151     }
152
153     // Set base pointers for each wxClassInfo
154     info = first;
155     while (info)
156     {
157         if (info->GetBaseClassName1())
158             info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
159         if (info->GetBaseClassName2())
160             info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
161         info = info->m_next;
162     }
163 }
164
165 void *wxLibrary::GetSymbol(const wxString& symbname)
166 {
167     void *symbol = NULL;    // return value
168
169 #if defined( __WXMAC__ )
170     Ptr symAddress ;
171     CFragSymbolClass symClass ;
172     Str255      symName ;
173
174     strcpy( (char*) symName , symbname ) ;
175     c2pstr( (char*) symName ) ;
176
177     if ( FindSymbol( m_handle , symName , &symAddress , &symClass ) == noErr )
178     {
179         symbol = (void *)symAddress ; 
180     }
181 #else
182     symbol = wxDllGetSymbol(m_handle, symbname);
183 #endif
184
185     if ( !symbol )
186     {
187         wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
188                       symbname.c_str());
189     }
190
191     return symbol;
192 }
193
194 // ---------------------------------------------------------------------------
195 // wxLibraries (only one instance should normally exist)
196 // ---------------------------------------------------------------------------
197
198 wxLibraries::wxLibraries()
199 {
200 }
201
202 wxLibraries::~wxLibraries()
203 {
204     wxNode *node = m_loaded.First();
205
206     while (node) {
207         wxLibrary *lib = (wxLibrary *)node->Data();
208         delete lib;
209
210         node = node->Next();
211     }
212 }
213
214 wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
215 {
216     wxNode *node;
217     wxLibrary *lib;
218     wxClassInfo *old_sm_first;
219
220     if ( (node = m_loaded.Find(name.GetData())) )
221         return ((wxLibrary *)node->Data());
222
223     // If DLL shares data, this is necessary.
224     old_sm_first = wxClassInfo::sm_first;
225     wxClassInfo::sm_first = NULL;
226
227     wxString lib_name = ConstructLibraryName(name);
228
229 #if defined(__UNIX__)
230     // found the first file in LD_LIBRARY_PATH with this name
231     wxString libPath("/lib:/usr/lib"); // system path first
232     const char *envLibPath = getenv("LD_LIBRARY_PATH");
233     if ( envLibPath )
234         libPath << ':' << envLibPath;
235     wxStringTokenizer tokenizer(libPath, _T(':'));
236     while ( tokenizer.HasMoreToken() )
237     {
238         wxString fullname(tokenizer.NextToken());
239
240         fullname << '/' << lib_name;
241         if ( wxFileExists(fullname) )
242         {
243             lib_name = fullname;
244
245             // found the library
246             break;
247         }
248     }
249     //else: not found in the path, leave the name as is (secutiry risk?)
250
251 #endif // __UNIX__
252
253     wxDllType handle;
254
255 #if defined(__WXMAC__)
256     FSSpec myFSSpec ;
257     Ptr myMainAddr ;
258     Str255      myErrName ;
259
260     wxMacPathToFSSpec( lib_name , &myFSSpec ) ;
261     if (GetDiskFragment( &myFSSpec , 0 , kCFragGoesToEOF , "\p" , kPrivateCFragCopy , &handle , &myMainAddr ,
262                 myErrName ) != noErr )
263     {
264         p2cstr( myErrName ) ;
265         wxASSERT_MSG( 1 , (char*)myErrName ) ;
266         return NULL ;
267     }
268 #else // !Mac
269     handle = wxDllOpen(lib_name);
270 #endif // OS
271
272     if ( !handle )
273     {
274         wxLogSysError(_("Failed to load shared library '%s'"),
275                       lib_name.c_str());
276
277         return NULL;
278     }
279
280     lib = new wxLibrary(handle);
281
282     wxClassInfo::sm_first = old_sm_first;
283
284     m_loaded.Append(name.GetData(), lib);
285
286     return lib;
287 }
288
289 wxObject *wxLibraries::CreateObject(const wxString& path)
290 {
291     wxNode *node = m_loaded.First();
292     wxObject *obj;
293
294     while (node) {
295         obj = ((wxLibrary *)node->Data())->CreateObject(path);
296         if (obj)
297             return obj;
298
299         node = node->Next();
300     }
301     return NULL;
302 }
303
304 #endif // wxUSE_DYNLIB_CLASS