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 warning << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg;
352 ControlProtocolInfo* cpi = new ControlProtocolInfo ();
354 cpi->descriptor = descriptor;
355 cpi->name = descriptor->name;
358 cpi->requested = false;
359 cpi->mandatory = descriptor->mandatory;
360 cpi->supports_feedback = descriptor->supports_feedback;
363 control_protocol_info.push_back (cpi);
365 DEBUG_TRACE (DEBUG::ControlProtocols,
366 string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
373 ControlProtocolDescriptor*
374 ControlProtocolManager::get_descriptor (string path)
376 Glib::Module* module = new Glib::Module(path);
377 ControlProtocolDescriptor *descriptor = 0;
378 ControlProtocolDescriptor* (*dfunc)(void);
382 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
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;
394 dfunc = (ControlProtocolDescriptor* (*)(void))func;
395 descriptor = dfunc();
398 descriptor->module = (void*)module;
405 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
407 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
413 ControlProtocolManager::cpi_by_name (string name)
415 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
416 if (name == (*i)->name) {
424 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
427 XMLNodeConstIterator citer;
428 XMLProperty const * prop;
430 Glib::Threads::Mutex::Lock lm (protocols_lock);
432 clist = node.children();
434 for (citer = clist.begin(); citer != clist.end(); ++citer) {
435 XMLNode const * child = *citer;
437 if (child->name() == X_("Protocol")) {
439 if ((prop = child->property (X_("active"))) == 0) {
443 bool active = string_is_affirmative (prop->value());
445 if ((prop = child->property (X_("name"))) == 0) {
449 ControlProtocolInfo* cpi = cpi_by_name (prop->value());
453 cpi->state = new XMLNode (**citer);
455 std::cerr << "protocol " << prop->value() << " active ? " << active << std::endl;
461 cpi->requested = true;
467 cpi->requested = false;
471 std::cerr << "protocol " << prop->value() << " not found\n";
480 ControlProtocolManager::get_state ()
482 XMLNode* root = new XMLNode (state_node_name);
483 Glib::Threads::Mutex::Lock lm (protocols_lock);
485 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
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);
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);
508 ControlProtocolManager&
509 ControlProtocolManager::instance ()
511 if (_instance == 0) {
512 _instance = new ControlProtocolManager ();
519 ControlProtocolManager::midi_connectivity_established ()
521 Glib::Threads::Mutex::Lock lm (protocols_lock);
523 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
524 (*p)->midi_connectivity_established ();
529 ControlProtocolManager::register_request_buffer_factories ()
531 Glib::Threads::Mutex::Lock lm (protocols_lock);
533 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
535 if ((*i)->descriptor == 0) {
536 warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
540 if ((*i)->descriptor->request_buffer_factory) {
541 EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);