Create export temporary files in the export directory
[ardour.git] / libs / ardour / control_protocol_manager.cc
1 /*
2     Copyright (C) 2000-2007 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <dlfcn.h>
21
22 #include <glibmm/fileutils.h>
23
24 #include "pbd/compose.h"
25 #include "pbd/file_utils.h"
26 #include "pbd/error.h"
27
28 #include "control_protocol/control_protocol.h"
29
30 #include "ardour/debug.h"
31 #include "ardour/control_protocol_manager.h"
32 #include "ardour/control_protocol_search_path.h"
33
34 using namespace ARDOUR;
35 using namespace std;
36 using namespace PBD;
37
38 #include "i18n.h"
39
40 ControlProtocolManager* ControlProtocolManager::_instance = 0;
41 const string ControlProtocolManager::state_node_name = X_("ControlProtocols");
42
43 ControlProtocolManager::ControlProtocolManager ()
44 {
45 }
46
47 ControlProtocolManager::~ControlProtocolManager()
48 {
49         Glib::Threads::Mutex::Lock lm (protocols_lock);
50
51         for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
52                 delete (*i);
53         }
54
55         control_protocols.clear ();
56
57
58         for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
59                 delete (*p);
60         }
61
62         control_protocol_info.clear();
63 }
64
65 void
66 ControlProtocolManager::set_session (Session* s)
67 {
68         SessionHandlePtr::set_session (s);
69
70         if (_session) {
71                 Glib::Threads::Mutex::Lock lm (protocols_lock);
72
73                 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
74                         if ((*i)->requested || (*i)->mandatory) {
75                                 instantiate (**i);
76                                 (*i)->requested = false;
77
78                                 if ((*i)->protocol) {
79                                         if ((*i)->state) {
80                                                 (*i)->protocol->set_state (*(*i)->state, Stateful::loading_state_version);
81                                         } else {
82                                                 /* guarantee a call to
83                                                    set_state() whether we have
84                                                    existing state or not
85                                                 */
86                                                 (*i)->protocol->set_state (XMLNode(""), Stateful::loading_state_version);
87                                         }
88                                 }
89                         }
90                 }
91         }
92 }
93
94 void
95 ControlProtocolManager::session_going_away()
96 {
97         SessionHandlePtr::session_going_away ();
98
99         {
100                 Glib::Threads::Mutex::Lock lm (protocols_lock);
101
102                 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
103                         delete *p;
104                 }
105
106                 control_protocols.clear ();
107
108                 for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
109                         // mark existing protocols as requested
110                         // otherwise the ControlProtocol instances are not recreated in set_session
111                         if ((*p)->protocol) {
112                                 (*p)->requested = true;
113                                 (*p)->protocol = 0;
114                         }
115                 }
116         }
117 }
118
119 ControlProtocol*
120 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
121 {
122         /* CALLER MUST HOLD LOCK */
123
124         if (_session == 0) {
125                 return 0;
126         }
127
128         cpi.descriptor = get_descriptor (cpi.path);
129
130         if (cpi.descriptor == 0) {
131                 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
132                 return 0;
133         }
134
135         if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) {
136                 error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg;
137                 return 0;
138         }
139
140         control_protocols.push_back (cpi.protocol);
141
142         ProtocolStatusChange (&cpi);
143
144         return cpi.protocol;
145 }
146
147 int
148 ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
149 {
150         if (!cpi.protocol) {
151                 return 0;
152         }
153
154         if (!cpi.descriptor) {
155                 return 0;
156         }
157
158         if (cpi.mandatory) {
159                 return 0;
160         }
161
162         cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
163
164         {
165                 Glib::Threads::Mutex::Lock lm (protocols_lock);
166                 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
167                 if (p != control_protocols.end()) {
168                         control_protocols.erase (p);
169                 } else {
170                         cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
171                 }
172         }
173
174         cpi.protocol = 0;
175         delete cpi.state;
176         cpi.state = 0;
177         dlclose (cpi.descriptor->module);
178
179         ProtocolStatusChange (&cpi);
180
181         return 0;
182 }
183
184 void
185 ControlProtocolManager::load_mandatory_protocols ()
186 {
187         if (_session == 0) {
188                 return;
189         }
190
191         Glib::Threads::Mutex::Lock lm (protocols_lock);
192
193         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
194                 if ((*i)->mandatory && ((*i)->protocol == 0)) {
195                         DEBUG_TRACE (DEBUG::ControlProtocols,
196                                      string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
197                         instantiate (**i);
198                 }
199         }
200 }
201
202 void
203 ControlProtocolManager::discover_control_protocols ()
204 {
205         vector<std::string> cp_modules;
206
207         Glib::PatternSpec so_extension_pattern("*.so");
208         Glib::PatternSpec dylib_extension_pattern("*.dylib");
209
210         find_matching_files_in_search_path (control_protocol_search_path (),
211                                             so_extension_pattern, cp_modules);
212
213         find_matching_files_in_search_path (control_protocol_search_path (),
214                                             dylib_extension_pattern, cp_modules);
215
216         DEBUG_TRACE (DEBUG::ControlProtocols, 
217                      string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
218         
219         for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
220                 control_protocol_discover (*i);
221         }
222 }
223
224 int
225 ControlProtocolManager::control_protocol_discover (string path)
226 {
227         ControlProtocolDescriptor* descriptor;
228
229 #ifdef __APPLE__
230         /* don't load OS X shared objects that are just symlinks to the real thing.
231          */
232
233         if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
234                 return 0;
235         }
236 #endif
237
238         if ((descriptor = get_descriptor (path)) != 0) {
239
240                 if (!descriptor->probe (descriptor)) {
241                         DEBUG_TRACE (DEBUG::ControlProtocols,
242                                      string_compose (_("Control protocol %1 not usable"), descriptor->name));
243                 } else {
244
245                         ControlProtocolInfo* cpi = new ControlProtocolInfo ();
246
247                         cpi->descriptor = descriptor;
248                         cpi->name = descriptor->name;
249                         cpi->path = path;
250                         cpi->protocol = 0;
251                         cpi->requested = false;
252                         cpi->mandatory = descriptor->mandatory;
253                         cpi->supports_feedback = descriptor->supports_feedback;
254                         cpi->state = 0;
255
256                         control_protocol_info.push_back (cpi);
257
258                         DEBUG_TRACE (DEBUG::ControlProtocols, 
259                                      string_compose(_("Control surface protocol discovered: \"%1\""), cpi->name));
260                 }
261
262                 dlclose (descriptor->module);
263         }
264
265         return 0;
266 }
267
268 ControlProtocolDescriptor*
269 ControlProtocolManager::get_descriptor (string path)
270 {
271         void *module;
272         ControlProtocolDescriptor *descriptor = 0;
273         ControlProtocolDescriptor* (*dfunc)(void);
274         const char *errstr;
275
276         if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
277                 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
278                 return 0;
279         }
280
281
282         dfunc = (ControlProtocolDescriptor* (*)(void)) dlsym (module, "protocol_descriptor");
283
284         if ((errstr = dlerror()) != 0) {
285                 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
286                 error << errstr << endmsg;
287                 dlclose (module);
288                 return 0;
289         }
290
291         descriptor = dfunc();
292         if (descriptor) {
293                 descriptor->module = module;
294         } else {
295                 dlclose (module);
296         }
297
298         return descriptor;
299 }
300
301 void
302 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
303 {
304         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
305                 method (*i);
306         }
307 }
308
309 ControlProtocolInfo*
310 ControlProtocolManager::cpi_by_name (string name)
311 {
312         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
313                 if (name == (*i)->name) {
314                         return *i;
315                 }
316         }
317         return 0;
318 }
319
320 int
321 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
322 {
323         XMLNodeList clist;
324         XMLNodeConstIterator citer;
325         XMLProperty* prop;
326
327         Glib::Threads::Mutex::Lock lm (protocols_lock);
328
329         clist = node.children();
330
331         for (citer = clist.begin(); citer != clist.end(); ++citer) {
332                 if ((*citer)->name() == X_("Protocol")) {
333
334                         if ((prop = (*citer)->property (X_("active"))) == 0) {
335                                 continue;
336                         }
337
338                         bool active = string_is_affirmative (prop->value());
339                         
340                         if ((prop = (*citer)->property (X_("name"))) == 0) {
341                                 continue;
342                         }
343
344                         ControlProtocolInfo* cpi = cpi_by_name (prop->value());
345                         
346                         if (cpi) {
347                                 
348                                 if (!(*citer)->children().empty()) {
349                                         cpi->state = new XMLNode (*((*citer)->children().front ()));
350                                 } else {
351                                         cpi->state = 0;
352                                 }
353                                 
354                                 if (active) {
355                                         if (_session) {
356                                                 instantiate (*cpi);
357                                         } else {
358                                                 cpi->requested = true;
359                                         }
360                                 } else {
361                                         if (_session) {
362                                                 teardown (*cpi);
363                                         } else {
364                                                 cpi->requested = false;
365                                         }
366                                 }
367                         }
368                 }
369         }
370
371         return 0;
372 }
373
374 XMLNode&
375 ControlProtocolManager::get_state ()
376 {
377         XMLNode* root = new XMLNode (state_node_name);
378         Glib::Threads::Mutex::Lock lm (protocols_lock);
379
380         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
381
382                 XMLNode * child;
383
384                 if ((*i)->protocol) {
385                         child = &((*i)->protocol->get_state());
386                         child->add_property (X_("active"), "yes");
387                         // should we update (*i)->state here?  probably.
388                         root->add_child_nocopy (*child);
389                 } else if ((*i)->state) {
390                         // keep ownership clear
391                         root->add_child_copy (*(*i)->state);
392                 } else {
393                         child = new XMLNode (X_("Protocol"));
394                         child->add_property (X_("name"), (*i)->name);
395                         child->add_property (X_("active"), "no");
396                         root->add_child_nocopy (*child);
397                 }
398         }
399
400         return *root;
401 }
402
403
404 ControlProtocolManager&
405 ControlProtocolManager::instance ()
406 {
407         if (_instance == 0) {
408                 _instance = new ControlProtocolManager ();
409         }
410
411         return *_instance;
412 }
413
414 void
415 ControlProtocolManager::midi_connectivity_established ()
416 {
417         Glib::Threads::Mutex::Lock lm (protocols_lock);
418
419         for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
420                 (*p)->midi_connectivity_established ();
421         }
422 }