1 /*
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>
8 *
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.
13 *
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.
18 *
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.
22 */
23
24 #include <glibmm/module.h>
25
26 #include <glibmm/fileutils.h>
27
28 #include "pbd/compose.h"
29 #include "pbd/event_loop.h"
30 #include "pbd/file_utils.h"
31 #include "pbd/error.h"
32
33 #include "control_protocol/control_protocol.h"
34
35 #include "ardour/debug.h"
36 #include "ardour/control_protocol_manager.h"
37
38 #include "ardour/search_paths.h"
39 #include "ardour/selection.h"
40 #include "ardour/session.h"
41
42 using namespace ARDOUR;
43 using namespace std;
44 using namespace PBD;
45
46 #include "pbd/i18n.h"
47
48 ControlProtocolManager* ControlProtocolManager::_instance = 0;
49 const string ControlProtocolManager::state_node_name = X_("ControlProtocols");
50 PBD::Signal1<void,StripableNotificationListPtr> ControlProtocolManager::StripableSelectionChanged;
51
~ControlProtocolInfo()52 ControlProtocolInfo::~ControlProtocolInfo ()
53 {
54 if (protocol && descriptor) {
55 descriptor->destroy (descriptor, protocol);
56 protocol = 0;
57 }
58
59 delete state; state = 0;
60
61 if (descriptor) {
62 delete (Glib::Module*) descriptor->module;
63 descriptor = 0;
64 }
65 }
66
ControlProtocolManager()67 ControlProtocolManager::ControlProtocolManager ()
68 {
69 }
70
~ControlProtocolManager()71 ControlProtocolManager::~ControlProtocolManager()
72 {
73 Glib::Threads::RWLock::WriterLock lm (protocols_lock);
74
75 for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
76 delete (*i);
77 }
78
79 control_protocols.clear ();
80
81
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.
84 delete (*p);
85 }
86
87 control_protocol_info.clear();
88 }
89
90 void
set_session(Session * s)91 ControlProtocolManager::set_session (Session* s)
92 {
93 SessionHandlePtr::set_session (s);
94
95 if (!_session) {
96 return;
97 }
98
99 {
100 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
101
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);
105 }
106 }
107 }
108
109 CoreSelection::StripableAutomationControls sac;
110 _session->selection().get_stripables (sac);
111
112 if (!sac.empty()) {
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));
117 }
118 }
119 if (!v->empty()) {
120 StripableSelectionChanged (v); /* EMIT SIGNAL */
121 }
122 }
123 }
124
125 int
activate(ControlProtocolInfo & cpi)126 ControlProtocolManager::activate (ControlProtocolInfo& cpi)
127 {
128 ControlProtocol* cp;
129
130 cpi.requested = true;
131
132 if (cpi.protocol && cpi.protocol->active()) {
133 warning << string_compose (_("Control protocol %1 was already active."), cpi.name) << endmsg;
134 return 0;
135 }
136
137 if ((cp = instantiate (cpi)) == 0) {
138 return -1;
139 }
140
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.
145 */
146
147 if (cpi.state) {
148 /* force this by tweaking the internals of the state
149 * XMLNode. Ugh.
150 */
151 cp->set_state (*cpi.state, Stateful::loading_state_version);
152 } else {
153 /* guarantee a call to
154 set_state() whether we have
155 existing state or not
156 */
157 cp->set_state (XMLNode(""), Stateful::loading_state_version);
158 }
159
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);
163 }
164
165 return 0;
166 }
167
168 int
deactivate(ControlProtocolInfo & cpi)169 ControlProtocolManager::deactivate (ControlProtocolInfo& cpi)
170 {
171 cpi.requested = false;
172 return teardown (cpi, true);
173 }
174
175 void
session_going_away()176 ControlProtocolManager::session_going_away()
177 {
178 SessionHandlePtr::session_going_away ();
179 /* Session::destroy() will explicitly call drop_protocols() so we don't
180 * have to worry about that here.
181 */
182 }
183
184 void
drop_protocols()185 ControlProtocolManager::drop_protocols ()
186 {
187 /* called explicitly by Session::destroy() so that we can clean up
188 * before the process cycle stops and ports vanish.
189 */
190
191 Glib::Threads::RWLock::WriterLock lm (protocols_lock);
192
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;
198 (*p)->protocol = 0;
199 ProtocolStatusChange (*p); /* EMIT SIGNAL */
200 }
201 }
202
203 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
204 delete *p;
205 }
206
207 control_protocols.clear ();
208 }
209
210 ControlProtocol*
instantiate(ControlProtocolInfo & cpi)211 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
212 {
213 /* CALLER MUST HOLD LOCK */
214
215 if (_session == 0) {
216 return 0;
217 }
218
219 cpi.descriptor = get_descriptor (cpi.path);
220
221 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
222
223 if (cpi.descriptor == 0) {
224 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
225 return 0;
226 }
227
228 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
229
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;
232 return 0;
233 }
234
235 control_protocols.push_back (cpi.protocol);
236
237 ProtocolStatusChange (&cpi);
238
239 return cpi.protocol;
240 }
241
242 int
teardown(ControlProtocolInfo & cpi,bool lock_required)243 ControlProtocolManager::teardown (ControlProtocolInfo& cpi, bool lock_required)
244 {
245 if (!cpi.protocol) {
246
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.
250 */
251
252 if (cpi.descriptor) {
253 cerr << "Closing descriptor for CPI anyway\n";
254 delete (Glib::Module*) cpi.descriptor->module;
255 cpi.descriptor = 0;
256 }
257
258 return 0;
259 }
260
261 if (!cpi.descriptor) {
262 return 0;
263 }
264
265 if (cpi.mandatory) {
266 return 0;
267 }
268
269 /* save current state */
270
271 delete cpi.state;
272 cpi.state = new XMLNode (cpi.protocol->get_state());
273 cpi.state->set_property (X_("active"), false);
274
275 cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
276
277 if (lock_required) {
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);
283 } else {
284 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
285 }
286 } else {
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);
290 } else {
291 cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
292 }
293 }
294
295 cpi.protocol = 0;
296
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().
301 */
302 cpi.descriptor = 0;
303
304 ProtocolStatusChange (&cpi);
305
306 return 0;
307 }
308
309 void
load_mandatory_protocols()310 ControlProtocolManager::load_mandatory_protocols ()
311 {
312 if (_session == 0) {
313 return;
314 }
315
316 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
317
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));
322 instantiate (**i);
323 }
324 }
325 }
326
327 struct ControlProtocolOrderByName
328 {
operator ()ControlProtocolOrderByName329 bool operator() (ControlProtocolInfo* const & a, ControlProtocolInfo* const & b) const {
330 return a->name < b->name;
331 }
332 };
333
334 void
discover_control_protocols()335 ControlProtocolManager::discover_control_protocols ()
336 {
337 vector<std::string> cp_modules;
338
339 #ifdef COMPILER_MSVC
340 /**
341 * Different build targets (Debug / Release etc) use different versions
342 * of the 'C' runtime (which can't be 'mixed & matched'). Therefore, in
343 * case the supplied search path contains multiple version(s) of a given
344 * module, only select the one(s) which match the current build target
345 */
346 #if defined (_DEBUG)
347 Glib::PatternSpec dll_extension_pattern("*D.dll");
348 #elif defined (RDC_BUILD)
349 Glib::PatternSpec dll_extension_pattern("*RDC.dll");
350 #elif defined (_WIN64)
351 Glib::PatternSpec dll_extension_pattern("*64.dll");
352 #else
353 Glib::PatternSpec dll_extension_pattern("*32.dll");
354 #endif
355 #else
356 Glib::PatternSpec dll_extension_pattern("*.dll");
357 #endif
358
359 Glib::PatternSpec so_extension_pattern("*.so");
360 Glib::PatternSpec dylib_extension_pattern("*.dylib");
361
362 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
363 dll_extension_pattern);
364
365 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
366 so_extension_pattern);
367
368 find_files_matching_pattern (cp_modules, control_protocol_search_path (),
369 dylib_extension_pattern);
370
371 DEBUG_TRACE (DEBUG::ControlProtocols,
372 string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
373
374 for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
375 control_protocol_discover (*i);
376 }
377
378 ControlProtocolOrderByName cpn;
379 control_protocol_info.sort (cpn);
380 }
381
382 int
control_protocol_discover(string path)383 ControlProtocolManager::control_protocol_discover (string path)
384 {
385 ControlProtocolDescriptor* descriptor;
386
387 #ifdef __APPLE__
388 /* don't load OS X shared objects that are just symlinks to the real thing.
389 */
390
391 if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
392 return 0;
393 }
394 #endif
395
396 if ((descriptor = get_descriptor (path)) != 0) {
397
398 if (!descriptor->probe (descriptor)) {
399 warning << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg;
400 } else {
401
402 ControlProtocolInfo* cpi = new ControlProtocolInfo ();
403
404 cpi->descriptor = descriptor;
405 cpi->name = descriptor->name;
406 cpi->path = path;
407 cpi->protocol = 0;
408 cpi->requested = false;
409 cpi->mandatory = descriptor->mandatory;
410 cpi->supports_feedback = descriptor->supports_feedback;
411 cpi->state = 0;
412
413 control_protocol_info.push_back (cpi);
414
415 DEBUG_TRACE (DEBUG::ControlProtocols,
416 string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
417 }
418 }
419
420 return 0;
421 }
422
423 ControlProtocolDescriptor*
get_descriptor(string path)424 ControlProtocolManager::get_descriptor (string path)
425 {
426 Glib::Module* module = new Glib::Module(path);
427 ControlProtocolDescriptor *descriptor = 0;
428 ControlProtocolDescriptor* (*dfunc)(void);
429 void* func = 0;
430
431 if (!(*module)) {
432 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
433 delete module;
434 return 0;
435 }
436
437 if (!module->get_symbol("protocol_descriptor", func)) {
438 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
439 error << Glib::Module::get_last_error() << endmsg;
440 delete module;
441 return 0;
442 }
443
444 dfunc = (ControlProtocolDescriptor* (*)(void))func;
445 descriptor = dfunc();
446
447 if (descriptor) {
448 descriptor->module = (void*)module;
449 }
450
451 return descriptor;
452 }
453
454 void
foreach_known_protocol(boost::function<void (const ControlProtocolInfo *)> method)455 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
456 {
457 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
458 method (*i);
459 }
460 }
461
462 ControlProtocolInfo*
cpi_by_name(string name)463 ControlProtocolManager::cpi_by_name (string name)
464 {
465 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
466 if (name == (*i)->name) {
467 return *i;
468 }
469 }
470 return 0;
471 }
472
473 int
set_state(const XMLNode & node,int session_specific_state)474 ControlProtocolManager::set_state (const XMLNode& node, int session_specific_state /* here: not version */)
475 {
476 XMLNodeList clist;
477 XMLNodeConstIterator citer;
478
479 Glib::Threads::RWLock::WriterLock lm (protocols_lock);
480
481 clist = node.children();
482
483 for (citer = clist.begin(); citer != clist.end(); ++citer) {
484 XMLNode const * child = *citer;
485
486 if (child->name() == X_("Protocol")) {
487
488 bool active;
489 std::string name;
490 if (!child->get_property (X_("active"), active) ||
491 !child->get_property (X_("name"), name)) {
492 continue;
493 }
494
495 ControlProtocolInfo* cpi = cpi_by_name (name);
496
497 if (cpi) {
498 DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("Protocolstate %1 %2\n", name, active ? "active" : "inactive"));
499
500 if (active) {
501 delete cpi->state;
502 cpi->state = new XMLNode (**citer);
503 cpi->state->set_property (X_("session-state"), session_specific_state ? true : false);
504 if (_session) {
505 instantiate (*cpi);
506 } else {
507 cpi->requested = true;
508 }
509 } else {
510 if (!cpi->state) {
511 cpi->state = new XMLNode (**citer);
512 cpi->state->set_property (X_("active"), false);
513 cpi->state->set_property (X_("session-state"), session_specific_state ? true : false);
514 }
515 cpi->requested = false;
516 if (_session) {
517 teardown (*cpi, false);
518 }
519 }
520 } else {
521 std::cerr << "protocol " << name << " not found\n";
522 }
523 }
524 }
525
526 return 0;
527 }
528
529 XMLNode&
get_state()530 ControlProtocolManager::get_state ()
531 {
532 XMLNode* root = new XMLNode (state_node_name);
533 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
534
535 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
536
537 if ((*i)->protocol) {
538 XMLNode& child_state ((*i)->protocol->get_state());
539 child_state.set_property (X_("active"), true);
540 delete ((*i)->state);
541 (*i)->state = new XMLNode (child_state);
542 root->add_child_nocopy (child_state);
543 } else if ((*i)->state) {
544 XMLNode* child_state = new XMLNode (*(*i)->state);
545 child_state->set_property (X_("active"), false);
546 root->add_child_nocopy (*child_state);
547 } else {
548 XMLNode* child_state = new XMLNode (X_("Protocol"));
549 child_state->set_property (X_("name"), (*i)->name);
550 child_state->set_property (X_("active"), false);
551 root->add_child_nocopy (*child_state);
552 }
553
554 }
555
556 return *root;
557 }
558
559
560 ControlProtocolManager&
instance()561 ControlProtocolManager::instance ()
562 {
563 if (_instance == 0) {
564 _instance = new ControlProtocolManager ();
565 }
566
567 return *_instance;
568 }
569
570 void
midi_connectivity_established()571 ControlProtocolManager::midi_connectivity_established ()
572 {
573 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
574
575 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
576 (*p)->midi_connectivity_established ();
577 }
578 }
579
580 void
register_request_buffer_factories()581 ControlProtocolManager::register_request_buffer_factories ()
582 {
583 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
584
585 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
586
587 if ((*i)->descriptor == 0) {
588 warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
589 continue;
590 }
591
592 if ((*i)->descriptor->request_buffer_factory) {
593 EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);
594 }
595 }
596 }
597
598 void
stripable_selection_changed(StripableNotificationListPtr sp)599 ControlProtocolManager::stripable_selection_changed (StripableNotificationListPtr sp)
600 {
601 /* this sets up the (static) data structures owned by ControlProtocol
602 that are "shared" across all control protocols.
603 */
604
605 DEBUG_TRACE (DEBUG::Selection, string_compose ("Surface manager: selection changed, now %1 stripables\n", sp ? sp->size() : -1));
606 StripableSelectionChanged (sp); /* EMIT SIGNAL */
607
608 /* now give each protocol the chance to respond to the selection change
609 */
610
611 {
612 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
613
614 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
615 DEBUG_TRACE (DEBUG::Selection, string_compose ("selection change notification for surface \"%1\"\n", (*p)->name()));
616 (*p)->stripable_selection_changed ();
617 }
618 }
619 }
620