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;
175 ProtocolStatusChange (*p); /* EMIT SIGNAL */
181 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
183 /* CALLER MUST HOLD LOCK */
189 cpi.descriptor = get_descriptor (cpi.path);
191 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
193 if (cpi.descriptor == 0) {
194 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
198 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
200 if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) {
201 error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg;
205 control_protocols.push_back (cpi.protocol);
207 ProtocolStatusChange (&cpi);
213 ControlProtocolManager::teardown (ControlProtocolInfo& cpi, bool lock_required)
217 /* we could still have a descriptor even if the protocol was
218 never instantiated. Close the associated module (shared
219 object/DLL) and make sure we forget about it.
222 if (cpi.descriptor) {
223 cerr << "Closing descriptor for CPI anyway\n";
224 delete (Glib::Module*) cpi.descriptor->module;
231 if (!cpi.descriptor) {
239 /* save current state */
242 cpi.state = new XMLNode (cpi.protocol->get_state());
243 cpi.state->set_property (X_("active"), false);
245 cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
248 Glib::Threads::Mutex::Lock lm (protocols_lock);
249 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
250 if (p != control_protocols.end()) {
251 control_protocols.erase (p);
253 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
256 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
257 if (p != control_protocols.end()) {
258 control_protocols.erase (p);
260 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
268 delete (Glib::Module*) cpi.descriptor->module;
269 /* cpi->descriptor is now inaccessible since dlclose() or equivalent
270 * has been performed, and the descriptor is (or could be) a static
271 * object made accessible by dlopen().
275 ProtocolStatusChange (&cpi);
281 ControlProtocolManager::load_mandatory_protocols ()
287 Glib::Threads::Mutex::Lock lm (protocols_lock);
289 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
290 if ((*i)->mandatory && ((*i)->protocol == 0)) {
291 DEBUG_TRACE (DEBUG::ControlProtocols,
292 string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
299 ControlProtocolManager::discover_control_protocols ()
301 vector<std::string> cp_modules;
305 * Different build targets (Debug / Release etc) use different versions
306 * of the 'C' runtime (which can't be 'mixed & matched'). Therefore, in
307 * case the supplied search path contains multiple version(s) of a given
308 * module, only select the one(s) which match the current build target
311 Glib::PatternSpec dll_extension_pattern("*D.dll");
312 #elif defined (RDC_BUILD)
313 Glib::PatternSpec dll_extension_pattern("*RDC.dll");
314 #elif defined (_WIN64)
315 Glib::PatternSpec dll_extension_pattern("*64.dll");
317 Glib::PatternSpec dll_extension_pattern("*32.dll");
320 Glib::PatternSpec dll_extension_pattern("*.dll");
323 Glib::PatternSpec so_extension_pattern("*.so");
324 Glib::PatternSpec dylib_extension_pattern("*.dylib");
326 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
327 dll_extension_pattern);
329 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
330 so_extension_pattern);
332 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
333 dylib_extension_pattern);
335 DEBUG_TRACE (DEBUG::ControlProtocols,
336 string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
338 for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
339 control_protocol_discover (*i);
344 ControlProtocolManager::control_protocol_discover (string path)
346 ControlProtocolDescriptor* descriptor;
349 /* don't load OS X shared objects that are just symlinks to the real thing.
352 if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
357 if ((descriptor = get_descriptor (path)) != 0) {
359 if (!descriptor->probe (descriptor)) {
360 warning << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg;
363 ControlProtocolInfo* cpi = new ControlProtocolInfo ();
365 cpi->descriptor = descriptor;
366 cpi->name = descriptor->name;
369 cpi->requested = false;
370 cpi->mandatory = descriptor->mandatory;
371 cpi->supports_feedback = descriptor->supports_feedback;
374 control_protocol_info.push_back (cpi);
376 DEBUG_TRACE (DEBUG::ControlProtocols,
377 string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
384 ControlProtocolDescriptor*
385 ControlProtocolManager::get_descriptor (string path)
387 Glib::Module* module = new Glib::Module(path);
388 ControlProtocolDescriptor *descriptor = 0;
389 ControlProtocolDescriptor* (*dfunc)(void);
393 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
398 if (!module->get_symbol("protocol_descriptor", func)) {
399 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
400 error << Glib::Module::get_last_error() << endmsg;
405 dfunc = (ControlProtocolDescriptor* (*)(void))func;
406 descriptor = dfunc();
409 descriptor->module = (void*)module;
416 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
418 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
424 ControlProtocolManager::cpi_by_name (string name)
426 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
427 if (name == (*i)->name) {
435 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
438 XMLNodeConstIterator citer;
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")) {
451 if (!child->get_property (X_("active"), active) ||
452 !child->get_property (X_("name"), name)) {
456 ControlProtocolInfo* cpi = cpi_by_name (name);
460 cpi->state = new XMLNode (**citer);
462 std::cerr << "protocol " << name << " active ? " << active << std::endl;
468 cpi->requested = true;
472 teardown (*cpi, false);
474 cpi->requested = false;
478 std::cerr << "protocol " << name << " not found\n";
487 ControlProtocolManager::get_state ()
489 XMLNode* root = new XMLNode (state_node_name);
490 Glib::Threads::Mutex::Lock lm (protocols_lock);
492 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
494 if ((*i)->protocol) {
495 XMLNode& child_state ((*i)->protocol->get_state());
496 child_state.set_property (X_("active"), true);
497 root->add_child_nocopy (child_state);
498 } else if ((*i)->state) {
499 XMLNode* child_state = new XMLNode (*(*i)->state);
500 child_state->set_property (X_("active"), false);
501 root->add_child_nocopy (*child_state);
503 XMLNode* child_state = new XMLNode (X_("Protocol"));
504 child_state->set_property (X_("name"), (*i)->name);
505 child_state->set_property (X_("active"), false);
506 root->add_child_nocopy (*child_state);
515 ControlProtocolManager&
516 ControlProtocolManager::instance ()
518 if (_instance == 0) {
519 _instance = new ControlProtocolManager ();
526 ControlProtocolManager::midi_connectivity_established ()
528 Glib::Threads::Mutex::Lock lm (protocols_lock);
530 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
531 (*p)->midi_connectivity_established ();
536 ControlProtocolManager::register_request_buffer_factories ()
538 Glib::Threads::Mutex::Lock lm (protocols_lock);
540 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
542 if ((*i)->descriptor == 0) {
543 warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
547 if ((*i)->descriptor->request_buffer_factory) {
548 EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);