2 Copyright (C) 2000-2007 Paul Davis
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.
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.
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.
20 #include <glibmm/module.h>
22 #include <glibmm/fileutils.h>
24 #include "pbd/compose.h"
25 #include "pbd/event_loop.h"
26 #include "pbd/file_utils.h"
27 #include "pbd/error.h"
29 #include "control_protocol/control_protocol.h"
31 #include "ardour/debug.h"
32 #include "ardour/control_protocol_manager.h"
34 #include "ardour/search_paths.h"
37 using namespace ARDOUR;
43 ControlProtocolManager* ControlProtocolManager::_instance = 0;
44 const string ControlProtocolManager::state_node_name = X_("ControlProtocols");
47 ControlProtocolInfo::~ControlProtocolInfo ()
49 if (protocol && descriptor) {
50 descriptor->destroy (descriptor, protocol);
54 delete state; state = 0;
57 delete (Glib::Module*) descriptor->module;
62 ControlProtocolManager::ControlProtocolManager ()
66 ControlProtocolManager::~ControlProtocolManager()
68 Glib::Threads::Mutex::Lock lm (protocols_lock);
70 for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
74 control_protocols.clear ();
77 for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
81 control_protocol_info.clear();
85 ControlProtocolManager::set_session (Session* s)
87 SessionHandlePtr::set_session (s);
90 Glib::Threads::Mutex::Lock lm (protocols_lock);
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);
101 ControlProtocolManager::activate (ControlProtocolInfo& cpi)
105 cpi.requested = true;
107 if ((cp = instantiate (cpi)) == 0) {
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.
118 /* force this by tweaking the internals of the state
121 cp->set_state (*cpi.state, Stateful::loading_state_version);
123 /* guarantee a call to
124 set_state() whether we have
125 existing state or not
127 cp->set_state (XMLNode(""), Stateful::loading_state_version);
130 cp->set_active (true);
136 ControlProtocolManager::deactivate (ControlProtocolInfo& cpi)
138 cpi.requested = false;
139 return teardown (cpi);
143 ControlProtocolManager::session_going_away()
145 SessionHandlePtr::session_going_away ();
146 /* Session::destroy() will explicitly call drop_protocols() so we don't
147 * have to worry about that here.
152 ControlProtocolManager::drop_protocols ()
154 /* called explicitly by Session::destroy() so that we can clean up
155 * before the process cycle stops and ports vanish.
158 Glib::Threads::Mutex::Lock lm (protocols_lock);
160 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
164 control_protocols.clear ();
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;
177 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
179 /* CALLER MUST HOLD LOCK */
185 cpi.descriptor = get_descriptor (cpi.path);
187 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
189 if (cpi.descriptor == 0) {
190 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
194 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
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;
201 control_protocols.push_back (cpi.protocol);
203 ProtocolStatusChange (&cpi);
209 ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
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.
218 if (cpi.descriptor) {
219 cerr << "Closing descriptor for CPI anyway\n";
220 delete (Glib::Module*) cpi.descriptor->module;
227 if (!cpi.descriptor) {
235 /* save current state */
238 cpi.state = new XMLNode (cpi.protocol->get_state());
239 cpi.state->add_property (X_("active"), "no");
241 cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
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);
249 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
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().
264 ProtocolStatusChange (&cpi);
270 ControlProtocolManager::load_mandatory_protocols ()
276 Glib::Threads::Mutex::Lock lm (protocols_lock);
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));
288 ControlProtocolManager::discover_control_protocols ()
290 vector<std::string> cp_modules;
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
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");
306 Glib::PatternSpec dll_extension_pattern("*32.dll");
309 Glib::PatternSpec dll_extension_pattern("*.dll");
312 Glib::PatternSpec so_extension_pattern("*.so");
313 Glib::PatternSpec dylib_extension_pattern("*.dylib");
315 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
316 dll_extension_pattern);
318 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
319 so_extension_pattern);
321 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
322 dylib_extension_pattern);
324 DEBUG_TRACE (DEBUG::ControlProtocols,
325 string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
327 for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
328 control_protocol_discover (*i);
333 ControlProtocolManager::control_protocol_discover (string path)
335 ControlProtocolDescriptor* descriptor;
338 /* don't load OS X shared objects that are just symlinks to the real thing.
341 if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
346 if ((descriptor = get_descriptor (path)) != 0) {
348 if (!descriptor->probe (descriptor)) {
349 DEBUG_TRACE (DEBUG::ControlProtocols,
350 string_compose (_("Control protocol %1 not usable"), descriptor->name));
353 ControlProtocolInfo* cpi = new ControlProtocolInfo ();
355 cpi->descriptor = descriptor;
356 cpi->name = descriptor->name;
359 cpi->requested = false;
360 cpi->mandatory = descriptor->mandatory;
361 cpi->supports_feedback = descriptor->supports_feedback;
364 control_protocol_info.push_back (cpi);
366 DEBUG_TRACE (DEBUG::ControlProtocols,
367 string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
374 ControlProtocolDescriptor*
375 ControlProtocolManager::get_descriptor (string path)
377 Glib::Module* module = new Glib::Module(path);
378 ControlProtocolDescriptor *descriptor = 0;
379 ControlProtocolDescriptor* (*dfunc)(void);
383 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
388 if (!module->get_symbol("protocol_descriptor", func)) {
389 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
390 error << Glib::Module::get_last_error() << endmsg;
395 dfunc = (ControlProtocolDescriptor* (*)(void))func;
396 descriptor = dfunc();
399 descriptor->module = (void*)module;
406 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
408 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
414 ControlProtocolManager::cpi_by_name (string name)
416 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
417 if (name == (*i)->name) {
425 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
428 XMLNodeConstIterator citer;
429 XMLProperty const * prop;
431 Glib::Threads::Mutex::Lock lm (protocols_lock);
433 clist = node.children();
435 for (citer = clist.begin(); citer != clist.end(); ++citer) {
436 XMLNode const * child = *citer;
438 if (child->name() == X_("Protocol")) {
440 if ((prop = child->property (X_("active"))) == 0) {
444 bool active = string_is_affirmative (prop->value());
446 if ((prop = child->property (X_("name"))) == 0) {
450 ControlProtocolInfo* cpi = cpi_by_name (prop->value());
454 cpi->state = new XMLNode (**citer);
460 cpi->requested = true;
466 cpi->requested = false;
477 ControlProtocolManager::get_state ()
479 XMLNode* root = new XMLNode (state_node_name);
480 Glib::Threads::Mutex::Lock lm (protocols_lock);
482 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
484 if ((*i)->protocol) {
485 XMLNode& child_state ((*i)->protocol->get_state());
486 child_state.add_property (X_("active"), "yes");
487 root->add_child_nocopy (child_state);
488 } else if ((*i)->state) {
489 XMLNode* child_state = new XMLNode (*(*i)->state);
490 child_state->add_property (X_("active"), "no");
491 root->add_child_nocopy (*child_state);
493 XMLNode* child_state = new XMLNode (X_("Protocol"));
494 child_state->add_property (X_("name"), (*i)->name);
495 child_state->add_property (X_("active"), "no");
496 root->add_child_nocopy (*child_state);
505 ControlProtocolManager&
506 ControlProtocolManager::instance ()
508 if (_instance == 0) {
509 _instance = new ControlProtocolManager ();
516 ControlProtocolManager::midi_connectivity_established ()
518 Glib::Threads::Mutex::Lock lm (protocols_lock);
520 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
521 (*p)->midi_connectivity_established ();
526 ControlProtocolManager::register_request_buffer_factories ()
528 Glib::Threads::Mutex::Lock lm (protocols_lock);
530 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
532 if ((*i)->descriptor == 0) {
533 warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
537 if ((*i)->descriptor->request_buffer_factory) {
538 EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);