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