2 * Copyright (C) 2006-2012 David Robillard <d@drobilla.net>
3 * Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2007-2016 Tim Mayberry <mojofunk@gmail.com>
5 * Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
6 * Copyright (C) 2014 John Emmas <john@creativepost.co.uk>
7 * Copyright (C) 2015-2018 Robin Gareus <robin@gareus.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <glibmm/module.h>
26 #include <glibmm/fileutils.h>
28 #include "pbd/compose.h"
29 #include "pbd/event_loop.h"
30 #include "pbd/file_utils.h"
31 #include "pbd/error.h"
33 #include "control_protocol/control_protocol.h"
35 #include "ardour/debug.h"
36 #include "ardour/control_protocol_manager.h"
38 #include "ardour/search_paths.h"
39 #include "ardour/selection.h"
40 #include "ardour/session.h"
42 using namespace ARDOUR;
48 ControlProtocolManager* ControlProtocolManager::_instance = 0;
49 const string ControlProtocolManager::state_node_name = X_("ControlProtocols");
50 PBD::Signal1<void,StripableNotificationListPtr> ControlProtocolManager::StripableSelectionChanged;
52 ControlProtocolInfo::~ControlProtocolInfo ()
54 if (protocol && descriptor) {
55 descriptor->destroy (descriptor, protocol);
59 delete state; state = 0;
62 delete (Glib::Module*) descriptor->module;
67 ControlProtocolManager::ControlProtocolManager ()
71 ControlProtocolManager::~ControlProtocolManager()
73 Glib::Threads::RWLock::WriterLock lm (protocols_lock);
75 for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
79 control_protocols.clear ();
82 for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
83 (*p)->protocol = 0; // protocol was already destroyed above.
87 control_protocol_info.clear();
91 ControlProtocolManager::set_session (Session* s)
93 SessionHandlePtr::set_session (s);
100 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
102 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
103 if ((*i)->requested || (*i)->mandatory) {
104 (void) activate (**i);
109 CoreSelection::StripableAutomationControls sac;
110 _session->selection().get_stripables (sac);
113 StripableNotificationListPtr v (new StripableNotificationList);
114 for (CoreSelection::StripableAutomationControls::iterator i = sac.begin(); i != sac.end(); ++i) {
115 if ((*i).stripable) {
116 v->push_back (boost::weak_ptr<Stripable> ((*i).stripable));
120 StripableSelectionChanged (v); /* EMIT SIGNAL */
126 ControlProtocolManager::activate (ControlProtocolInfo& cpi)
130 cpi.requested = true;
132 if (cpi.protocol && cpi.protocol->active()) {
133 warning << string_compose (_("Control protocol %1 was already active."), cpi.name) << endmsg;
137 if ((cp = instantiate (cpi)) == 0) {
141 /* we split the set_state() and set_active() operations so that
142 protocols that need state to configure themselves (e.g. "What device
143 is connected, or supposed to be connected?") can get it before
144 actually starting any interaction.
148 /* force this by tweaking the internals of the state
151 cp->set_state (*cpi.state, Stateful::loading_state_version);
153 /* guarantee a call to
154 set_state() whether we have
155 existing state or not
157 cp->set_state (XMLNode(""), Stateful::loading_state_version);
160 if (cp->set_active (true)) {
161 error << string_compose (_("Control protocol support for %1 failed to activate"), cpi.name) << endmsg;
162 teardown (cpi, false);
169 ControlProtocolManager::deactivate (ControlProtocolInfo& cpi)
171 cpi.requested = false;
172 return teardown (cpi, true);
176 ControlProtocolManager::session_going_away()
178 SessionHandlePtr::session_going_away ();
179 /* Session::destroy() will explicitly call drop_protocols() so we don't
180 * have to worry about that here.
185 ControlProtocolManager::drop_protocols ()
187 /* called explicitly by Session::destroy() so that we can clean up
188 * before the process cycle stops and ports vanish.
191 Glib::Threads::RWLock::WriterLock lm (protocols_lock);
193 for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
194 // mark existing protocols as requested
195 // otherwise the ControlProtocol instances are not recreated in set_session
196 if ((*p)->protocol) {
197 (*p)->requested = true;
199 ProtocolStatusChange (*p); /* EMIT SIGNAL */
203 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
207 control_protocols.clear ();
211 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
213 /* CALLER MUST HOLD LOCK */
219 cpi.descriptor = get_descriptor (cpi.path);
221 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
223 if (cpi.descriptor == 0) {
224 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
228 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
230 if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) {
231 error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg;
235 control_protocols.push_back (cpi.protocol);
237 ProtocolStatusChange (&cpi);
243 ControlProtocolManager::teardown (ControlProtocolInfo& cpi, bool lock_required)
247 /* we could still have a descriptor even if the protocol was
248 never instantiated. Close the associated module (shared
249 object/DLL) and make sure we forget about it.
252 if (cpi.descriptor) {
253 cerr << "Closing descriptor for CPI anyway\n";
254 delete (Glib::Module*) cpi.descriptor->module;
261 if (!cpi.descriptor) {
269 /* save current state */
272 cpi.state = new XMLNode (cpi.protocol->get_state());
273 cpi.state->set_property (X_("active"), false);
275 cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
278 /* the lock is required when the protocol is torn down by a user from the GUI. */
279 Glib::Threads::RWLock::WriterLock lm (protocols_lock);
280 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
281 if (p != control_protocols.end()) {
282 control_protocols.erase (p);
284 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
287 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
288 if (p != control_protocols.end()) {
289 control_protocols.erase (p);
291 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
297 delete (Glib::Module*) cpi.descriptor->module;
298 /* cpi->descriptor is now inaccessible since dlclose() or equivalent
299 * has been performed, and the descriptor is (or could be) a static
300 * object made accessible by dlopen().
304 ProtocolStatusChange (&cpi);
310 ControlProtocolManager::load_mandatory_protocols ()
316 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
318 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
319 if ((*i)->mandatory && ((*i)->protocol == 0)) {
320 DEBUG_TRACE (DEBUG::ControlProtocols,
321 string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
328 ControlProtocolManager::discover_control_protocols ()
330 vector<std::string> cp_modules;
334 * Different build targets (Debug / Release etc) use different versions
335 * of the 'C' runtime (which can't be 'mixed & matched'). Therefore, in
336 * case the supplied search path contains multiple version(s) of a given
337 * module, only select the one(s) which match the current build target
340 Glib::PatternSpec dll_extension_pattern("*D.dll");
341 #elif defined (RDC_BUILD)
342 Glib::PatternSpec dll_extension_pattern("*RDC.dll");
343 #elif defined (_WIN64)
344 Glib::PatternSpec dll_extension_pattern("*64.dll");
346 Glib::PatternSpec dll_extension_pattern("*32.dll");
349 Glib::PatternSpec dll_extension_pattern("*.dll");
352 Glib::PatternSpec so_extension_pattern("*.so");
353 Glib::PatternSpec dylib_extension_pattern("*.dylib");
355 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
356 dll_extension_pattern);
358 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
359 so_extension_pattern);
361 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
362 dylib_extension_pattern);
364 DEBUG_TRACE (DEBUG::ControlProtocols,
365 string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
367 for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
368 control_protocol_discover (*i);
373 ControlProtocolManager::control_protocol_discover (string path)
375 ControlProtocolDescriptor* descriptor;
378 /* don't load OS X shared objects that are just symlinks to the real thing.
381 if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
386 if ((descriptor = get_descriptor (path)) != 0) {
388 if (!descriptor->probe (descriptor)) {
389 warning << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg;
392 ControlProtocolInfo* cpi = new ControlProtocolInfo ();
394 cpi->descriptor = descriptor;
395 cpi->name = descriptor->name;
398 cpi->requested = false;
399 cpi->mandatory = descriptor->mandatory;
400 cpi->supports_feedback = descriptor->supports_feedback;
403 control_protocol_info.push_back (cpi);
405 DEBUG_TRACE (DEBUG::ControlProtocols,
406 string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
413 ControlProtocolDescriptor*
414 ControlProtocolManager::get_descriptor (string path)
416 Glib::Module* module = new Glib::Module(path);
417 ControlProtocolDescriptor *descriptor = 0;
418 ControlProtocolDescriptor* (*dfunc)(void);
422 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
427 if (!module->get_symbol("protocol_descriptor", func)) {
428 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
429 error << Glib::Module::get_last_error() << endmsg;
434 dfunc = (ControlProtocolDescriptor* (*)(void))func;
435 descriptor = dfunc();
438 descriptor->module = (void*)module;
445 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
447 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
453 ControlProtocolManager::cpi_by_name (string name)
455 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
456 if (name == (*i)->name) {
464 ControlProtocolManager::set_state (const XMLNode& node, int session_specific_state /* here: not version */)
467 XMLNodeConstIterator citer;
469 Glib::Threads::RWLock::WriterLock lm (protocols_lock);
471 clist = node.children();
473 for (citer = clist.begin(); citer != clist.end(); ++citer) {
474 XMLNode const * child = *citer;
476 if (child->name() == X_("Protocol")) {
480 if (!child->get_property (X_("active"), active) ||
481 !child->get_property (X_("name"), name)) {
485 ControlProtocolInfo* cpi = cpi_by_name (name);
488 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("Protocolstate %1 %2\n", name, active ? "active" : "inactive"));
492 cpi->state = new XMLNode (**citer);
493 cpi->state->set_property (X_("session-state"), session_specific_state ? true : false);
497 cpi->requested = true;
501 cpi->state = new XMLNode (**citer);
502 cpi->state->set_property (X_("active"), false);
503 cpi->state->set_property (X_("session-state"), session_specific_state ? true : false);
505 cpi->requested = false;
507 teardown (*cpi, false);
511 std::cerr << "protocol " << name << " not found\n";
520 ControlProtocolManager::get_state ()
522 XMLNode* root = new XMLNode (state_node_name);
523 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
525 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
527 if ((*i)->protocol) {
528 XMLNode& child_state ((*i)->protocol->get_state());
529 child_state.set_property (X_("active"), true);
530 delete ((*i)->state);
531 (*i)->state = new XMLNode (child_state);
532 root->add_child_nocopy (child_state);
533 } else if ((*i)->state) {
534 XMLNode* child_state = new XMLNode (*(*i)->state);
535 child_state->set_property (X_("active"), false);
536 root->add_child_nocopy (*child_state);
538 XMLNode* child_state = new XMLNode (X_("Protocol"));
539 child_state->set_property (X_("name"), (*i)->name);
540 child_state->set_property (X_("active"), false);
541 root->add_child_nocopy (*child_state);
550 ControlProtocolManager&
551 ControlProtocolManager::instance ()
553 if (_instance == 0) {
554 _instance = new ControlProtocolManager ();
561 ControlProtocolManager::midi_connectivity_established ()
563 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
565 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
566 (*p)->midi_connectivity_established ();
571 ControlProtocolManager::register_request_buffer_factories ()
573 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
575 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
577 if ((*i)->descriptor == 0) {
578 warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
582 if ((*i)->descriptor->request_buffer_factory) {
583 EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);
589 ControlProtocolManager::stripable_selection_changed (StripableNotificationListPtr sp)
591 /* this sets up the (static) data structures owned by ControlProtocol
592 that are "shared" across all control protocols.
595 DEBUG_TRACE (DEBUG::Selection, string_compose ("Surface manager: selection changed, now %1 stripables\n", sp ? sp->size() : -1));
596 StripableSelectionChanged (sp); /* EMIT SIGNAL */
598 /* now give each protocol the chance to respond to the selection change
602 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
604 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
605 DEBUG_TRACE (DEBUG::Selection, string_compose ("selection change notification for surface \"%1\"\n", (*p)->name()));
606 (*p)->stripable_selection_changed ();