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