restore/extend/simplify ControlProtocol API to allow tracking of selection
[ardour.git] / libs / surfaces / generic_midi / midifunction.cc
1 /*
2     Copyright (C) 2009 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <cstring>
20
21 #include "midi++/port.h"
22
23 #include "midifunction.h"
24 #include "generic_midi_control_protocol.h"
25
26 #include "pbd/compose.h"
27
28 #include "ardour/debug.h"
29
30 using namespace MIDI;
31 using namespace PBD;
32
33 MIDIFunction::MIDIFunction (MIDI::Parser& p)
34         : MIDIInvokable (p)
35 {
36 }
37
38 MIDIFunction::~MIDIFunction ()
39 {
40 }
41
42 int
43 MIDIFunction::setup (GenericMidiControlProtocol& ui, const std::string& invokable_name, const std::string& arg, MIDI::byte* msg_data, size_t data_sz)
44 {
45         MIDIInvokable::init (ui, invokable_name, msg_data, data_sz);
46
47         _argument = arg;
48
49         if (strcasecmp (_invokable_name.c_str(), "transport-stop") == 0) {
50                 _function = TransportStop;
51         } else if (strcasecmp (_invokable_name.c_str(), "transport-roll") == 0) {
52                 _function = TransportRoll;
53         } else if (strcasecmp (_invokable_name.c_str(), "transport-zero") == 0) {
54                 _function = TransportZero;
55         } else if (strcasecmp (_invokable_name.c_str(), "transport-start") == 0) {
56                 _function = TransportStart;
57         } else if (strcasecmp (_invokable_name.c_str(), "transport-end") == 0) {
58                 _function = TransportEnd;
59         } else if (strcasecmp (_invokable_name.c_str(), "loop-toggle") == 0) {
60                 _function = TransportLoopToggle;
61         } else if (strcasecmp (_invokable_name.c_str(), "toggle-rec-enable") == 0) {
62                 _function = TransportRecordToggle;
63         } else if (strcasecmp (_invokable_name.c_str(), "rec-enable") == 0) {
64                 _function = TransportRecordEnable;
65         } else if (strcasecmp (_invokable_name.c_str(), "rec-disable") == 0) {
66                 _function = TransportRecordDisable;
67         } else if (strcasecmp (_invokable_name.c_str(), "next-bank") == 0) {
68                 _function = NextBank;
69         } else if (strcasecmp (_invokable_name.c_str(), "prev-bank") == 0) {
70                 _function = PrevBank;
71         } else if (strcasecmp (_invokable_name.c_str(), "set-bank") == 0) {
72                 if (_argument.empty()) {
73                         return -1;
74                 }
75                 _function = SetBank;
76         } else if (strcasecmp (_invokable_name.c_str(), "select") == 0) {
77                 if (_argument.empty()) {
78                         return -1;
79                 }
80                 _function = Select;
81         } else if (strcasecmp (_invokable_name.c_str(), "track-set-solo") == 0) {
82                 if (_argument.empty()) {
83                         return -1;
84                 }
85                 _function = TrackSetSolo;
86         } else if (strcasecmp (_invokable_name.c_str(), "track-set-mute") == 0) {
87                 if (_argument.empty()) {
88                         return -1;
89                 }
90                 _function = TrackSetMute;
91         } else {
92                 return -1;
93         }
94
95         return 0;
96 }
97
98 void
99 MIDIFunction::execute ()
100 {
101         switch (_function) {
102         case NextBank:
103                 _ui->next_bank();
104                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: next_bank\n");
105                 break;
106
107         case PrevBank:
108                 _ui->prev_bank();
109                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: prev_bank\n");
110                 break;
111
112         case SetBank:
113                 if (!_argument.empty()) {
114                         uint32_t bank;
115                         sscanf (_argument.c_str(), "%d", &bank);
116                         _ui->set_current_bank (bank);
117                         DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Function: set_current_bank = %1\n", (int) bank));
118                 }
119                 break;
120
121         case TransportStop:
122                 _ui->transport_stop ();
123                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_stop\n");
124                 break;
125
126         case TransportRoll:
127                 _ui->transport_play ();
128                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_play\n");
129                 break;
130
131         case TransportStart:
132                 _ui->goto_start ();
133                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_start\n");
134                 break;
135
136         case TransportZero:
137                 // need this in BasicUI
138                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_zero-not implemented\n");
139                 break;
140
141         case TransportEnd:
142                 _ui->goto_end ();
143                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_end\n");
144                 break;
145
146         case TransportLoopToggle:
147                 _ui->loop_toggle ();
148                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: loop_toggle\n");
149                 break;
150
151         case TransportRecordToggle:
152                 _ui->rec_enable_toggle ();
153                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: toggle_record_enable\n");
154                 break;
155
156         case TransportRecordEnable:
157                 _ui->set_record_enable (true);
158                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = true\n");
159                 break;
160
161         case TransportRecordDisable:
162                 _ui->set_record_enable (false);
163                 DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = false\n");
164                 break;
165
166         case Select:
167                 if (!_argument.empty()) {
168                         uint32_t rid;
169                         sscanf (_argument.c_str(), "%d", &rid);
170                         // XX fix me ... need to get stripable, not RID
171                         //_ui->toggle_selection (rid, ARDOUR::PresentationInfo::Flag (ARDOUR::PresentationInfo::Route|ARDOUR::PresentationInfo::VCA));
172                         DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Function: SetRouteSelection = %1\n", rid));
173                 }
174                 break;
175         case TrackSetMute:
176                 break;
177         case TrackSetSolo:
178                 break;
179         case TrackSetSoloIsolate:
180                 break;
181         case TrackSetGain:
182                 break;
183         case TrackSetRecordEnable:
184                 break;
185         default:
186                 break;
187         }
188 }
189
190 XMLNode&
191 MIDIFunction::get_state ()
192 {
193
194         XMLNode* node = new XMLNode ("MIDIFunction");
195         return *node;
196 }
197
198 int
199 MIDIFunction::set_state (const XMLNode& /*node*/, int /*version*/)
200 {
201         return 0;
202 }
203