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