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