send a slightly more useful message if a control protocol's probe() method fails
[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 <glibmm/module.h>
21
22 #include <glibmm/fileutils.h>
23
24 #include "pbd/compose.h"
25 #include "pbd/event_loop.h"
26 #include "pbd/file_utils.h"
27 #include "pbd/error.h"
28
29 #include "control_protocol/control_protocol.h"
30
31 #include "ardour/debug.h"
32 #include "ardour/control_protocol_manager.h"
33
34 #include "ardour/search_paths.h"
35
36
37 using namespace ARDOUR;
38 using namespace std;
39 using namespace PBD;
40
41 #include "pbd/i18n.h"
42
43 ControlProtocolManager* ControlProtocolManager::_instance = 0;
44 const string ControlProtocolManager::state_node_name = X_("ControlProtocols");
45
46
47 ControlProtocolInfo::~ControlProtocolInfo ()
48 {
49         if (protocol && descriptor) {
50                 descriptor->destroy (descriptor, protocol);
51                 protocol = 0;
52         }
53
54         delete state; state = 0;
55
56         if (descriptor) {
57                 delete (Glib::Module*) descriptor->module;
58                 descriptor = 0;
59         }
60 }
61
62 ControlProtocolManager::ControlProtocolManager ()
63 {
64 }
65
66 ControlProtocolManager::~ControlProtocolManager()
67 {
68         Glib::Threads::Mutex::Lock lm (protocols_lock);
69
70         for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
71                 delete (*i);
72         }
73
74         control_protocols.clear ();
75
76
77         for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
78                 delete (*p);
79         }
80
81         control_protocol_info.clear();
82 }
83
84 void
85 ControlProtocolManager::set_session (Session* s)
86 {
87         SessionHandlePtr::set_session (s);
88
89         if (_session) {
90                 Glib::Threads::Mutex::Lock lm (protocols_lock);
91
92                 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
93                         if ((*i)->requested || (*i)->mandatory) {
94                                 (void) activate (**i);
95                         }
96                 }
97         }
98 }
99
100 int
101 ControlProtocolManager::activate (ControlProtocolInfo& cpi)
102 {
103         ControlProtocol* cp;
104
105         cpi.requested = true;
106
107         if ((cp = instantiate (cpi)) == 0) {
108                 return -1;
109         }
110
111         /* we split the set_state() and set_active() operations so that
112            protocols that need state to configure themselves (e.g. "What device
113            is connected, or supposed to be connected?") can get it before
114            actually starting any interaction.
115         */
116
117         if (cpi.state) {
118                 /* force this by tweaking the internals of the state
119                  * XMLNode. Ugh.
120                  */
121                 cp->set_state (*cpi.state, Stateful::loading_state_version);
122         } else {
123                 /* guarantee a call to
124                    set_state() whether we have
125                    existing state or not
126                 */
127                 cp->set_state (XMLNode(""), Stateful::loading_state_version);
128         }
129
130         cp->set_active (true);
131
132         return 0;
133 }
134
135 int
136 ControlProtocolManager::deactivate (ControlProtocolInfo& cpi)
137 {
138         cpi.requested = false;
139         return teardown (cpi);
140 }
141
142 void
143 ControlProtocolManager::session_going_away()
144 {
145         SessionHandlePtr::session_going_away ();
146         /* Session::destroy() will explicitly call drop_protocols() so we don't
147          * have to worry about that here.
148          */
149 }
150
151 void
152 ControlProtocolManager::drop_protocols ()
153 {
154         /* called explicitly by Session::destroy() so that we can clean up
155          * before the process cycle stops and ports vanish.
156          */
157
158         Glib::Threads::Mutex::Lock lm (protocols_lock);
159
160         for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
161                 delete *p;
162         }
163
164         control_protocols.clear ();
165
166         for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
167                 // mark existing protocols as requested
168                 // otherwise the ControlProtocol instances are not recreated in set_session
169                 if ((*p)->protocol) {
170                         (*p)->requested = true;
171                         (*p)->protocol = 0;
172                 }
173         }
174 }
175
176 ControlProtocol*
177 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
178 {
179         /* CALLER MUST HOLD LOCK */
180
181         if (_session == 0) {
182                 return 0;
183         }
184
185         cpi.descriptor = get_descriptor (cpi.path);
186
187         DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
188
189         if (cpi.descriptor == 0) {
190                 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
191                 return 0;
192         }
193
194         DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
195
196         if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) {
197                 error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg;
198                 return 0;
199         }
200
201         control_protocols.push_back (cpi.protocol);
202
203         ProtocolStatusChange (&cpi);
204
205         return cpi.protocol;
206 }
207
208 int
209 ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
210 {
211         if (!cpi.protocol) {
212
213                 /* we could still have a descriptor even if the protocol was
214                    never instantiated. Close the associated module (shared
215                    object/DLL) and make sure we forget about it.
216                 */
217
218                 if (cpi.descriptor) {
219                         cerr << "Closing descriptor for CPI anyway\n";
220                         delete (Glib::Module*) cpi.descriptor->module;
221                         cpi.descriptor = 0;
222                 }
223
224                 return 0;
225         }
226
227         if (!cpi.descriptor) {
228                 return 0;
229         }
230
231         if (cpi.mandatory) {
232                 return 0;
233         }
234
235         /* save current state */
236
237         delete cpi.state;
238         cpi.state = new XMLNode (cpi.protocol->get_state());
239         cpi.state->add_property (X_("active"), "no");
240
241         cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
242
243         {
244                 Glib::Threads::Mutex::Lock lm (protocols_lock);
245                 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
246                 if (p != control_protocols.end()) {
247                         control_protocols.erase (p);
248                 } else {
249                         cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
250                 }
251         }
252
253         cpi.protocol = 0;
254
255         delete cpi.state;
256         cpi.state = 0;
257         delete (Glib::Module*) cpi.descriptor->module;
258         /* cpi->descriptor is now inaccessible since dlclose() or equivalent
259          * has been performed, and the descriptor is (or could be) a static
260          * object made accessible by dlopen().
261          */
262         cpi.descriptor = 0;
263
264         ProtocolStatusChange (&cpi);
265
266         return 0;
267 }
268
269 void
270 ControlProtocolManager::load_mandatory_protocols ()
271 {
272         if (_session == 0) {
273                 return;
274         }
275
276         Glib::Threads::Mutex::Lock lm (protocols_lock);
277
278         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
279                 if ((*i)->mandatory && ((*i)->protocol == 0)) {
280                         DEBUG_TRACE (DEBUG::ControlProtocols,
281                                      string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
282                         instantiate (**i);
283                 }
284         }
285 }
286
287 void
288 ControlProtocolManager::discover_control_protocols ()
289 {
290         vector<std::string> cp_modules;
291
292 #ifdef COMPILER_MSVC
293    /**
294     * Different build targets (Debug / Release etc) use different versions
295     * of the 'C' runtime (which can't be 'mixed & matched'). Therefore, in
296     * case the supplied search path contains multiple version(s) of a given
297     * module, only select the one(s) which match the current build target
298     */
299         #if defined (_DEBUG)
300                 Glib::PatternSpec dll_extension_pattern("*D.dll");
301         #elif defined (RDC_BUILD)
302                 Glib::PatternSpec dll_extension_pattern("*RDC.dll");
303         #elif defined (_WIN64)
304                 Glib::PatternSpec dll_extension_pattern("*64.dll");
305         #else
306                 Glib::PatternSpec dll_extension_pattern("*32.dll");
307         #endif
308 #else
309         Glib::PatternSpec dll_extension_pattern("*.dll");
310 #endif
311
312         Glib::PatternSpec so_extension_pattern("*.so");
313         Glib::PatternSpec dylib_extension_pattern("*.dylib");
314
315         find_files_matching_pattern (cp_modules, control_protocol_search_path (),
316                                      dll_extension_pattern);
317
318         find_files_matching_pattern (cp_modules, control_protocol_search_path (),
319                                      so_extension_pattern);
320
321         find_files_matching_pattern (cp_modules, control_protocol_search_path (),
322                                      dylib_extension_pattern);
323
324         DEBUG_TRACE (DEBUG::ControlProtocols,
325                      string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
326
327         for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
328                 control_protocol_discover (*i);
329         }
330 }
331
332 int
333 ControlProtocolManager::control_protocol_discover (string path)
334 {
335         ControlProtocolDescriptor* descriptor;
336
337 #ifdef __APPLE__
338         /* don't load OS X shared objects that are just symlinks to the real thing.
339          */
340
341         if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
342                 return 0;
343         }
344 #endif
345
346         if ((descriptor = get_descriptor (path)) != 0) {
347
348                 if (!descriptor->probe (descriptor)) {
349                         warning << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg;
350                 } else {
351
352                         ControlProtocolInfo* cpi = new ControlProtocolInfo ();
353
354                         cpi->descriptor = descriptor;
355                         cpi->name = descriptor->name;
356                         cpi->path = path;
357                         cpi->protocol = 0;
358                         cpi->requested = false;
359                         cpi->mandatory = descriptor->mandatory;
360                         cpi->supports_feedback = descriptor->supports_feedback;
361                         cpi->state = 0;
362
363                         control_protocol_info.push_back (cpi);
364
365                         DEBUG_TRACE (DEBUG::ControlProtocols,
366                                      string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
367                 }
368         }
369
370         return 0;
371 }
372
373 ControlProtocolDescriptor*
374 ControlProtocolManager::get_descriptor (string path)
375 {
376         Glib::Module* module = new Glib::Module(path);
377         ControlProtocolDescriptor *descriptor = 0;
378         ControlProtocolDescriptor* (*dfunc)(void);
379         void* func = 0;
380
381         if (!(*module)) {
382                 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
383                 delete module;
384                 return 0;
385         }
386
387         if (!module->get_symbol("protocol_descriptor", func)) {
388                 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
389                 error << Glib::Module::get_last_error() << endmsg;
390                 delete module;
391                 return 0;
392         }
393
394         dfunc = (ControlProtocolDescriptor* (*)(void))func;
395         descriptor = dfunc();
396
397         if (descriptor) {
398                 descriptor->module = (void*)module;
399         }
400
401         return descriptor;
402 }
403
404 void
405 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
406 {
407         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
408                 method (*i);
409         }
410 }
411
412 ControlProtocolInfo*
413 ControlProtocolManager::cpi_by_name (string name)
414 {
415         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
416                 if (name == (*i)->name) {
417                         return *i;
418                 }
419         }
420         return 0;
421 }
422
423 int
424 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
425 {
426         XMLNodeList clist;
427         XMLNodeConstIterator citer;
428         XMLProperty const * prop;
429
430         Glib::Threads::Mutex::Lock lm (protocols_lock);
431
432         clist = node.children();
433
434         for (citer = clist.begin(); citer != clist.end(); ++citer) {
435                 XMLNode const * child = *citer;
436
437                 if (child->name() == X_("Protocol")) {
438
439                         if ((prop = child->property (X_("active"))) == 0) {
440                                 continue;
441                         }
442
443                         bool active = string_is_affirmative (prop->value());
444
445                         if ((prop = child->property (X_("name"))) == 0) {
446                                 continue;
447                         }
448
449                         ControlProtocolInfo* cpi = cpi_by_name (prop->value());
450
451                         if (cpi) {
452                                 delete cpi->state;
453                                 cpi->state = new XMLNode (**citer);
454
455                                 std::cerr << "protocol " << prop->value() << " active ? " << active << std::endl;
456
457                                 if (active) {
458                                         if (_session) {
459                                                 instantiate (*cpi);
460                                         } else {
461                                                 cpi->requested = true;
462                                         }
463                                 } else {
464                                         if (_session) {
465                                                 teardown (*cpi);
466                                         } else {
467                                                 cpi->requested = false;
468                                         }
469                                 }
470                         } else {
471                                 std::cerr << "protocol " << prop->value() << " not found\n";
472                         }
473                 }
474         }
475
476         return 0;
477 }
478
479 XMLNode&
480 ControlProtocolManager::get_state ()
481 {
482         XMLNode* root = new XMLNode (state_node_name);
483         Glib::Threads::Mutex::Lock lm (protocols_lock);
484
485         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
486
487                 if ((*i)->protocol) {
488                         XMLNode& child_state ((*i)->protocol->get_state());
489                         child_state.add_property (X_("active"), "yes");
490                         root->add_child_nocopy (child_state);
491                 } else if ((*i)->state) {
492                         XMLNode* child_state = new XMLNode (*(*i)->state);
493                         child_state->add_property (X_("active"), "no");
494                         root->add_child_nocopy (*child_state);
495                 } else {
496                         XMLNode* child_state = new XMLNode (X_("Protocol"));
497                         child_state->add_property (X_("name"), (*i)->name);
498                         child_state->add_property (X_("active"), "no");
499                         root->add_child_nocopy (*child_state);
500                 }
501
502         }
503
504         return *root;
505 }
506
507
508 ControlProtocolManager&
509 ControlProtocolManager::instance ()
510 {
511         if (_instance == 0) {
512                 _instance = new ControlProtocolManager ();
513         }
514
515         return *_instance;
516 }
517
518 void
519 ControlProtocolManager::midi_connectivity_established ()
520 {
521         Glib::Threads::Mutex::Lock lm (protocols_lock);
522
523         for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
524                 (*p)->midi_connectivity_established ();
525         }
526 }
527
528 void
529 ControlProtocolManager::register_request_buffer_factories ()
530 {
531         Glib::Threads::Mutex::Lock lm (protocols_lock);
532
533         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
534
535                 if ((*i)->descriptor == 0) {
536                         warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
537                         continue;
538                 }
539
540                 if ((*i)->descriptor->request_buffer_factory) {
541                         EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);
542                 }
543         }
544 }