#include <pbd/error.h>
#include <pbd/pathscanner.h>
+#include <control_protocol/control_protocol.h>
+
#include <ardour/session.h>
-#include <ardour/control_protocol.h>
#include <ardour/control_protocol_manager.h>
using namespace ARDOUR;
-using namespace PBD;
using namespace std;
+using namespace PBD;
#include "i18n.h"
ControlProtocolManager* ControlProtocolManager::_instance = 0;
+const string ControlProtocolManager::state_node_name = X_("ControlProtocols");
ControlProtocolManager::ControlProtocolManager ()
{
ControlProtocolManager::~ControlProtocolManager()
{
- LockMonitor lm (protocols_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (protocols_lock);
for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
delete (*i);
ControlProtocolManager::set_session (Session& s)
{
_session = &s;
- _session->going_away.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
+ _session->GoingAway.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
+
+ for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
+ if ((*i)->requested || (*i)->mandatory) {
+ instantiate (**i);
+ (*i)->requested = false;
+
+ if ((*i)->state) {
+ (*i)->protocol->set_state (*(*i)->state);
+ }
+ }
+ }
}
void
_session = 0;
{
- LockMonitor lm (protocols_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (protocols_lock);
for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
delete *p;
}
return 0;
}
- LockMonitor lm (protocols_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (protocols_lock);
control_protocols.push_back (cpi.protocol);
return cpi.protocol;
return 0;
}
+ if (cpi.mandatory) {
+ return 0;
+ }
+
cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
{
- LockMonitor lm (protocols_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (protocols_lock);
list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol);
if (p != control_protocols.end()) {
control_protocols.erase (p);
return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
}
+void
+ControlProtocolManager::load_mandatory_protocols ()
+{
+ if (_session == 0) {
+ return;
+ }
+
+ for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
+ if ((*i)->mandatory && ((*i)->protocol == 0)) {
+ info << string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name) << endmsg;
+ instantiate (**i);
+ }
+ }
+}
+
void
ControlProtocolManager::discover_control_protocols (string path)
{
vector<string *> *found;
PathScanner scanner;
+ cerr << "looking for control protocols in " << path << endl;
+
found = scanner (path, protocol_filter, 0, false, true);
for (vector<string*>::iterator i = found->begin(); i != found->end(); ++i) {
if ((descriptor = get_descriptor (path)) != 0) {
- ControlProtocolInfo* info = new ControlProtocolInfo ();
-
- info->descriptor = descriptor;
- info->name = descriptor->name;
- info->path = path;
- info->protocol = 0;
-
- control_protocol_info.push_back (info);
+ ControlProtocolInfo* cpi = new ControlProtocolInfo ();
+
+ if (!descriptor->probe (descriptor)) {
+ info << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg;
+ } else {
+
+ cpi->descriptor = descriptor;
+ cpi->name = descriptor->name;
+ cpi->path = path;
+ cpi->protocol = 0;
+ cpi->requested = false;
+ cpi->mandatory = descriptor->mandatory;
+ cpi->state = 0;
+
+ control_protocol_info.push_back (cpi);
+
+ info << string_compose(_("Control surface protocol discovered: \"%1\""), cpi->name) << endmsg;
+ }
dlclose (descriptor->module);
-
}
return 0;
method (*i);
}
}
+
+ControlProtocolInfo*
+ControlProtocolManager::cpi_by_name (string name)
+{
+ for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
+ if (name == (*i)->name) {
+ return *i;
+ }
+ }
+ return 0;
+}
+
+int
+ControlProtocolManager::set_state (const XMLNode& node)
+{
+ XMLNodeList clist;
+ XMLNodeConstIterator citer;
+ XMLProperty* prop;
+
+ clist = node.children();
+
+ for (citer = clist.begin(); citer != clist.end(); ++citer) {
+ if ((*citer)->name() == X_("Protocol")) {
+ prop = (*citer)->property (X_("active"));
+ if (prop && prop->value() == X_("yes")) {
+ if ((prop = (*citer)->property (X_("name"))) != 0) {
+ ControlProtocolInfo* cpi = cpi_by_name (prop->value());
+ if (cpi) {
+ if (_session) {
+ instantiate (*cpi);
+ } else {
+ cpi->requested = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+XMLNode&
+ControlProtocolManager::get_state (void)
+{
+ XMLNode* root = new XMLNode (state_node_name);
+ Glib::Mutex::Lock lm (protocols_lock);
+
+ for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
+ XMLNode* child = new XMLNode (X_("Protocol"));
+ child->add_property (X_("name"), (*i)->name);
+ child->add_property (X_("active"), (*i)->protocol ? "yes" : "no");
+ root->add_child_nocopy (*child);
+ }
+
+ return *root;
+}