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 if (cp->set_active (true)) {
131 error << string_compose (_("Control protocol support for %1 failed to activate"), cpi.name) << endmsg;
132 teardown (cpi, false);
139 ControlProtocolManager::deactivate (ControlProtocolInfo& cpi)
141 cpi.requested = false;
142 return teardown (cpi, true);
146 ControlProtocolManager::session_going_away()
148 SessionHandlePtr::session_going_away ();
149 /* Session::destroy() will explicitly call drop_protocols() so we don't
150 * have to worry about that here.
155 ControlProtocolManager::drop_protocols ()
157 /* called explicitly by Session::destroy() so that we can clean up
158 * before the process cycle stops and ports vanish.
161 Glib::Threads::Mutex::Lock lm (protocols_lock);
163 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
167 control_protocols.clear ();
169 for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
170 // mark existing protocols as requested
171 // otherwise the ControlProtocol instances are not recreated in set_session
172 if ((*p)->protocol) {
173 (*p)->requested = true;
180 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
182 /* CALLER MUST HOLD LOCK */
188 cpi.descriptor = get_descriptor (cpi.path);
190 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
192 if (cpi.descriptor == 0) {
193 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
197 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
199 if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) {
200 error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg;
204 control_protocols.push_back (cpi.protocol);
206 ProtocolStatusChange (&cpi);
212 ControlProtocolManager::teardown (ControlProtocolInfo& cpi, bool lock_required)
216 /* we could still have a descriptor even if the protocol was
217 never instantiated. Close the associated module (shared
218 object/DLL) and make sure we forget about it.
221 if (cpi.descriptor) {
222 cerr << "Closing descriptor for CPI anyway\n";
223 delete (Glib::Module*) cpi.descriptor->module;
230 if (!cpi.descriptor) {
238 /* save current state */
241 cpi.state = new XMLNode (cpi.protocol->get_state());
242 cpi.state->add_property (X_("active"), "no");
244 cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
247 Glib::Threads::Mutex::Lock lm (protocols_lock);
248 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
249 if (p != control_protocols.end()) {
250 control_protocols.erase (p);
252 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
255 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
256 if (p != control_protocols.end()) {
257 control_protocols.erase (p);
259 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
267 delete (Glib::Module*) cpi.descriptor->module;
268 /* cpi->descriptor is now inaccessible since dlclose() or equivalent
269 * has been performed, and the descriptor is (or could be) a static
270 * object made accessible by dlopen().
274 ProtocolStatusChange (&cpi);
280 ControlProtocolManager::load_mandatory_protocols ()
286 Glib::Threads::Mutex::Lock lm (protocols_lock);
288 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
289 if ((*i)->mandatory && ((*i)->protocol == 0)) {
290 DEBUG_TRACE (DEBUG::ControlProtocols,
291 string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
298 ControlProtocolManager::discover_control_protocols ()
300 vector<std::string> cp_modules;
304 * Different build targets (Debug / Release etc) use different versions
305 * of the 'C' runtime (which can't be 'mixed & matched'). Therefore, in
306 * case the supplied search path contains multiple version(s) of a given
307 * module, only select the one(s) which match the current build target
310 Glib::PatternSpec dll_extension_pattern("*D.dll");
311 #elif defined (RDC_BUILD)
312 Glib::PatternSpec dll_extension_pattern("*RDC.dll");
313 #elif defined (_WIN64)
314 Glib::PatternSpec dll_extension_pattern("*64.dll");
316 Glib::PatternSpec dll_extension_pattern("*32.dll");
319 Glib::PatternSpec dll_extension_pattern("*.dll");
322 Glib::PatternSpec so_extension_pattern("*.so");
323 Glib::PatternSpec dylib_extension_pattern("*.dylib");
325 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
326 dll_extension_pattern);
328 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
329 so_extension_pattern);
331 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
332 dylib_extension_pattern);
334 DEBUG_TRACE (DEBUG::ControlProtocols,
335 string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
337 for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
338 control_protocol_discover (*i);
343 ControlProtocolManager::control_protocol_discover (string path)
345 ControlProtocolDescriptor* descriptor;
348 /* don't load OS X shared objects that are just symlinks to the real thing.
351 if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
356 if ((descriptor = get_descriptor (path)) != 0) {
358 if (!descriptor->probe (descriptor)) {
359 warning << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg;
362 ControlProtocolInfo* cpi = new ControlProtocolInfo ();
364 cpi->descriptor = descriptor;
365 cpi->name = descriptor->name;
368 cpi->requested = false;
369 cpi->mandatory = descriptor->mandatory;
370 cpi->supports_feedback = descriptor->supports_feedback;
373 control_protocol_info.push_back (cpi);
375 DEBUG_TRACE (DEBUG::ControlProtocols,
376 string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
383 ControlProtocolDescriptor*
384 ControlProtocolManager::get_descriptor (string path)
386 Glib::Module* module = new Glib::Module(path);
387 ControlProtocolDescriptor *descriptor = 0;
388 ControlProtocolDescriptor* (*dfunc)(void);
392 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
397 if (!module->get_symbol("protocol_descriptor", func)) {
398 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
399 error << Glib::Module::get_last_error() << endmsg;
404 dfunc = (ControlProtocolDescriptor* (*)(void))func;
405 descriptor = dfunc();
408 descriptor->module = (void*)module;
415 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
417 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
423 ControlProtocolManager::cpi_by_name (string name)
425 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
426 if (name == (*i)->name) {
434 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
437 XMLNodeConstIterator citer;
438 XMLProperty const * prop;
440 Glib::Threads::Mutex::Lock lm (protocols_lock);
442 clist = node.children();
444 for (citer = clist.begin(); citer != clist.end(); ++citer) {
445 XMLNode const * child = *citer;
447 if (child->name() == X_("Protocol")) {
449 if ((prop = child->property (X_("active"))) == 0) {
453 bool active = string_is_affirmative (prop->value());
455 if ((prop = child->property (X_("name"))) == 0) {
459 ControlProtocolInfo* cpi = cpi_by_name (prop->value());
463 cpi->state = new XMLNode (**citer);
465 std::cerr << "protocol " << prop->value() << " active ? " << active << std::endl;
471 cpi->requested = true;
475 teardown (*cpi, true);
477 cpi->requested = false;
481 std::cerr << "protocol " << prop->value() << " not found\n";
490 ControlProtocolManager::get_state ()
492 XMLNode* root = new XMLNode (state_node_name);
493 Glib::Threads::Mutex::Lock lm (protocols_lock);
495 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
497 if ((*i)->protocol) {
498 XMLNode& child_state ((*i)->protocol->get_state());
499 child_state.add_property (X_("active"), "yes");
500 root->add_child_nocopy (child_state);
501 } else if ((*i)->state) {
502 XMLNode* child_state = new XMLNode (*(*i)->state);
503 child_state->add_property (X_("active"), "no");
504 root->add_child_nocopy (*child_state);
506 XMLNode* child_state = new XMLNode (X_("Protocol"));
507 child_state->add_property (X_("name"), (*i)->name);
508 child_state->add_property (X_("active"), "no");
509 root->add_child_nocopy (*child_state);
518 ControlProtocolManager&
519 ControlProtocolManager::instance ()
521 if (_instance == 0) {
522 _instance = new ControlProtocolManager ();
529 ControlProtocolManager::midi_connectivity_established ()
531 Glib::Threads::Mutex::Lock lm (protocols_lock);
533 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
534 (*p)->midi_connectivity_established ();
539 ControlProtocolManager::register_request_buffer_factories ()
541 Glib::Threads::Mutex::Lock lm (protocols_lock);
543 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
545 if ((*i)->descriptor == 0) {
546 warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
550 if ((*i)->descriptor->request_buffer_factory) {
551 EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);