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