diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index e74235402c..9711f5dfc2 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -109,6 +109,8 @@ MackieControlProtocol::MackieControlProtocol (Session& session) , needs_ipmidi_restart (false) , _metering_active (true) , _initialized (false) + , _surfaces_state (0) + , _surfaces_version (0) { DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n"); @@ -133,6 +135,7 @@ MackieControlProtocol::~MackieControlProtocol() tear_down_gui (); _active = false; + delete _surfaces_state; /* stop event loop */ DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol BaseUI::quit ()\n"); @@ -665,6 +668,8 @@ MackieControlProtocol::create_surfaces () return -1; } + surface->set_state (*_surfaces_state, _surfaces_version); + { Glib::Threads::Mutex::Lock lm (surfaces_lock); surfaces.push_back (surface); @@ -746,13 +751,20 @@ MackieControlProtocol::get_state() node->add_property (X_("device-profile"), _device_profile.name()); node->add_property (X_("device-name"), _device_info.name()); + XMLNode* snode = new XMLNode (X_("Surfaces")); + for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) { + snode->add_child_nocopy ((*s)->get_state()); + } + + node->add_child_nocopy (*snode); + DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state done\n"); return *node; } int -MackieControlProtocol::set_state (const XMLNode & node, int /*version*/) +MackieControlProtocol::set_state (const XMLNode & node, int version) { DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::set_state: active %1\n", _active)); @@ -781,6 +793,16 @@ MackieControlProtocol::set_state (const XMLNode & node, int /*version*/) if ((prop = node.property (X_("device-profile"))) != 0) { set_profile (prop->value()); } + + XMLNode* snode = node.child (X_("Surfaces")); + + delete _surfaces_state; + _surfaces_state = 0; + + if (snode) { + _surfaces_state = new XMLNode (*snode); + _surfaces_version = version; + } set_active (active); diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h index 2b80aa708e..4d8545230b 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.h +++ b/libs/surfaces/mackie/mackie_control_protocol.h @@ -287,8 +287,9 @@ class MackieControlProtocol bool needs_ipmidi_restart; bool _metering_active; bool _initialized; - ARDOUR::RouteNotificationList _last_selected_routes; + XMLNode* _surfaces_state; + int _surfaces_version; int create_surfaces (); bool periodic(); diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc index 07cc918b55..694c73b1bc 100644 --- a/libs/surfaces/mackie/surface.cc +++ b/libs/surfaces/mackie/surface.cc @@ -141,6 +141,39 @@ Surface::~Surface () DEBUG_TRACE (DEBUG::MackieControl, "Surface::~Surface done\n"); } +XMLNode& +Surface::get_state() +{ + char buf[64]; + snprintf (buf, sizeof (buf), X_("surface-%u"), _number); + XMLNode* node = new XMLNode (buf); + + node->add_child_nocopy (_port->get_state()); + + return *node; +} + +int +Surface::set_state (const XMLNode& node, int version) +{ + char buf[64]; + snprintf (buf, sizeof (buf), X_("surface-%u"), _number); + XMLNode* mynode = node.child (buf); + + if (!mynode) { + return 0; + } + + XMLNode* portnode = mynode->child (X_("Port")); + if (portnode) { + if (_port->set_state (*portnode, version)) { + return -1; + } + } + + return 0; +} + const MidiByteArray& Surface::sysex_hdr() const { diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h index f3b36222b9..1ed83aef1d 100644 --- a/libs/surfaces/mackie/surface.h +++ b/libs/surfaces/mackie/surface.h @@ -3,6 +3,7 @@ #include +#include "pbd/xml++.h" #include "midi++/types.h" #include "control_protocol/types.h" @@ -146,6 +147,9 @@ public: void notify_metering_state_changed(); void turn_it_on (); + XMLNode& get_state (); + int set_state (const XMLNode&, int version); + protected: private: diff --git a/libs/surfaces/mackie/surface_port.cc b/libs/surfaces/mackie/surface_port.cc index 508f501f59..c9b35ee86c 100644 --- a/libs/surfaces/mackie/surface_port.cc +++ b/libs/surfaces/mackie/surface_port.cc @@ -87,6 +87,56 @@ SurfacePort::~SurfacePort() } } +XMLNode& +SurfacePort::get_state () +{ + XMLNode* node = new XMLNode (X_("Port")); + + if (_surface->mcp().device_info().uses_ipmidi()) { + /* no state required for IPMidi ports */ + return *node; + } + + XMLNode* child; + + child = new XMLNode (X_("Input")); + child->add_child_nocopy (_async_in->get_state()); + node->add_child_nocopy (*child); + + + child = new XMLNode (X_("Output")); + child->add_child_nocopy (_async_out->get_state()); + node->add_child_nocopy (*child); + + return *node; +} + +int +SurfacePort::set_state (const XMLNode& node, int version) +{ + if (_surface->mcp().device_info().uses_ipmidi()) { + return 0; + } + + XMLNode* child; + + if ((child = node.child (X_("Input"))) != 0) { + XMLNode* portnode = child->child (Port::state_node_name.c_str()); + if (portnode) { + _async_in->set_state (*portnode, version); + } + } + + if ((child = node.child (X_("Output"))) != 0) { + XMLNode* portnode = child->child (Port::state_node_name.c_str()); + if (portnode) { + _async_out->set_state (*portnode, version); + } + } + + return 0; +} + // wrapper for one day when strerror_r is working properly string fetch_errmsg (int error_number) { diff --git a/libs/surfaces/mackie/surface_port.h b/libs/surfaces/mackie/surface_port.h index 751ee848d7..b361294fa9 100644 --- a/libs/surfaces/mackie/surface_port.h +++ b/libs/surfaces/mackie/surface_port.h @@ -50,15 +50,18 @@ class Surface; class SurfacePort { public: - SurfacePort (Mackie::Surface&); - virtual ~SurfacePort(); - - /// an easier way to output bytes via midi - int write (const MidiByteArray&); + SurfacePort (Mackie::Surface&); + virtual ~SurfacePort(); + + /// an easier way to output bytes via midi + int write (const MidiByteArray&); MIDI::Port& input_port() const { return *_input_port; } MIDI::Port& output_port() const { return *_output_port; } + XMLNode& get_state (); + int set_state (const XMLNode&, int version); + protected: private: