/[svn]/linuxsampler/trunk/src/plugins/InstrumentEditorFactory.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/plugins/InstrumentEditorFactory.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1374 by schoenebeck, Wed Oct 3 18:37:56 2007 UTC revision 1653 by schoenebeck, Wed Jan 30 01:51:46 2008 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2007 Christian Schoenebeck                              *   *   Copyright (C) 2007, 2008 Christian Schoenebeck                        *
4   *                                                                         *   *                                                                         *
5   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
6   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 20  Line 20 
20    
21  #include "InstrumentEditorFactory.h"  #include "InstrumentEditorFactory.h"
22    
23    #include "../common/global_private.h"
24    
25    #if defined(WIN32)
26    #include <windows.h>
27    #else
28  #include <dlfcn.h>  #include <dlfcn.h>
29  #include <errno.h>  #include <errno.h>
 #include <string.h>  
30  #include <dirent.h>  #include <dirent.h>
31    #include <sys/types.h>
32    #include <sys/stat.h>
33    #include <unistd.h>
34    #endif
35    #include <string.h>
36    
37  #ifndef CONFIG_PLUGIN_DIR  #ifndef CONFIG_PLUGIN_DIR
38  # error "Configuration macro CONFIG_PLUGIN_DIR not defined!"  # error "Configuration macro CONFIG_PLUGIN_DIR not defined!"
39  #endif // CONFIG_PLUGIN_DIR  #endif // CONFIG_PLUGIN_DIR
40    
41    #if defined(WIN32)
42    typedef void* (*InnerFactoryRegisterFunction)(void);
43    #endif
44    
45  namespace LinuxSampler {  namespace LinuxSampler {
46    
47      std::map<String, InstrumentEditorFactory::InnerFactory*> InstrumentEditorFactory::InnerFactories;      std::map<String, InstrumentEditorFactory::InnerFactory*> InstrumentEditorFactory::InnerFactories;
# Line 91  namespace LinuxSampler { Line 104  namespace LinuxSampler {
104      void InstrumentEditorFactory::LoadPlugins() {      void InstrumentEditorFactory::LoadPlugins() {
105          if (!bPluginsLoaded) {          if (!bPluginsLoaded) {
106              dmsg(1,("Loading instrument editor plugins..."));              dmsg(1,("Loading instrument editor plugins..."));
107                #if defined(WIN32)
108                WIN32_FIND_DATA win32FindData;
109                const String plugindir = (String)CONFIG_PLUGIN_DIR + (String)("\\*.DLL");
110                HANDLE hDir = FindFirstFile(plugindir.c_str(), &win32FindData);
111                if (hDir == INVALID_HANDLE_VALUE) {
112                    if (GetLastError() != ERROR_FILE_NOT_FOUND) {
113                        std::cerr << "Could not open instrument editor plugins "
114                                  << "directory (" << CONFIG_PLUGIN_DIR << "), "
115                                  << "Error: " << GetLastError() << std::endl;
116                    } else {
117                        dmsg(1,("None"));
118                    }
119                    // either dir doesn't exist or is empty
120                    return;
121                }
122    
123                do {
124                    // skip directory entries
125                    if (win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
126                        continue;
127                    // dir entry name as full qualified path
128                    const String sPath = (String)CONFIG_PLUGIN_DIR + ((String)"\\" + (String)win32FindData.cFileName);
129                    // load the DLL
130                    HINSTANCE hinstLib;
131                    void* pDLL = hinstLib = LoadLibrary(sPath.c_str());
132                    if (!pDLL) {
133                        std::cerr << "Failed to load instrument editor plugin: "
134                                  << sPath << std::endl;
135                        continue;
136                    }
137    
138                    //(InnerFactory*) (*fn)(void);
139                    InnerFactoryRegisterFunction fn =
140                        (InnerFactoryRegisterFunction)
141                            GetProcAddress(
142                                hinstLib,
143                                "createInstrumentEditorInnerFactory"
144                            );
145                    if (fn == NULL) {
146                        std::cerr << "ERROR: unable to find "
147                                     "createInstrumentEditorInnerFactory() "
148                                     "in DLL\n" << std::flush;
149                        FreeLibrary(hinstLib);
150                        continue;
151                    }
152    
153                    // get the plugin instance and register it to the factory
154    
155                    InnerFactory* pInnerFactory = (InnerFactory*)fn();
156                    if (!pInnerFactory) {
157                        std::cerr << "ERROR: !pInnerFactory\n" << std::flush;
158                        FreeLibrary(hinstLib);
159                        continue;
160                    }
161                    InstrumentEditor* pEditor = pInnerFactory->Create();
162                    if (InnerFactories.count(pEditor->Name())) {
163                        std::cerr << "ERROR: a plugin with name '"
164                                  << pEditor->Name()
165                                  << "' already loaded (skipping)\n"
166                                  << std::flush;
167                        pInnerFactory->Destroy(pEditor);
168                        FreeLibrary(hinstLib);
169                        continue;
170                    }
171                    InnerFactories[pEditor->Name()] = pInnerFactory;
172                    pInnerFactory->Destroy(pEditor);
173    
174                    LoadedDLLs.push_back(pDLL);
175                } while (FindNextFile(hDir, &win32FindData));
176                if (hDir != INVALID_HANDLE_VALUE) FindClose(hDir);
177                #else // POSIX
178                            #if defined(__APPLE__)  /*  20071224 Toshi Nagata  */
179                            String Config_plugin_dir = (String)CONFIG_PLUGIN_DIR;
180                            if (Config_plugin_dir.find("~") == 0)
181                                       Config_plugin_dir.replace(0, 1, getenv("HOME"));
182                            DIR* hDir = opendir(Config_plugin_dir.c_str());
183                            #else
184              DIR* hDir = opendir(CONFIG_PLUGIN_DIR);              DIR* hDir = opendir(CONFIG_PLUGIN_DIR);
185                            #endif
186              if (!hDir) {              if (!hDir) {
187                  std::cerr << "Could not open instrument editor plugins directory "                  std::cerr << "Could not open instrument editor plugins directory "
188                            << "(" << CONFIG_PLUGIN_DIR << "): "                            << "(" << CONFIG_PLUGIN_DIR << "): "
# Line 99  namespace LinuxSampler { Line 190  namespace LinuxSampler {
190                  return;                  return;
191              }              }
192              for (dirent* pEntry = readdir(hDir); pEntry; pEntry = readdir(hDir)) {              for (dirent* pEntry = readdir(hDir); pEntry; pEntry = readdir(hDir)) {
193                    // dir entry name as full qualified path
194                            #if defined(__APPLE__)  /*  20080110 Toshi Nagata  */
195                    const String sPath = Config_plugin_dir + ("/" + String(pEntry->d_name));
196                            #else
197                    const String sPath = CONFIG_PLUGIN_DIR + ("/" + String(pEntry->d_name));
198                            #endif
199                  // skip entries that are not regular files                  // skip entries that are not regular files
200                  if (pEntry->d_type != DT_REG) continue;                  struct stat entry_stat;
201                  String sPath = pEntry->d_name;                  if (lstat(sPath.c_str(), &entry_stat) != 0 ||
202                       (entry_stat.st_mode & S_IFMT) != S_IFREG)
203                       continue;
204                  // skip files that are not .so files                  // skip files that are not .so files
205                  if (                  if (sPath.length() < 3 ||
206                      sPath.substr(sPath.length() - 3) != ".so" &&                      sPath.substr(sPath.length() - 3) != ".so" &&
207                      sPath.find(".so.") == String::npos                      sPath.find(".so.") == String::npos
208                  ) continue;                  ) continue;
                 // make it a full qualified path  
                 sPath = CONFIG_PLUGIN_DIR + ("/" + sPath);  
209                  // load the DLL (the plugins should register themselfes automatically)                  // load the DLL (the plugins should register themselfes automatically)
210                  void* pDLL = dlopen(sPath.c_str(), RTLD_NOW);                  void* pDLL = dlopen(sPath.c_str(), RTLD_NOW);
211                  if (pDLL) LoadedDLLs.push_back(pDLL);                  if (pDLL) LoadedDLLs.push_back(pDLL);
212                  else {                  else {
213                      std::cerr << "Failed to load instrument editor plugin: "                      std::cerr << "Failed to load instrument editor plugin: '"
214                                << sPath << std::endl;                                << sPath << "', cause: " << dlerror() << std::endl;
215                  }                  }
216              }              }
217              closedir(hDir);              closedir(hDir);
218                #endif
219              bPluginsLoaded = true;              bPluginsLoaded = true;
220              dmsg(1,("OK\n"));              dmsg(1,("OK\n"));
221          }          }
# Line 135  namespace LinuxSampler { Line 233  namespace LinuxSampler {
233              // free the DLLs              // free the DLLs
234              {              {
235                  std::list<void*>::iterator iter = LoadedDLLs.begin();                  std::list<void*>::iterator iter = LoadedDLLs.begin();
236                  for (; iter != LoadedDLLs.end(); iter++) dlclose(*iter);                  for (; iter != LoadedDLLs.end(); iter++) {
237                        #if defined(WIN32)
238                        FreeLibrary((HINSTANCE)*iter);
239                        #else
240                        dlclose(*iter);
241                        #endif
242                    }
243                  LoadedDLLs.clear();                  LoadedDLLs.clear();
244                  dmsg(1,("OK\n"));                  dmsg(1,("OK\n"));
245              }              }

Legend:
Removed from v.1374  
changed lines
  Added in v.1653

  ViewVC Help
Powered by ViewVC