X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fcontrol_protocol_manager.cc;h=1ff6c28ef36482af33dc87d5fc2e860b289f4359;hb=1bd4c5b3a212460eed1773f6b049d18c89625565;hp=893124f0f59a5e1ca4f403677dcd7f0dc41f1889;hpb=a157537898eccf08009281633b19970515366a78;p=ardour.git diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc index 893124f0f5..1ff6c28ef3 100644 --- a/libs/ardour/control_protocol_manager.cc +++ b/libs/ardour/control_protocol_manager.cc @@ -4,17 +4,19 @@ #include #include +#include + #include -#include #include 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 () { @@ -27,7 +29,7 @@ ControlProtocolManager::ControlProtocolManager () ControlProtocolManager::~ControlProtocolManager() { - LockMonitor lm (protocols_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (protocols_lock); for (list::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) { delete (*i); @@ -41,7 +43,18 @@ void 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::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { + if ((*i)->requested || (*i)->mandatory) { + instantiate (**i); + (*i)->requested = false; + + if ((*i)->protocol && (*i)->state) { + (*i)->protocol->set_state (*(*i)->state); + } + } + } } void @@ -50,7 +63,7 @@ ControlProtocolManager::drop_session () _session = 0; { - LockMonitor lm (protocols_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (protocols_lock); for (list::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) { delete *p; } @@ -77,9 +90,13 @@ ControlProtocolManager::instantiate (ControlProtocolInfo& cpi) return 0; } - LockMonitor lm (protocols_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (protocols_lock); control_protocols.push_back (cpi.protocol); + if (cpi.state) { + cpi.protocol->set_state (*cpi.state); + } + return cpi.protocol; } @@ -94,10 +111,14 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi) 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::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol); if (p != control_protocols.end()) { control_protocols.erase (p); @@ -116,12 +137,29 @@ static bool protocol_filter (const string& str, void *arg) return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3)); } +void +ControlProtocolManager::load_mandatory_protocols () +{ + if (_session == 0) { + return; + } + + for (list::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 *found; PathScanner scanner; + info << string_compose (_("looking for control protocols in %1"), path) << endmsg; + found = scanner (path, protocol_filter, 0, false, true); for (vector::iterator i = found->begin(); i != found->end(); ++i) { @@ -139,17 +177,27 @@ ControlProtocolManager::control_protocol_discover (string path) 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->supports_feedback = descriptor->supports_feedback; + 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; @@ -195,3 +243,99 @@ ControlProtocolManager::foreach_known_protocol (sigc::slot::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 (!(*citer)->children().empty()) { + cpi->state = (*citer)->children().front (); + } else { + cpi->state = 0; + } + + 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::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; +} + +void +ControlProtocolManager::set_protocol_states (const XMLNode& node) +{ + XMLNodeList nlist; + XMLNodeConstIterator niter; + XMLProperty* prop; + + nlist = node.children(); + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + + XMLNode* child = (*niter); + + if ((prop = child->property ("name")) == 0) { + error << _("control protocol XML node has no name property. Ignored.") << endmsg; + continue; + } + + ControlProtocolInfo* cpi = cpi_by_name (prop->value()); + + if (!cpi) { + warning << string_compose (_("control protocol \"%1\" is not known. Ignored"), prop->value()) << endmsg; + continue; + } + + /* copy the node so that ownership is clear */ + + cpi->state = new XMLNode (*child); + } +}