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