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