use session stripable selection API
[ardour.git] / libs / surfaces / generic_midi / midifunction.cc
index d6cbdb9a6e7eb0c537aa11241dd6358343b30db1..4d2b19fdfd9d563194fe6ddd52d010af110d2eaf 100644 (file)
@@ -1,6 +1,6 @@
 /*
     Copyright (C) 2009 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
 #include "midifunction.h"
 #include "generic_midi_control_protocol.h"
 
+#include "pbd/compose.h"
+
+#include "ardour/debug.h"
+
 using namespace MIDI;
+using namespace PBD;
 
-MIDIFunction::MIDIFunction (MIDI::Port& p)
-       : _port (p)
+MIDIFunction::MIDIFunction (MIDI::Parser& p)
+       : MIDIInvokable (p)
 {
-       sysex_size = 0;
-       sysex = 0;
 }
 
 MIDIFunction::~MIDIFunction ()
 {
-       delete sysex;
 }
 
 int
-MIDIFunction::init (GenericMidiControlProtocol& ui, const std::string& function_name, MIDI::byte* sysex_data, size_t sysex_sz)
+MIDIFunction::setup (GenericMidiControlProtocol& ui, const std::string& invokable_name, const std::string& arg, MIDI::byte* msg_data, size_t data_sz)
 {
-       if (strcasecmp (function_name.c_str(), "transport-stop") == 0) {
+        MIDIInvokable::init (ui, invokable_name, msg_data, data_sz);
+
+       _argument = arg;
+
+       if (strcasecmp (_invokable_name.c_str(), "transport-stop") == 0) {
                _function = TransportStop;
-       } else if (strcasecmp (function_name.c_str(), "transport-roll") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "transport-roll") == 0) {
                _function = TransportRoll;
-       } else if (strcasecmp (function_name.c_str(), "transport-zero") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "transport-zero") == 0) {
                _function = TransportZero;
-       } else if (strcasecmp (function_name.c_str(), "transport-start") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "transport-start") == 0) {
                _function = TransportStart;
-       } else if (strcasecmp (function_name.c_str(), "transport-end") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "transport-end") == 0) {
                _function = TransportEnd;
-       } else if (strcasecmp (function_name.c_str(), "loop-toggle") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "loop-toggle") == 0) {
                _function = TransportLoopToggle;
-       } else if (strcasecmp (function_name.c_str(), "rec-enable") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "toggle-rec-enable") == 0) {
+               _function = TransportRecordToggle;
+       } else if (strcasecmp (_invokable_name.c_str(), "rec-enable") == 0) {
                _function = TransportRecordEnable;
-       } else if (strcasecmp (function_name.c_str(), "rec-disable") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "rec-disable") == 0) {
                _function = TransportRecordDisable;
-       } else if (strcasecmp (function_name.c_str(), "next-bank") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "next-bank") == 0) {
                _function = NextBank;
-       } else if (strcasecmp (function_name.c_str(), "prev-bank") == 0) {
+       } else if (strcasecmp (_invokable_name.c_str(), "prev-bank") == 0) {
                _function = PrevBank;
+       } else if (strcasecmp (_invokable_name.c_str(), "set-bank") == 0) {
+               if (_argument.empty()) {
+                       return -1;
+               }
+               _function = SetBank;
+       } else if (strcasecmp (_invokable_name.c_str(), "select") == 0) {
+               if (_argument.empty()) {
+                       return -1;
+               }
+               _function = Select;
+       } else if (strcasecmp (_invokable_name.c_str(), "track-set-solo") == 0) {
+               if (_argument.empty()) {
+                       return -1;
+               }
+               _function = TrackSetSolo;
+       } else if (strcasecmp (_invokable_name.c_str(), "track-set-mute") == 0) {
+               if (_argument.empty()) {
+                       return -1;
+               }
+               _function = TrackSetMute;
        } else {
                return -1;
        }
 
-       _ui = &ui;
-
-       if (sysex_sz) {
-               /* we take ownership of the sysex data */
-               sysex = sysex_data;
-               sysex_size = sysex_sz;
-       }
-
        return 0;
 }
 
@@ -81,139 +101,86 @@ MIDIFunction::execute ()
        switch (_function) {
        case NextBank:
                _ui->next_bank();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: next_bank\n");
                break;
 
        case PrevBank:
                _ui->prev_bank();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: prev_bank\n");
+               break;
+
+       case SetBank:
+               if (!_argument.empty()) {
+                       uint32_t bank;
+                       sscanf (_argument.c_str(), "%d", &bank);
+                       _ui->set_current_bank (bank);
+                       DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Function: set_current_bank = %1\n", (int) bank));
+               }
                break;
 
        case TransportStop:
                _ui->transport_stop ();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_stop\n");
                break;
 
        case TransportRoll:
                _ui->transport_play ();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_play\n");
                break;
 
        case TransportStart:
                _ui->goto_start ();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_start\n");
                break;
 
        case TransportZero:
                // need this in BasicUI
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_zero-not implemented\n");
                break;
 
        case TransportEnd:
                _ui->goto_end ();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_end\n");
                break;
 
        case TransportLoopToggle:
                _ui->loop_toggle ();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: loop_toggle\n");
+               break;
+
+       case TransportRecordToggle:
+               _ui->rec_enable_toggle ();
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: toggle_record_enable\n");
                break;
 
        case TransportRecordEnable:
                _ui->set_record_enable (true);
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = true\n");
                break;
 
        case TransportRecordDisable:
                _ui->set_record_enable (false);
+               DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = false\n");
                break;
-       }
-}
-
-void
-MIDIFunction::midi_sense_note_on (Parser &p, EventTwoBytes *tb)
-{
-       midi_sense_note (p, tb, true);
-}
-
-void
-MIDIFunction::midi_sense_note_off (Parser &p, EventTwoBytes *tb)
-{
-       midi_sense_note (p, tb, false);
-}
-
-void
-MIDIFunction::midi_sense_note (Parser &, EventTwoBytes *msg, bool /* is_on */)
-{
-       if (msg->note_number == control_additional) {
-               execute ();
-       }
-}
-
-void
-MIDIFunction::midi_sense_controller (Parser &, EventTwoBytes *msg)
-{
-       if (control_additional == msg->controller_number) {
-               execute ();
-       }
-}
-
-void
-MIDIFunction::midi_sense_program_change (Parser &, byte msg)
-{
-       if (msg == control_additional) {
-               execute ();
-       }
-}
-
-void
-MIDIFunction::midi_sense_sysex (Parser &, byte* msg, size_t sz)
-{
-       if (sz != sysex_size) {
-               return;
-       }
-
-       if (memcmp (msg, sysex, sysex_size) != 0) {
-               return;
-       }
-
-       execute ();
-}
 
-void
-MIDIFunction::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
-{
-       midi_sense_connection[0].disconnect ();
-       midi_sense_connection[1].disconnect ();
-
-       control_type = ev;
-       control_channel = chn;
-       control_additional = additional;
-
-       if (_port.input() == 0) {
-               return;
-       }
-
-       Parser& p = *_port.input();
-
-       int chn_i = chn;
-
-       /* incoming MIDI is parsed by Ardour' MidiUI event loop/thread, and we want our handlers to execute in that context, so we use
-          Signal::connect_same_thread() here.
-       */
-
-       switch (ev) {
-       case MIDI::off:
-               p.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIFunction::midi_sense_note_off, this, _1, _2));
+       case Select:
+               if (!_argument.empty()) {
+                       uint32_t rid;
+                       sscanf (_argument.c_str(), "%d", &rid);
+                       _ui->toggle_selection (rid, ARDOUR::PresentationInfo::Flag (ARDOUR::PresentationInfo::Route|ARDOUR::PresentationInfo::VCA));
+                       DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Function: SetRouteSelection = %1\n", rid));
+               }
                break;
-
-       case MIDI::on:
-               p.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIFunction::midi_sense_note_on, this, _1, _2));
+       case TrackSetMute:
                break;
-               
-       case MIDI::controller:
-               p.channel_controller[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIFunction::midi_sense_controller, this, _1, _2));
+       case TrackSetSolo:
                break;
-
-       case MIDI::program:
-               p.channel_program_change[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIFunction::midi_sense_program_change, this, _1, _2));
+       case TrackSetSoloIsolate:
                break;
-
-       case MIDI::sysex:
-               p.sysex.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIFunction::midi_sense_sysex, this, _1, _2, _3));
+       case TrackSetGain:
+               break;
+       case TrackSetRecordEnable:
                break;
-
        default:
                break;
        }
@@ -222,12 +189,13 @@ MIDIFunction::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
 XMLNode&
 MIDIFunction::get_state ()
 {
+
        XMLNode* node = new XMLNode ("MIDIFunction");
        return *node;
 }
 
 int
-MIDIFunction::set_state (const XMLNode& node, int version)
+MIDIFunction::set_state (const XMLNode& /*node*/, int /*version*/)
 {
        return 0;
 }