From e79a7e8ff95d50fec527e6f6381cd30bcf57c8f8 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 27 Sep 2007 04:20:31 +0000 Subject: [PATCH] auto-re-connect ALSA seq ports at startup, if they were connected; may break OS X compilation till tomorrow morning (US Eastern TZ) git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2489 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/option_editor.cc | 13 +- libs/ardour/ardour/configuration.h | 12 +- libs/ardour/configuration.cc | 56 +---- libs/ardour/globals.cc | 27 +-- libs/ardour/plugin.cc | 3 +- libs/midi++2/SConscript | 1 - libs/midi++2/alsa_sequencer_midiport.cc | 198 +++++++++++++++--- libs/midi++2/coremidi_midiport.cc | 27 ++- libs/midi++2/fd_midiport.cc | 22 +- libs/midi++2/fifomidi.cc | 8 +- libs/midi++2/midi++/alsa_rawmidi.h | 4 +- libs/midi++2/midi++/alsa_sequencer.h | 11 +- libs/midi++2/midi++/coremidi_midiport.h | 5 +- libs/midi++2/midi++/factory.h | 3 +- libs/midi++2/midi++/fd_midiport.h | 5 +- libs/midi++2/midi++/fifomidi.h | 5 +- libs/midi++2/midi++/manager.h | 5 +- libs/midi++2/midi++/nullmidi.h | 5 +- libs/midi++2/midi++/port.h | 23 +- libs/midi++2/midi++/port_request.h | 67 ------ libs/midi++2/midifactory.cc | 19 +- libs/midi++2/midimanager.cc | 105 +--------- libs/midi++2/midiport.cc | 56 ++++- libs/midi++2/miditrace.cc | 1 - libs/midi++2/mmctest.cc | 1 - libs/midi++2/port_request.cc | 41 ---- .../generic_midi_control_protocol.cc | 1 - .../mackie/mackie_control_protocol_poll.cc | 1 - 28 files changed, 326 insertions(+), 399 deletions(-) delete mode 100644 libs/midi++2/midi++/port_request.h delete mode 100644 libs/midi++2/port_request.cc diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc index c328532f6a..f0cf59da1c 100644 --- a/gtk2_ardour/option_editor.cc +++ b/gtk2_ardour/option_editor.cc @@ -712,12 +712,15 @@ OptionEditor::add_midi_port () smod = "duplex"; } - MIDI::PortRequest req (X_("ardour"), - dialog.port_name.get_text(), - smod, - MIDI::PortFactory::default_port_type()); - if (MIDI::Manager::instance()->add_port (req) != 0) { + XMLNode node (X_("MIDI-port")); + + node.add_property ("tag", dialog.port_name.get_text()); + node.add_property ("device", X_("ardour")); // XXX this can't be right for all types + node.add_property ("type", MIDI::PortFactory::default_port_type()); + node.add_property ("mode", smod); + + if (MIDI::Manager::instance()->add_port (node) != 0) { redisplay_midi_ports (); } } diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h index 31cb74ab33..7982813900 100644 --- a/libs/ardour/ardour/configuration.h +++ b/libs/ardour/ardour/configuration.h @@ -42,17 +42,7 @@ class Configuration : public Stateful Configuration(); virtual ~Configuration(); - struct MidiPortDescriptor { - std::string tag; - std::string device; - std::string type; - std::string mode; - - MidiPortDescriptor (const XMLNode&); - XMLNode& get_state(); - }; - - std::map midi_ports; + std::map midi_ports; void map_parameters (sigc::slot theSlot); diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc index 60bc01fdfa..c19541ddbd 100644 --- a/libs/ardour/configuration.cc +++ b/libs/ardour/configuration.cc @@ -217,10 +217,12 @@ Configuration::set_state (const XMLNode& root) if (node->name() == "MIDI-port") { try { - pair newpair; - newpair.second = new MidiPortDescriptor (*node); - newpair.first = newpair.second->tag; - midi_ports.insert (newpair); + MIDI::Port::Descriptor desc (*node); + map::iterator x; + if ((x = midi_ports.find (desc.tag)) != midi_ports.end()) { + midi_ports.erase (x); + } + midi_ports.insert (pair(desc.tag,*node)); } catch (failed_constructor& err) { @@ -263,52 +265,6 @@ Configuration::set_variables (const XMLNode& node, ConfigVariableBase::Owner own } -Configuration::MidiPortDescriptor::MidiPortDescriptor (const XMLNode& node) -{ - const XMLProperty *prop; - bool have_tag = false; - bool have_device = false; - bool have_type = false; - bool have_mode = false; - - if ((prop = node.property ("tag")) != 0) { - tag = prop->value(); - have_tag = true; - } - - if ((prop = node.property ("device")) != 0) { - device = prop->value(); - have_device = true; - } - - if ((prop = node.property ("type")) != 0) { - type = prop->value(); - have_type = true; - } - - if ((prop = node.property ("mode")) != 0) { - mode = prop->value(); - have_mode = true; - } - - if (!have_tag || !have_device || !have_type || !have_mode) { - throw failed_constructor(); - } -} - -XMLNode& -Configuration::MidiPortDescriptor::get_state() -{ - XMLNode* root = new XMLNode("MIDI-port"); - - root->add_property("tag", tag); - root->add_property("device", device); - root->add_property("type", type); - root->add_property("mode", mode); - - return *root; -} - void Configuration::map_parameters (sigc::slot theSlot) { diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index b4286c089f..10d67421fb 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -32,6 +32,8 @@ #include #endif +#include + #include #include @@ -40,7 +42,6 @@ #include #include -#include #include #include @@ -110,29 +111,13 @@ setup_osc () static int setup_midi () { - std::map::iterator i; - if (Config->midi_ports.size() == 0) { warning << _("no MIDI ports specified: no MMC or MTC control possible") << endmsg; return 0; } - for (i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) { - Configuration::MidiPortDescriptor* port_descriptor; - - port_descriptor = (*i).second; - - MIDI::PortRequest request (port_descriptor->device, - port_descriptor->tag, - port_descriptor->mode, - port_descriptor->type); - - if (request.status != MIDI::PortRequest::OK) { - error << string_compose(_("MIDI port specifications for \"%1\" are not understandable."), port_descriptor->tag) << endmsg; - continue; - } - - MIDI::Manager::instance()->add_port (request); + for (std::map::iterator i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) { + MIDI::Manager::instance()->add_port (i->second); } MIDI::Port* first; @@ -144,8 +129,6 @@ setup_midi () /* More than one port, so try using specific names for each port */ - map::iterator i; - if (Config->get_mmc_port_name() != N_("default")) { default_mmc_port = MIDI::Manager::instance()->port (Config->get_mmc_port_name()); } @@ -443,7 +426,7 @@ find_file (string name, string dir, string subdir = "") for (vector::iterator i = split_path.begin(); i != split_path.end(); ++i) { path = *i; path += "/" + name; - if (access (path.c_str(), R_OK) == 0) { + if (Glib::file_test (path, Glib::FILE_TEST_EXISTS)) { // cerr << "Using file " << path << " found in ARDOUR_PATH." << endl; return path; } diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index d95ab702ac..7b956b564b 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -112,7 +113,7 @@ Plugin::get_nth_control (uint32_t n, bool do_not_create) Plugin::ParameterDescriptor desc; get_parameter_descriptor (n, desc); - + controls[n] = new PortControllable (describe_parameter (n), *this, n, desc.lower, desc.upper, desc.toggled, desc.logarithmic); } diff --git a/libs/midi++2/SConscript b/libs/midi++2/SConscript index 4fb1ba682e..27c09184ba 100644 --- a/libs/midi++2/SConscript +++ b/libs/midi++2/SConscript @@ -23,7 +23,6 @@ midiparser.cc midiport.cc mmc.cc mtc.cc -port_request.cc version.cc """) diff --git a/libs/midi++2/alsa_sequencer_midiport.cc b/libs/midi++2/alsa_sequencer_midiport.cc index 9ffd9f7832..dc6ea9092f 100644 --- a/libs/midi++2/alsa_sequencer_midiport.cc +++ b/libs/midi++2/alsa_sequencer_midiport.cc @@ -23,10 +23,12 @@ #include #include +#include #include #include -#include + +#include "i18n.h" //#define DOTRACE 1 @@ -44,31 +46,31 @@ using namespace PBD; snd_seq_t* ALSA_SequencerMidiPort::seq = 0; -ALSA_SequencerMidiPort::ALSA_SequencerMidiPort (PortRequest &req) - : Port (req) +ALSA_SequencerMidiPort::ALSA_SequencerMidiPort (const XMLNode& node) + : Port (node) , decoder (0) , encoder (0) , port_id (-1) { TR_FN(); int err; + Descriptor desc (node); - if (!seq && init_client (req.devname) < 0) { + if (!seq && init_client (desc.device) < 0) { _ok = false; } else { - if (0 <= (err = CreatePorts (req)) && + if (0 <= (err = create_ports (desc)) && 0 <= (err = snd_midi_event_new (1024, &decoder)) && // Length taken from ARDOUR::Session::midi_read () 0 <= (err = snd_midi_event_new (64, &encoder))) { // Length taken from ARDOUR::Session::mmc_buffer snd_midi_event_init (decoder); snd_midi_event_init (encoder); _ok = true; - req.status = PortRequest::OK; - } else { - req.status = PortRequest::Unknown; - } + } } + + set_state (node); } ALSA_SequencerMidiPort::~ALSA_SequencerMidiPort () @@ -160,17 +162,17 @@ ALSA_SequencerMidiPort::read (byte *buf, size_t max) } int -ALSA_SequencerMidiPort::CreatePorts (PortRequest &req) +ALSA_SequencerMidiPort::create_ports (const Port::Descriptor& desc) { int err; unsigned int caps = 0; - if (req.mode == O_WRONLY || req.mode == O_RDWR) + if (desc.mode == O_WRONLY || desc.mode == O_RDWR) caps |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; - if (req.mode == O_RDONLY || req.mode == O_RDWR) + if (desc.mode == O_RDONLY || desc.mode == O_RDWR) caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; - if (0 <= (err = snd_seq_create_simple_port (seq, req.tagname, caps, + if (0 <= (err = snd_seq_create_simple_port (seq, desc.tag.c_str(), caps, (SND_SEQ_PORT_TYPE_MIDI_GENERIC| SND_SEQ_PORT_TYPE_SOFTWARE| SND_SEQ_PORT_TYPE_APPLICATION)))) { @@ -259,23 +261,165 @@ ALSA_SequencerMidiPort::discover (vector& ports) if (port_capability & SND_SEQ_PORT_CAP_READ) { if (port_capability & SND_SEQ_PORT_CAP_WRITE) { - mode = "duplex"; - } else { - mode = "output"; - } - } else if (port_capability & SND_SEQ_PORT_CAP_WRITE) { - if (port_capability & SND_SEQ_PORT_CAP_READ) { - mode = "duplex"; - } else { - mode = "input"; - } - } - - ports.back().ports.push_back (PortRequest (client, port, mode, "alsa/sequencer")); - ++n; + mode = "duplex"; + } else { + mode = "output"; + } + } else if (port_capability & SND_SEQ_PORT_CAP_WRITE) { + if (port_capability & SND_SEQ_PORT_CAP_READ) { + mode = "duplex"; + } else { + mode = "input"; + } } + + XMLNode node (X_("MIDI-port")); + node.add_property ("device", client); + node.add_property ("tag", port); + node.add_property ("mode", mode); + node.add_property ("type", "alsa/sequencer"); + + ports.back().ports.push_back (node); + ++n; + } } } return n; } + +void +ALSA_SequencerMidiPort::get_connections (vector& connections, int dir) const +{ + snd_seq_query_subscribe_t *subs; + snd_seq_addr_t seq_addr; + + snd_seq_query_subscribe_alloca (&subs); + + // Get port connections... + + if (dir) { + snd_seq_query_subscribe_set_type(subs, SND_SEQ_QUERY_SUBS_WRITE); + } else { + snd_seq_query_subscribe_set_type(subs, SND_SEQ_QUERY_SUBS_READ); + } + + snd_seq_query_subscribe_set_index(subs, 0); + seq_addr.client = snd_seq_client_id (seq); + seq_addr.port = port_id; + snd_seq_query_subscribe_set_root(subs, &seq_addr); + + while (snd_seq_query_port_subscribers(seq, subs) >= 0) { + + seq_addr = *snd_seq_query_subscribe_get_addr (subs); + + connections.push_back (SequencerPortAddress (seq_addr.client, + seq_addr.port)); + + snd_seq_query_subscribe_set_index(subs, snd_seq_query_subscribe_get_index(subs) + 1); + } +} + +XMLNode& +ALSA_SequencerMidiPort::get_state () const +{ + XMLNode& root (Port::get_state ()); + vector connections; + XMLNode* sub = 0; + char buf[256]; + + get_connections (connections, 1); + + if (!connections.empty()) { + if (!sub) { + sub = new XMLNode (X_("connections")); + } + for (vector::iterator i = connections.begin(); i != connections.end(); ++i) { + XMLNode* cnode = new XMLNode (X_("read")); + snprintf (buf, sizeof (buf), "%d:%d", i->first, i->second); + cnode->add_property ("dest", buf); + sub->add_child_nocopy (*cnode); + } + } + + connections.clear (); + get_connections (connections, 0); + + if (!connections.empty()) { + if (!sub) { + sub = new XMLNode (X_("connections")); + } + for (vector::iterator i = connections.begin(); i != connections.end(); ++i) { + XMLNode* cnode = new XMLNode (X_("write")); + snprintf (buf, sizeof (buf), "%d:%d", i->first, i->second); + cnode->add_property ("dest", buf); + sub->add_child_nocopy (*cnode); + } + } + + if (sub) { + root.add_child_nocopy (*sub); + } + + return root; +} + +void +ALSA_SequencerMidiPort::set_state (const XMLNode& node) +{ + Port::set_state (node); + + XMLNodeList children (node.children()); + XMLNodeIterator iter; + + for (iter = children.begin(); iter != children.end(); ++iter) { + + if ((*iter)->name() == X_("connections")) { + + XMLNodeList gchildren ((*iter)->children()); + XMLNodeIterator gciter; + + for (gciter = gchildren.begin(); gciter != gchildren.end(); ++gciter) { + XMLProperty* prop; + + if ((prop = (*gciter)->property ("dest")) != 0) { + int client; + int port; + + if (sscanf (prop->value().c_str(), "%d:%d", &client, &port) == 2) { + + snd_seq_port_subscribe_t *sub; + snd_seq_addr_t seq_addr; + + snd_seq_port_subscribe_alloca(&sub); + + if ((*gciter)->name() == X_("write")) { + + seq_addr.client = snd_seq_client_id (seq); + seq_addr.port = port_id; + snd_seq_port_subscribe_set_sender(sub, &seq_addr); + + seq_addr.client = client; + seq_addr.port = port; + snd_seq_port_subscribe_set_dest(sub, &seq_addr); + + } else { + + seq_addr.client = snd_seq_client_id (seq); + seq_addr.port = port_id; + snd_seq_port_subscribe_set_dest(sub, &seq_addr); + + seq_addr.client = client; + seq_addr.port = port; + snd_seq_port_subscribe_set_sender(sub, &seq_addr); + } + + snd_seq_subscribe_port (seq, sub); + } + } + } + + break; + } + } +} diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc index 38f84fe750..82da9b0621 100644 --- a/libs/midi++2/coremidi_midiport.cc +++ b/libs/midi++2/coremidi_midiport.cc @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -36,15 +35,15 @@ MIDITimeStamp CoreMidi_MidiPort::MIDIGetCurrentHostTime() return mach_absolute_time(); } -CoreMidi_MidiPort::CoreMidi_MidiPort (PortRequest &req) : Port (req) +CoreMidi_MidiPort::CoreMidi_MidiPort (const XMLNode& node) : Port (node) { + Descriptor desc (node); + firstrecv = true; int err; - if (0 == (err = Open(req))) { + if (0 == (err = Open(desc))) { _ok = true; - req.status = PortRequest::OK; - } else - req.status = PortRequest::Unknown; + } } CoreMidi_MidiPort::~CoreMidi_MidiPort () {Close();} @@ -77,21 +76,21 @@ int CoreMidi_MidiPort::write (byte *msg, size_t msglen) } } -int CoreMidi_MidiPort::Open (PortRequest &req) +int CoreMidi_MidiPort::Open (const Descriptor& desc) { OSStatus err; CFStringRef coutputStr; string str; - - coutputStr = CFStringCreateWithCString(0, req.devname, CFStringGetSystemEncoding()); + + coutputStr = CFStringCreateWithCString(0, desc.device.c_str(), CFStringGetSystemEncoding()); err = MIDIClientCreate(coutputStr, 0, 0, &midi_client); CFRelease(coutputStr); - if (!midi_client) { + if (!midi_client) { //error << "Cannot open CoreMidi client : " << err << endmsg. - goto error; - } + goto error; + } - str = req.tagname + string("_in"); + str = desc.tag + string("_in"); coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding()); err = MIDIDestinationCreate(midi_client, coutputStr, read_proc, this, &midi_destination); CFRelease(coutputStr); @@ -100,7 +99,7 @@ int CoreMidi_MidiPort::Open (PortRequest &req) goto error; } - str = req.tagname + string("_out"); + str = desc.tag + string("_out"); coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding()); err = MIDISourceCreate(midi_client, coutputStr, &midi_source); CFRelease(coutputStr); diff --git a/libs/midi++2/fd_midiport.cc b/libs/midi++2/fd_midiport.cc index 1d21642a00..2fd7a5e5f2 100644 --- a/libs/midi++2/fd_midiport.cc +++ b/libs/midi++2/fd_midiport.cc @@ -34,40 +34,38 @@ using namespace PBD; string *FD_MidiPort::midi_dirpath = 0; string *FD_MidiPort::midi_filename_pattern = 0; -FD_MidiPort::FD_MidiPort (PortRequest &req, +FD_MidiPort::FD_MidiPort (const XMLNode& node, const string &dirpath, const string &pattern) - : Port (req) + : Port (node) { - open (req); + Descriptor desc (node); + + open (desc); if (_fd < 0) { switch (errno) { case EBUSY: error << "MIDI: port device in use" << endmsg; - req.status = PortRequest::Busy; break; case ENOENT: error << "MIDI: no such port device" << endmsg; - req.status = PortRequest::NoSuchFile; break; case EACCES: error << "MIDI: access to port denied" << endmsg; - req.status = PortRequest::NotAllowed; break; default: - req.status = PortRequest::Unknown; + break; } } else { _ok = true; - req.status = PortRequest::OK; if (midi_dirpath == 0) { midi_dirpath = new string (dirpath); midi_filename_pattern = new string (pattern); } - if (req.mode & O_NONBLOCK == 0) { + if (desc.mode & O_NONBLOCK == 0) { /* we unconditionally set O_NONBLOCK during open, but the request didn't ask for it, so remove it. @@ -80,11 +78,11 @@ FD_MidiPort::FD_MidiPort (PortRequest &req, } void -FD_MidiPort::open (PortRequest &req) +FD_MidiPort::open (const Descriptor& desc) { - int mode = req.mode | O_NONBLOCK; - _fd = ::open (req.devname, mode); + int mode = desc.mode | O_NONBLOCK; + _fd = ::open (desc.device.c_str(), mode); } vector * diff --git a/libs/midi++2/fifomidi.cc b/libs/midi++2/fifomidi.cc index 7bb126ddeb..a81520bb95 100644 --- a/libs/midi++2/fifomidi.cc +++ b/libs/midi++2/fifomidi.cc @@ -26,19 +26,19 @@ using namespace MIDI; -FIFO_MidiPort::FIFO_MidiPort (PortRequest &req) - : FD_MidiPort (req, ".", "midi") +FIFO_MidiPort::FIFO_MidiPort (const XMLNode& node) + : FD_MidiPort (node, ".", "midi") { } void -FIFO_MidiPort::open (PortRequest &req) +FIFO_MidiPort::open (const Port::Descriptor& desc) { /* This is a placeholder for the fun-and-games I think we will need to do with FIFO's. */ - _fd = ::open (req.devname, req.mode|O_NDELAY); + _fd = ::open (desc.device.c_str(), desc.mode|O_NDELAY); } diff --git a/libs/midi++2/midi++/alsa_rawmidi.h b/libs/midi++2/midi++/alsa_rawmidi.h index 7edee58322..e5abc2832f 100644 --- a/libs/midi++2/midi++/alsa_rawmidi.h +++ b/libs/midi++2/midi++/alsa_rawmidi.h @@ -34,8 +34,8 @@ class ALSA_RawMidiPort : public MIDI::FD_MidiPort { public: - ALSA_RawMidiPort (MIDI::PortRequest &req) - : FD_MidiPort (req, "/dev/snd", "midi") {} + ALSA_RawMidiPort (const XMLNode& node) + : FD_MidiPort (node, "/dev/snd", "midi") {} virtual ~ALSA_RawMidiPort () {} static std::string typestring; diff --git a/libs/midi++2/midi++/alsa_sequencer.h b/libs/midi++2/midi++/alsa_sequencer.h index 7e929d38c2..dbd794fffb 100644 --- a/libs/midi++2/midi++/alsa_sequencer.h +++ b/libs/midi++2/midi++/alsa_sequencer.h @@ -27,7 +27,6 @@ #include #include -#include namespace MIDI { @@ -35,7 +34,7 @@ class ALSA_SequencerMidiPort : public Port { public: - ALSA_SequencerMidiPort (PortRequest &req); + ALSA_SequencerMidiPort (const XMLNode&); virtual ~ALSA_SequencerMidiPort (); /* select(2)/poll(2)-based I/O */ @@ -45,6 +44,9 @@ class ALSA_SequencerMidiPort : public Port static int discover (std::vector&); static std::string typestring; + XMLNode& get_state() const; + void set_state (const XMLNode&); + protected: /* Direct I/O */ @@ -60,10 +62,13 @@ class ALSA_SequencerMidiPort : public Port int port_id; snd_seq_event_t SEv; - int CreatePorts(PortRequest &req); + int create_ports (const Port::Descriptor&); static int init_client (std::string name); static snd_seq_t* seq; + + typedef std::pair SequencerPortAddress; + void get_connections (std::vector&, int dir) const; }; }; /* namespace MIDI */ diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h index 828872f85c..a954f4ca2a 100644 --- a/libs/midi++2/midi++/coremidi_midiport.h +++ b/libs/midi++2/midi++/coremidi_midiport.h @@ -28,7 +28,6 @@ #include #include -#include #include @@ -36,7 +35,7 @@ namespace MIDI { class CoreMidi_MidiPort:public Port { public: - CoreMidi_MidiPort(PortRequest & req); + CoreMidi_MidiPort(const XMLNode& node); virtual ~ CoreMidi_MidiPort(); virtual int selectable() const { @@ -68,7 +67,7 @@ namespace MIDI { MIDIEndpointRef midi_destination; MIDIEndpointRef midi_source; - int Open(PortRequest & req); + int Open(const Port::Descriptor&); void Close(); static MIDITimeStamp MIDIGetCurrentHostTime(); diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h index bd130f8701..cec8edaa5c 100644 --- a/libs/midi++2/midi++/factory.h +++ b/libs/midi++2/midi++/factory.h @@ -23,13 +23,12 @@ #include #include -#include namespace MIDI { class PortFactory { public: - Port *create_port (PortRequest &req); + Port *create_port (const XMLNode&); static bool ignore_duplicate_devices (Port::Type); static int get_known_ports (std::vector&); diff --git a/libs/midi++2/midi++/fd_midiport.h b/libs/midi++2/midi++/fd_midiport.h index e971a18f8c..d353d5c75f 100644 --- a/libs/midi++2/midi++/fd_midiport.h +++ b/libs/midi++2/midi++/fd_midiport.h @@ -29,7 +29,6 @@ #include #include -#include namespace MIDI { @@ -37,7 +36,7 @@ class FD_MidiPort : public Port { public: - FD_MidiPort (PortRequest &req, + FD_MidiPort (const XMLNode& node, const std::string &dirpath, const std::string &pattern); @@ -51,7 +50,7 @@ class FD_MidiPort : public Port protected: int _fd; - virtual void open (PortRequest &req); + virtual void open (const Port::Descriptor&); virtual int write (byte *msg, size_t msglen) { int nwritten; diff --git a/libs/midi++2/midi++/fifomidi.h b/libs/midi++2/midi++/fifomidi.h index ea644dde06..3439c27dcf 100644 --- a/libs/midi++2/midi++/fifomidi.h +++ b/libs/midi++2/midi++/fifomidi.h @@ -25,7 +25,6 @@ #include #include -#include #include namespace MIDI { @@ -34,7 +33,7 @@ class FIFO_MidiPort : public MIDI::FD_MidiPort { public: - FIFO_MidiPort (PortRequest &req); + FIFO_MidiPort (const XMLNode&); ~FIFO_MidiPort () {}; static std::string typestring; @@ -45,7 +44,7 @@ class FIFO_MidiPort : public MIDI::FD_MidiPort } private: - void open (PortRequest &req); + void open (const Port::Descriptor&); }; } // namespace MIDI diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h index d13be58af6..8487fc4db0 100644 --- a/libs/midi++2/midi++/manager.h +++ b/libs/midi++2/midi++/manager.h @@ -27,7 +27,6 @@ #include #include -#include namespace MIDI { @@ -35,7 +34,7 @@ class Manager { public: ~Manager (); - Port *add_port (PortRequest &); + Port *add_port (const XMLNode& node); int remove_port (Port*); Port *port (std::string name); @@ -68,8 +67,6 @@ class Manager { return theManager; } - static int parse_port_request (std::string str, Port::Type type); - int get_known_ports (std::vector&); private: diff --git a/libs/midi++2/midi++/nullmidi.h b/libs/midi++2/midi++/nullmidi.h index d3d53826bb..1dd2baaa10 100644 --- a/libs/midi++2/midi++/nullmidi.h +++ b/libs/midi++2/midi++/nullmidi.h @@ -24,7 +24,6 @@ #include #include -#include namespace MIDI { @@ -32,8 +31,8 @@ class Null_MidiPort : public Port { public: - Null_MidiPort (PortRequest &req) - : Port (req) { + Null_MidiPort (const XMLNode& node) + : Port (node) { /* reset devname and tagname */ diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index e095ce0c64..0e9b94781b 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -23,12 +23,11 @@ #include #include +#include #include #include -class XMLNode; - namespace MIDI { class Channel; @@ -46,10 +45,11 @@ class Port : public sigc::trackable { }; - Port (PortRequest &); + Port (const XMLNode&); virtual ~Port (); virtual XMLNode& get_state () const; + virtual void set_state (const XMLNode&); /* Direct I/O */ @@ -124,6 +124,16 @@ class Port : public sigc::trackable { int mode () const { return _mode; } bool ok () const { return _ok; } + struct Descriptor { + std::string tag; + std::string device; + int mode; + Port::Type type; + + Descriptor (const XMLNode&); + XMLNode& get_state(); + }; + protected: bool _ok; Type _type; @@ -144,6 +154,13 @@ class Port : public sigc::trackable { static size_t nports; }; +struct PortSet { + PortSet (std::string str) : owner (str) { } + + std::string owner; + std::list ports; +}; + std::ostream & operator << ( std::ostream & os, const Port & port ); } // namespace MIDI diff --git a/libs/midi++2/midi++/port_request.h b/libs/midi++2/midi++/port_request.h deleted file mode 100644 index cd4e758ebb..0000000000 --- a/libs/midi++2/midi++/port_request.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#ifndef __midi_port_request_h__ -#define __midi_port_request_h__ - -#include -#include - -namespace MIDI { - -struct PortRequest { - enum Status { - Unknown, - OK, - Busy, - NoSuchFile, - TypeUnsupported, - NotAllowed - }; - const char *devname; - const char *tagname; - int mode; - Port::Type type; - Status status; - - PortRequest () { - devname = 0; - tagname = 0; - mode = 0; - type = Port::Unknown; - status = Unknown; - } - - PortRequest (const std::string &xdev, - const std::string &xtag, - const std::string &xmode, - const std::string &xtype); -}; - -struct PortSet { - PortSet (std::string str) : owner (str) { } - - std::string owner; - std::list ports; -}; - -} // namespace MIDI - -#endif // __midi_port_request_h__ - diff --git a/libs/midi++2/midifactory.cc b/libs/midi++2/midifactory.cc index cb8846214e..d0dee02c73 100644 --- a/libs/midi++2/midifactory.cc +++ b/libs/midi++2/midifactory.cc @@ -52,43 +52,40 @@ using namespace MIDI; using namespace PBD; Port * -PortFactory::create_port (PortRequest &req) - +PortFactory::create_port (const XMLNode& node) { + Port::Descriptor desc (node); Port *port; - switch (req.type) { + switch (desc.type) { #ifdef WITH_ALSA case Port::ALSA_RawMidi: - port = new ALSA_RawMidiPort (req); + port = new ALSA_RawMidiPort (node); break; case Port::ALSA_Sequencer: - port = new ALSA_SequencerMidiPort (req); + port = new ALSA_SequencerMidiPort (node); break; #endif // WITH_ALSA #if WITH_COREMIDI case Port::CoreMidi_MidiPort: - port = new CoreMidi_MidiPort (req); + port = new CoreMidi_MidiPort (node); break; #endif // WITH_COREMIDI case Port::Null: - port = new Null_MidiPort (req); + port = new Null_MidiPort (node); break; case Port::FIFO: - port = new FIFO_MidiPort (req); + port = new FIFO_MidiPort (node); break; default: - req.status = PortRequest::TypeUnsupported; return 0; } - req.status = PortRequest::OK; - return port; } diff --git a/libs/midi++2/midimanager.cc b/libs/midi++2/midimanager.cc index cc4ca6abec..3791d409d7 100644 --- a/libs/midi++2/midimanager.cc +++ b/libs/midi++2/midimanager.cc @@ -27,7 +27,6 @@ #include #include #include -#include using namespace std; using namespace MIDI; @@ -64,27 +63,27 @@ Manager::~Manager () } Port * -Manager::add_port (PortRequest &req) - +Manager::add_port (const XMLNode& node) { + Port::Descriptor desc (node); PortFactory factory; Port *port; PortMap::iterator existing; pair newpair; - if (!PortFactory::ignore_duplicate_devices (req.type)) { + if (!PortFactory::ignore_duplicate_devices (desc.type)) { - if ((existing = ports_by_device.find (req.devname)) != ports_by_device.end()) { + if ((existing = ports_by_device.find (desc.device)) != ports_by_device.end()) { port = (*existing).second; - if (port->mode() == req.mode) { + if (port->mode() == desc.mode) { /* Same mode - reuse the port, and just create a new tag entry. */ - newpair.first = req.tagname; + newpair.first = desc.tag; newpair.second = port; ports_by_tag.insert (newpair); @@ -97,10 +96,10 @@ Manager::add_port (PortRequest &req) operation. */ - if ((req.mode == O_RDWR && port->mode() != O_RDWR) || - (req.mode != O_RDWR && port->mode() == O_RDWR)) { + if ((desc.mode == O_RDWR && port->mode() != O_RDWR) || + (desc.mode != O_RDWR && port->mode() == O_RDWR)) { error << "MIDIManager: port tagged \"" - << req.tagname + << desc.tag << "\" cannot be opened duplex and non-duplex" << endmsg; return 0; @@ -110,7 +109,7 @@ Manager::add_port (PortRequest &req) } } - port = factory.create_port (req); + port = factory.create_port (node); if (port == 0) { return 0; @@ -262,90 +261,6 @@ Manager::foreach_port (int (*func)(const Port &, size_t, void *), return 0; } -int -Manager::parse_port_request (string str, Port::Type type) -{ - PortRequest *req; - string::size_type colon; - string tag; - - if (str.length() == 0) { - error << "MIDI: missing port specification" << endmsg; - return -1; - } - - /* Port specifications look like: - - devicename - devicename:tagname - devicename:tagname:mode - - where - - "devicename" is the full path to the requested file - - "tagname" (optional) is the name used to refer to the - port. If not given, g_path_get_basename (devicename) - will be used. - - "mode" (optional) is either "r" or "w" or something else. - if it is "r", the port will be opened - read-only, if "w", the port will be opened - write-only. Any other value, or no mode - specification at all, will cause the port to - be opened for reading and writing. - */ - - req = new PortRequest; - colon = str.find_first_of (':'); - - if (colon != string::npos) { - req->devname = strdup (str.substr (0, colon).c_str()); - } else { - req->devname = strdup (str.c_str()); - } - - if (colon < str.length()) { - - tag = str.substr (colon+1); - - /* see if there is a mode specification in the tag part */ - - colon = tag.find_first_of (':'); - - if (colon != string::npos) { - string modestr; - - req->tagname = strdup (tag.substr (0, colon).c_str()); - - modestr = tag.substr (colon+1); - if (modestr == "r") { - req->mode = O_RDONLY; - } else if (modestr == "w") { - req->mode = O_WRONLY; - } else { - req->mode = O_RDWR; - } - - } else { - req->tagname = strdup (tag.c_str()); - req->mode = O_RDWR; - } - - } else { - // check when tagname is freed - req->tagname = g_path_get_basename (req->devname); - req->mode = O_RDWR; - } - - req->type = type; - - if (MIDI::Manager::instance()->add_port (*req) == 0) { - return -1; - } - - return 0; -} int Manager::get_known_ports (vector& ports) diff --git a/libs/midi++2/midiport.cc b/libs/midi++2/midiport.cc index f881e3ed23..0c18090989 100644 --- a/libs/midi++2/midiport.cc +++ b/libs/midi++2/midiport.cc @@ -17,26 +17,27 @@ $Id$ */ - +#include #include #include #include +#include #include #include #include -#include #include -//using namespace Select; using namespace MIDI; +using namespace std; size_t Port::nports = 0; -Port::Port (PortRequest &req) - +Port::Port (const XMLNode& node) { + Descriptor desc (node); + _ok = false; /* derived class must set to true if constructor succeeds. */ @@ -47,9 +48,9 @@ Port::Port (PortRequest &req) output_parser = 0; slowdown = 0; - _devname = req.devname; - _tagname = req.tagname; - _mode = req.mode; + _devname = desc.device; + _tagname = desc.tag; + _mode = desc.mode; if (_mode == O_RDONLY || _mode == O_RDWR) { input_parser = new Parser (*this); @@ -97,6 +98,12 @@ Port::get_state () const return *node; } +void +Port::set_state (const XMLNode& node) +{ + // relax +} + int Port::clock () @@ -163,3 +170,36 @@ std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port ) return os; } +Port::Descriptor::Descriptor (const XMLNode& node) +{ + const XMLProperty *prop; + bool have_tag = false; + bool have_device = false; + bool have_type = false; + bool have_mode = false; + + if ((prop = node.property ("tag")) != 0) { + tag = prop->value(); + have_tag = true; + } + + if ((prop = node.property ("device")) != 0) { + device = prop->value(); + have_device = true; + } + + if ((prop = node.property ("type")) != 0) { + type = PortFactory::string_to_type (prop->value()); + have_type = true; + } + + if ((prop = node.property ("mode")) != 0) { + mode = PortFactory::string_to_mode (prop->value()); + have_mode = true; + } + + if (!have_tag || !have_device || !have_type || !have_mode) { + throw failed_constructor(); + } +} + diff --git a/libs/midi++2/miditrace.cc b/libs/midi++2/miditrace.cc index d7c65d9f29..fafe822f82 100644 --- a/libs/midi++2/miditrace.cc +++ b/libs/midi++2/miditrace.cc @@ -11,7 +11,6 @@ Transmitter fatal (Transmitter::Fatal); TextReceiver text_receiver ("mmctest"); #include "midi++/port.h" -#include "midi++/port_request.h" #include "midi++/manager.h" using namespace MIDI; diff --git a/libs/midi++2/mmctest.cc b/libs/midi++2/mmctest.cc index 36fbd61124..062f6e8d32 100644 --- a/libs/midi++2/mmctest.cc +++ b/libs/midi++2/mmctest.cc @@ -11,7 +11,6 @@ Transmitter fatal (Transmitter::Fatal); TextReceiver text_receiver ("mmctest"); #include "midi++/port.h" -#include "midi++/port_request.h" #include "midi++/manager.h" #include "midi++/mmc.h" diff --git a/libs/midi++2/port_request.cc b/libs/midi++2/port_request.cc deleted file mode 100644 index 352ed77fb7..0000000000 --- a/libs/midi++2/port_request.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2000 Paul Barton-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. - - $Id$ -*/ - -#include -#include -#include - -using namespace std; -using namespace MIDI; - -PortRequest::PortRequest (const string &xdev, - const string &xtag, - const string &xmode, - const string &xtype) - -{ - status = OK; - - devname = strdup (xdev.c_str()); - tagname = strdup (xtag.c_str()); - mode = PortFactory::string_to_mode (xmode); - type = PortFactory::string_to_type (xtype); -} - diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index 4bbf3745c6..720711d94b 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -24,7 +24,6 @@ #include #include -#include #include #include diff --git a/libs/surfaces/mackie/mackie_control_protocol_poll.cc b/libs/surfaces/mackie/mackie_control_protocol_poll.cc index 81342dc9b5..521b804f93 100644 --- a/libs/surfaces/mackie/mackie_control_protocol_poll.cc +++ b/libs/surfaces/mackie/mackie_control_protocol_poll.cc @@ -9,7 +9,6 @@ #include #include #include -#include #include "i18n.h" #include -- 2.30.2