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