]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dynlib.cpp
Added (untested) support for sub-locales.
[wxWidgets.git] / src / common / dynlib.cpp
index 6a49d9bc3a3d2f6abd70c082d397c5e16dcd2efa..6b8bf78e38f06d4cbd4e15fbae7ad8120acd3db8 100644 (file)
 #pragma implementation "dynlib.h"
 #endif
 
+#include  "wx/wxprec.h"
+
+#ifdef    __BORLANDC__
+  #pragma hdrstop
+#endif  //__BORLANDC__
+
+#ifndef WX_PRECOMP
+#endif //WX_PRECOMP
+
 #include <wx/dynlib.h>
 #include <wx/filefn.h>
 #include <wx/list.h>
@@ -22,7 +31,7 @@
 // System dependent include
 // ---------------------------------------------------------------------------
 
-#if defined(__LINUX__) || defined(__SGI__)
+#if defined(__UNIX__)
 #include <dlfcn.h>
 #endif
 
 #include <windows.h>
 #endif
 
+#ifdef LoadLibrary
+#undef LoadLibrary
+#endif
+
 // ---------------------------------------------------------------------------
 // Global variables
 // ---------------------------------------------------------------------------
@@ -42,28 +55,23 @@ wxLibraries wxTheLibraries;
 
 wxLibrary::wxLibrary(void *handle)
 {
-  typedef wxClassLibrary *(*t_get_list)(void);
-  t_get_list get_list;
+  typedef wxClassInfo *(*t_get_first)(void);
+  t_get_first get_first;
 
   m_handle = handle;
+  m_destroy = TRUE;
 
-  get_list = (t_get_list)GetSymbol("GetClassList");
-  m_liblist = (*get_list)();
+  // Some system may use a local heap for library.
+  get_first = (t_get_first)GetSymbol("wxGetClassFirst");
+  // It is a wxWindows DLL.
+  if (get_first)
+    PrepareClasses(get_first());
 }
 
 wxLibrary::~wxLibrary()
 {
-  if (m_handle) {
-    typedef void (*t_free_list)(wxClassLibrary *);
-    t_free_list free_list;
-
-    free_list = (t_free_list) GetSymbol("FreeClassList");
-    if (free_list != NULL)
-      free_list(m_liblist);
-    else
-      delete m_liblist;
-
-#if defined(__LINUX__) || defined(__SGI__)
+  if (m_handle && m_destroy) {
+#if defined(__UNIX__)
     dlclose(m_handle);
 #endif
 #ifdef __WINDOWS__
@@ -74,16 +82,55 @@ wxLibrary::~wxLibrary()
 
 wxObject *wxLibrary::CreateObject(const wxString& name)
 {
-  return m_liblist->CreateObject(name);
+  wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
+
+  if (!info)
+    return NULL;
+
+  return info->CreateObject();
+}
+
+void wxLibrary::PrepareClasses(wxClassInfo *first)
+{
+  // Index all class infos by their class name
+  wxClassInfo *info = first;
+  while (info)
+  {
+    if (info->m_className)
+      classTable.Put(info->m_className, (wxObject *)info);
+    info = info->GetNext();
+  }
+
+  // Set base pointers for each wxClassInfo
+  info = first;
+  while (info)
+  {
+    if (info->GetBaseClassName1())
+      info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
+    if (info->GetBaseClassName2())
+      info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
+    info = info->m_next;
+  }
 }
 
 void *wxLibrary::GetSymbol(const wxString& symbname)
 {
-#if defined(__LINUX__) || defined(__SGI__)
+#if defined(__UNIX__)
   return dlsym(m_handle, WXSTRINGCAST symbname);
-#endif
-#ifdef __WINDOWS__
-  return GetProcAddress(m_handle, WXSTRINGCAST symbname);
+#elif defined( __WINDOWS__ )
+  return GetProcAddress((HINSTANCE) m_handle, WXSTRINGCAST symbname);
+#elif defined( __WXMAC__ )
+  Ptr symAddress ;
+  CFragSymbolClass symClass ;
+  Str255       symName ;
+       
+  strcpy( (char*) symName , symbname ) ;
+  c2pstr( (char*) symName ) ;
+       
+  if ( FindSymbol( (CFragConnectionID) m_handle , symName , &symAddress , &symClass ) == noErr )
+  {
+    return symAddress ; 
+  }
 #endif
   return NULL;
 }
@@ -113,30 +160,63 @@ wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
   wxString lib_name = name;
   wxNode *node;
   wxLibrary *lib;
+  wxClassInfo *old_sm_first;
 
   if ( (node = m_loaded.Find(name.GetData())) )
     return ((wxLibrary *)node->Data());
 
-#if defined(__LINUX__) || defined(__SGI__)
-  lib_name.Prepend("lib");
+  // If DLL shares data, this is necessary.
+  old_sm_first = wxClassInfo::sm_first;
+  wxClassInfo::sm_first = NULL;
+
+#if defined(__UNIX__)
+  lib_name.Prepend("./lib");
   lib_name += ".so";
 
   printf("lib_name = %s\n", WXSTRINGCAST lib_name);
 
   void *handle = dlopen(WXSTRINGCAST lib_name, RTLD_LAZY);
 
+  printf("error = %s\n", dlerror());
+
   if (!handle)
     return NULL;
-#endif
-#ifdef __WINDOWS__
+#elif defined(__WINDOWS__)
   lib_name += ".dll";
 
-  HMODULE handle = LoadLibrary(lib_name);
+#ifdef UNICODE
+  HMODULE handle = LoadLibraryW(lib_name);
+#else
+#ifdef __WIN16__
+  HMODULE handle = ::LoadLibrary(lib_name);
+#else
+  HMODULE handle = LoadLibraryA(lib_name);
+#endif
+#endif
   if (!handle)
     return NULL;
+#elif defined(__WXMAC__)
+  FSSpec myFSSpec ;
+  CFragConnectionID handle ;
+  Ptr  myMainAddr ;
+  Str255       myErrName ;
+       
+  wxMacPathToFSSpec( lib_name , &myFSSpec ) ;
+  if (GetDiskFragment( &myFSSpec , 0 , kCFragGoesToEOF , "\p" , kPrivateCFragCopy , &handle , &myMainAddr ,
+    myErrName ) != noErr )
+  {
+    p2cstr( myErrName ) ;
+    wxASSERT_MSG( 1 , (char*)myErrName ) ;
+       return NULL ;
+  }
+#else
+  return NULL;
 #endif
+
   lib = new wxLibrary((void *)handle);
 
+  wxClassInfo::sm_first = old_sm_first;
+
   m_loaded.Append(name.GetData(), lib);
   return lib;
 }
@@ -148,97 +228,10 @@ wxObject *wxLibraries::CreateObject(const wxString& path)
 
   while (node) {
     obj = ((wxLibrary *)node->Data())->CreateObject(path);
-    if (obj) 
+    if (obj)
       return obj;
 
     node = node->Next();
   }
   return NULL;
 }
-
-// ---------------------------------------------------------------------------
-// wxClassLibrary (this class is used to access the internal class)
-// ---------------------------------------------------------------------------
-
-wxClassLibrary::wxClassLibrary(void)
-{
-}
-
-wxClassLibrary::~wxClassLibrary(void)
-{
-  uint i;
-
-  for (i=0;i<m_list.Count();i++)
-    delete (m_list[i]);
-}
-
-void wxClassLibrary::RegisterClass(wxClassInfo *class_info,
-                                   const wxString& path)
-{
-  wxClassLibInfo *info = new wxClassLibInfo;
-
-  info->class_info = class_info;
-  info->path = path;
-  m_list.Add(info);
-}
-
-void wxClassLibrary::UnregisterClass(wxClassInfo *class_info)
-{
-  uint i = 0;
-
-  while (i < m_list.Count()) {
-    if (m_list[i]->class_info == class_info) {
-      delete (m_list[i]);
-      m_list.Remove(i);
-      return;
-    }
-    i++;
-  }
-}
-
-bool wxClassLibrary::CreateObjects(const wxString& path,
-                                   wxArrayClassInfo& objs)
-{
-  wxClassLibInfo *info;
-  uint i = 0;
-
-  while (i < m_list.Count()) {
-    info = m_list[i];
-    if (wxMatchWild(path, info->path))
-      objs.Add(info->class_info);
-    i++;
-  }
-  return (i > 0);
-}
-
-bool wxClassLibrary::FetchInfos(const wxString& path,
-                                wxArrayClassLibInfo& infos)
-{
-  wxClassLibInfo *info;
-  uint i = 0;
-
-  while (i < m_list.Count()) {
-    info = m_list[i];
-    if (wxMatchWild(path, info->path)) {
-      wxClassLibInfo *inf = new wxClassLibInfo;
-      *inf = *info;
-      infos.Add(inf);
-    }
-    i++;
-  }
-  return (i > 0);
-}
-
-wxObject *wxClassLibrary::CreateObject(const wxString& path)
-{
-  wxClassLibInfo *info;
-  uint i = 0;
-
-  while (i < m_list.Count()) {
-    info = m_list[i];
-    if (wxMatchWild(path, info->path))
-      return info->class_info->CreateObject();
-    i++;
-  }
-  return NULL;
-}