2 Copyright (C) 2000-2007 Paul Davis
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.
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.
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.
22 #include "pbd/compose.h"
23 #include "pbd/file_utils.h"
24 #include "pbd/error.h"
26 #include "control_protocol/control_protocol.h"
28 #include "ardour/session.h"
29 #include "ardour/control_protocol_manager.h"
30 #include "ardour/control_protocol_search_path.h"
32 using namespace ARDOUR
;
38 ControlProtocolManager
* ControlProtocolManager::_instance
= 0;
39 const string
ControlProtocolManager::state_node_name
= X_("ControlProtocols");
41 ControlProtocolManager::ControlProtocolManager ()
46 ControlProtocolManager::~ControlProtocolManager()
48 Glib::Mutex::Lock
lm (protocols_lock
);
50 for (list
<ControlProtocol
*>::iterator i
= control_protocols
.begin(); i
!= control_protocols
.end(); ++i
) {
54 control_protocols
.clear ();
57 for (list
<ControlProtocolInfo
*>::iterator p
= control_protocol_info
.begin(); p
!= control_protocol_info
.end(); ++p
) {
61 control_protocol_info
.clear();
65 ControlProtocolManager::set_session (Session
* s
)
67 SessionHandlePtr::set_session (s
);
70 Glib::Mutex::Lock
lm (protocols_lock
);
72 for (list
<ControlProtocolInfo
*>::iterator i
= control_protocol_info
.begin(); i
!= control_protocol_info
.end(); ++i
) {
73 if ((*i
)->requested
|| (*i
)->mandatory
) {
75 (*i
)->requested
= false;
77 if ((*i
)->protocol
&& (*i
)->state
) {
78 (*i
)->protocol
->set_state (*(*i
)->state
, Stateful::loading_state_version
);
86 ControlProtocolManager::session_going_away()
88 SessionHandlePtr::session_going_away ();
91 Glib::Mutex::Lock
lm (protocols_lock
);
93 for (list
<ControlProtocol
*>::iterator p
= control_protocols
.begin(); p
!= control_protocols
.end(); ++p
) {
97 control_protocols
.clear ();
99 for (list
<ControlProtocolInfo
*>::iterator p
= control_protocol_info
.begin(); p
!= control_protocol_info
.end(); ++p
) {
100 // mark existing protocols as requested
101 // otherwise the ControlProtocol instances are not recreated in set_session
102 if ((*p
)->protocol
) {
103 (*p
)->requested
= true;
111 ControlProtocolManager::instantiate (ControlProtocolInfo
& cpi
)
113 /* CALLER MUST HOLD LOCK */
119 cpi
.descriptor
= get_descriptor (cpi
.path
);
121 if (cpi
.descriptor
== 0) {
122 error
<< string_compose (_("control protocol name \"%1\" has no descriptor"), cpi
.name
) << endmsg
;
126 if ((cpi
.protocol
= cpi
.descriptor
->initialize (cpi
.descriptor
, _session
)) == 0) {
127 error
<< string_compose (_("control protocol name \"%1\" could not be initialized"), cpi
.name
) << endmsg
;
131 control_protocols
.push_back (cpi
.protocol
);
137 ControlProtocolManager::teardown (ControlProtocolInfo
& cpi
)
143 if (!cpi
.descriptor
) {
151 cpi
.descriptor
->destroy (cpi
.descriptor
, cpi
.protocol
);
154 Glib::Mutex::Lock
lm (protocols_lock
);
155 list
<ControlProtocol
*>::iterator p
= find (control_protocols
.begin(), control_protocols
.end(), cpi
.protocol
);
156 if (p
!= control_protocols
.end()) {
157 control_protocols
.erase (p
);
159 cerr
<< "Programming error: ControlProtocolManager::teardown() called for " << cpi
.name
<< ", but it was not found in control_protocols" << endl
;
164 dlclose (cpi
.descriptor
->module
);
169 ControlProtocolManager::load_mandatory_protocols ()
175 Glib::Mutex::Lock
lm (protocols_lock
);
177 for (list
<ControlProtocolInfo
*>::iterator i
= control_protocol_info
.begin(); i
!= control_protocol_info
.end(); ++i
) {
178 if ((*i
)->mandatory
&& ((*i
)->protocol
== 0)) {
179 info
<< string_compose (_("Instantiating mandatory control protocol %1"), (*i
)->name
) << endmsg
;
186 ControlProtocolManager::discover_control_protocols ()
188 vector
<sys::path
> cp_modules
;
190 Glib::PatternSpec
so_extension_pattern("*.so");
191 Glib::PatternSpec
dylib_extension_pattern("*.dylib");
193 find_matching_files_in_search_path (control_protocol_search_path (),
194 so_extension_pattern
, cp_modules
);
196 find_matching_files_in_search_path (control_protocol_search_path (),
197 dylib_extension_pattern
, cp_modules
);
199 info
<< string_compose (_("looking for control protocols in %1"), control_protocol_search_path().to_string()) << endmsg
;
201 for (vector
<sys::path
>::iterator i
= cp_modules
.begin(); i
!= cp_modules
.end(); ++i
) {
202 control_protocol_discover ((*i
).to_string());
207 ControlProtocolManager::control_protocol_discover (string path
)
209 ControlProtocolDescriptor
* descriptor
;
211 if ((descriptor
= get_descriptor (path
)) != 0) {
213 ControlProtocolInfo
* cpi
= new ControlProtocolInfo ();
215 if (!descriptor
->probe (descriptor
)) {
216 info
<< string_compose (_("Control protocol %1 not usable"), descriptor
->name
) << endmsg
;
219 cpi
->descriptor
= descriptor
;
220 cpi
->name
= descriptor
->name
;
223 cpi
->requested
= false;
224 cpi
->mandatory
= descriptor
->mandatory
;
225 cpi
->supports_feedback
= descriptor
->supports_feedback
;
228 control_protocol_info
.push_back (cpi
);
230 info
<< string_compose(_("Control surface protocol discovered: \"%1\""), cpi
->name
) << endmsg
;
233 dlclose (descriptor
->module
);
239 ControlProtocolDescriptor
*
240 ControlProtocolManager::get_descriptor (string path
)
243 ControlProtocolDescriptor
*descriptor
= 0;
244 ControlProtocolDescriptor
* (*dfunc
)(void);
247 if ((module
= dlopen (path
.c_str(), RTLD_NOW
)) == 0) {
248 error
<< string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path
, dlerror()) << endmsg
;
253 dfunc
= (ControlProtocolDescriptor
* (*)(void)) dlsym (module
, "protocol_descriptor");
255 if ((errstr
= dlerror()) != 0) {
256 error
<< string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path
) << endmsg
;
257 error
<< errstr
<< endmsg
;
262 descriptor
= dfunc();
264 descriptor
->module
= module
;
273 ControlProtocolManager::foreach_known_protocol (boost::function
<void(const ControlProtocolInfo
*)> method
)
275 for (list
<ControlProtocolInfo
*>::iterator i
= control_protocol_info
.begin(); i
!= control_protocol_info
.end(); ++i
) {
281 ControlProtocolManager::cpi_by_name (string name
)
283 for (list
<ControlProtocolInfo
*>::iterator i
= control_protocol_info
.begin(); i
!= control_protocol_info
.end(); ++i
) {
284 if (name
== (*i
)->name
) {
292 ControlProtocolManager::set_state (const XMLNode
& node
, int /*version*/)
295 XMLNodeConstIterator citer
;
298 Glib::Mutex::Lock
lm (protocols_lock
);
300 clist
= node
.children();
302 for (citer
= clist
.begin(); citer
!= clist
.end(); ++citer
) {
303 if ((*citer
)->name() == X_("Protocol")) {
305 prop
= (*citer
)->property (X_("active"));
307 if (prop
&& string_is_affirmative (prop
->value())) {
308 if ((prop
= (*citer
)->property (X_("name"))) != 0) {
309 ControlProtocolInfo
* cpi
= cpi_by_name (prop
->value());
311 if (!(*citer
)->children().empty()) {
312 cpi
->state
= (*citer
)->children().front ();
320 cpi
->requested
= true;
331 ControlProtocolManager::get_state (void)
333 XMLNode
* root
= new XMLNode (state_node_name
);
334 Glib::Mutex::Lock
lm (protocols_lock
);
336 for (list
<ControlProtocolInfo
*>::iterator i
= control_protocol_info
.begin(); i
!= control_protocol_info
.end(); ++i
) {
340 if ((*i
)->protocol
) {
341 child
= &((*i
)->protocol
->get_state());
342 child
->add_property (X_("active"), "yes");
343 // should we update (*i)->state here? probably.
344 root
->add_child_nocopy (*child
);
346 else if ((*i
)->state
) {
347 // keep ownership clear
348 root
->add_child_copy (*(*i
)->state
);
351 child
= new XMLNode (X_("Protocol"));
352 child
->add_property (X_("name"), (*i
)->name
);
353 child
->add_property (X_("active"), "no");
354 root
->add_child_nocopy (*child
);
362 ControlProtocolManager::set_protocol_states (const XMLNode
& node
)
365 XMLNodeConstIterator niter
;
368 nlist
= node
.children();
370 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
372 XMLNode
* child
= (*niter
);
374 if ((prop
= child
->property ("name")) == 0) {
375 error
<< _("control protocol XML node has no name property. Ignored.") << endmsg
;
379 ControlProtocolInfo
* cpi
= cpi_by_name (prop
->value());
382 warning
<< string_compose (_("control protocol \"%1\" is not known. Ignored"), prop
->value()) << endmsg
;
386 /* copy the node so that ownership is clear */
388 cpi
->state
= new XMLNode (*child
);
392 ControlProtocolManager
&
393 ControlProtocolManager::instance ()
395 if (_instance
== 0) {
396 _instance
= new ControlProtocolManager ();