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