~ubuntu-branches/ubuntu/gutsy/audacity/gutsy-backports

« back to all changes in this revision

Viewing changes to src/LoadModules.cpp

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-18 21:58:19 UTC
  • mfrom: (13.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080218215819-tmbcf1rx238r8gdv
Tags: 1.3.4-1.1ubuntu1~gutsy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
 
 
3
  Audacity: A Digital Audio Editor
 
4
 
 
5
  LoadModules.cpp
 
6
 
 
7
  Dominic Mazzoni
 
8
  James Crook
 
9
 
 
10
 
 
11
*******************************************************************//*!
 
12
 
 
13
\file LoadModules.cpp
 
14
\brief Based on LoadLadspa, this code loads pluggable Audacity 
 
15
extension modules.  It also has the code to (a) invoke a script
 
16
server and (b) invoke a function returning a replacement window,
 
17
i.e. an alternative to the usual interface, for Audacity.
 
18
 
 
19
*//*******************************************************************/
 
20
 
 
21
#include <wx/dynlib.h>
 
22
#include <wx/list.h>
 
23
#include <wx/log.h>
 
24
#include <wx/string.h>
 
25
 
 
26
#include "Audacity.h"
 
27
#include "AudacityApp.h"
 
28
#include "Internat.h"
 
29
#include "BatchCommands.h"
 
30
#include "../lib-src/lib-widget-extra/NonGuiThread.h"
 
31
 
 
32
#define initFnName      "ExtensionModuleInit"
 
33
#define scriptFnName    "RegScriptServerFunc"
 
34
#define mainPanelFnName "MainPanelFunc"
 
35
 
 
36
typedef _declspec( dllimport) int (*tModuleInit)(int);
 
37
typedef _declspec( dllimport) wxWindow * (*tPanelFn)(int);
 
38
 
 
39
// This variable will hold the address of a subroutine in 
 
40
// a DLL that can hijack the normal panel.
 
41
tPanelFn pPanelHijack=NULL;
 
42
 
 
43
// Next two commented out lines are handy when investigating
 
44
// strange DLL behaviour.  Instead of dynamic linking,
 
45
// link the library which has the replacement panel statically.
 
46
// Give the address of the routine here.
 
47
// This is a great help in identifying missing 
 
48
// symbols which otherwise cause a dll to unload after loading
 
49
// without an explanation as to why!
 
50
//extern wxWindow * MainPanelFunc( int i );
 
51
//tPanelFn pPanelHijack=&MainPanelFunc;
 
52
 
 
53
/// IF pPanelHijack has been found in a module DLL
 
54
/// THEN when this function is called we'll go and
 
55
/// create that window instead of the normal one.
 
56
wxWindow * MakeHijackPanel()
 
57
{
 
58
   if( pPanelHijack == NULL )
 
59
      return NULL;
 
60
   return pPanelHijack(0);
 
61
}
 
62
 
 
63
//------- Start of stuff related to invoking a batch command ----
 
64
// Our DLL may call commands back in Audacity.
 
65
// It will do that through the ExecCommand function.
 
66
extern "C" {
 
67
 
 
68
typedef __declspec( dllexport) int (*tpExecScriptServerFunc)( wxString * pOut, wxString * pIn);
 
69
typedef __declspec( dllimport) int (*tpRegScriptServerFunc)(tpExecScriptServerFunc pFn);
 
70
 
 
71
// This is the function which actually obeys one command.
 
72
__declspec( dllexport) int ExecCommand( wxString * pOut, wxString * pIn )
 
73
{
 
74
   // Create a Batch that will have just one command in it...
 
75
   BatchCommands Batch;
 
76
   bool rc;
 
77
 
 
78
   // Find the command name terminator...ingore line if not found
 
79
   int splitAt = pIn->Find(wxT(':'));
 
80
   if (splitAt < 0) {
 
81
      *pOut= wxT("BAD - Missing ':'?");
 
82
      return false;
 
83
   }
 
84
 
 
85
   // Parse and clean
 
86
   wxString cmd = pIn->Left(splitAt).Strip(wxString::both);
 
87
   wxString parm = pIn->Mid(splitAt + 1).Strip(wxString::trailing);
 
88
 
 
89
   rc = Batch.ApplyCommand( cmd, parm );
 
90
   if( rc )
 
91
   {
 
92
      *pOut = wxT("OK");
 
93
      return rc;
 
94
   }
 
95
   *pOut = wxT("FAILED to Execute");
 
96
   return rc;
 
97
}
 
98
}
 
99
 
 
100
// This variable will hold the address of a subroutine in
 
101
// a DLL that starts a thread and reads script commands.
 
102
tpRegScriptServerFunc scriptFn = NULL;
 
103
 
 
104
// We pass the ExecFunction to any scripting DLL that needs it
 
105
// right here.
 
106
void RegisterAndRun(  )
 
107
{
 
108
   wxASSERT( scriptFn != NULL );
 
109
   while( true )
 
110
      scriptFn(&ExecCommand);
 
111
}
 
112
 
 
113
//------- End of stuff related to invoking a batch command ----
 
114
 
 
115
void LoadModule(wxString fname)
 
116
{
 
117
   wxLogDebug(wxT("About to load %s"), fname );
 
118
   wxLogNull logNo;
 
119
   tModuleInit mainFn = NULL;
 
120
 
 
121
   // As a courtesy to some modules that might be bridges to
 
122
   // open other modules, we set the current working
 
123
   // directory to be the module's directory.
 
124
 
 
125
   wxString saveOldCWD = ::wxGetCwd();
 
126
   wxString prefix = ::wxPathOnly(fname);
 
127
   ::wxSetWorkingDirectory(prefix);
 
128
 
 
129
   wxDynamicLibrary* pDLL = new wxDynamicLibrary();
 
130
   if (pDLL && pDLL->Load(fname, wxDL_LAZY)) 
 
131
   {
 
132
      int result =1;
 
133
      mainFn   = (tModuleInit)(pDLL->GetSymbol(wxT(initFnName)));
 
134
 
 
135
      if (mainFn) 
 
136
         result = mainFn( 0 );
 
137
 
 
138
      if(( scriptFn == NULL ) &&(result>=0 ))
 
139
         scriptFn = (tpRegScriptServerFunc)(pDLL->GetSymbol(wxT(scriptFnName)));
 
140
 
 
141
      if((pPanelHijack==NULL ) && (result>=0))
 
142
         pPanelHijack = (tPanelFn)(pDLL->GetSymbol(wxT(mainPanelFnName)));
 
143
   }
 
144
 
 
145
   ::wxSetWorkingDirectory(saveOldCWD);
 
146
}
 
147
 
 
148
void LoadModules()
 
149
{
 
150
   wxArrayString audacityPathList = wxGetApp().audacityPathList;
 
151
   wxArrayString pathList;
 
152
   wxArrayString files;
 
153
   wxString pathVar;
 
154
   unsigned int i;
 
155
 
 
156
#if 0
 
157
   // Code from LoadLadspa that might be useful in load modules.
 
158
   pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
 
159
   if (pathVar != wxT(""))
 
160
      wxGetApp().AddMultiPathsToPathList(pathVar, pathList);
 
161
 
 
162
   #ifdef __WXGTK__
 
163
   wxGetApp().AddUniquePathToPathList(INSTALL_PREFIX wxT("/modules"), pathList);
 
164
   wxGetApp().AddUniquePathToPathList(wxT("/usr/local/lib/modules"), pathList);
 
165
   wxGetApp().AddUniquePathToPathList(wxT("/usr/lib/modules"), pathList);
 
166
   #endif
 
167
#endif
 
168
 
 
169
   for(i=0; i<audacityPathList.GetCount(); i++) {
 
170
      wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
 
171
      wxGetApp().AddUniquePathToPathList(prefix + wxT("modules"),
 
172
                                         pathList);
 
173
   }
 
174
 
 
175
   #ifdef __WXMSW__
 
176
   wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, wxFILE, files);   
 
177
   #else
 
178
   wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, wxFILE, files);
 
179
   #endif
 
180
 
 
181
   for(i=0; i<files.GetCount(); i++)
 
182
      LoadModule(files[i]);
 
183
   // After loading all the modules, we may have a registered scripting function.
 
184
   if( scriptFn )
 
185
   {
 
186
      NonGuiThread::StartChild( &RegisterAndRun );
 
187
   }
 
188
}
 
189
 
 
190
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
 
191
// version control system. Please do not modify past this point.
 
192
//
 
193
// Local Variables:
 
194
// c-basic-offset: 3
 
195
// indent-tabs-mode: nil
 
196
// End:
 
197
//
 
198
// vim: et sts=3 sw=3
 
199
 
 
200