Mackie Control support now saves & restores port connections for devices not using...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 13 Dec 2013 21:00:08 +0000 (16:00 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 13 Dec 2013 21:04:34 +0000 (16:04 -0500)
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/mackie_control_protocol.h
libs/surfaces/mackie/surface.cc
libs/surfaces/mackie/surface.h
libs/surfaces/mackie/surface_port.cc
libs/surfaces/mackie/surface_port.h

index e74235402cf73e0010825257dc5b519d6bc712c7..9711f5dfc2e01e91b4dfecdbb77bd1bbae56f5a8 100644 (file)
@@ -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);
 
index 2b80aa708e5e255183bdbaa5b7636db5390c3647..4d8545230b4b11d18c481def2d610531350b7c05 100644 (file)
@@ -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();
index 07cc918b55c381c6553e586e2485e6507ccfa07c..694c73b1bcb638f49bb3772bceeb6a55159f33cb 100644 (file)
@@ -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
 {
index f3b36222b9aebdec5ca0b1c4aae2565fc7865541..1ed83aef1db88af2c9a2e9ba7751af282c9a0c42 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdint.h>
 
+#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:
index 508f501f59892037982bf861af6259bf3f563756..c9b35ee86ce3cf57c6396b4c3e449116268fa504 100644 (file)
@@ -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)
 {
index 751ee848d7499a2bb321c2725b5104951f97f2f1..b361294fa91c6f14a9fcc4a204dc3d0955a3d679 100644 (file)
@@ -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: