From 47add43cd028855cda2292bef9dcde607f948490 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 19 Jul 2007 18:21:58 +0000 Subject: [PATCH] new functionality to add MIDI ports from the options editor, not totally finished but functional git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2152 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/SConscript | 1 + gtk2_ardour/ardour_ui_ed.cc | 7 +- gtk2_ardour/midi_port_dialog.cc | 55 ++++++ gtk2_ardour/midi_port_dialog.h | 21 +++ gtk2_ardour/option_editor.cc | 238 ++++++++++++++++++------ gtk2_ardour/option_editor.h | 6 + libs/midi++2/alsa_sequencer_midiport.cc | 76 +++++++- libs/midi++2/coremidi_midiport.cc | 7 + libs/midi++2/midi++/alsa_sequencer.h | 3 + libs/midi++2/midi++/coremidi_midiport.h | 3 + libs/midi++2/midi++/factory.h | 3 + libs/midi++2/midi++/manager.h | 5 + libs/midi++2/midi++/port_request.h | 10 +- libs/midi++2/midifactory.cc | 31 +++ libs/midi++2/midimanager.cc | 6 + 15 files changed, 412 insertions(+), 60 deletions(-) create mode 100644 gtk2_ardour/midi_port_dialog.cc create mode 100644 gtk2_ardour/midi_port_dialog.h diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 1ee37e71f7..da23bb11c6 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -162,6 +162,7 @@ marker.cc marker_time_axis.cc marker_time_axis_view.cc marker_view.cc +midi_port_dialog.cc mixer_strip.cc mixer_ui.cc new_session_dialog.cc diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 8ab8e6931a..fbb700e20e 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -704,8 +704,11 @@ ARDOUR_UI::build_menu_bar () * until the Menu GObject class is registered, which happens * when the first menu instance is created. */ - Gtk::Settings::get_default()->property_gtk_can_change_accels() = true; - + // XXX bug in gtkmm causes this to popup an error message + // Gtk::Settings::get_default()->property_gtk_can_change_accels() = true; + // so use this instead ... + gtk_settings_set_long_property (gtk_settings_get_default(), "gtk-can-change-accels", 1, "Ardour:designers"); + wall_clock_box.add (wall_clock_label); wall_clock_box.set_name ("WallClock"); wall_clock_label.set_name ("WallClock"); diff --git a/gtk2_ardour/midi_port_dialog.cc b/gtk2_ardour/midi_port_dialog.cc new file mode 100644 index 0000000000..2bb686d70b --- /dev/null +++ b/gtk2_ardour/midi_port_dialog.cc @@ -0,0 +1,55 @@ +#include +#include +#include + +#include +#include + +#include "midi_port_dialog.h" + +#include "i18n.h" + +using namespace std; +using namespace PBD; +using namespace Gtk; +using namespace Gtkmm2ext; +using namespace sigc; + +static const char* mode_strings[] = { "duplex", "output", "input", (char*) 0 }; + +MidiPortDialog::MidiPortDialog () + : ArdourDialog ("midi_port_dialog"), + port_label (_("Port name")) + +{ + vector str = internationalize (PACKAGE, mode_strings); + set_popdown_strings (port_mode_combo, str); + port_mode_combo.set_active_text (str.front()); + + hpacker.pack_start (port_label); + hpacker.pack_start (port_name); + hpacker.pack_start (port_mode_combo); + + port_label.show (); + port_name.show (); + port_mode_combo.show (); + hpacker.show (); + + get_vbox()->pack_start (hpacker); + + port_name.signal_activate().connect (mem_fun (*this, &MidiPortDialog::entry_activated)); + + add_button (Stock::ADD, RESPONSE_ACCEPT); + add_button (Stock::CANCEL, RESPONSE_CANCEL); +} + +void +MidiPortDialog::entry_activated () +{ + response (RESPONSE_ACCEPT); +} + +MidiPortDialog::~MidiPortDialog () +{ + +} diff --git a/gtk2_ardour/midi_port_dialog.h b/gtk2_ardour/midi_port_dialog.h new file mode 100644 index 0000000000..a76400e91b --- /dev/null +++ b/gtk2_ardour/midi_port_dialog.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +#include "ardour_dialog.h" + +class MidiPortDialog : public ArdourDialog +{ + public: + MidiPortDialog (); + ~MidiPortDialog (); + + Gtk::HBox hpacker; + Gtk::Label port_label; + Gtk::Entry port_name; + Gtk::ComboBoxText port_mode_combo; + + private: + void entry_activated (); +}; diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc index ad34e8ed0b..415d9747e2 100644 --- a/gtk2_ardour/option_editor.cc +++ b/gtk2_ardour/option_editor.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include "utils.h" #include "editing.h" #include "option_editor.h" +#include "midi_port_dialog.h" #include "i18n.h" @@ -75,8 +77,10 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui) /* MIDI */ + midi_port_table (4, 10), 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")), /* Click */ @@ -134,10 +138,8 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui) notebook.pages().push_back (TabElem (audition_packer, _("Audition"))); notebook.pages().push_back (TabElem (fade_packer, _("Layers & Fades"))); - if (!MIDI::Manager::instance()->get_midi_ports().empty()) { - setup_midi_options (); - notebook.pages().push_back (TabElem (midi_packer, _("MIDI"))); - } + setup_midi_options (); + notebook.pages().push_back (TabElem (midi_packer, _("MIDI"))); set_session (0); show_all_children(); @@ -368,41 +370,108 @@ void OptionEditor::setup_midi_options () { HBox* hbox; + + midi_port_table.set_row_spacings (6); + midi_port_table.set_col_spacings (10); + + redisplay_midi_ports (); + + mmc_device_id_adjustment.signal_value_changed().connect (mem_fun (*this, &OptionEditor::mmc_device_id_adjusted)); + + hbox = manage (new HBox); + hbox->set_border_width (6); + hbox->pack_start (midi_port_table, true, false); + + midi_packer.pack_start (*hbox, false, false); + midi_packer.pack_start (add_midi_port_button, false, false); + + add_midi_port_button.signal_clicked().connect (mem_fun (*this, &OptionEditor::add_midi_port)); +} + +void +OptionEditor::redisplay_midi_ports () +{ MIDI::Manager::PortMap::const_iterator i; const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports(); int n; - ToggleButton* tb; - RadioButton* rb; - Gtk::Table* table = manage (new Table (ports.size() + 4, 10)); + /* remove all existing widgets */ - table->set_row_spacings (6); - table->set_col_spacings (10); + // XXX broken in gtkmm 2.10 + // midi_port_table.clear (); - table->attach (*(manage (new Label (_("Port")))), 0, 1, 0, 1); - table->attach (*(manage (new Label (_("Offline")))), 1, 2, 0, 1); - table->attach (*(manage (new Label (_("Trace\nInput")))), 2, 3, 0, 1); - table->attach (*(manage (new Label (_("Trace\nOutput")))), 3, 4, 0, 1); - table->attach (*(manage (new Label (_("MTC")))), 4, 5, 0, 1); - table->attach (*(manage (new Label (_("MMC")))), 6, 7, 0, 1); - table->attach (*(manage (new Label (_("MIDI Parameter\nControl")))), 8, 9, 0, 1); + for (vector::iterator w = midi_port_table_widgets.begin(); w != midi_port_table_widgets.end(); ++w) { + midi_port_table.remove (**w); + } - table->attach (*(manage (new HSeparator())), 0, 9, 1, 2); - table->attach (*(manage (new VSeparator())), 5, 6, 0, 8); - table->attach (*(manage (new VSeparator())), 7, 8, 0, 8); + midi_port_table_widgets.clear (); + + midi_port_table.resize (ports.size() + 4, 10); + + Gtk::Label* label; + + label = (manage (new Label (_("Port")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 0, 1, 0, 1); + label = (manage (new Label (_("Offline")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 1, 2, 0, 1); + label = (manage (new Label (_("Trace\nInput")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 2, 3, 0, 1); + label = (manage (new Label (_("Trace\nOutput")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 3, 4, 0, 1); + label = (manage (new Label (_("MTC")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 4, 5, 0, 1); + label = (manage (new Label (_("MMC")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 6, 7, 0, 1); + label = (manage (new Label (_("MIDI Parameter\nControl")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 8, 9, 0, 1); + + Gtk::HSeparator* hsep = (manage (new HSeparator())); + hsep->show (); + midi_port_table_widgets.push_back (hsep); + midi_port_table.attach (*hsep, 0, 9, 1, 2); + Gtk::VSeparator* vsep = (manage (new VSeparator())); + vsep->show (); + midi_port_table_widgets.push_back (vsep); + midi_port_table.attach (*vsep, 5, 6, 0, 8); + vsep = (manage (new VSeparator())); + vsep->show (); + midi_port_table_widgets.push_back (vsep); + midi_port_table.attach (*vsep, 7, 8, 0, 8); - table->attach (*(manage (new Label (_("MMC Device ID")))), 9, 10, 0, 1); - table->attach (mmc_device_id_spinner, 9, 10, 1, 2); - - mmc_device_id_adjustment.signal_value_changed().connect (mem_fun (*this, &OptionEditor::mmc_device_id_adjusted)); + label = (manage (new Label (_("MMC Device ID")))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 9, 10, 0, 1); + midi_port_table_widgets.push_back (&mmc_device_id_spinner); + midi_port_table.attach (mmc_device_id_spinner, 9, 10, 1, 2); for (n = 0, i = ports.begin(); i != ports.end(); ++n, ++i) { pair > newpair; + ToggleButton* tb; + RadioButton* rb; newpair.first = i->second; - table->attach (*(manage (new Label (i->first))), 0, 1, n+2, n+3,FILL|EXPAND, FILL ); + label = (manage (new Label (i->first))); + label->show (); + midi_port_table_widgets.push_back (label); + midi_port_table.attach (*label, 0, 1, n+2, n+3,FILL|EXPAND, FILL ); + tb = manage (new ToggleButton (_("online"))); tb->set_name ("OptionEditorToggleButton"); @@ -416,22 +485,29 @@ OptionEditor::setup_midi_options () set_size_request_to_display_given_text (*tb, _("online"), 15, 12); } - tb->set_active (!(*i).second->input()->offline()); - tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_online_toggled), (*i).second, tb)); - (*i).second->input()->OfflineStatusChanged.connect (bind (mem_fun(*this, &OptionEditor::map_port_online), (*i).second, tb)); - table->attach (*tb, 1, 2, n+2, n+3, FILL|EXPAND, FILL); + if (i->second->input()) { + tb->set_active (!i->second->input()->offline()); + tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_online_toggled), i->second, tb)); + i->second->input()->OfflineStatusChanged.connect (bind (mem_fun(*this, &OptionEditor::map_port_online), (*i).second, tb)); + } + tb->show (); + midi_port_table_widgets.push_back (tb); + midi_port_table.attach (*tb, 1, 2, n+2, n+3, FILL|EXPAND, FILL); tb = manage (new ToggleButton ()); tb->set_name ("OptionEditorToggleButton"); tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_in_toggled), (*i).second, tb)); tb->set_size_request (10, 10); - table->attach (*tb, 2, 3, n+2, n+3, FILL|EXPAND, FILL); + tb->show (); + midi_port_table_widgets.push_back (tb); + midi_port_table.attach (*tb, 2, 3, n+2, n+3, FILL|EXPAND, FILL); tb = manage (new ToggleButton ()); tb->set_name ("OptionEditorToggleButton"); tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_out_toggled), (*i).second, tb)); tb->set_size_request (10, 10); - table->attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL); + tb->show (); + midi_port_table.attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL); rb = manage (new RadioButton ()); newpair.second.push_back (rb); @@ -442,10 +518,12 @@ OptionEditor::setup_midi_options () rb->set_group (mtc_button_group); } - table->attach (*rb, 4, 5, n+2, n+3, FILL|EXPAND, FILL); + 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)); - if (Config->get_mtc_port_name() == i->first) { + if (session && i->second == session->mtc_port()) { rb->set_active (true); } @@ -457,10 +535,12 @@ OptionEditor::setup_midi_options () } else { rb->set_group (mmc_button_group); } - table->attach (*rb, 6, 7, n+2, n+3, FILL|EXPAND, FILL); + 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)); - if (Config->get_mmc_port_name() == i->first) { + if (session && i->second == session->mmc_port()) { rb->set_active (true); } @@ -472,22 +552,60 @@ OptionEditor::setup_midi_options () } else { rb->set_group (midi_button_group); } - table->attach (*rb, 8, 9, n+2, n+3, FILL|EXPAND, FILL); + 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)); - if (Config->get_midi_port_name() == i->first) { + if (session && i->second == session->midi_port()) { rb->set_active (true); } port_toggle_buttons.insert (newpair); } - table->show_all (); + midi_port_table.show(); +} - hbox = manage (new HBox); - hbox->set_border_width (6); - hbox->pack_start (*table, true, false); - midi_packer.pack_start (*hbox, false, false); +void +OptionEditor::add_midi_port () +{ + MidiPortDialog dialog; + + dialog.set_position (WIN_POS_MOUSE); + dialog.set_transient_for (*this); + + dialog.show (); + + int ret = dialog.run (); + + switch (ret) { + case RESPONSE_ACCEPT: + break; + default: + return; + break; + } + + Glib::ustring mode = dialog.port_mode_combo.get_active_text(); + std::string smod; + + if (mode == _("input")) { + smod = X_("input"); + } else if (mode == (_("output"))) { + smod = X_("output"); + } else { + 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) { + redisplay_midi_ports (); + } } void @@ -543,23 +661,27 @@ OptionEditor::port_online_toggled (MIDI::Port* port, ToggleButton* tb) { bool wanted = tb->get_active(); - if (wanted != port->input()->offline()) { - port->input()->set_offline (wanted); - } + if (port->input()) { + if (wanted != port->input()->offline()) { + port->input()->set_offline (wanted); + } + } } void OptionEditor::map_port_online (MIDI::Port* port, ToggleButton* tb) { bool bstate = tb->get_active (); - - if (bstate != port->input()->offline()) { - if (port->input()->offline()) { - tb->set_label (_("offline")); - tb->set_active (false); - } else { - tb->set_label (_("online")); - tb->set_active (true); + + if (port->input()) { + if (bstate != port->input()->offline()) { + if (port->input()->offline()) { + tb->set_label (_("offline")); + tb->set_active (false); + } else { + tb->set_label (_("online")); + tb->set_active (true); + } } } } @@ -579,8 +701,10 @@ OptionEditor::port_trace_in_toggled (MIDI::Port* port, ToggleButton* tb) { bool trace = tb->get_active(); - if (port->input()->tracing() != trace) { - port->input()->trace (trace, &cerr, string (port->name()) + string (" input: ")); + if (port->input()) { + if (port->input()->tracing() != trace) { + port->input()->trace (trace, &cerr, string (port->name()) + string (" input: ")); + } } } @@ -589,8 +713,10 @@ OptionEditor::port_trace_out_toggled (MIDI::Port* port, ToggleButton* tb) { bool trace = tb->get_active(); - if (port->output()->tracing() != trace) { - port->output()->trace (trace, &cerr, string (port->name()) + string (" output: ")); + if (port->output()) { + if (port->output()->tracing() != trace) { + port->output()->trace (trace, &cerr, string (port->name()) + string (" output: ")); + } } } diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h index 7754b0555d..8efbb94221 100644 --- a/gtk2_ardour/option_editor.h +++ b/gtk2_ardour/option_editor.h @@ -110,8 +110,14 @@ class OptionEditor : public Gtk::Dialog Gtk::RadioButton::Group mmc_button_group; Gtk::RadioButton::Group midi_button_group; + Gtk::Table midi_port_table; + std::vector midi_port_table_widgets; Gtk::Adjustment mmc_device_id_adjustment; Gtk::SpinButton mmc_device_id_spinner; + Gtk::Button add_midi_port_button; + + void add_midi_port (); + void redisplay_midi_ports (); void port_online_toggled (MIDI::Port*,Gtk::ToggleButton*); void port_trace_in_toggled (MIDI::Port*,Gtk::ToggleButton*); diff --git a/libs/midi++2/alsa_sequencer_midiport.cc b/libs/midi++2/alsa_sequencer_midiport.cc index a47678bf1b..9ffd9f7832 100644 --- a/libs/midi++2/alsa_sequencer_midiport.cc +++ b/libs/midi++2/alsa_sequencer_midiport.cc @@ -170,7 +170,10 @@ ALSA_SequencerMidiPort::CreatePorts (PortRequest &req) if (req.mode == O_RDONLY || req.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, SND_SEQ_PORT_TYPE_MIDI_GENERIC))) { + if (0 <= (err = snd_seq_create_simple_port (seq, req.tagname, caps, + (SND_SEQ_PORT_TYPE_MIDI_GENERIC| + SND_SEQ_PORT_TYPE_SOFTWARE| + SND_SEQ_PORT_TYPE_APPLICATION)))) { port_id = err; @@ -205,3 +208,74 @@ ALSA_SequencerMidiPort::init_client (std::string name) return -1; } } + +int +ALSA_SequencerMidiPort::discover (vector& ports) +{ + int n = 0; + + snd_seq_client_info_t *client_info; + snd_seq_port_info_t *port_info; + + snd_seq_client_info_alloca (&client_info); + snd_seq_port_info_alloca (&port_info); + snd_seq_client_info_set_client (client_info, -1); + + while (snd_seq_query_next_client(seq, client_info) >= 0) { + + int alsa_client; + + if ((alsa_client = snd_seq_client_info_get_client(client_info)) <= 0) { + break; + } + + snd_seq_port_info_set_client(port_info, alsa_client); + snd_seq_port_info_set_port(port_info, -1); + + char client[256]; + snprintf (client, sizeof (client), "%d:%s", alsa_client, snd_seq_client_info_get_name(client_info)); + + ports.push_back (PortSet (client)); + + while (snd_seq_query_next_port(seq, port_info) >= 0) { + +#if 0 + int type = snd_seq_port_info_get_type(pinfo); + if (!(type & SND_SEQ_PORT_TYPE_PORT)) { + continue; + } +#endif + + unsigned int port_capability = snd_seq_port_info_get_capability(port_info); + + if ((port_capability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0) { + + int alsa_port = snd_seq_port_info_get_port(port_info); + + char port[256]; + snprintf (port, sizeof (port), "%d:%s", alsa_port, snd_seq_port_info_get_name(port_info)); + + std::string mode; + + 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; + } + } + } + + return n; +} diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc index 8d1d927b7b..38f84fe750 100644 --- a/libs/midi++2/coremidi_midiport.cc +++ b/libs/midi++2/coremidi_midiport.cc @@ -142,3 +142,10 @@ void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon, } } +int +CoreMidi_MidiPort::discover (vector& ports) +{ + /* XXX do dynamic port discovery here */ + + return 0; +} diff --git a/libs/midi++2/midi++/alsa_sequencer.h b/libs/midi++2/midi++/alsa_sequencer.h index 5ca70529c5..78e4a01683 100644 --- a/libs/midi++2/midi++/alsa_sequencer.h +++ b/libs/midi++2/midi++/alsa_sequencer.h @@ -27,6 +27,7 @@ #include #include +#include namespace MIDI { @@ -40,6 +41,8 @@ class ALSA_SequencerMidiPort : public Port /* select(2)/poll(2)-based I/O */ virtual int selectable() const; + + static int discover (std::vector&); protected: /* Direct I/O */ diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h index d7df23aa04..20fe739b94 100644 --- a/libs/midi++2/midi++/coremidi_midiport.h +++ b/libs/midi++2/midi++/coremidi_midiport.h @@ -40,6 +40,9 @@ namespace MIDI { virtual int selectable() const { return -1; } + + static int discover (std::vector&); + protected: /* Direct I/O */ int write(byte * msg, size_t msglen); diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h index f2963624fe..186c3973e3 100644 --- a/libs/midi++2/midi++/factory.h +++ b/libs/midi++2/midi++/factory.h @@ -23,6 +23,7 @@ #include #include +#include namespace MIDI { @@ -31,6 +32,8 @@ class PortFactory { Port *create_port (PortRequest &req); static bool ignore_duplicate_devices (Port::Type); + static int get_known_ports (std::vector&); + static std::string default_port_type (); }; } // namespace MIDI diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h index 40140cfde2..c230933689 100644 --- a/libs/midi++2/midi++/manager.h +++ b/libs/midi++2/midi++/manager.h @@ -21,10 +21,13 @@ #define __midi_manager_h__ #include +#include + #include #include #include +#include namespace MIDI { @@ -70,6 +73,8 @@ class Manager { static int parse_port_request (std::string str, Port::Type type); + int get_known_ports (std::vector&); + private: /* This is a SINGLETON pattern */ diff --git a/libs/midi++2/midi++/port_request.h b/libs/midi++2/midi++/port_request.h index 0cb4ffded6..cd4e758ebb 100644 --- a/libs/midi++2/midi++/port_request.h +++ b/libs/midi++2/midi++/port_request.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1999 Paul Barton-Davis + 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 @@ -20,6 +20,7 @@ #ifndef __midi_port_request_h__ #define __midi_port_request_h__ +#include #include namespace MIDI { @@ -53,6 +54,13 @@ struct PortRequest { 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 0a86c94cb9..0912c8ae7b 100644 --- a/libs/midi++2/midifactory.cc +++ b/libs/midi++2/midifactory.cc @@ -17,6 +17,8 @@ $Id$ */ +#include + #include #include #include @@ -101,3 +103,32 @@ PortFactory::ignore_duplicate_devices (Port::Type type) return ret; } +int +PortFactory::get_known_ports (vector& ports) +{ + int n = 0; +#ifdef WITH_ALSA + n += ALSA_SequencerMidiPort::discover (ports); +#endif // WITH_ALSA + +#if WITH_COREMIDI + n += CoreMidi_MidiPort::discover (ports); +#endif // WITH_COREMIDI + + return n; +} + +std::string +PortFactory::default_port_type () +{ + +#ifdef WITH_ALSA + return "alsa/sequencer"; +#endif + +#ifdef WITH_COREMIDI + return "coremidi"; +#endif // WITH_COREMIDI + + PBD::fatal << "programming error: no default port type defined in midifactory.cc" << endmsg; +} diff --git a/libs/midi++2/midimanager.cc b/libs/midi++2/midimanager.cc index 44fd89108c..3b7323541d 100644 --- a/libs/midi++2/midimanager.cc +++ b/libs/midi++2/midimanager.cc @@ -380,3 +380,9 @@ Manager::parse_port_request (string str, Port::Type type) return 0; } + +int +Manager::get_known_ports (vector& ports) +{ + return PortFactory::get_known_ports (ports); +}