merge with master and fix 4 conflicts by hand
[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
130         {
131                 Glib::Threads::Mutex::Lock lm (protocols_lock);
132
133                 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
134                         delete *p;
135                 }
136
137                 control_protocols.clear ();
138
139                 for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
140                         // mark existing protocols as requested
141                         // otherwise the ControlProtocol instances are not recreated in set_session
142                         if ((*p)->protocol) {
143                                 (*p)->requested = true;
144                                 (*p)->protocol = 0;
145                         }
146                 }
147         }
148 }
149
150 ControlProtocol*
151 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
152 {
153         /* CALLER MUST HOLD LOCK */
154
155         if (_session == 0) {
156                 return 0;
157         }
158
159         cpi.descriptor = get_descriptor (cpi.path);
160
161         DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
162
163         if (cpi.descriptor == 0) {
164                 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
165                 return 0;
166         }
167
168         DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
169
170         if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) {
171                 error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg;
172                 return 0;
173         }
174
175         control_protocols.push_back (cpi.protocol);
176
177         ProtocolStatusChange (&cpi);
178
179         return cpi.protocol;
180 }
181
182 int
183 ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
184 {
185         if (!cpi.protocol) {
186                 return 0;
187         }
188
189         if (!cpi.descriptor) {
190                 return 0;
191         }
192
193         if (cpi.mandatory) {
194                 return 0;
195         }
196         
197         /* save current state */
198
199         delete cpi.state;
200         cpi.state = new XMLNode (cpi.protocol->get_state());
201         cpi.state->add_property (X_("active"), "no");
202
203         cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
204
205         {
206                 Glib::Threads::Mutex::Lock lm (protocols_lock);
207                 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
208                 if (p != control_protocols.end()) {
209                         control_protocols.erase (p);
210                 } else {
211                         cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
212                 }
213         }
214
215         cpi.protocol = 0;
216         delete cpi.state;
217         cpi.state = 0;
218         delete (Glib::Module*)cpi.descriptor->module;
219
220         ProtocolStatusChange (&cpi);
221
222         return 0;
223 }
224
225 void
226 ControlProtocolManager::load_mandatory_protocols ()
227 {
228         if (_session == 0) {
229                 return;
230         }
231
232         Glib::Threads::Mutex::Lock lm (protocols_lock);
233
234         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
235                 if ((*i)->mandatory && ((*i)->protocol == 0)) {
236                         DEBUG_TRACE (DEBUG::ControlProtocols,
237                                      string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
238                         instantiate (**i);
239                 }
240         }
241 }
242
243 void
244 ControlProtocolManager::discover_control_protocols ()
245 {
246         vector<std::string> cp_modules;
247
248 #ifdef COMPILER_MSVC
249    /**
250     * Different build targets (Debug / Release etc) use different versions
251     * of the 'C' runtime (which can't be 'mixed & matched'). Therefore, in
252     * case the supplied search path contains multiple version(s) of a given
253     * module, only select the one(s) which match the current build target
254     */
255         #if defined (_DEBUG)
256                 Glib::PatternSpec dll_extension_pattern("*D.dll");
257         #elif defined (RDC_BUILD)
258                 Glib::PatternSpec dll_extension_pattern("*RDC.dll");
259         #elif defined (_WIN64)
260                 Glib::PatternSpec dll_extension_pattern("*64.dll");
261         #else
262                 Glib::PatternSpec dll_extension_pattern("*32.dll");
263         #endif
264 #else
265         Glib::PatternSpec dll_extension_pattern("*.dll");
266 #endif
267
268         Glib::PatternSpec so_extension_pattern("*.so");
269         Glib::PatternSpec dylib_extension_pattern("*.dylib");
270
271         find_matching_files_in_search_path (control_protocol_search_path (),
272                                             dll_extension_pattern, cp_modules);
273
274         find_matching_files_in_search_path (control_protocol_search_path (),
275                                             so_extension_pattern, cp_modules);
276
277         find_matching_files_in_search_path (control_protocol_search_path (),
278                                             dylib_extension_pattern, cp_modules);
279
280         DEBUG_TRACE (DEBUG::ControlProtocols, 
281                      string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
282         
283         for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
284                 control_protocol_discover (*i);
285         }
286 }
287
288 int
289 ControlProtocolManager::control_protocol_discover (string path)
290 {
291         ControlProtocolDescriptor* descriptor;
292
293 #ifdef __APPLE__
294         /* don't load OS X shared objects that are just symlinks to the real thing.
295          */
296
297         if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
298                 return 0;
299         }
300 #endif
301
302         if ((descriptor = get_descriptor (path)) != 0) {
303
304                 if (!descriptor->probe (descriptor)) {
305                         DEBUG_TRACE (DEBUG::ControlProtocols,
306                                      string_compose (_("Control protocol %1 not usable"), descriptor->name));
307                 } else {
308
309                         ControlProtocolInfo* cpi = new ControlProtocolInfo ();
310
311                         cpi->descriptor = descriptor;
312                         cpi->name = descriptor->name;
313                         cpi->path = path;
314                         cpi->protocol = 0;
315                         cpi->requested = false;
316                         cpi->mandatory = descriptor->mandatory;
317                         cpi->supports_feedback = descriptor->supports_feedback;
318                         cpi->state = 0;
319
320                         control_protocol_info.push_back (cpi);
321
322                         DEBUG_TRACE (DEBUG::ControlProtocols, 
323                                      string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
324                 }
325
326                 delete (Glib::Module*)descriptor->module;
327         }
328
329         return 0;
330 }
331
332 ControlProtocolDescriptor*
333 ControlProtocolManager::get_descriptor (string path)
334 {
335         Glib::Module* module = new Glib::Module(path);
336         ControlProtocolDescriptor *descriptor = 0;
337         ControlProtocolDescriptor* (*dfunc)(void);
338         void* func = 0;
339
340         if (!(*module)) {
341                 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
342                 delete module;
343                 return 0;
344         }
345
346         if (!module->get_symbol("protocol_descriptor", func)) {
347                 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
348                 error << Glib::Module::get_last_error() << endmsg;
349                 delete module;
350                 return 0;
351         }
352
353         dfunc = (ControlProtocolDescriptor* (*)(void))func;
354         descriptor = dfunc();
355
356         if (descriptor) {
357                 descriptor->module = (void*)module;
358         } else {
359                 delete module;
360         }
361
362         return descriptor;
363 }
364
365 void
366 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
367 {
368         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
369                 method (*i);
370         }
371 }
372
373 ControlProtocolInfo*
374 ControlProtocolManager::cpi_by_name (string name)
375 {
376         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
377                 if (name == (*i)->name) {
378                         return *i;
379                 }
380         }
381         return 0;
382 }
383
384 int
385 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
386 {
387         XMLNodeList clist;
388         XMLNodeConstIterator citer;
389         XMLProperty* prop;
390
391         Glib::Threads::Mutex::Lock lm (protocols_lock);
392
393         clist = node.children();
394
395         for (citer = clist.begin(); citer != clist.end(); ++citer) {
396                 if ((*citer)->name() == X_("Protocol")) {
397
398                         if ((prop = (*citer)->property (X_("active"))) == 0) {
399                                 continue;
400                         }
401
402                         bool active = string_is_affirmative (prop->value());
403                         
404                         if ((prop = (*citer)->property (X_("name"))) == 0) {
405                                 continue;
406                         }
407
408                         ControlProtocolInfo* cpi = cpi_by_name (prop->value());
409                         
410                         if (cpi) {
411                                 cpi->state = new XMLNode (**citer);
412                                 
413                                 if (active) {
414                                         if (_session) {
415                                                 instantiate (*cpi);
416                                         } else {
417                                                 cpi->requested = true;
418                                         }
419                                 } else {
420                                         if (_session) {
421                                                 teardown (*cpi);
422                                         } else {
423                                                 cpi->requested = false;
424                                         }
425                                 }
426                         }
427                 }
428         }
429
430         return 0;
431 }
432
433 XMLNode&
434 ControlProtocolManager::get_state ()
435 {
436         XMLNode* root = new XMLNode (state_node_name);
437         Glib::Threads::Mutex::Lock lm (protocols_lock);
438
439         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
440
441                 if ((*i)->protocol) {
442                         XMLNode& child_state ((*i)->protocol->get_state());
443                         child_state.add_property (X_("active"), "yes");
444                         root->add_child_nocopy (child_state);
445                 } else if ((*i)->state) {
446                         XMLNode* child_state = new XMLNode (*(*i)->state);
447                         child_state->add_property (X_("active"), "no");
448                         root->add_child_nocopy (*child_state);
449                 } else {
450                         XMLNode* child_state = new XMLNode (X_("Protocol"));
451                         child_state->add_property (X_("name"), (*i)->name);
452                         child_state->add_property (X_("active"), "no");
453                         root->add_child_nocopy (*child_state);
454                 }
455
456         }
457
458         return *root;
459 }
460
461
462 ControlProtocolManager&
463 ControlProtocolManager::instance ()
464 {
465         if (_instance == 0) {
466                 _instance = new ControlProtocolManager ();
467         }
468
469         return *_instance;
470 }
471
472 void
473 ControlProtocolManager::midi_connectivity_established ()
474 {
475         Glib::Threads::Mutex::Lock lm (protocols_lock);
476
477         for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
478                 (*p)->midi_connectivity_established ();
479         }
480 }