summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-07-20 16:05:00 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-07-20 16:05:00 +0000
commitab3020cee102913aa6399d6fb5535e7e55093120 (patch)
tree65d00ee6ff10dc58be876d541b51927481240758
parente644ddc4c8efa1b134a61b7a5a7f4112d2e90465 (diff)
permit MIDI port removal now, and save MIDI ports back to the ardour.rc file
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2163 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/option_editor.cc115
-rw-r--r--gtk2_ardour/option_editor.h8
-rw-r--r--libs/ardour/configuration.cc11
-rw-r--r--libs/ardour/globals.cc12
-rw-r--r--libs/midi++2/coremidi_midiport.cc9
-rw-r--r--libs/midi++2/midi++/alsa_rawmidi.h10
-rw-r--r--libs/midi++2/midi++/alsa_sequencer.h5
-rw-r--r--libs/midi++2/midi++/coremidi_midiport.h15
-rw-r--r--libs/midi++2/midi++/factory.h3
-rw-r--r--libs/midi++2/midi++/fd_midiport.h1
-rw-r--r--libs/midi++2/midi++/fifomidi.h7
-rw-r--r--libs/midi++2/midi++/manager.h5
-rw-r--r--libs/midi++2/midi++/nullmidi.h7
-rw-r--r--libs/midi++2/midi++/port.h8
-rw-r--r--libs/midi++2/midifactory.cc61
-rw-r--r--libs/midi++2/midimanager.cc76
-rw-r--r--libs/midi++2/midiport.cc16
-rw-r--r--libs/midi++2/port_request.cc45
-rw-r--r--libs/pbd/convert.cc20
-rw-r--r--libs/pbd/pbd/convert.h1
20 files changed, 261 insertions, 174 deletions
diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc
index 415d9747e2..e066b3cab7 100644
--- a/gtk2_ardour/option_editor.cc
+++ b/gtk2_ardour/option_editor.cc
@@ -77,7 +77,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
/* MIDI */
- midi_port_table (4, 10),
+ midi_port_table (4, 11),
mmc_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
mmc_device_id_spinner (mmc_device_id_adjustment),
add_midi_port_button (_("Add new MIDI port")),
@@ -179,27 +179,7 @@ OptionEditor::set_session (Session *s)
smpte_offset_negative_button.set_active (session->smpte_offset_negative());
- /* set up port assignments */
-
- std::map<MIDI::Port*,vector<RadioButton*> >::iterator res;
-
- if (session->mtc_port()) {
- if ((res = port_toggle_buttons.find (session->mtc_port())) != port_toggle_buttons.end()) {
- (*res).second[MtcIndex]->set_active (true);
- }
- }
-
- if (session->mmc_port ()) {
- if ((res = port_toggle_buttons.find (session->mmc_port())) != port_toggle_buttons.end()) {
- (*res).second[MmcIndex]->set_active (true);
- }
- }
-
- if (session->midi_port()) {
- if ((res = port_toggle_buttons.find (session->midi_port())) != port_toggle_buttons.end()) {
- (*res).second[MidiIndex]->set_active (true);
- }
- }
+ redisplay_midi_ports ();
setup_click_editor ();
connect_audition_editor ();
@@ -406,7 +386,7 @@ OptionEditor::redisplay_midi_ports ()
midi_port_table_widgets.clear ();
- midi_port_table.resize (ports.size() + 4, 10);
+ midi_port_table.resize (ports.size() + 4, 11);
Gtk::Label* label;
@@ -461,11 +441,19 @@ OptionEditor::redisplay_midi_ports ()
for (n = 0, i = ports.begin(); i != ports.end(); ++n, ++i) {
- pair<MIDI::Port*,vector<RadioButton*> > newpair;
ToggleButton* tb;
RadioButton* rb;
+ Button* bb;
- newpair.first = i->second;
+ /* the remove button. create early so we can pass it to various callbacks */
+
+ bb = manage (new Button (Stock::REMOVE));
+ bb->set_name ("OptionEditorToggleButton");
+ bb->show ();
+ midi_port_table_widgets.push_back (bb);
+ midi_port_table.attach (*bb, 9, 10, n+2, n+3, FILL|EXPAND, FILL);
+ bb->signal_clicked().connect (bind (mem_fun(*this, &OptionEditor::remove_midi_port), i->second));
+ bb->set_sensitive (port_removable (i->second));
label = (manage (new Label (i->first)));
label->show ();
@@ -507,10 +495,10 @@ OptionEditor::redisplay_midi_ports ()
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_out_toggled), (*i).second, tb));
tb->set_size_request (10, 10);
tb->show ();
+ midi_port_table_widgets.push_back (tb);
midi_port_table.attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL);
rb = manage (new RadioButton ());
- newpair.second.push_back (rb);
rb->set_name ("OptionEditorToggleButton");
if (n == 0) {
mtc_button_group = rb->get_group();
@@ -521,14 +509,13 @@ OptionEditor::redisplay_midi_ports ()
rb->show ();
midi_port_table_widgets.push_back (rb);
midi_port_table.attach (*rb, 4, 5, n+2, n+3, FILL|EXPAND, FILL);
- rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mtc_port_chosen), (*i).second, rb));
+ rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mtc_port_chosen), (*i).second, rb, bb));
if (session && i->second == session->mtc_port()) {
rb->set_active (true);
}
rb = manage (new RadioButton ());
- newpair.second.push_back (rb);
rb->set_name ("OptionEditorToggleButton");
if (n == 0) {
mmc_button_group = rb->get_group();
@@ -538,14 +525,13 @@ OptionEditor::redisplay_midi_ports ()
rb->show ();
midi_port_table_widgets.push_back (rb);
midi_port_table.attach (*rb, 6, 7, n+2, n+3, FILL|EXPAND, FILL);
- rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mmc_port_chosen), (*i).second, rb));
+ rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mmc_port_chosen), (*i).second, rb, bb));
if (session && i->second == session->mmc_port()) {
rb->set_active (true);
}
rb = manage (new RadioButton ());
- newpair.second.push_back (rb);
rb->set_name ("OptionEditorToggleButton");
if (n == 0) {
midi_button_group = rb->get_group();
@@ -555,19 +541,25 @@ OptionEditor::redisplay_midi_ports ()
rb->show ();
midi_port_table_widgets.push_back (rb);
midi_port_table.attach (*rb, 8, 9, n+2, n+3, FILL|EXPAND, FILL);
- rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::midi_port_chosen), (*i).second, rb));
+ rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::midi_port_chosen), (*i).second, rb, bb));
if (session && i->second == session->midi_port()) {
rb->set_active (true);
}
-
- port_toggle_buttons.insert (newpair);
+
}
midi_port_table.show();
}
void
+OptionEditor::remove_midi_port (MIDI::Port* port)
+{
+ MIDI::Manager::instance()->remove_port (port);
+ redisplay_midi_ports ();
+}
+
+void
OptionEditor::add_midi_port ()
{
MidiPortDialog dialog;
@@ -608,51 +600,60 @@ OptionEditor::add_midi_port ()
}
}
+bool
+OptionEditor::port_removable (MIDI::Port *port)
+{
+ if (!session) {
+ return true;
+ }
+
+ if (port == session->mtc_port() ||
+ port == session->mmc_port() ||
+ port == session->midi_port()) {
+ return false;
+ }
+ return true;
+}
+
void
-OptionEditor::mtc_port_chosen (MIDI::Port *port, Gtk::RadioButton* rb)
+OptionEditor::mtc_port_chosen (MIDI::Port *port, Gtk::RadioButton* rb, Gtk::Button* bb)
{
if (session) {
if (rb->get_active()) {
- if (port) {
- session->set_mtc_port (port->name());
- Config->set_mtc_port_name (port->name());
- } else {
- session->set_mtc_port ("");
- }
- rb->set_active (true);
+ session->set_mtc_port (port->name());
+ Config->set_mtc_port_name (port->name());
+ } else {
+ session->set_mtc_port ("");
}
+ bb->set_sensitive (port_removable (port));
}
}
void
-OptionEditor::mmc_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb)
+OptionEditor::mmc_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb, Gtk::Button* bb)
{
if (session) {
if (rb->get_active()) {
- if (port) {
- session->set_mmc_port (port->name());
- Config->set_mtc_port_name (port->name());
- } else {
- session->set_mmc_port ("");
- }
- rb->set_active (true);
+ session->set_mmc_port (port->name());
+ Config->set_mtc_port_name (port->name());
+ } else {
+ session->set_mmc_port ("");
}
+ bb->set_sensitive (port_removable (port));
}
}
void
-OptionEditor::midi_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb)
+OptionEditor::midi_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb, Gtk::Button* bb)
{
if (session) {
if (rb->get_active()) {
- if (port) {
- session->set_midi_port (port->name());
- Config->set_midi_port_name (port->name());
- } else {
- session->set_midi_port ("");
- }
- rb->set_active (true);
+ session->set_midi_port (port->name());
+ Config->set_midi_port_name (port->name());
+ } else {
+ session->set_midi_port ("");
}
+ bb->set_sensitive (port_removable (port));
}
}
diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h
index 8efbb94221..81372f5775 100644
--- a/gtk2_ardour/option_editor.h
+++ b/gtk2_ardour/option_editor.h
@@ -117,15 +117,17 @@ class OptionEditor : public Gtk::Dialog
Gtk::Button add_midi_port_button;
void add_midi_port ();
+ void remove_midi_port (MIDI::Port*);
void redisplay_midi_ports ();
void port_online_toggled (MIDI::Port*,Gtk::ToggleButton*);
void port_trace_in_toggled (MIDI::Port*,Gtk::ToggleButton*);
void port_trace_out_toggled (MIDI::Port*,Gtk::ToggleButton*);
- void mmc_port_chosen (MIDI::Port*,Gtk::RadioButton*);
- void mtc_port_chosen (MIDI::Port*,Gtk::RadioButton*);
- void midi_port_chosen (MIDI::Port*,Gtk::RadioButton*);
+ void mmc_port_chosen (MIDI::Port*,Gtk::RadioButton*, Gtk::Button*);
+ void mtc_port_chosen (MIDI::Port*,Gtk::RadioButton*, Gtk::Button*);
+ void midi_port_chosen (MIDI::Port*,Gtk::RadioButton*, Gtk::Button*);
+ bool port_removable (MIDI::Port*);
void mmc_device_id_adjusted ();
diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc
index c8d71c5155..60bc01fdfa 100644
--- a/libs/ardour/configuration.cc
+++ b/libs/ardour/configuration.cc
@@ -23,6 +23,8 @@
#include <pbd/failed_constructor.h>
#include <pbd/xml++.h>
+#include <midi++/manager.h>
+
#include <ardour/ardour.h>
#include <ardour/configuration.h>
#include <ardour/audio_diskstream.h>
@@ -157,9 +159,12 @@ Configuration::get_state ()
LocaleGuard lg (X_("POSIX"));
root = new XMLNode("Ardour");
- typedef map<string, MidiPortDescriptor*>::const_iterator CI;
- for(CI m = midi_ports.begin(); m != midi_ports.end(); ++m){
- root->add_child_nocopy(m->second->get_state());
+
+ MIDI::Manager::PortMap::const_iterator i;
+ const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
+
+ for(i = ports.begin(); i != ports.end(); ++i) {
+ root->add_child_nocopy(i->second->get_state());
}
root->add_child_nocopy (get_variables (sigc::mem_fun (*this, &Configuration::save_config_options_predicate)));
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index a6fb0fcf41..c7b1b92cb8 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -137,6 +137,10 @@ setup_midi ()
nports++;
}
+ MIDI::Port* first;
+ const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
+ first = ports.begin()->second;
+
if (nports > 1) {
/* More than one port, so try using specific names for each port */
@@ -158,22 +162,22 @@ setup_midi ()
/* If that didn't work, just use the first listed port */
if (default_mmc_port == 0) {
- default_mmc_port = MIDI::Manager::instance()->port (0);
+ default_mmc_port = first;
}
if (default_mtc_port == 0) {
- default_mtc_port = MIDI::Manager::instance()->port (0);
+ default_mtc_port = first;
}
if (default_midi_port == 0) {
- default_midi_port = MIDI::Manager::instance()->port (0);
+ default_midi_port = first;
}
} else {
/* Only one port described, so use it for both MTC and MMC */
- default_mmc_port = MIDI::Manager::instance()->port (0);
+ default_mmc_port = first;
default_mtc_port = default_mmc_port;
default_midi_port = default_mmc_port;
}
diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc
index 38f84fe750..307abfa8d6 100644
--- a/libs/midi++2/coremidi_midiport.cc
+++ b/libs/midi++2/coremidi_midiport.cc
@@ -49,6 +49,15 @@ CoreMidi_MidiPort::CoreMidi_MidiPort (PortRequest &req) : Port (req)
CoreMidi_MidiPort::~CoreMidi_MidiPort () {Close();}
+XMLNode&
+CoreMidi::MidiPort::get_state() const
+{
+ XMLNode& node (Port::get_state());
+ node.add_property ("type", "coremidi");
+ return node;
+}
+
+
void CoreMidi_MidiPort::Close ()
{
if (midi_destination) MIDIEndpointDispose(midi_destination);
diff --git a/libs/midi++2/midi++/alsa_rawmidi.h b/libs/midi++2/midi++/alsa_rawmidi.h
index d2aa6f5181..7edee58322 100644
--- a/libs/midi++2/midi++/alsa_rawmidi.h
+++ b/libs/midi++2/midi++/alsa_rawmidi.h
@@ -28,6 +28,8 @@
#include <midi++/port.h>
#include <midi++/fd_midiport.h>
+namespace MIDI {
+
class ALSA_RawMidiPort : public MIDI::FD_MidiPort
{
@@ -35,8 +37,16 @@ class ALSA_RawMidiPort : public MIDI::FD_MidiPort
ALSA_RawMidiPort (MIDI::PortRequest &req)
: FD_MidiPort (req, "/dev/snd", "midi") {}
virtual ~ALSA_RawMidiPort () {}
+
+ static std::string typestring;
+
+ protected:
+ std::string get_typestring () const {
+ return typestring;
+ }
};
+}
#endif // __alsa_rawmidi_h__
diff --git a/libs/midi++2/midi++/alsa_sequencer.h b/libs/midi++2/midi++/alsa_sequencer.h
index 78e4a01683..7e929d38c2 100644
--- a/libs/midi++2/midi++/alsa_sequencer.h
+++ b/libs/midi++2/midi++/alsa_sequencer.h
@@ -43,6 +43,7 @@ class ALSA_SequencerMidiPort : public Port
virtual int selectable() const;
static int discover (std::vector<PortSet>&);
+ static std::string typestring;
protected:
/* Direct I/O */
@@ -50,6 +51,10 @@ class ALSA_SequencerMidiPort : public Port
int write (byte *msg, size_t msglen);
int read (byte *buf, size_t max);
+ std::string get_typestring () const {
+ return typestring;
+ }
+
private:
snd_midi_event_t *decoder, *encoder;
int port_id;
diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h
index 20fe739b94..89047540cb 100644
--- a/libs/midi++2/midi++/coremidi_midiport.h
+++ b/libs/midi++2/midi++/coremidi_midiport.h
@@ -42,15 +42,23 @@ namespace MIDI {
}
static int discover (std::vector<PortSet>&);
+ static std::string typestring;
protected:
/* Direct I/O */
int write(byte * msg, size_t msglen);
+
int read(byte * buf, size_t max) {
return 0;
- } /* CoreMidi callback */
- static void read_proc(const MIDIPacketList * pktlist,
- void *refCon, void *connRefCon);
+ }
+
+ /* CoreMidi callback */
+ static void read_proc(const MIDIPacketList * pktlist,
+ void *refCon, void *connRefCon);
+
+ std::string get_typestring () const {
+ return typestring;
+ }
private:
byte midi_buffer[1024];
@@ -63,6 +71,7 @@ namespace MIDI {
static MIDITimeStamp MIDIGetCurrentHostTime();
bool firstrecv;
+
};
} // namespace MIDI
diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h
index 186c3973e3..bd130f8701 100644
--- a/libs/midi++2/midi++/factory.h
+++ b/libs/midi++2/midi++/factory.h
@@ -34,6 +34,9 @@ class PortFactory {
static bool ignore_duplicate_devices (Port::Type);
static int get_known_ports (std::vector<PortSet>&);
static std::string default_port_type ();
+ static Port::Type string_to_type (const std::string&);
+ static std::string mode_to_string (int);
+ static int string_to_mode (const std::string&);
};
} // namespace MIDI
diff --git a/libs/midi++2/midi++/fd_midiport.h b/libs/midi++2/midi++/fd_midiport.h
index d7fae400a0..e971a18f8c 100644
--- a/libs/midi++2/midi++/fd_midiport.h
+++ b/libs/midi++2/midi++/fd_midiport.h
@@ -46,6 +46,7 @@ class FD_MidiPort : public Port
}
virtual int selectable() const;
+
static std::vector<std::string *> *list_devices ();
protected:
diff --git a/libs/midi++2/midi++/fifomidi.h b/libs/midi++2/midi++/fifomidi.h
index 57d1502c45..ea644dde06 100644
--- a/libs/midi++2/midi++/fifomidi.h
+++ b/libs/midi++2/midi++/fifomidi.h
@@ -37,6 +37,13 @@ class FIFO_MidiPort : public MIDI::FD_MidiPort
FIFO_MidiPort (PortRequest &req);
~FIFO_MidiPort () {};
+ static std::string typestring;
+
+ protected:
+ std::string get_typestring () const {
+ return typestring;
+ }
+
private:
void open (PortRequest &req);
};
diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h
index c230933689..d13be58af6 100644
--- a/libs/midi++2/midi++/manager.h
+++ b/libs/midi++2/midi++/manager.h
@@ -36,10 +36,9 @@ class Manager {
~Manager ();
Port *add_port (PortRequest &);
- int remove_port (std::string port);
+ int remove_port (Port*);
Port *port (std::string name);
- Port *port (size_t number);
size_t nports () { return ports_by_device.size(); }
@@ -50,9 +49,7 @@ class Manager {
channel_t inputChannelNumber;
channel_t outputChannelNumber;
- int set_input_port (size_t port);
int set_input_port (std::string);
- int set_output_port (size_t port);
int set_output_port (std::string);
int set_input_channel (channel_t);
int set_output_channel (channel_t);
diff --git a/libs/midi++2/midi++/nullmidi.h b/libs/midi++2/midi++/nullmidi.h
index 13591db4e6..d3d53826bb 100644
--- a/libs/midi++2/midi++/nullmidi.h
+++ b/libs/midi++2/midi++/nullmidi.h
@@ -54,6 +54,13 @@ class Null_MidiPort : public Port
}
virtual int selectable() const { return -1; }
+
+ static std::string typestring;
+
+ protected:
+ std::string get_typestring () const {
+ return typestring;
+ }
};
} // namespace MIDI
diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h
index 123ac9e3d8..0b5e72d81b 100644
--- a/libs/midi++2/midi++/port.h
+++ b/libs/midi++2/midi++/port.h
@@ -26,6 +26,8 @@
#include <midi++/types.h>
#include <midi++/parser.h>
+class XMLNode;
+
namespace MIDI {
class Channel;
@@ -46,6 +48,8 @@ class Port : public sigc::trackable {
Port (PortRequest &);
virtual ~Port ();
+ virtual XMLNode& get_state () const;
+
/* Direct I/O */
virtual int write (byte *msg, size_t msglen) = 0;
@@ -118,7 +122,6 @@ class Port : public sigc::trackable {
Type type () const { return _type; }
int mode () const { return _mode; }
bool ok () const { return _ok; }
- size_t number () const { return _number; }
protected:
bool _ok;
@@ -126,7 +129,6 @@ class Port : public sigc::trackable {
std::string _devname;
std::string _tagname;
int _mode;
- size_t _number;
Channel *_channel[16];
sigc::connection thru_connection;
unsigned int bytes_written;
@@ -135,6 +137,8 @@ class Port : public sigc::trackable {
Parser *output_parser;
size_t slowdown;
+ virtual std::string get_typestring () const = 0;
+
private:
static size_t nports;
};
diff --git a/libs/midi++2/midifactory.cc b/libs/midi++2/midifactory.cc
index 0912c8ae7b..cb8846214e 100644
--- a/libs/midi++2/midifactory.cc
+++ b/libs/midi++2/midifactory.cc
@@ -17,25 +17,39 @@
$Id$
*/
+#include <fcntl.h>
+
#include <pbd/error.h>
+#include <pbd/convert.h>
#include <midi++/types.h>
#include <midi++/factory.h>
#include <midi++/nullmidi.h>
#include <midi++/fifomidi.h>
+std::string MIDI::Null_MidiPort::typestring = "null";
+std::string MIDI::FIFO_MidiPort::typestring = "fifo";
+
#ifdef WITH_ALSA
#include <midi++/alsa_sequencer.h>
#include <midi++/alsa_rawmidi.h>
+
+std::string MIDI::ALSA_SequencerMidiPort::typestring = "alsa/sequencer";
+std::string MIDI::ALSA_RawMidiPort::typestring = "alsa/raw";
+
#endif // WITH_ALSA
#ifdef WITH_COREMIDI
#include <midi++/coremidi_midiport.h>
+
+std::string MIDI::CoreMidi_MidiPort::typestring = "coremidi";
+
#endif // WITH_COREMIDI
using namespace std;
using namespace MIDI;
+using namespace PBD;
Port *
PortFactory::create_port (PortRequest &req)
@@ -132,3 +146,50 @@ PortFactory::default_port_type ()
PBD::fatal << "programming error: no default port type defined in midifactory.cc" << endmsg;
}
+
+Port::Type
+PortFactory::string_to_type (const string& xtype)
+{
+ if (0){
+#ifdef WITH_ALSA
+ } else if (strings_equal_ignore_case (xtype, ALSA_RawMidiPort::typestring)) {
+ return Port::ALSA_RawMidi;
+ } else if (strings_equal_ignore_case (xtype, ALSA_SequencerMidiPort::typestring)) {
+ return Port::ALSA_Sequencer;
+#endif
+#ifdef WITH_COREMIDI
+ } else if (strings_equal_ignore_case (xtype, CoreMidi_MidiPort::typestring)) {
+ return Port::CoreMidi_MidiPort;
+#endif
+ } else if (strings_equal_ignore_case (xtype, Null_MidiPort::typestring)) {
+ return Port::Null;
+ } else if (strings_equal_ignore_case (xtype, FIFO_MidiPort::typestring)) {
+ return Port::FIFO;
+ }
+
+ return Port::Unknown;
+}
+
+string
+PortFactory::mode_to_string (int mode)
+{
+ if (mode == O_RDONLY) {
+ return "input";
+ } else if (mode == O_WRONLY) {
+ return "output";
+ }
+
+ return "duplex";
+}
+
+int
+PortFactory::string_to_mode (const string& str)
+{
+ if (strings_equal_ignore_case (str, "output") || strings_equal_ignore_case (str, "out")) {
+ return O_WRONLY;
+ } else if (strings_equal_ignore_case (str, "input") || strings_equal_ignore_case (str, "in")) {
+ return O_RDONLY;
+ }
+
+ return O_RDWR;
+}
diff --git a/libs/midi++2/midimanager.cc b/libs/midi++2/midimanager.cc
index 3b7323541d..cc4ca6abec 100644
--- a/libs/midi++2/midimanager.cc
+++ b/libs/midi++2/midimanager.cc
@@ -145,18 +145,32 @@ Manager::add_port (PortRequest &req)
}
int
-Manager::remove_port (string name)
+Manager::remove_port (Port* port)
{
PortMap::iterator res;
- if ((res = ports_by_device.find (name)) == ports_by_device.end()) {
- return -1;
+ for (res = ports_by_device.begin(); res != ports_by_device.end(); ) {
+ PortMap::iterator tmp;
+ tmp = res;
+ ++tmp;
+ if (res->second == port) {
+ ports_by_device.erase (res);
+ }
+ res = tmp;
}
-
- ports_by_device.erase (res);
- ports_by_device.erase ((*res).second->name());
- delete (*res).second;
+
+ for (res = ports_by_tag.begin(); res != ports_by_tag.end(); ) {
+ PortMap::iterator tmp;
+ tmp = res;
+ ++tmp;
+ if (res->second == port) {
+ ports_by_tag.erase (res);
+ }
+ res = tmp;
+ }
+
+ delete port;
return 0;
}
@@ -184,22 +198,6 @@ Manager::set_input_port (string tag)
}
int
-Manager::set_input_port (size_t portnum)
-
-{
- PortMap::iterator res;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if ((*res).second->number() == portnum) {
- inputPort = (*res).second;
- return 0;
- }
- }
-
- return -1;
-}
-
-int
Manager::set_output_port (string tag)
{
@@ -231,22 +229,6 @@ Manager::set_output_port (string tag)
return 0;
}
-int
-Manager::set_output_port (size_t portnum)
-
-{
- PortMap::iterator res;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if ((*res).second->number() == portnum) {
- outputPort = (*res).second;
- return 0;
- }
- }
-
- return -1;
-}
-
Port *
Manager::port (string name)
{
@@ -261,25 +243,9 @@ Manager::port (string name)
return 0;
}
-Port *
-Manager::port (size_t portnum)
-
-{
- PortMap::iterator res;
-
- for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
- if ((*res).second->number() == portnum) {
- return (*res).second;
- }
- }
-
- return 0;
-}
-
int
Manager::foreach_port (int (*func)(const Port &, size_t, void *),
void *arg)
-
{
PortMap::const_iterator i;
int retval;
diff --git a/libs/midi++2/midiport.cc b/libs/midi++2/midiport.cc
index a42aac2984..a4b28ce461 100644
--- a/libs/midi++2/midiport.cc
+++ b/libs/midi++2/midiport.cc
@@ -21,10 +21,13 @@
#include <cstdio>
#include <fcntl.h>
+#include <pbd/xml++.h>
+
#include <midi++/types.h>
#include <midi++/port.h>
#include <midi++/channel.h>
#include <midi++/port_request.h>
+#include <midi++/factory.h>
//using namespace Select;
using namespace MIDI;
@@ -47,7 +50,6 @@ Port::Port (PortRequest &req)
_devname = req.devname;
_tagname = req.tagname;
_mode = req.mode;
- _number = nports++;
if (_mode == O_RDONLY || _mode == O_RDWR) {
input_parser = new Parser (*this);
@@ -83,6 +85,18 @@ Port::~Port ()
}
}
+XMLNode&
+Port::get_state () const
+{
+ XMLNode* node = new XMLNode ("MIDI-port");
+ node->add_property ("tag", _tagname);
+ node->add_property ("device", _devname);
+ node->add_property ("mode", PortFactory::mode_to_string (_mode));
+ node->add_property ("type", get_typestring());
+
+ return *node;
+}
+
int
Port::clock ()
diff --git a/libs/midi++2/port_request.cc b/libs/midi++2/port_request.cc
index d081bdb570..352ed77fb7 100644
--- a/libs/midi++2/port_request.cc
+++ b/libs/midi++2/port_request.cc
@@ -18,10 +18,9 @@
$Id$
*/
-#include <fcntl.h>
-#include <string.h>
#include <midi++/port.h>
#include <midi++/port_request.h>
+#include <midi++/factory.h>
using namespace std;
using namespace MIDI;
@@ -36,45 +35,7 @@ PortRequest::PortRequest (const string &xdev,
devname = strdup (xdev.c_str());
tagname = strdup (xtag.c_str());
-
- if (xmode == "output" ||
- xmode == "out" ||
- xmode == "OUTPUT" ||
- xmode == "OUT") {
- mode = O_WRONLY;
-
- } else if (xmode == "input" ||
- xmode == "in" ||
- xmode == "INPUT" ||
- xmode == "IN") {
- mode = O_RDONLY;
-
- } else if (xmode == "duplex" ||
- xmode == "DUPLEX" ||
- xmode == "inout" ||
- xmode == "INOUT") {
- mode = O_RDWR;
- } else {
- status = Unknown;
- }
-
- if (xtype == "ALSA/RAW" ||
- xtype == "alsa/raw") {
- type = Port::ALSA_RawMidi;
- } else if (xtype == "ALSA/SEQUENCER" ||
- xtype == "alsa/sequencer") {
- type = Port::ALSA_Sequencer;
- } else if (xtype == "COREMIDI" ||
- xtype == "coremidi") {
- type = Port::CoreMidi_MidiPort;
- } else if (xtype == "NULL" ||
- xtype == "null") {
- type = Port::Null;
- } else if (xtype == "FIFO" ||
- xtype == "fifo") {
- type = Port::FIFO;
- } else {
- status = Unknown;
- }
+ mode = PortFactory::string_to_mode (xmode);
+ type = PortFactory::string_to_type (xtype);
}
diff --git a/libs/pbd/convert.cc b/libs/pbd/convert.cc
index 832c54acd8..ff426cfb80 100644
--- a/libs/pbd/convert.cc
+++ b/libs/pbd/convert.cc
@@ -18,6 +18,8 @@
*/
#include <cmath>
+#include <locale>
+#include <algorithm>
#include <stdint.h>
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
@@ -234,4 +236,22 @@ length2string (const int64_t frames, const double sample_rate)
return duration_str;
}
+static bool
+chars_equal_ignore_case(char x, char y)
+{
+ static std::locale loc;
+ return toupper(x, loc) == toupper(y, loc);
+}
+
+bool
+strings_equal_ignore_case (const string& a, const string& b)
+{
+ if (a.length() == b.length()) {
+ return std::equal (a.begin(), a.end(), b.begin(), chars_equal_ignore_case);
+ }
+ return false;
+}
+
+
+
} // namespace PBD
diff --git a/libs/pbd/pbd/convert.h b/libs/pbd/pbd/convert.h
index 55006529ae..00176659cf 100644
--- a/libs/pbd/pbd/convert.h
+++ b/libs/pbd/pbd/convert.h
@@ -35,6 +35,7 @@ void url_decode (std::string&);
std::string length2string (const int64_t frames, const double sample_rate);
std::vector<std::string> internationalize (const char *, const char **);
+bool strings_equal_ignore_case (const std::string& a, const std::string& b);
} //namespace PBD