summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-07-06 22:34:10 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2016-09-27 14:59:30 -0500
commitcf28d717837857f1d568343bf17cc0b36db62269 (patch)
treea571d54c79198b2123c735e2127fce6769de03fe
parent6dbe3a1e3b0692bc49df74aedf96b341e1f6efbd (diff)
push2: basic GUI dialog
-rw-r--r--gtk2_ardour/icons/push2-small.pngbin0 -> 41186 bytes
-rw-r--r--libs/surfaces/push2/push2.cc102
-rw-r--r--libs/surfaces/push2/push2.h27
-rw-r--r--libs/surfaces/push2/wscript5
4 files changed, 132 insertions, 2 deletions
diff --git a/gtk2_ardour/icons/push2-small.png b/gtk2_ardour/icons/push2-small.png
new file mode 100644
index 0000000000..eaa9a34c90
--- /dev/null
+++ b/gtk2_ardour/icons/push2-small.png
Binary files differ
diff --git a/libs/surfaces/push2/push2.cc b/libs/surfaces/push2/push2.cc
index f1d37b246c..ce9723ac8f 100644
--- a/libs/surfaces/push2/push2.cc
+++ b/libs/surfaces/push2/push2.cc
@@ -69,6 +69,8 @@ Push2::Push2 (ARDOUR::Session& s)
, modifier_state (None)
, splash_start (0)
, bank_start (0)
+ , connection_state (ConnectionState (0))
+ , gui (0)
{
context = Cairo::Context::create (frame_buffer);
tc_clock_layout = Pango::Layout::create (context);
@@ -100,6 +102,14 @@ Push2::Push2 (ARDOUR::Session& s)
throw failed_constructor ();
}
+ ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (port_reg_connection, MISSING_INVALIDATOR, boost::bind (&Push2::port_registration_handler, this), this);
+
+ /* Catch port connections and disconnections */
+ ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&Push2::connection_handler, this, _1, _2, _3, _4, _5), this);
+
+ /* ports might already be there */
+
+ port_registration_handler ();
}
Push2::~Push2 ()
@@ -107,6 +117,34 @@ Push2::~Push2 ()
stop ();
}
+void
+Push2::port_registration_handler ()
+{
+ if (_async_in->connected() && _async_out->connected()) {
+ /* don't waste cycles here */
+ return;
+ }
+
+ string input_port_name = X_("Ableton Push 2 MIDI 1 in");
+ string output_port_name = X_("Ableton Push 2 MIDI 1 out");
+ vector<string> in;
+ vector<string> out;
+
+ AudioEngine::instance()->get_ports (string_compose (".*%1", input_port_name), DataType::MIDI, PortFlags (IsPhysical|IsOutput), in);
+ AudioEngine::instance()->get_ports (string_compose (".*%1", output_port_name), DataType::MIDI, PortFlags (IsPhysical|IsInput), out);
+
+ if (!in.empty() && !out.empty()) {
+ cerr << "Push2: both ports found\n";
+ cerr << "\tconnecting to " << in.front() << " + " << out.front() << endl;
+ if (!_async_in->connected()) {
+ AudioEngine::instance()->connect (_async_in->name(), in.front());
+ }
+ if (!_async_out->connected()) {
+ AudioEngine::instance()->connect (_async_out->name(), out.front());
+ }
+ }
+}
+
int
Push2::open ()
{
@@ -1478,3 +1516,67 @@ Push2::pad_filter (MidiBuffer& in, MidiBuffer& out) const
return matched;
}
+
+bool
+Push2::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
+{
+ DEBUG_TRACE (DEBUG::FaderPort, "FaderPort::connection_handler start\n");
+ if (!_input_port || !_output_port) {
+ return false;
+ }
+
+ string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_async_in)->name());
+ string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_async_out)->name());
+
+ if (ni == name1 || ni == name2) {
+ if (yn) {
+ connection_state |= InputConnected;
+ } else {
+ connection_state &= ~InputConnected;
+ }
+ } else if (no == name1 || no == name2) {
+ if (yn) {
+ connection_state |= OutputConnected;
+ } else {
+ connection_state &= ~OutputConnected;
+ }
+ } else {
+ DEBUG_TRACE (DEBUG::FaderPort, string_compose ("Connections between %1 and %2 changed, but I ignored it\n", name1, name2));
+ /* not our ports */
+ return false;
+ }
+
+ if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
+
+ /* XXX this is a horrible hack. Without a short sleep here,
+ something prevents the device wakeup messages from being
+ sent and/or the responses from being received.
+ */
+
+ g_usleep (100000);
+ DEBUG_TRACE (DEBUG::FaderPort, "device now connected for both input and output\n");
+ // connected ();
+
+ } else {
+ DEBUG_TRACE (DEBUG::FaderPort, "Device disconnected (input or output or both) or not yet fully connected\n");
+ }
+
+ ConnectionChange (); /* emit signal for our GUI */
+
+ DEBUG_TRACE (DEBUG::FaderPort, "FaderPort::connection_handler end\n");
+
+ return true; /* connection status changed */
+}
+
+boost::shared_ptr<Port>
+Push2::output_port()
+{
+ return _async_out;
+}
+
+boost::shared_ptr<Port>
+Push2::input_port()
+{
+ return _async_in;
+}
+
diff --git a/libs/surfaces/push2/push2.h b/libs/surfaces/push2/push2.h
index dab96260c6..7e480495ad 100644
--- a/libs/surfaces/push2/push2.h
+++ b/libs/surfaces/push2/push2.h
@@ -74,10 +74,19 @@ class Push2 : public ARDOUR::ControlProtocol
static bool probe ();
static void* request_factory (uint32_t);
+ bool has_editor () const { return true; }
+ void* get_gui () const;
+ void tear_down_gui ();
+
int set_active (bool yn);
XMLNode& get_state();
int set_state (const XMLNode & node, int version);
+ PBD::Signal0<void> ConnectionChange;
+
+ boost::shared_ptr<ARDOUR::Port> input_port();
+ boost::shared_ptr<ARDOUR::Port> output_port();
+
private:
libusb_device_handle *handle;
uint8_t frame_header[16];
@@ -452,6 +461,24 @@ class Push2 : public ARDOUR::ControlProtocol
bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
boost::weak_ptr<ARDOUR::Stripable> first_selected_stripable;
+
+ PBD::ScopedConnection port_reg_connection;
+ void port_registration_handler ();
+
+ enum ConnectionState {
+ InputConnected = 0x1,
+ OutputConnected = 0x2
+ };
+
+ int connection_state;
+ bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
+ PBD::ScopedConnection port_connection;
+
+ /* GUI */
+
+ mutable void *gui;
+ void build_gui ();
+
};
diff --git a/libs/surfaces/push2/wscript b/libs/surfaces/push2/wscript
index 36e9a644c4..2a76b10648 100644
--- a/libs/surfaces/push2/wscript
+++ b/libs/surfaces/push2/wscript
@@ -25,6 +25,7 @@ def build(bld):
interface.cc
midi_byte_array.cc
leds.cc
+ gui.cc
'''
obj.export_includes = ['.']
obj.defines = [ 'PACKAGE="ardour_push2"' ]
@@ -33,8 +34,8 @@ def build(bld):
obj.includes = [ '.', './push2']
obj.name = 'libardour_push2'
obj.target = 'ardour_push2'
- obj.uselib = 'CAIROMM PANGOMM USB'
- obj.use = 'libardour libardour_cp libpbd libtimecode'
+ obj.uselib = 'CAIROMM PANGOMM USB GTKMM'
+ obj.use = 'libardour libardour_cp libgtkmm2ext libpbd libtimecode'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
def shutdown():