crossport control surface work from mb2 branch

git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@13295 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-10-17 01:03:14 +00:00
parent 1abd960ec8
commit 05457ee552
6 changed files with 102 additions and 67 deletions

View File

@ -745,6 +745,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void map_meter_falloff ();
void toggle_control_protocol (ARDOUR::ControlProtocolInfo*);
void control_protocol_status_change (ARDOUR::ControlProtocolInfo*);
void toggle_control_protocol_feedback (ARDOUR::ControlProtocolInfo*, const char* group_name, std::string action_name);
bool first_idle ();

View File

@ -640,13 +640,61 @@ ARDOUR_UI::install_actions ()
ActionManager::add_action_group (common_actions);
}
void
ARDOUR_UI::control_protocol_status_change (ControlProtocolInfo* cpi)
{
string action_name = "Toggle";
action_name += legalize_for_path (cpi->name);
action_name += "Surface";
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (X_("Editor"), action_name.c_str());
if (!act) {
return;
}
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
if (!tact) {
return;
}
if (tact->get_active() == (cpi->protocol != 0)) {
/* action state matches current protocol state, ignore this
bogus toggle (e.g. caused by initial ::set_active() call
*/
return;
}
if (cpi->protocol == 0) {
tact->set_active (false);
} else {
tact->set_active (true);
}
}
void
ARDOUR_UI::toggle_control_protocol (ControlProtocolInfo* cpi)
{
if (!session) {
/* this happens when we build the menu bar when control protocol support
has been used in the past for some given protocol - the item needs
to be made active, but there is no session yet.
string action_name = "Toggle";
action_name += legalize_for_path (cpi->name);
action_name += "Surface";
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (X_("Editor"), action_name.c_str());
if (!act) {
return;
}
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
if (!tact) {
return;
}
if (tact->get_active() == (cpi->protocol != 0)) {
/* action state matches current protocol state, ignore this
bogus toggle (e.g. caused by initial ::set_active() call
*/
return;
}
@ -790,7 +838,7 @@ ARDOUR_UI::build_control_surface_menu ()
*i,
"Editor",
action_name)));
ui += "<menu action='";
ui += submenu_name;
ui += "'>\n<menuitem action='";

View File

@ -69,11 +69,11 @@ struct ControlProtocolInfo {
static const std::string state_node_name;
void set_protocol_states (const XMLNode&);
int set_state (const XMLNode&);
XMLNode& get_state (void);
sigc::signal<void,ControlProtocolInfo*> ProtocolStatusChange;
private:
static ControlProtocolManager* _instance;

View File

@ -126,6 +126,8 @@ ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
Glib::Mutex::Lock lm (protocols_lock);
control_protocols.push_back (cpi.protocol);
ProtocolStatusChange (&cpi); // EMIT SIGNAL
return cpi.protocol;
}
@ -154,17 +156,13 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
} else {
cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl;
}
list<ControlProtocolInfo*>::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;
}
}
cpi.protocol = 0;
dlclose (cpi.descriptor->module);
ProtocolStatusChange (&cpi); // EMIT SIGNAL
return 0;
}
@ -307,28 +305,43 @@ 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 = (*citer)->property (X_("active"))) == 0) {
continue;
}
if (prop && string_is_affirmative (prop->value())) {
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;
}
bool active = string_is_affirmative (prop->value());
if ((prop = (*citer)->property (X_("name"))) == 0) {
continue;
}
ControlProtocolInfo* cpi = cpi_by_name (prop->value());
if (cpi) {
if (!(*citer)->children().empty()) {
cpi->state = new XMLNode (*((*citer)->children().front ()));
} else {
cpi->state = 0;
}
if (active) {
if (_session) {
instantiate (*cpi);
} else {
cpi->requested = true;
}
} else {
if (_session) {
teardown (*cpi);
} else {
cpi->requested = false;
}
}
}
}
}
}
return 0;
}
@ -363,33 +376,3 @@ ControlProtocolManager::get_state (void)
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);
}
}

View File

@ -1356,7 +1356,7 @@ Session::set_state (const XMLNode& node)
}
if ((child = find_named_node (node, "ControlProtocols")) != 0) {
ControlProtocolManager::instance().set_protocol_states (*child);
ControlProtocolManager::instance().set_state (*child);
}
/* here beginneth the second phase ... */

View File

@ -70,12 +70,17 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
GenericMidiControlProtocol::~GenericMidiControlProtocol ()
{
Glib::Mutex::Lock lm2 (controllables_lock);
for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ++iter) {
MIDIControllable* existingBinding = (*iter);
delete existingBinding;
}
}
int
GenericMidiControlProtocol::set_active (bool yn)
{
/* start/stop delivery/outbound thread */
return 0;
}
@ -339,7 +344,6 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
_feedback_interval = 10000;
}
// Are we using the autobinding feature? If so skip this part
if ( !auto_binding ) {
Controllable* c;
@ -350,15 +354,14 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
}
Glib::Mutex::Lock lm2 (controllables_lock);
controllables.clear ();
nlist = node.children(); // "controls"
controllables.clear ();
if (nlist.empty()) {
return 0;
}
nlist = nlist.front()->children ();
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((prop = (*niter)->property ("id")) != 0) {