X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fcontrol_protocol_manager.cc;h=00c05b280039fef867b74767bd9f1700f65ebee1;hb=c7e404a1c0ee9af941a335e4bdd2f667b0c6317a;hp=57a89cc2d9643cb495d41972571171f322c791c7;hpb=eb3f77df5748e81c4a6bfe737cd9b5a3d721a86c;p=ardour.git diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc index 57a89cc2d9..00c05b2800 100644 --- a/libs/ardour/control_protocol_manager.cc +++ b/libs/ardour/control_protocol_manager.cc @@ -1,19 +1,36 @@ +/* + Copyright (C) 2000-2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include #include #include -#include "control_protocol.h" +#include #include #include - - - using namespace ARDOUR; using namespace std; +using namespace PBD; #include "i18n.h" @@ -38,19 +55,29 @@ ControlProtocolManager::~ControlProtocolManager() } control_protocols.clear (); - + + + for (list::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) { + delete (*p); + } + + control_protocol_info.clear(); } 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); + } } } } @@ -66,6 +93,14 @@ ControlProtocolManager::drop_session () delete *p; } control_protocols.clear (); + + for (list::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) { + // otherwise the ControlProtocol instances are not recreated in set_session + if ((*p)->protocol) { + (*p)->requested = true; + (*p)->protocol = 0; + } + } } } @@ -116,6 +151,15 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi) list::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol); if (p != control_protocols.end()) { control_protocols.erase (p); + } else { + cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl; + } + + list::iterator p2 = find (control_protocol_info.begin(), control_protocol_info.end(), &cpi); + if (p2 != control_protocol_info.end()) { + control_protocol_info.erase (p2); + } else { + cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocol_info" << endl; } } @@ -126,9 +170,11 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi) static bool protocol_filter (const string& str, void *arg) { - /* Not a dotfile, has a prefix before a period, suffix is "so" */ + /* Not a dotfile, has a prefix before a period, suffix is "so", or "dylib" */ - return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3)); + return str[0] != '.' + && ((str.length() > 3 && str.find (".so") == (str.length() - 3)) + || (str.length() > 6 && str.find (".dylib") == (str.length() - 6))); } void @@ -152,7 +198,7 @@ ControlProtocolManager::discover_control_protocols (string path) vector *found; PathScanner scanner; - cerr << "looking for control protocols in " << path << endl; + info << string_compose (_("looking for control protocols in %1"), path) << endmsg; found = scanner (path, protocol_filter, 0, false, true); @@ -183,6 +229,8 @@ ControlProtocolManager::control_protocol_discover (string 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); @@ -258,11 +306,19 @@ ControlProtocolManager::set_state (const XMLNode& node) 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 { @@ -283,11 +339,57 @@ ControlProtocolManager::get_state (void) 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); + + XMLNode * child; + + if ((*i)->protocol) { + child = &((*i)->protocol->get_state()); + child->add_property (X_("active"), "yes"); + // should we update (*i)->state here? probably. + root->add_child_nocopy (*child); + } + else if ((*i)->state) { + // keep ownership clear + root->add_child_copy (*(*i)->state); + } + else { + child = new XMLNode (X_("Protocol")); + child->add_property (X_("name"), (*i)->name); + child->add_property (X_("active"), "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); + } +}