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