fix gcc4.4 compile warning
[ardour.git] / libs / midi++2 / jack_midiport.cc
index 9b96155b88c2f662f3dcf8b593648796494b6f01..ba675082a4d496392241ddd7b58433a6a512b889 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "pbd/error.h"
 #include "pbd/compose.h"
+#include "pbd/strsplit.h"
 
 #include "midi++/types.h"
 #include "midi++/jack.h"
@@ -35,6 +36,9 @@ using namespace PBD;
 
 pthread_t JACK_MidiPort::_process_thread;
 
+Signal0<void> JACK_MidiPort::JackHalted;
+Signal0<void> JACK_MidiPort::MakeConnections;
+
 JACK_MidiPort::JACK_MidiPort(const XMLNode& node, jack_client_t* jack_client)
        : Port(node)
        , _jack_client(jack_client)
@@ -47,21 +51,38 @@ JACK_MidiPort::JACK_MidiPort(const XMLNode& node, jack_client_t* jack_client)
        if (!create_ports (node)) {
                _ok = true;
        }
+
+       MakeConnections.connect_same_thread (connect_connection, boost::bind (&JACK_MidiPort::make_connections, this));
+       JackHalted.connect_same_thread (halt_connection, boost::bind (&JACK_MidiPort::jack_halted, this));
+
+       set_state (node);
 }
 
 JACK_MidiPort::~JACK_MidiPort()
 {
        if (_jack_input_port) {
-               jack_port_unregister (_jack_client, _jack_input_port);
+               if (_jack_client) {
+                       jack_port_unregister (_jack_client, _jack_input_port);
+               }
                _jack_input_port = 0;
        }
 
        if (_jack_output_port) {
-               jack_port_unregister (_jack_client, _jack_input_port);
+               if (_jack_client) {
+                       jack_port_unregister (_jack_client, _jack_input_port);
+               }
                _jack_input_port = 0;
        }
 }
 
+void
+JACK_MidiPort::jack_halted ()
+{
+       _jack_client = 0;
+       _jack_input_port = 0;
+       _jack_output_port = 0;
+}
+
 void
 JACK_MidiPort::cycle_start (nframes_t nframes)
 {
@@ -124,8 +145,14 @@ JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp)
                }
 
                if (vec.len[0]) {
+                        if (!vec.buf[0]->owns_buffer()) {
+                                vec.buf[0]->set_buffer (0, 0, true);
+                        }
                        vec.buf[0]->set (msg, msglen, timestamp);
                } else {
+                        if (!vec.buf[1]->owns_buffer()) {
+                                vec.buf[1]->set_buffer (0, 0, true);
+                        }
                        vec.buf[1]->set (msg, msglen, timestamp);
                }
 
@@ -212,7 +239,7 @@ JACK_MidiPort::flush (void* jack_port_buffer)
 }
 
 int
-JACK_MidiPort::read (byte * buf, size_t bufsize)
+JACK_MidiPort::read (byte *, size_t)
 {
        timestamp_t time;
        Evoral::EventType type;
@@ -270,12 +297,96 @@ XMLNode&
 JACK_MidiPort::get_state () const
 {
        XMLNode& root (Port::get_state ());
+
+       if (_jack_output_port) {
+               
+               const char** jc = jack_port_get_connections (_jack_output_port);
+               string connection_string;
+               if (jc) {
+                       for (int i = 0; jc[i]; ++i) {
+                               if (i > 0) {
+                                       connection_string += ',';
+                               }
+                               connection_string += jc[i];
+                       }
+                       free (jc);
+               }
+               
+               if (!connection_string.empty()) {
+                       root.add_property ("outbound", connection_string);
+               }
+       } else {
+               if (!_outbound_connections.empty()) {
+                       root.add_property ("outbound", _outbound_connections);
+               }
+       }
+
+       if (_jack_input_port) {
+
+               const char** jc = jack_port_get_connections (_jack_input_port);
+               string connection_string;
+               if (jc) {
+                       for (int i = 0; jc[i]; ++i) {
+                               if (i > 0) {
+                                       connection_string += ',';
+                               }
+                               connection_string += jc[i];
+                       }
+                       free (jc);
+               }
+
+               if (!connection_string.empty()) {
+                       root.add_property ("inbound", connection_string);
+               }
+       } else {
+               if (!_inbound_connections.empty()) {
+                       root.add_property ("inbound", _inbound_connections);
+               }
+       }
+
        return root;
 }
 
 void
-JACK_MidiPort::set_state (const XMLNode& /*node*/)
+JACK_MidiPort::set_state (const XMLNode& node)
+{
+       Port::set_state (node);
+       const XMLProperty* prop;
+
+       if ((prop = node.property ("inbound")) != 0 && _jack_input_port) {
+               _inbound_connections = prop->value ();
+       }
+
+       if ((prop = node.property ("outbound")) != 0 && _jack_output_port) {
+               _outbound_connections = prop->value();
+       }
+}
+
+void
+JACK_MidiPort::make_connections ()
 {
+       if (!_inbound_connections.empty()) {
+               vector<string> ports;
+               split (_inbound_connections, ports, ',');
+               for (vector<string>::iterator x = ports.begin(); x != ports.end(); ++x) {
+                       if (_jack_client) {
+                               jack_connect (_jack_client, (*x).c_str(), jack_port_name (_jack_input_port));
+                               /* ignore failures */
+                       }
+               }
+       }
+
+       if (!_outbound_connections.empty()) {
+               vector<string> ports;
+               split (_outbound_connections, ports, ',');
+               for (vector<string>::iterator x = ports.begin(); x != ports.end(); ++x) {
+                       if (_jack_client) {
+                               jack_connect (_jack_client, jack_port_name (_jack_output_port), (*x).c_str());
+                               /* ignore failures */
+                       }
+               }
+       }
+       connect_connection.disconnect ();
 }
 
 void