Merge branch 'windows' of git.ardour.org:ardour/ardour into windows
[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 #ifdef SearchPath
34 #undef SearchPath
35 #endif
36
37 #include "ardour/control_protocol_search_path.h"
38
39
40 using namespace ARDOUR;
41 using namespace std;
42 using namespace PBD;
43
44 #include "i18n.h"
45
46 ControlProtocolManager* ControlProtocolManager::_instance = 0;
47 const string ControlProtocolManager::state_node_name = X_("ControlProtocols");
48
49 ControlProtocolManager::ControlProtocolManager ()
50 {
51 }
52
53 ControlProtocolManager::~ControlProtocolManager()
54 {
55         Glib::Threads::Mutex::Lock lm (protocols_lock);
56
57         for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
58                 delete (*i);
59         }
60
61         control_protocols.clear ();
62
63
64         for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
65                 delete (*p);
66         }
67
68         control_protocol_info.clear();
69 }
70
71 void
72 ControlProtocolManager::set_session (Session* s)
73 {
74         SessionHandlePtr::set_session (s);
75
76         if (_session) {
77                 Glib::Threads::Mutex::Lock lm (protocols_lock);
78
79                 for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
80                         if ((*i)->requested || (*i)->mandatory) {
81                                 
82                                 instantiate (**i);
83                                 (*i)->requested = false;
84
85                                 if ((*i)->protocol) {
86                                         if ((*i)->state) {
87                                                 (*i)->protocol->set_state (*(*i)->state, Stateful::loading_state_version);
88                                         } else {
89                                                 /* guarantee a call to
90                                                    set_state() whether we have
91                                                    existing state or not
92                                                 */
93                                                 (*i)->protocol->set_state (XMLNode(""), Stateful::loading_state_version);
94                                         }
95                                 }
96                         }
97                 }
98         }
99 }
100
101 void
102 ControlProtocolManager::session_going_away()
103 {
104         SessionHandlePtr::session_going_away ();
105
106         {
107                 Glib::Threads::Mutex::Lock lm (protocols_lock);
108
109                 for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
110                         delete *p;
111                 }
112
113                 control_protocols.clear ();
114
115                 for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) {
116                         // mark existing protocols as requested
117                         // otherwise the ControlProtocol instances are not recreated in set_session
118                         if ((*p)->protocol) {
119                                 (*p)->requested = true;
120                                 (*p)->protocol = 0;
121                         }
122                 }
123         }
124 }
125
126 ControlProtocol*
127 ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
128 {
129         /* CALLER MUST HOLD LOCK */
130
131         if (_session == 0) {
132                 return 0;
133         }
134
135         cpi.descriptor = get_descriptor (cpi.path);
136
137         DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("instantiating %1\n", cpi.name));
138
139         if (cpi.descriptor == 0) {
140                 error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg;
141                 return 0;
142         }
143
144         DEBUG_TRACE (DEBUG::ControlProtocols, string_compose ("initializing %1\n", cpi.name));
145
146         if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) {
147                 error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg;
148                 return 0;
149         }
150
151         control_protocols.push_back (cpi.protocol);
152
153         ProtocolStatusChange (&cpi);
154
155         return cpi.protocol;
156 }
157
158 int
159 ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
160 {
161         if (!cpi.protocol) {
162                 return 0;
163         }
164
165         if (!cpi.descriptor) {
166                 return 0;
167         }
168
169         if (cpi.mandatory) {
170                 return 0;
171         }
172
173         cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
174
175         {
176                 Glib::Threads::Mutex::Lock lm (protocols_lock);
177                 list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
178                 if (p != control_protocols.end()) {
179                         control_protocols.erase (p);
180                 } else {
181                         cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
182                 }
183         }
184
185         cpi.protocol = 0;
186         delete cpi.state;
187         cpi.state = 0;
188         delete (Glib::Module*)cpi.descriptor->module;
189
190         ProtocolStatusChange (&cpi);
191
192         return 0;
193 }
194
195 void
196 ControlProtocolManager::load_mandatory_protocols ()
197 {
198         if (_session == 0) {
199                 return;
200         }
201
202         Glib::Threads::Mutex::Lock lm (protocols_lock);
203
204         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
205                 if ((*i)->mandatory && ((*i)->protocol == 0)) {
206                         DEBUG_TRACE (DEBUG::ControlProtocols,
207                                      string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name));
208                         instantiate (**i);
209                 }
210         }
211 }
212
213 void
214 ControlProtocolManager::discover_control_protocols ()
215 {
216         vector<std::string> cp_modules;
217
218         Glib::PatternSpec so_extension_pattern("*.so");
219         Glib::PatternSpec dylib_extension_pattern("*.dylib");
220
221         find_matching_files_in_search_path (control_protocol_search_path (),
222                                             so_extension_pattern, cp_modules);
223
224         find_matching_files_in_search_path (control_protocol_search_path (),
225                                             dylib_extension_pattern, cp_modules);
226
227         DEBUG_TRACE (DEBUG::ControlProtocols, 
228                      string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
229         
230         for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
231                 control_protocol_discover (*i);
232         }
233 }
234
235 int
236 ControlProtocolManager::control_protocol_discover (string path)
237 {
238         ControlProtocolDescriptor* descriptor;
239
240 #ifdef __APPLE__
241         /* don't load OS X shared objects that are just symlinks to the real thing.
242          */
243
244         if (path.find (".dylib") && Glib::file_test (path, Glib::FILE_TEST_IS_SYMLINK)) {
245                 return 0;
246         }
247 #endif
248
249         if ((descriptor = get_descriptor (path)) != 0) {
250
251                 if (!descriptor->probe (descriptor)) {
252                         DEBUG_TRACE (DEBUG::ControlProtocols,
253                                      string_compose (_("Control protocol %1 not usable"), descriptor->name));
254                 } else {
255
256                         ControlProtocolInfo* cpi = new ControlProtocolInfo ();
257
258                         cpi->descriptor = descriptor;
259                         cpi->name = descriptor->name;
260                         cpi->path = path;
261                         cpi->protocol = 0;
262                         cpi->requested = false;
263                         cpi->mandatory = descriptor->mandatory;
264                         cpi->supports_feedback = descriptor->supports_feedback;
265                         cpi->state = 0;
266
267                         control_protocol_info.push_back (cpi);
268
269                         DEBUG_TRACE (DEBUG::ControlProtocols, 
270                                      string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
271                 }
272
273                 delete (Glib::Module*)descriptor->module;
274         }
275
276         return 0;
277 }
278
279 ControlProtocolDescriptor*
280 ControlProtocolManager::get_descriptor (string path)
281 {
282         Glib::Module* module = new Glib::Module(path);
283         ControlProtocolDescriptor *descriptor = 0;
284         ControlProtocolDescriptor* (*dfunc)(void);
285         void* func = 0;
286
287         if (!(*module)) {
288                 error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
289                 delete module;
290                 return 0;
291         }
292
293         if (!module->get_symbol("protocol_descriptor", func)) {
294                 error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
295                 error << Glib::Module::get_last_error() << endmsg;
296                 delete module;
297                 return 0;
298         }
299
300         dfunc = (ControlProtocolDescriptor* (*)(void))func;
301         descriptor = dfunc();
302
303         if (descriptor) {
304                 descriptor->module = (void*)module;
305         } else {
306                 delete module;
307         }
308
309         return descriptor;
310 }
311
312 void
313 ControlProtocolManager::foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)> method)
314 {
315         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
316                 method (*i);
317         }
318 }
319
320 ControlProtocolInfo*
321 ControlProtocolManager::cpi_by_name (string name)
322 {
323         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
324                 if (name == (*i)->name) {
325                         return *i;
326                 }
327         }
328         return 0;
329 }
330
331 int
332 ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
333 {
334         XMLNodeList clist;
335         XMLNodeConstIterator citer;
336         XMLProperty* prop;
337
338         Glib::Threads::Mutex::Lock lm (protocols_lock);
339
340         clist = node.children();
341
342         for (citer = clist.begin(); citer != clist.end(); ++citer) {
343                 if ((*citer)->name() == X_("Protocol")) {
344
345                         if ((prop = (*citer)->property (X_("active"))) == 0) {
346                                 continue;
347                         }
348
349                         bool active = string_is_affirmative (prop->value());
350                         
351                         if ((prop = (*citer)->property (X_("name"))) == 0) {
352                                 continue;
353                         }
354
355                         ControlProtocolInfo* cpi = cpi_by_name (prop->value());
356                         
357                         if (cpi) {
358                                 cpi->state = new XMLNode (**citer);
359                                 
360                                 if (active) {
361                                         if (_session) {
362                                                 instantiate (*cpi);
363                                         } else {
364                                                 cpi->requested = true;
365                                         }
366                                 } else {
367                                         if (_session) {
368                                                 teardown (*cpi);
369                                         } else {
370                                                 cpi->requested = false;
371                                         }
372                                 }
373                         }
374                 }
375         }
376
377         return 0;
378 }
379
380 XMLNode&
381 ControlProtocolManager::get_state ()
382 {
383         XMLNode* root = new XMLNode (state_node_name);
384         Glib::Threads::Mutex::Lock lm (protocols_lock);
385
386         for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
387
388                 XMLNode * child;
389
390                 if ((*i)->protocol) {
391                         child = &((*i)->protocol->get_state());
392                         child->add_property (X_("active"), "yes");
393                         // should we update (*i)->state here?  probably.
394                         root->add_child_nocopy (*child);
395                 } else if ((*i)->state) {
396                         // keep ownership clear
397                         root->add_child_copy (*(*i)->state);
398                 } else {
399                         child = new XMLNode (X_("Protocol"));
400                         child->add_property (X_("name"), (*i)->name);
401                         child->add_property (X_("active"), "no");
402                         root->add_child_nocopy (*child);
403                 }
404         }
405
406         return *root;
407 }
408
409
410 ControlProtocolManager&
411 ControlProtocolManager::instance ()
412 {
413         if (_instance == 0) {
414                 _instance = new ControlProtocolManager ();
415         }
416
417         return *_instance;
418 }
419
420 void
421 ControlProtocolManager::midi_connectivity_established ()
422 {
423         Glib::Threads::Mutex::Lock lm (protocols_lock);
424
425         for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
426                 (*p)->midi_connectivity_established ();
427         }
428 }