7205b3e79e18368b429b8b62e814a729263ee56c
[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                 if (!sac.empty()) {
100                         StripableNotificationListPtr v (new StripableNotificationList);
101                         for (CoreSelection::StripableAutomationControls::iterator i = sac.begin(); i != sac.end(); ++i) {
102                                 if ((*i).stripable) {
103                                         v->push_back (boost::weak_ptr<Stripable> ((*i).stripable));
104                                 }
105                         }
106                         if (!v->empty()) {
107                                 StripableSelectionChanged (v); /* EMIT SIGNAL */
108                         }
109                 }
110
111                 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
112
113                 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
114                         if ((*i)->requested || (*i)->mandatory) {
115                                 (void) activate (**i);
116                         }
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                                 std::cerr << "protocol " << name << " active ? " << active << std::endl;
487
488                                 if (active) {
489                                         delete cpi->state;
490                                         cpi->state = new XMLNode (**citer);
491                                         if (_session) {
492                                                 instantiate (*cpi);
493                                         } else {
494                                                 cpi->requested = true;
495                                         }
496                                 } else {
497                                         if (!cpi->state) {
498                                                 cpi->state = new XMLNode (**citer);
499                                                 cpi->state->set_property (X_("active"), false);
500                                         }
501                                         cpi->requested = false;
502                                         if (_session) {
503                                                 teardown (*cpi, false);
504                                         }
505                                 }
506                         } else {
507                                 std::cerr << "protocol " << name << " not found\n";
508                         }
509                 }
510         }
511
512         return 0;
513 }
514
515 XMLNode&
516 ControlProtocolManager::get_state ()
517 {
518         XMLNode* root = new XMLNode (state_node_name);
519         Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
520
521         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
522
523                 if ((*i)->protocol) {
524                         XMLNode& child_state ((*i)->protocol->get_state());
525                         child_state.set_property (X_("active"), true);
526                         root->add_child_nocopy (child_state);
527                 } else if ((*i)->state) {
528                         XMLNode* child_state = new XMLNode (*(*i)->state);
529                         child_state->set_property (X_("active"), false);
530                         root->add_child_nocopy (*child_state);
531                 } else {
532                         XMLNode* child_state = new XMLNode (X_("Protocol"));
533                         child_state->set_property (X_("name"), (*i)->name);
534                         child_state->set_property (X_("active"), false);
535                         root->add_child_nocopy (*child_state);
536                 }
537
538         }
539
540         return *root;
541 }
542
543
544 ControlProtocolManager&
545 ControlProtocolManager::instance ()
546 {
547         if (_instance == 0) {
548                 _instance = new ControlProtocolManager ();
549         }
550
551         return *_instance;
552 }
553
554 void
555 ControlProtocolManager::midi_connectivity_established ()
556 {
557         Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
558
559         for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
560                 (*p)->midi_connectivity_established ();
561         }
562 }
563
564 void
565 ControlProtocolManager::register_request_buffer_factories ()
566 {
567         Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
568
569         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
570
571                 if ((*i)->descriptor == 0) {
572                         warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
573                         continue;
574                 }
575
576                 if ((*i)->descriptor->request_buffer_factory) {
577                         EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);
578                 }
579         }
580 }
581
582 void
583 ControlProtocolManager::stripable_selection_changed (StripableNotificationListPtr sp)
584 {
585         /* this sets up the (static) data structures owned by ControlProtocol
586            that are "shared" across all control protocols.
587         */
588
589         DEBUG_TRACE (DEBUG::Selection, string_compose ("Surface manager: selection changed, now %1 stripables\n", sp ? sp->size() : -1));
590         StripableSelectionChanged (sp); /* EMIT SIGNAL */
591
592         /* now give each protocol the chance to respond to the selection change
593          */
594
595         {
596                 Glib::Threads::RWLock::ReaderLock lm (protocols_lock);
597
598                 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
599                         DEBUG_TRACE (DEBUG::Selection, string_compose ("selection change notification for surface \"%1\"\n", (*p)->name()));
600                         (*p)->stripable_selection_changed ();
601                 }
602         }
603 }