possible extra housekeeping for control protocol modules.
[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 "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         cerr << "Tear down CPI module for " << cpi.name << endl;
242         delete (Glib::Module*) cpi.descriptor->module;
243         /* cpi->descriptor is now inaccessible since dlclose() or equivalent
244          * has been performed, and the descriptor is (or could be) a static
245          * object made accessible by dlopen().
246          */
247         cpi.descriptor = 0;
248
249         ProtocolStatusChange (&cpi);
250
251         return 0;
252 }
253
254 void
255 ControlProtocolManager::load_mandatory_protocols ()
256 {
257         if (_session == 0) {
258                 return;
259         }
260
261         Glib::Threads::Mutex::Lock lm (protocols_lock);
262
263         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
264                 if ((*i)->mandatory && ((*i)->protocol == 0)) {
265                         DEBUG_TRACE (DEBUG::ControlProtocols,
266                                      string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
267                         instantiate (**i);
268                 }
269         }
270 }
271
272 void
273 ControlProtocolManager::discover_control_protocols ()
274 {
275         vector<std::string> cp_modules;
276
277 #ifdef COMPILER_MSVC
278    /**
279     * Different build targets (Debug / Release etc) use different versions
280     * of the 'C' runtime (which can't be 'mixed & matched'). Therefore, in
281     * case the supplied search path contains multiple version(s) of a given
282     * module, only select the one(s) which match the current build target
283     */
284         #if defined (_DEBUG)
285                 Glib::PatternSpec dll_extension_pattern("*D.dll");
286         #elif defined (RDC_BUILD)
287                 Glib::PatternSpec dll_extension_pattern("*RDC.dll");
288         #elif defined (_WIN64)
289                 Glib::PatternSpec dll_extension_pattern("*64.dll");
290         #else
291                 Glib::PatternSpec dll_extension_pattern("*32.dll");
292         #endif
293 #else
294         Glib::PatternSpec dll_extension_pattern("*.dll");
295 #endif
296
297         Glib::PatternSpec so_extension_pattern("*.so");
298         Glib::PatternSpec dylib_extension_pattern("*.dylib");
299
300         find_files_matching_pattern (cp_modules, control_protocol_search_path (),
301                                      dll_extension_pattern);
302
303         find_files_matching_pattern (cp_modules, control_protocol_search_path (),
304                                      so_extension_pattern);
305
306         find_files_matching_pattern (cp_modules, control_protocol_search_path (),
307                                      dylib_extension_pattern);
308
309         DEBUG_TRACE (DEBUG::ControlProtocols,
310                      string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
311
312         for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
313                 control_protocol_discover (*i);
314         }
315 }
316
317 int
318 ControlProtocolManager::control_protocol_discover (string path)
319 {
320         ControlProtocolDescriptor* descriptor;
321
322 #ifdef __APPLE__
323         /* don't load OS X shared objects that are just symlinks to the real thing.
324          */
325
326         if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
327                 return 0;
328         }
329 #endif
330
331         if ((descriptor = get_descriptor (path)) != 0) {
332
333                 if (!descriptor->probe (descriptor)) {
334                         DEBUG_TRACE (DEBUG::ControlProtocols,
335                                      string_compose (_("Control protocol %1 not usable"), descriptor->name));
336                 } else {
337
338                         ControlProtocolInfo* cpi = new ControlProtocolInfo ();
339
340                         cpi->descriptor = descriptor;
341                         cpi->name = descriptor->name;
342                         cpi->path = path;
343                         cpi->protocol = 0;
344                         cpi->requested = false;
345                         cpi->mandatory = descriptor->mandatory;
346                         cpi->supports_feedback = descriptor->supports_feedback;
347                         cpi->state = 0;
348
349                         control_protocol_info.push_back (cpi);
350
351                         DEBUG_TRACE (DEBUG::ControlProtocols,
352                                      string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
353                 }
354         }
355
356         return 0;
357 }
358
359 ControlProtocolDescriptor*
360 ControlProtocolManager::get_descriptor (string path)
361 {
362         Glib::Module* module = new Glib::Module(path);
363         ControlProtocolDescriptor *descriptor = 0;
364         ControlProtocolDescriptor* (*dfunc)(void);
365         void* func = 0;
366
367         if (!(*module)) {
368                 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
369                 delete module;
370                 return 0;
371         }
372
373         if (!module->get_symbol("protocol_descriptor", func)) {
374                 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
375                 error << Glib::Module::get_last_error() << endmsg;
376                 delete module;
377                 return 0;
378         }
379
380         dfunc = (ControlProtocolDescriptor* (*)(void))func;
381         descriptor = dfunc();
382
383         if (descriptor) {
384                 descriptor->module = (void*)module;
385         }
386
387         return descriptor;
388 }
389
390 void
391 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
392 {
393         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
394                 method (*i);
395         }
396 }
397
398 ControlProtocolInfo*
399 ControlProtocolManager::cpi_by_name (string name)
400 {
401         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
402                 if (name == (*i)->name) {
403                         return *i;
404                 }
405         }
406         return 0;
407 }
408
409 int
410 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
411 {
412         XMLNodeList clist;
413         XMLNodeConstIterator citer;
414         XMLProperty* prop;
415
416         Glib::Threads::Mutex::Lock lm (protocols_lock);
417
418         clist = node.children();
419
420         for (citer = clist.begin(); citer != clist.end(); ++citer) {
421                 if ((*citer)->name() == X_("Protocol")) {
422
423                         if ((prop = (*citer)->property (X_("active"))) == 0) {
424                                 continue;
425                         }
426
427                         bool active = string_is_affirmative (prop->value());
428
429                         if ((prop = (*citer)->property (X_("name"))) == 0) {
430                                 continue;
431                         }
432
433                         ControlProtocolInfo* cpi = cpi_by_name (prop->value());
434
435                         if (cpi) {
436                                 cpi->state = new XMLNode (**citer);
437
438                                 if (active) {
439                                         if (_session) {
440                                                 instantiate (*cpi);
441                                         } else {
442                                                 cpi->requested = true;
443                                         }
444                                 } else {
445                                         if (_session) {
446                                                 teardown (*cpi);
447                                         } else {
448                                                 cpi->requested = false;
449                                         }
450                                 }
451                         }
452                 }
453         }
454
455         return 0;
456 }
457
458 XMLNode&
459 ControlProtocolManager::get_state ()
460 {
461         XMLNode* root = new XMLNode (state_node_name);
462         Glib::Threads::Mutex::Lock lm (protocols_lock);
463
464         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
465
466                 if ((*i)->protocol) {
467                         XMLNode& child_state ((*i)->protocol->get_state());
468                         child_state.add_property (X_("active"), "yes");
469                         root->add_child_nocopy (child_state);
470                 } else if ((*i)->state) {
471                         XMLNode* child_state = new XMLNode (*(*i)->state);
472                         child_state->add_property (X_("active"), "no");
473                         root->add_child_nocopy (*child_state);
474                 } else {
475                         XMLNode* child_state = new XMLNode (X_("Protocol"));
476                         child_state->add_property (X_("name"), (*i)->name);
477                         child_state->add_property (X_("active"), "no");
478                         root->add_child_nocopy (*child_state);
479                 }
480
481         }
482
483         return *root;
484 }
485
486
487 ControlProtocolManager&
488 ControlProtocolManager::instance ()
489 {
490         if (_instance == 0) {
491                 _instance = new ControlProtocolManager ();
492         }
493
494         return *_instance;
495 }
496
497 void
498 ControlProtocolManager::midi_connectivity_established ()
499 {
500         Glib::Threads::Mutex::Lock lm (protocols_lock);
501
502         for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
503                 (*p)->midi_connectivity_established ();
504         }
505 }
506
507 void
508 ControlProtocolManager::register_request_buffer_factories ()
509 {
510         Glib::Threads::Mutex::Lock lm (protocols_lock);
511
512         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
513
514                 if ((*i)->descriptor == 0) {
515                         warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg;
516                         continue;
517                 }
518
519                 if ((*i)->descriptor->request_buffer_factory) {
520                         EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory);
521                 }
522         }
523 }