Only show user-presets in favorite sidebar
[ardour.git] / libs / surfaces / mackie / mackie_control_protocol.cc
1 /*
2         Copyright (C) 2006,2007 John Anderson
3         Copyright (C) 2012 Paul Davis
4
5         This program is free software; you can redistribute it and/or modify
6         it under the terms of the GNU General Public License as published by
7         the Free Software Foundation; either version 2 of the License, or
8         (at your option) any later version.
9
10         This program is distributed in the hope that it will be useful,
11         but WITHOUT ANY WARRANTY; without even the implied warranty of
12         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13         GNU General Public License for more details.
14
15         You should have received a copy of the GNU General Public License
16         along with this program; if not, write to the Free Software
17         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <fcntl.h>
21 #include <iostream>
22 #include <algorithm>
23 #include <cmath>
24 #include <sstream>
25 #include <vector>
26 #include <iomanip>
27
28 #include <inttypes.h>
29 #include <float.h>
30 #include <sys/time.h>
31 #include <errno.h>
32
33 #include <boost/shared_array.hpp>
34 #include <glibmm/miscutils.h>
35
36 #include "midi++/types.h"
37 #include "midi++/port.h"
38 #include "midi++/ipmidi_port.h"
39 #include "pbd/pthread_utils.h"
40 #include "pbd/error.h"
41 #include "pbd/memento_command.h"
42 #include "pbd/convert.h"
43
44 #include "ardour/audio_track.h"
45 #include "ardour/automation_control.h"
46 #include "ardour/async_midi_port.h"
47 #include "ardour/dB.h"
48 #include "ardour/debug.h"
49 #include "ardour/location.h"
50 #include "ardour/meter.h"
51 #include "ardour/midi_track.h"
52 #include "ardour/panner.h"
53 #include "ardour/panner_shell.h"
54 #include "ardour/profile.h"
55 #include "ardour/record_enable_control.h"
56 #include "ardour/route.h"
57 #include "ardour/route_group.h"
58 #include "ardour/session.h"
59 #include "ardour/tempo.h"
60 #include "ardour/track.h"
61 #include "ardour/types.h"
62 #include "ardour/audioengine.h"
63 #include "ardour/vca_manager.h"
64
65 #include "mackie_control_protocol.h"
66
67 #include "midi_byte_array.h"
68 #include "mackie_control_exception.h"
69 #include "device_profile.h"
70 #include "surface_port.h"
71 #include "surface.h"
72 #include "strip.h"
73 #include "control_group.h"
74 #include "meter.h"
75 #include "button.h"
76 #include "fader.h"
77 #include "pot.h"
78
79 using namespace ARDOUR;
80 using namespace std;
81 using namespace PBD;
82 using namespace Glib;
83 using namespace ArdourSurface;
84 using namespace Mackie;
85
86 #include "pbd/i18n.h"
87
88 #include "pbd/abstract_ui.cc" // instantiate template
89
90 const int MackieControlProtocol::MODIFIER_OPTION = 0x1;
91 const int MackieControlProtocol::MODIFIER_CONTROL = 0x2;
92 const int MackieControlProtocol::MODIFIER_SHIFT = 0x4;
93 const int MackieControlProtocol::MODIFIER_CMDALT = 0x8;
94 const int MackieControlProtocol::MODIFIER_ZOOM = 0x10;
95 const int MackieControlProtocol::MODIFIER_SCRUB = 0x20;
96 const int MackieControlProtocol::MODIFIER_MARKER = 0x40;
97 const int MackieControlProtocol::MODIFIER_NUDGE = 0x80;
98 const int MackieControlProtocol::MAIN_MODIFIER_MASK = (MackieControlProtocol::MODIFIER_OPTION|
99                                                        MackieControlProtocol::MODIFIER_CONTROL|
100                                                        MackieControlProtocol::MODIFIER_SHIFT|
101                                                        MackieControlProtocol::MODIFIER_CMDALT);
102
103 MackieControlProtocol* MackieControlProtocol::_instance = 0;
104
105 bool MackieControlProtocol::probe()
106 {
107         return true;
108 }
109
110 MackieControlProtocol::MackieControlProtocol (Session& session)
111         : ControlProtocol (session, X_("Mackie"))
112         , AbstractUI<MackieControlUIRequest> (name())
113         , _current_initial_bank (0)
114         , _sample_last (0)
115         , _timecode_type (ARDOUR::AnyTime::BBT)
116         , _gui (0)
117         , _scrub_mode (false)
118         , _flip_mode (Normal)
119         , _view_mode (Mixer)
120         , _subview_mode (None)
121         , _current_selected_track (-1)
122         , _modifier_state (0)
123         , _ipmidi_base (MIDI::IPMIDIPort::lowest_ipmidi_port_default)
124         , needs_ipmidi_restart (false)
125         , _metering_active (true)
126         , _initialized (false)
127         , configuration_state (0)
128         , state_version (0)
129         , marker_modifier_consumed_by_button (false)
130         , nudge_modifier_consumed_by_button (false)
131 {
132         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
133
134         DeviceInfo::reload_device_info ();
135         DeviceProfile::reload_device_profiles ();
136
137         for (int i = 0; i < 9; i++) {
138                 _last_bank[i] = 0;
139         }
140
141         PresentationInfo::Change.connect (gui_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this, _1), this);
142
143         _instance = this;
144
145         build_button_map ();
146 }
147
148 MackieControlProtocol::~MackieControlProtocol()
149 {
150         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol init\n");
151
152         for (Surfaces::const_iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
153                 (*si)->reset ();
154         }
155
156         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol drop_connections ()\n");
157         drop_connections ();
158
159         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol tear_down_gui ()\n");
160         tear_down_gui ();
161
162         delete configuration_state;
163
164         /* stop event loop */
165         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol BaseUI::quit ()\n");
166         BaseUI::quit ();
167
168         try {
169                 DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol close()\n");
170                 close();
171         }
172         catch (exception & e) {
173                 cout << "~MackieControlProtocol caught " << e.what() << endl;
174         }
175         catch (...) {
176                 cout << "~MackieControlProtocol caught unknown" << endl;
177         }
178
179         _instance = 0;
180
181         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol done\n");
182 }
183
184 void
185 MackieControlProtocol::thread_init ()
186 {
187         pthread_set_name (event_loop_name().c_str());
188
189         PBD::notify_event_loops_about_thread_creation (pthread_self(), event_loop_name(), 2048);
190         ARDOUR::SessionEvent::create_per_thread_pool (event_loop_name(), 128);
191
192         set_thread_priority ();
193 }
194
195 void
196 MackieControlProtocol::ping_devices ()
197 {
198         /* should not be called if surfaces are not connected, but will not
199          * malfunction if it is.
200          */
201
202         for (Surfaces::const_iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
203                 (*si)->connected ();
204         }
205 }
206
207 // go to the previous track.
208 void
209 MackieControlProtocol::prev_track()
210 {
211         if (_current_initial_bank >= 1) {
212                 switch_banks (_current_initial_bank - 1);
213         }
214 }
215
216 // go to the next track.
217 void
218 MackieControlProtocol::next_track()
219 {
220         Sorted sorted = get_sorted_stripables();
221         if (_current_initial_bank + 1 < sorted.size()) {
222                 switch_banks (_current_initial_bank + 1);
223         }
224 }
225
226 bool
227 MackieControlProtocol::stripable_is_locked_to_strip (boost::shared_ptr<Stripable> r) const
228 {
229         for (Surfaces::const_iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
230                 if ((*si)->stripable_is_locked_to_strip (r)) {
231                         return true;
232                 }
233         }
234         return false;
235 }
236
237 // predicate for sort call in get_sorted_stripables
238 struct StripableByPresentationOrder
239 {
240         bool operator () (const boost::shared_ptr<Stripable> & a, const boost::shared_ptr<Stripable> & b) const
241         {
242                 return a->presentation_info().order() < b->presentation_info().order();
243         }
244
245         bool operator () (const Stripable & a, const Stripable & b) const
246         {
247                 return a.presentation_info().order() < b.presentation_info().order();
248         }
249
250         bool operator () (const Stripable * a, const Stripable * b) const
251         {
252                 return a->presentation_info().order() < b->presentation_info().order();
253         }
254 };
255
256 MackieControlProtocol::Sorted
257 MackieControlProtocol::get_sorted_stripables()
258 {
259         Sorted sorted;
260
261         // fetch all stripables
262         StripableList stripables;
263
264         session->get_stripables (stripables);
265
266         // sort in presentation order, and exclude master, control and hidden stripables
267         // and any stripables that are already set.
268
269         for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) {
270
271                 boost::shared_ptr<Stripable> s = *it;
272
273                 if (s->presentation_info().special()) {
274                         continue;
275                 }
276
277                 /* don't include locked routes */
278
279                 if (stripable_is_locked_to_strip (s)) {
280                         continue;
281                 }
282
283                 switch (_view_mode) {
284                 case Mixer:
285                         if (!s->presentation_info().hidden()) {
286                                 sorted.push_back (s);
287                         }
288                         break;
289                 case AudioTracks:
290                         if (is_audio_track(s) && !s->presentation_info().hidden()) {
291                                 sorted.push_back (s);
292                         }
293                         break;
294                 case Busses:
295                         if (Profile->get_mixbus()) {
296 #ifdef MIXBUS
297                                 if (s->mixbus()) {
298                                         sorted.push_back (s);
299                                 }
300 #endif
301                         } else {
302                                 if (!is_track(s) && !s->presentation_info().hidden()) {
303                                         sorted.push_back (s);
304                                 }
305                         }
306                         break;
307                 case MidiTracks:
308                         if (is_midi_track(s) && !s->presentation_info().hidden()) {
309                                 sorted.push_back (s);
310                         }
311                         break;
312                 case Plugins:
313                         break;
314                 case Auxes: // in ardour, for now aux and buss are same. for mixbus, "Busses" are mixbuses, "Auxes" are ardour buses
315 #ifdef MIXBUS
316                         if (!s->mixbus() && !is_track(s) && !s->presentation_info().hidden())
317 #else
318                         if (!is_track(s) && !s->presentation_info().hidden())
319 #endif
320                         {
321                                 sorted.push_back (s);
322                         }
323                         break;
324                 case Hidden: // Show all the tracks we have hidden
325                         if (s->presentation_info().hidden()) {
326                                 // maybe separate groups
327                                 sorted.push_back (s);
328                         }
329                         break;
330                 case Selected: // For example: a group (this is USER)
331                         if (s->is_selected() && !s->presentation_info().hidden()) {
332                                 sorted.push_back (s);
333                         }
334                         break;
335                 }
336         }
337
338         sort (sorted.begin(), sorted.end(), StripableByPresentationOrder());
339         return sorted;
340 }
341
342 void
343 MackieControlProtocol::refresh_current_bank()
344 {
345         switch_banks (_current_initial_bank, true);
346 }
347
348 uint32_t
349 MackieControlProtocol::n_strips (bool with_locked_strips) const
350 {
351         uint32_t strip_count = 0;
352
353         for (Surfaces::const_iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
354                 strip_count += (*si)->n_strips (with_locked_strips);
355         }
356
357         return strip_count;
358 }
359
360 int
361 MackieControlProtocol::switch_banks (uint32_t initial, bool force)
362 {
363         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch banking to start at %1 force ? %2 current = %3\n", initial, force, _current_initial_bank));
364
365         if (initial == _current_initial_bank && !force) {
366                 /* everything is as it should be */
367                 return 0;
368         }
369
370         Sorted sorted = get_sorted_stripables();
371         uint32_t strip_cnt = n_strips (false); // do not include locked strips
372                                                // in this count
373
374         if (initial >= sorted.size() && !force) {
375                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("bank target %1 exceeds route range %2\n",
376                                                                    _current_initial_bank, sorted.size()));
377                 /* too high, we can't get there */
378                 return -1;
379         }
380
381         if (sorted.size() <= strip_cnt && _current_initial_bank == 0 && !force) {
382                 /* no banking - not enough stripables to fill all strips and we're
383                  * not at the first one.
384                  */
385                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("less routes (%1) than strips (%2) and we're at the end already (%3)\n",
386                                                                    sorted.size(), strip_cnt, _current_initial_bank));
387                 return -1;
388         }
389
390         _current_initial_bank = initial;
391         _current_selected_track = -1;
392
393         // Map current bank of stripables onto each surface(+strip)
394
395         if (_current_initial_bank < sorted.size()) {
396
397                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to %1, %2, available stripables %3 on %4 surfaces\n",
398                                                                    _current_initial_bank, strip_cnt, sorted.size(),
399                                                                    surfaces.size()));
400
401                 // link stripables to strips
402
403                 Sorted::iterator r = sorted.begin() + _current_initial_bank;
404
405                 for (Surfaces::iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
406                         vector<boost::shared_ptr<Stripable> > stripables;
407                         uint32_t added = 0;
408
409                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface has %1 unlocked strips\n", (*si)->n_strips (false)));
410
411                         for (; r != sorted.end() && added < (*si)->n_strips (false); ++r, ++added) {
412                                 stripables.push_back (*r);
413                         }
414
415                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("give surface %1 stripables\n", stripables.size()));
416
417                         (*si)->map_stripables (stripables);
418                 }
419
420         } else {
421                 /* all strips need to be reset */
422                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("clear all strips, bank target %1  is outside route range %2\n",
423                                                                    _current_initial_bank, sorted.size()));
424                 for (Surfaces::iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
425                         vector<boost::shared_ptr<Stripable> > stripables;
426                         /* pass in an empty stripables list, so that all strips will be reset */
427                         (*si)->map_stripables (stripables);
428                 }
429                 return -1;
430         }
431
432         /* current bank has not been saved */
433         session->set_dirty();
434
435         return 0;
436 }
437
438 int
439 MackieControlProtocol::set_active (bool yn)
440 {
441         DEBUG_TRACE (DEBUG::MackieControl, string_compose("MackieControlProtocol::set_active init with yn: '%1'\n", yn));
442
443         if (yn == active()) {
444                 return 0;
445         }
446
447         if (yn) {
448
449                 /* start event loop */
450
451                 BaseUI::run ();
452
453                 connect_session_signals ();
454
455                 if (!_device_info.name().empty()) {
456                         set_device (_device_info.name(), true);
457                 }
458
459                 /* set up periodic task for timecode display and metering and automation
460                  */
461
462                 // set different refresh time for qcon and standard mackie MCU
463
464                 int iTimeCodeRefreshTime = 100; // default value for mackie MCU (100ms)
465                 int iStripDisplayRefreshTime = 10; // default value for Mackie MCU (10ms)
466
467                 if(_device_info.is_qcon()){
468                         // set faster timecode display refresh speed (55ms)
469                         iTimeCodeRefreshTime = 55;
470                         // set slower refresh time on qcon than on mackie (15ms)
471                         iStripDisplayRefreshTime = 15;
472                 }
473
474                 Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (iTimeCodeRefreshTime); // milliseconds
475                 periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::periodic));
476                 periodic_timeout->attach (main_loop()->get_context());
477
478                 /* periodic task used to update strip displays */
479
480                 Glib::RefPtr<Glib::TimeoutSource> redisplay_timeout = Glib::TimeoutSource::create (iStripDisplayRefreshTime); // milliseconds
481                 redisplay_connection = redisplay_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::redisplay));
482                 redisplay_timeout->attach (main_loop()->get_context());
483
484         } else {
485
486                 BaseUI::quit ();
487                 close ();
488
489         }
490
491         ControlProtocol::set_active (yn);
492
493         DEBUG_TRACE (DEBUG::MackieControl, string_compose("MackieControlProtocol::set_active done with yn: '%1'\n", yn));
494
495         return 0;
496 }
497
498 bool
499 MackieControlProtocol::hui_heartbeat ()
500 {
501         Glib::Threads::Mutex::Lock lm (surfaces_lock);
502
503         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
504                 (*s)->hui_heartbeat ();
505         }
506
507         return true;
508 }
509
510 bool
511 MackieControlProtocol::periodic ()
512 {
513         if (!active()) {
514                 return false;
515         }
516
517         if (!_initialized) {
518                 /* wait for higher-frequency redisplay() callback to initialize
519                  * us
520                  */
521                 return true;
522         }
523
524         update_timecode_display ();
525
526         ARDOUR::microseconds_t now_usecs = ARDOUR::get_microseconds ();
527
528         {
529                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
530
531                 for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
532                         (*s)->periodic (now_usecs);
533                 }
534         }
535
536         return true;
537 }
538
539 bool
540 MackieControlProtocol::redisplay ()
541 {
542         if (!active()) {
543                 return false;
544         }
545
546         if (needs_ipmidi_restart) {
547                 ipmidi_restart ();
548                 return true;
549         }
550
551         if (!_initialized) {
552                 initialize();
553         }
554
555         ARDOUR::microseconds_t now = ARDOUR::get_microseconds ();
556
557         {
558                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
559
560                 for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
561                         (*s)->redisplay (now, false);
562                 }
563         }
564
565         return true;
566 }
567
568 void
569 MackieControlProtocol::update_timecode_beats_led()
570 {
571         if (!_device_info.has_timecode_display()) {
572                 return;
573         }
574
575         DEBUG_TRACE (DEBUG::MackieControl, string_compose("MackieControlProtocol::update_timecode_beats_led(): %1\n", _timecode_type));
576         switch (_timecode_type) {
577                 case ARDOUR::AnyTime::BBT:
578                         update_global_led (Led::Beats, on);
579                         update_global_led (Led::Timecode, off);
580                         break;
581                 case ARDOUR::AnyTime::Timecode:
582                         update_global_led (Led::Timecode, on);
583                         update_global_led (Led::Beats, off);
584                         break;
585                 default:
586                         ostringstream os;
587                         os << "Unknown Anytime::Type " << _timecode_type;
588                         throw runtime_error (os.str());
589         }
590 }
591
592 void
593 MackieControlProtocol::update_global_button (int id, LedState ls)
594 {
595         boost::shared_ptr<Surface> surface;
596
597         {
598                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
599
600                 if (surfaces.empty()) {
601                         return;
602                 }
603
604                 if (!_device_info.has_global_controls()) {
605                         return;
606                 }
607                 // surface needs to be master surface
608                 surface = _master_surface;
609         }
610
611         map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (id);
612         if (x != surface->controls_by_device_independent_id.end()) {
613                 Button * button = dynamic_cast<Button*> (x->second);
614                 surface->write (button->set_state (ls));
615         } else {
616                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Button %1 not found\n", id));
617         }
618 }
619
620 void
621 MackieControlProtocol::update_global_led (int id, LedState ls)
622 {
623         Glib::Threads::Mutex::Lock lm (surfaces_lock);
624
625         if (surfaces.empty()) {
626                 return;
627         }
628
629         if (!_device_info.has_global_controls()) {
630                 return;
631         }
632         boost::shared_ptr<Surface> surface = _master_surface;
633
634         map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (id);
635
636         if (x != surface->controls_by_device_independent_id.end()) {
637                 Led * led = dynamic_cast<Led*> (x->second);
638                 DEBUG_TRACE (DEBUG::MackieControl, "Writing LedState\n");
639                 surface->write (led->set_state (ls));
640         } else {
641                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Led %1 not found\n", id));
642         }
643 }
644
645 void
646 MackieControlProtocol::device_ready ()
647 {
648         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("device ready init (active=%1)\n", active()));
649         update_surfaces ();
650         set_subview_mode (MackieControlProtocol::None, boost::shared_ptr<Stripable>());
651         set_flip_mode (Normal);
652 }
653
654 // send messages to surface to set controls to correct values
655 void
656 MackieControlProtocol::update_surfaces()
657 {
658         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::update_surfaces() init (active=%1)\n", active()));
659         if (!active()) {
660                 return;
661         }
662
663         // do the initial bank switch to connect signals
664         // _current_initial_bank is initialised by set_state
665         (void) switch_banks (_current_initial_bank, true);
666
667         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::update_surfaces() finished\n");
668 }
669
670 void
671 MackieControlProtocol::initialize()
672 {
673         {
674                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
675
676                 if (surfaces.empty()) {
677                         return;
678                 }
679
680                 if (!_master_surface->active ()) {
681                         return;
682                 }
683
684                 // sometimes the jog wheel is a pot
685                 if (_device_info.has_jog_wheel()) {
686                         _master_surface->blank_jog_ring ();
687                 }
688         }
689
690         // update global buttons and displays
691
692         notify_record_state_changed();
693         notify_transport_state_changed();
694         update_timecode_beats_led();
695
696         _initialized = true;
697 }
698
699 void
700 MackieControlProtocol::connect_session_signals()
701 {
702         // receive routes added
703         session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_routes_added, this, _1), this);
704         // receive VCAs added
705         session->vca_manager().VCAAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_vca_added, this, _1), this);
706
707         // receive record state toggled
708         session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_record_state_changed, this), this);
709         // receive transport state changed
710         session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_transport_state_changed, this), this);
711         session->TransportLooped.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_loop_state_changed, this), this);
712         // receive punch-in and punch-out
713         Config->ParameterChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_parameter_changed, this, _1), this);
714         session->config.ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_parameter_changed, this, _1), this);
715         // receive rude solo changed
716         session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_solo_active_changed, this, _1), this);
717
718         // make sure remote id changed signals reach here
719         // see also notify_stripable_added
720         Sorted sorted = get_sorted_stripables();
721 }
722
723 void
724 MackieControlProtocol::set_profile (const string& profile_name)
725 {
726         map<string,DeviceProfile>::iterator d = DeviceProfile::device_profiles.find (profile_name);
727
728         if (d == DeviceProfile::device_profiles.end()) {
729                 _device_profile = DeviceProfile (profile_name);
730                 return;
731         }
732
733         _device_profile = d->second;
734 }
735
736 int
737 MackieControlProtocol::set_device_info (const string& device_name)
738 {
739         map<string,DeviceInfo>::iterator d = DeviceInfo::device_info.find (device_name);
740
741         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("new device chosen %1\n", device_name));
742
743         if (d == DeviceInfo::device_info.end()) {
744                 return -1;
745         }
746
747         _device_info = d->second;
748
749         return 0;
750 }
751
752 int
753 MackieControlProtocol::set_device (const string& device_name, bool force)
754 {
755         if (device_name == device_info().name() && !force) {
756                 /* already using that device, nothing to do */
757                 return 0;
758         }
759         /* get state from the current setup, and make sure it is stored in
760            the configuration_states node so that if we switch back to this device,
761            we will have its state available.
762         */
763
764         {
765                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
766                 if (!surfaces.empty()) {
767                         update_configuration_state ();
768                 }
769         }
770
771         if (set_device_info (device_name)) {
772                 return -1;
773         }
774
775         clear_surfaces ();
776         port_connection.disconnect ();
777         hui_connection.disconnect ();
778
779         if (_device_info.device_type() == DeviceInfo::HUI) {
780                 Glib::RefPtr<Glib::TimeoutSource> hui_timeout = Glib::TimeoutSource::create (1000); // milliseconds
781                 hui_connection = hui_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::hui_heartbeat));
782                 hui_timeout->attach (main_loop()->get_context());
783         }
784
785         if (!_device_info.uses_ipmidi()) {
786                 /* notice that the handler for this will execute in our event
787                    loop, not in the thread where the
788                    PortConnectedOrDisconnected signal is emitted.
789                 */
790                 ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::connection_handler, this, _1, _2, _3, _4, _5), this);
791         }
792
793         if (create_surfaces ()) {
794                 return -1;
795         }
796
797         DeviceChanged ();
798
799         return 0;
800 }
801
802 gboolean
803 ArdourSurface::ipmidi_input_handler (GIOChannel*, GIOCondition condition, void *data)
804 {
805         ArdourSurface::MackieControlProtocol::ipMIDIHandler* ipm = static_cast<ArdourSurface::MackieControlProtocol::ipMIDIHandler*>(data);
806         return ipm->mcp->midi_input_handler (Glib::IOCondition (condition), ipm->port);
807 }
808
809 int
810 MackieControlProtocol::create_surfaces ()
811 {
812         string device_name;
813         surface_type_t stype = mcu; // type not yet determined
814
815         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Create %1 surfaces for %2\n", 1 + _device_info.extenders(), _device_info.name()));
816
817         if (!_device_info.uses_ipmidi()) {
818                 _input_bundle.reset (new ARDOUR::Bundle (_("Mackie Control In"), true));
819                 _output_bundle.reset (new ARDOUR::Bundle (_("Mackie Control Out"), false));
820         } else {
821                 _input_bundle.reset ();
822                 _output_bundle.reset ();
823
824         }
825         for (uint32_t n = 0; n < 1 + _device_info.extenders(); ++n) {
826                 bool is_master = false;
827
828                 if (n == _device_info.master_position()) {
829                         is_master = true;
830                         if (_device_info.extenders() == 0) {
831                                 device_name = _device_info.name();
832                         } else {
833                                 device_name = X_("mackie control");
834                         }
835
836                 }
837
838                 if (!is_master) {
839                         device_name = string_compose (X_("mackie control ext %1"), n+1);
840                 }
841
842                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Port Name for surface %1 is %2\n", n, device_name));
843
844                 boost::shared_ptr<Surface> surface;
845
846                 if (is_master) {
847                         stype = mcu;
848                 } else {
849                         stype = ext;
850                 }
851                 try {
852                         surface.reset (new Surface (*this, device_name, n, stype));
853                 } catch (...) {
854                         return -1;
855                 }
856
857                 if (is_master) {
858                         _master_surface = surface;
859                 }
860
861                 if (configuration_state) {
862                         XMLNode* this_device = 0;
863                         XMLNodeList const& devices = configuration_state->children();
864                         for (XMLNodeList::const_iterator d = devices.begin(); d != devices.end(); ++d) {
865                                 XMLProperty const * prop = (*d)->property (X_("name"));
866                                 if (prop && prop->value() == _device_info.name()) {
867                                         this_device = *d;
868                                         break;
869                                 }
870                         }
871                         if (this_device) {
872                                 XMLNode* snode = this_device->child (X_("Surfaces"));
873                                 if (snode) {
874                                         surface->set_state (*snode, state_version);
875                                 }
876                         }
877                 }
878
879                 {
880                         Glib::Threads::Mutex::Lock lm (surfaces_lock);
881                         surfaces.push_back (surface);
882                 }
883
884                 if (!_device_info.uses_ipmidi()) {
885
886                         _input_bundle->add_channel (
887                                 surface->port().input_port().name(),
888                                 ARDOUR::DataType::MIDI,
889                                 session->engine().make_port_name_non_relative (surface->port().input_port().name())
890                                 );
891
892                         _output_bundle->add_channel (
893                                 surface->port().output_port().name(),
894                                 ARDOUR::DataType::MIDI,
895                                 session->engine().make_port_name_non_relative (surface->port().output_port().name())
896                                 );
897                 }
898
899                 MIDI::Port& input_port (surface->port().input_port());
900                 AsyncMIDIPort* asp = dynamic_cast<AsyncMIDIPort*> (&input_port);
901
902                 if (asp) {
903
904                         /* async MIDI port */
905
906                         asp->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &MackieControlProtocol::midi_input_handler), &input_port));
907                         asp->xthread().attach (main_loop()->get_context());
908
909                 } else {
910
911                         /* ipMIDI port, no IOSource method at this time */
912
913                         int fd;
914
915                         if ((fd = input_port.selectable ()) >= 0) {
916
917                                 GIOChannel* ioc = g_io_channel_unix_new (fd);
918                                 surface->input_source = g_io_create_watch (ioc, GIOCondition (G_IO_IN|G_IO_HUP|G_IO_ERR));
919
920                                 /* make surface's input source now hold the
921                                  * only reference on the IO channel
922                                  */
923                                 g_io_channel_unref (ioc);
924
925                                 /* hack up an object so that in the callback from the event loop
926                                    we have both the MackieControlProtocol and the input port.
927
928                                    If we were using C++ for this stuff we wouldn't need this
929                                    but a nasty, not-fixable bug in the binding between C
930                                    and C++ makes it necessary to avoid C++ for the IO
931                                    callback setup.
932                                 */
933
934                                 ipMIDIHandler* ipm = new ipMIDIHandler (); /* we will leak this sizeof(pointer)*2 sized object */
935                                 ipm->mcp = this;
936                                 ipm->port = &input_port;
937
938                                 g_source_set_callback (surface->input_source, (GSourceFunc) ipmidi_input_handler, ipm, NULL);
939                                 g_source_attach (surface->input_source, main_loop()->get_context()->gobj());
940                         }
941                 }
942         }
943
944         if (!_device_info.uses_ipmidi()) {
945                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
946                 for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
947                         (*s)->port().reconnect ();
948                 }
949         }
950
951         session->BundleAddedOrRemoved ();
952
953         assert (_master_surface);
954
955         return 0;
956 }
957
958 void
959 MackieControlProtocol::close()
960 {
961         port_connection.disconnect ();
962         session_connections.drop_connections ();
963         stripable_connections.drop_connections ();
964         periodic_connection.disconnect ();
965
966         clear_surfaces();
967 }
968
969 /** Ensure that the configuration_state XML node contains an up-to-date
970  *  copy of the state node the current device. If configuration_state already
971  *  contains a state node for the device, it will deleted and replaced.
972  */
973 void
974 MackieControlProtocol::update_configuration_state ()
975 {
976         /* CALLER MUST HOLD SURFACES LOCK */
977
978         if (!configuration_state) {
979                 configuration_state = new XMLNode (X_("Configurations"));
980         }
981
982         XMLNode* devnode = new XMLNode (X_("Configuration"));
983         devnode->set_property (X_("name"), _device_info.name());
984
985         configuration_state->remove_nodes_and_delete (X_("name"), _device_info.name());
986         configuration_state->add_child_nocopy (*devnode);
987
988         XMLNode* snode = new XMLNode (X_("Surfaces"));
989
990         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
991                 snode->add_child_nocopy ((*s)->get_state());
992         }
993
994         devnode->add_child_nocopy (*snode);
995 }
996
997 XMLNode&
998 MackieControlProtocol::get_state()
999 {
1000         XMLNode& node (ControlProtocol::get_state());
1001
1002         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state init\n");
1003
1004         // add current bank
1005         node.set_property (X_("bank"), _current_initial_bank);
1006
1007         // ipMIDI base port (possibly not used)
1008         node.set_property (X_("ipmidi-base"), _ipmidi_base);
1009
1010         node.set_property (X_("device-profile"), _device_profile.name());
1011         node.set_property (X_("device-name"), _device_info.name());
1012
1013         {
1014                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
1015                 update_configuration_state ();
1016         }
1017
1018         /* force a copy of the _surfaces_state node, because we want to retain ownership */
1019         node.add_child_copy (*configuration_state);
1020
1021         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state done\n");
1022
1023         return node;
1024 }
1025
1026 bool
1027 MackieControlProtocol::profile_exists (string const & name) const
1028 {
1029         return DeviceProfile::device_profiles.find (name) != DeviceProfile::device_profiles.end();
1030 }
1031
1032 int
1033 MackieControlProtocol::set_state (const XMLNode & node, int version)
1034 {
1035         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::set_state: active %1\n", active()));
1036
1037         if (ControlProtocol::set_state (node, version)) {
1038                 return -1;
1039         }
1040
1041         uint16_t ipmidi_base;
1042         if (node.get_property (X_("ipmidi-base"), ipmidi_base)) {
1043                 set_ipmidi_base (ipmidi_base);
1044         }
1045
1046         uint32_t bank = 0;
1047         // fetch current bank
1048         node.get_property (X_("bank"), bank);
1049
1050         std::string device_name;
1051         if (node.get_property (X_("device-name"), device_name)) {
1052                 set_device_info (device_name);
1053         }
1054
1055         std::string device_profile_name;
1056         if (node.get_property (X_("device-profile"), device_profile_name)) {
1057                 if (device_profile_name.empty()) {
1058                         string default_profile_name;
1059
1060                         /* start by looking for a user-edited profile for the current device name */
1061
1062                         default_profile_name = DeviceProfile::name_when_edited (_device_info.name());
1063
1064                         if (!profile_exists (default_profile_name)) {
1065
1066                                 /* no user-edited profile for this device name, so try the user-edited default profile */
1067
1068                                 default_profile_name = DeviceProfile::name_when_edited (DeviceProfile::default_profile_name);
1069
1070                                 if (!profile_exists (default_profile_name)) {
1071
1072                                         /* no user-edited version, so just try the device name */
1073
1074                                         default_profile_name = _device_info.name();
1075
1076                                         if (!profile_exists (default_profile_name)) {
1077
1078                                                 /* no generic device specific profile, just try the fixed default */
1079                                                 default_profile_name = DeviceProfile::default_profile_name;
1080                                         }
1081                                 }
1082                         }
1083
1084                         set_profile (default_profile_name);
1085
1086                 } else {
1087                         if (profile_exists (device_profile_name)) {
1088                                 set_profile (device_profile_name);
1089                         } else {
1090                                 set_profile (DeviceProfile::default_profile_name);
1091                         }
1092                 }
1093         }
1094
1095         XMLNode* dnode = node.child (X_("Configurations"));
1096
1097         delete configuration_state;
1098         configuration_state = 0;
1099
1100         if (dnode) {
1101                 configuration_state = new XMLNode (*dnode);
1102                 state_version = version;
1103         }
1104
1105         (void) switch_banks (bank, true);
1106
1107         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::set_state done\n");
1108
1109         return 0;
1110 }
1111
1112 string
1113 MackieControlProtocol::format_bbt_timecode (samplepos_t now_sample)
1114 {
1115         Timecode::BBT_Time bbt_time;
1116
1117         session->bbt_time (now_sample, bbt_time);
1118
1119         // The Mackie protocol spec is built around a BBT time display of
1120         //
1121         // digits:     888/88/88/888
1122         // semantics:  BBB/bb/ss/ttt
1123         //
1124         // The third field is "subdivisions" which is a concept found in Logic
1125         // but not present in Ardour. Instead Ardour displays a 4 digit tick
1126         // count, which we need to spread across the 5 digits of ss/ttt.
1127
1128         ostringstream os;
1129
1130         os << setw(3) << setfill('0') << bbt_time.bars;
1131         os << setw(2) << setfill('0') << bbt_time.beats;
1132         os << ' ';
1133         os << setw(1) << setfill('0') << bbt_time.ticks / 1000;
1134         os << setw(3) << setfill('0') << bbt_time.ticks % 1000;
1135
1136         return os.str();
1137 }
1138
1139 string
1140 MackieControlProtocol::format_timecode_timecode (samplepos_t now_sample)
1141 {
1142         Timecode::Time timecode;
1143         session->timecode_time (now_sample, timecode);
1144
1145         // According to the Logic docs
1146         // digits: 888/88/88/888
1147         // Timecode mode: Hours/Minutes/Seconds/Samples
1148         ostringstream os;
1149         os << setw(2) << setfill('0') << timecode.hours;
1150         os << ' ';
1151         os << setw(2) << setfill('0') << timecode.minutes;
1152         os << setw(2) << setfill('0') << timecode.seconds;
1153         os << ' ';
1154         os << setw(2) << setfill('0') << timecode.frames;
1155
1156         return os.str();
1157 }
1158
1159 void
1160 MackieControlProtocol::update_timecode_display()
1161 {
1162         Glib::Threads::Mutex::Lock lm (surfaces_lock);
1163
1164         if (surfaces.empty()) {
1165                 return;
1166         }
1167
1168         boost::shared_ptr<Surface> surface = _master_surface;
1169
1170         if (surface->type() != mcu || !_device_info.has_timecode_display() || !surface->active ()) {
1171                 return;
1172         }
1173
1174         // do assignment here so current_sample is fixed
1175         samplepos_t current_sample = session->transport_sample();
1176         string timecode;
1177         // For large jumps in play head possition do full reset
1178         int moved = (current_sample - _sample_last) / session->sample_rate ();
1179         if (moved) {
1180                 DEBUG_TRACE (DEBUG::MackieControl, "Timecode reset\n");
1181                 _timecode_last = string (10, ' ');
1182         }
1183         _sample_last = current_sample;
1184
1185         switch (_timecode_type) {
1186         case ARDOUR::AnyTime::BBT:
1187                 timecode = format_bbt_timecode (current_sample);
1188                 break;
1189         case ARDOUR::AnyTime::Timecode:
1190                 timecode = format_timecode_timecode (current_sample);
1191                 break;
1192         default:
1193                 return;
1194         }
1195
1196         // only write the timecode string to the MCU if it's changed
1197         // since last time. This is to reduce midi bandwidth used.
1198         if (timecode != _timecode_last) {
1199                 surface->display_timecode (timecode, _timecode_last);
1200                 _timecode_last = timecode;
1201         }
1202 }
1203
1204 ///////////////////////////////////////////
1205 // Session signals
1206 ///////////////////////////////////////////
1207
1208 void MackieControlProtocol::notify_parameter_changed (std::string const & p)
1209 {
1210         if (p == "punch-in") {
1211                 update_global_button (Button::Drop, session->config.get_punch_in() ? flashing : off);
1212         } else if (p == "punch-out") {
1213                 update_global_button (Button::Replace, session->config.get_punch_out() ? flashing : off);
1214         } else if (p == "clicking") {
1215                 update_global_button (Button::Click, Config->get_clicking());
1216         } else if (p == "follow-edits") {
1217                 /* we can't respond to this at present, because "follow-edits"
1218                  * is  a property of the (G)UI configuration object, to which we
1219                  * have no access. For now, this means that the lit state of
1220                  * this button (if there is one) won't reflect the setting.
1221                  */
1222
1223                 //update_global_button (Button::Enter, session->config.get_follow_edits() ? on : off);
1224         } else if (p == "external-sync") {
1225                 update_global_button (Button::Cancel, session->config.get_external_sync() ? on : off);
1226         } else {
1227                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("parameter changed: %1\n", p));
1228         }
1229 }
1230
1231 void
1232 MackieControlProtocol::notify_stripable_removed ()
1233 {
1234         Glib::Threads::Mutex::Lock lm (surfaces_lock);
1235         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
1236                 (*s)->master_monitor_may_have_changed ();
1237         }
1238 }
1239
1240 void
1241 MackieControlProtocol::notify_vca_added (ARDOUR::VCAList& vl)
1242 {
1243         refresh_current_bank ();
1244 }
1245
1246 // RouteList is the set of Routes that have just been added
1247 void
1248 MackieControlProtocol::notify_routes_added (ARDOUR::RouteList & rl)
1249 {
1250         {
1251                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
1252
1253                 if (surfaces.empty()) {
1254                         return;
1255                 }
1256         }
1257
1258         /* special case: single route, and it is the monitor or master out */
1259
1260         if (rl.size() == 1 && (rl.front()->is_monitor() || rl.front()->is_master())) {
1261                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
1262                 for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
1263                         (*s)->master_monitor_may_have_changed ();
1264                 }
1265         }
1266
1267         // currently assigned banks are less than the full set of
1268         // strips, so activate the new strip now.
1269
1270         refresh_current_bank();
1271
1272         // otherwise route added, but current bank needs no updating
1273 }
1274
1275 void
1276 MackieControlProtocol::notify_solo_active_changed (bool active)
1277 {
1278         boost::shared_ptr<Surface> surface;
1279
1280         {
1281                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
1282
1283                 if (surfaces.empty()) {
1284                         return;
1285                 }
1286
1287                 surface = _master_surface;
1288         }
1289
1290         map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (Led::RudeSolo);
1291         if (x != surface->controls_by_device_independent_id.end()) {
1292                 Led* rude_solo = dynamic_cast<Led*> (x->second);
1293                 if (rude_solo) {
1294                         surface->write (rude_solo->set_state (active ? flashing : off));
1295                 }
1296         }
1297 }
1298
1299 void
1300 MackieControlProtocol::notify_presentation_info_changed (PBD::PropertyChange const & what_changed)
1301 {
1302         PBD::PropertyChange order_or_hidden;
1303
1304         order_or_hidden.add (Properties::hidden);
1305         order_or_hidden.add (Properties::order);
1306
1307         if (!what_changed.contains (order_or_hidden)) {
1308                 return;
1309         }
1310
1311         {
1312                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
1313
1314                 if (surfaces.empty()) {
1315                         return;
1316                 }
1317         }
1318
1319         refresh_current_bank();
1320 }
1321
1322 ///////////////////////////////////////////
1323 // Transport signals
1324 ///////////////////////////////////////////
1325
1326 void
1327 MackieControlProtocol::notify_loop_state_changed()
1328 {
1329         update_global_button (Button::Loop, session->get_play_loop());
1330 }
1331
1332 void
1333 MackieControlProtocol::notify_transport_state_changed()
1334 {
1335         if (!_device_info.has_global_controls()) {
1336                 return;
1337         }
1338
1339         // switch various play and stop buttons on / off
1340         update_global_button (Button::Loop, session->get_play_loop());
1341         update_global_button (Button::Play, session->transport_speed() == 1.0);
1342         update_global_button (Button::Stop, session->transport_stopped ());
1343         update_global_button (Button::Rewind, session->transport_speed() < 0.0);
1344         update_global_button (Button::Ffwd, session->transport_speed() > 1.0);
1345
1346         // sometimes a return to start leaves time code at old time
1347         _timecode_last = string (10, ' ');
1348
1349         notify_metering_state_changed ();
1350 }
1351
1352 void
1353 MackieControlProtocol::notify_metering_state_changed()
1354 {
1355         Glib::Threads::Mutex::Lock lm (surfaces_lock);
1356
1357         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
1358                 (*s)->notify_metering_state_changed ();
1359         }
1360 }
1361
1362 void
1363 MackieControlProtocol::notify_record_state_changed ()
1364 {
1365         if (!_device_info.has_global_controls()) {
1366                 return;
1367         }
1368
1369         boost::shared_ptr<Surface> surface;
1370
1371         {
1372                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
1373                 if (surfaces.empty()) {
1374                         return;
1375                 }
1376                 surface = _master_surface;
1377         }
1378
1379         /* rec is a tristate */
1380
1381         map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (Button::Record);
1382         if (x != surface->controls_by_device_independent_id.end()) {
1383                 Button * rec = dynamic_cast<Button*> (x->second);
1384                 if (rec) {
1385                         LedState ls;
1386
1387                         switch (session->record_status()) {
1388                         case Session::Disabled:
1389                                 DEBUG_TRACE (DEBUG::MackieControl, "record state changed to disabled, LED off\n");
1390                                 ls = off;
1391                                 break;
1392                         case Session::Recording:
1393                                 DEBUG_TRACE (DEBUG::MackieControl, "record state changed to recording, LED on\n");
1394                                 ls = on;
1395                                 break;
1396                         case Session::Enabled:
1397                                 
1398                                 if(_device_info.is_qcon()){
1399                                         // For qcon the rec button is two state only (on/off)
1400                                         DEBUG_TRACE (DEBUG::MackieControl, "record state changed to enabled, LED on (QCon)\n");
1401                                         ls = on;
1402                                         break;
1403
1404                                 }
1405                                 else{
1406                                         // For standard Mackie MCU the record LED is flashing
1407                                         DEBUG_TRACE (DEBUG::MackieControl, "record state changed to enabled, LED flashing\n");
1408                                         ls = flashing;
1409                                         break;
1410                                 }
1411
1412                                 break;
1413                         }
1414
1415                         surface->write (rec->set_state (ls));
1416                 }
1417         }
1418 }
1419
1420 list<boost::shared_ptr<ARDOUR::Bundle> >
1421 MackieControlProtocol::bundles ()
1422 {
1423         list<boost::shared_ptr<ARDOUR::Bundle> > b;
1424
1425         if (_input_bundle) {
1426                 b.push_back (_input_bundle);
1427                 b.push_back (_output_bundle);
1428         }
1429
1430         return b;
1431 }
1432
1433 void
1434 MackieControlProtocol::do_request (MackieControlUIRequest* req)
1435 {
1436         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("doing request type %1\n", req->type));
1437         if (req->type == CallSlot) {
1438
1439                 call_slot (MISSING_INVALIDATOR, req->the_slot);
1440
1441         } else if (req->type == Quit) {
1442
1443                 stop ();
1444         }
1445 }
1446
1447 int
1448 MackieControlProtocol::stop ()
1449 {
1450         BaseUI::quit ();
1451
1452         return 0;
1453 }
1454
1455 void
1456 MackieControlProtocol::update_led (Surface& surface, Button& button, Mackie::LedState ls)
1457 {
1458         if (ls != none) {
1459                 surface.port().write (button.set_state (ls));
1460         }
1461 }
1462
1463 void
1464 MackieControlProtocol::build_button_map ()
1465 {
1466         /* this maps our device-independent button codes to the methods that handle them.
1467          */
1468
1469 #define DEFINE_BUTTON_HANDLER(b,p,r) button_map.insert (pair<Button::ID,ButtonHandlers> ((b), ButtonHandlers ((p),(r))));
1470
1471         DEFINE_BUTTON_HANDLER (Button::Track, &MackieControlProtocol::track_press, &MackieControlProtocol::track_release);
1472         DEFINE_BUTTON_HANDLER (Button::Send, &MackieControlProtocol::send_press, &MackieControlProtocol::send_release);
1473         DEFINE_BUTTON_HANDLER (Button::Pan, &MackieControlProtocol::pan_press, &MackieControlProtocol::pan_release);
1474         DEFINE_BUTTON_HANDLER (Button::Plugin, &MackieControlProtocol::plugin_press, &MackieControlProtocol::plugin_release);
1475         DEFINE_BUTTON_HANDLER (Button::Eq, &MackieControlProtocol::eq_press, &MackieControlProtocol::eq_release);
1476         DEFINE_BUTTON_HANDLER (Button::Dyn, &MackieControlProtocol::dyn_press, &MackieControlProtocol::dyn_release);
1477         DEFINE_BUTTON_HANDLER (Button::Left, &MackieControlProtocol::left_press, &MackieControlProtocol::left_release);
1478         DEFINE_BUTTON_HANDLER (Button::Right, &MackieControlProtocol::right_press, &MackieControlProtocol::right_release);
1479         DEFINE_BUTTON_HANDLER (Button::ChannelLeft, &MackieControlProtocol::channel_left_press, &MackieControlProtocol::channel_left_release);
1480         DEFINE_BUTTON_HANDLER (Button::ChannelRight, &MackieControlProtocol::channel_right_press, &MackieControlProtocol::channel_right_release);
1481         DEFINE_BUTTON_HANDLER (Button::Flip, &MackieControlProtocol::flip_press, &MackieControlProtocol::flip_release);
1482         DEFINE_BUTTON_HANDLER (Button::View, &MackieControlProtocol::view_press, &MackieControlProtocol::view_release);
1483         DEFINE_BUTTON_HANDLER (Button::NameValue, &MackieControlProtocol::name_value_press, &MackieControlProtocol::name_value_release);
1484         DEFINE_BUTTON_HANDLER (Button::TimecodeBeats, &MackieControlProtocol::timecode_beats_press, &MackieControlProtocol::timecode_beats_release);
1485 //      DEFINE_BUTTON_HANDLER (Button::F1, &MackieControlProtocol::F1_press, &MackieControlProtocol::F1_release);
1486 //      DEFINE_BUTTON_HANDLER (Button::F2, &MackieControlProtocol::F2_press, &MackieControlProtocol::F2_release);
1487 //      DEFINE_BUTTON_HANDLER (Button::F3, &MackieControlProtocol::F3_press, &MackieControlProtocol::F3_release);
1488 //      DEFINE_BUTTON_HANDLER (Button::F4, &MackieControlProtocol::F4_press, &MackieControlProtocol::F4_release);
1489 //      DEFINE_BUTTON_HANDLER (Button::F5, &MackieControlProtocol::F5_press, &MackieControlProtocol::F5_release);
1490 //      DEFINE_BUTTON_HANDLER (Button::F6, &MackieControlProtocol::F6_press, &MackieControlProtocol::F6_release);
1491 //      DEFINE_BUTTON_HANDLER (Button::F7, &MackieControlProtocol::F7_press, &MackieControlProtocol::F7_release);
1492 //      DEFINE_BUTTON_HANDLER (Button::F8, &MackieControlProtocol::F8_press, &MackieControlProtocol::F8_release);
1493         DEFINE_BUTTON_HANDLER (Button::MidiTracks, &MackieControlProtocol::miditracks_press, &MackieControlProtocol::miditracks_release);
1494         DEFINE_BUTTON_HANDLER (Button::Inputs, &MackieControlProtocol::inputs_press, &MackieControlProtocol::inputs_release);
1495         DEFINE_BUTTON_HANDLER (Button::AudioTracks, &MackieControlProtocol::audiotracks_press, &MackieControlProtocol::audiotracks_release);
1496         DEFINE_BUTTON_HANDLER (Button::AudioInstruments, &MackieControlProtocol::audioinstruments_press, &MackieControlProtocol::audioinstruments_release);
1497         DEFINE_BUTTON_HANDLER (Button::Aux, &MackieControlProtocol::aux_press, &MackieControlProtocol::aux_release);
1498         DEFINE_BUTTON_HANDLER (Button::Busses, &MackieControlProtocol::busses_press, &MackieControlProtocol::busses_release);
1499         DEFINE_BUTTON_HANDLER (Button::Outputs, &MackieControlProtocol::outputs_press, &MackieControlProtocol::outputs_release);
1500         DEFINE_BUTTON_HANDLER (Button::User, &MackieControlProtocol::user_press, &MackieControlProtocol::user_release);
1501         DEFINE_BUTTON_HANDLER (Button::Shift, &MackieControlProtocol::shift_press, &MackieControlProtocol::shift_release);
1502         DEFINE_BUTTON_HANDLER (Button::Option, &MackieControlProtocol::option_press, &MackieControlProtocol::option_release);
1503         DEFINE_BUTTON_HANDLER (Button::Ctrl, &MackieControlProtocol::control_press, &MackieControlProtocol::control_release);
1504         DEFINE_BUTTON_HANDLER (Button::CmdAlt, &MackieControlProtocol::cmd_alt_press, &MackieControlProtocol::cmd_alt_release);
1505         DEFINE_BUTTON_HANDLER (Button::Read, &MackieControlProtocol::read_press, &MackieControlProtocol::read_release);
1506         DEFINE_BUTTON_HANDLER (Button::Write, &MackieControlProtocol::write_press, &MackieControlProtocol::write_release);
1507         DEFINE_BUTTON_HANDLER (Button::Trim, &MackieControlProtocol::trim_press, &MackieControlProtocol::trim_release);
1508         DEFINE_BUTTON_HANDLER (Button::Touch, &MackieControlProtocol::touch_press, &MackieControlProtocol::touch_release);
1509         DEFINE_BUTTON_HANDLER (Button::Latch, &MackieControlProtocol::latch_press, &MackieControlProtocol::latch_release);
1510         DEFINE_BUTTON_HANDLER (Button::Grp, &MackieControlProtocol::grp_press, &MackieControlProtocol::grp_release);
1511         DEFINE_BUTTON_HANDLER (Button::Save, &MackieControlProtocol::save_press, &MackieControlProtocol::save_release);
1512         DEFINE_BUTTON_HANDLER (Button::Undo, &MackieControlProtocol::undo_press, &MackieControlProtocol::undo_release);
1513         DEFINE_BUTTON_HANDLER (Button::Cancel, &MackieControlProtocol::cancel_press, &MackieControlProtocol::cancel_release);
1514         DEFINE_BUTTON_HANDLER (Button::Enter, &MackieControlProtocol::enter_press, &MackieControlProtocol::enter_release);
1515         DEFINE_BUTTON_HANDLER (Button::Marker, &MackieControlProtocol::marker_press, &MackieControlProtocol::marker_release);
1516         DEFINE_BUTTON_HANDLER (Button::Nudge, &MackieControlProtocol::nudge_press, &MackieControlProtocol::nudge_release);
1517         DEFINE_BUTTON_HANDLER (Button::Loop, &MackieControlProtocol::loop_press, &MackieControlProtocol::loop_release);
1518         DEFINE_BUTTON_HANDLER (Button::Drop, &MackieControlProtocol::drop_press, &MackieControlProtocol::drop_release);
1519         DEFINE_BUTTON_HANDLER (Button::Replace, &MackieControlProtocol::replace_press, &MackieControlProtocol::replace_release);
1520         DEFINE_BUTTON_HANDLER (Button::Click, &MackieControlProtocol::click_press, &MackieControlProtocol::click_release);
1521         DEFINE_BUTTON_HANDLER (Button::ClearSolo, &MackieControlProtocol::clearsolo_press, &MackieControlProtocol::clearsolo_release);
1522         DEFINE_BUTTON_HANDLER (Button::Rewind, &MackieControlProtocol::rewind_press, &MackieControlProtocol::rewind_release);
1523         DEFINE_BUTTON_HANDLER (Button::Ffwd, &MackieControlProtocol::ffwd_press, &MackieControlProtocol::ffwd_release);
1524         DEFINE_BUTTON_HANDLER (Button::Stop, &MackieControlProtocol::stop_press, &MackieControlProtocol::stop_release);
1525         DEFINE_BUTTON_HANDLER (Button::Play, &MackieControlProtocol::play_press, &MackieControlProtocol::play_release);
1526         DEFINE_BUTTON_HANDLER (Button::Record, &MackieControlProtocol::record_press, &MackieControlProtocol::record_release);
1527         DEFINE_BUTTON_HANDLER (Button::CursorUp, &MackieControlProtocol::cursor_up_press, &MackieControlProtocol::cursor_up_release);
1528         DEFINE_BUTTON_HANDLER (Button::CursorDown, &MackieControlProtocol::cursor_down_press, &MackieControlProtocol::cursor_down_release);
1529         DEFINE_BUTTON_HANDLER (Button::CursorLeft, &MackieControlProtocol::cursor_left_press, &MackieControlProtocol::cursor_left_release);
1530         DEFINE_BUTTON_HANDLER (Button::CursorRight, &MackieControlProtocol::cursor_right_press, &MackieControlProtocol::cursor_right_release);
1531         DEFINE_BUTTON_HANDLER (Button::Zoom, &MackieControlProtocol::zoom_press, &MackieControlProtocol::zoom_release);
1532         DEFINE_BUTTON_HANDLER (Button::Scrub, &MackieControlProtocol::scrub_press, &MackieControlProtocol::scrub_release);
1533         DEFINE_BUTTON_HANDLER (Button::UserA, &MackieControlProtocol::user_a_press, &MackieControlProtocol::user_a_release);
1534         DEFINE_BUTTON_HANDLER (Button::UserB, &MackieControlProtocol::user_b_press, &MackieControlProtocol::user_b_release);
1535         DEFINE_BUTTON_HANDLER (Button::MasterFaderTouch, &MackieControlProtocol::master_fader_touch_press, &MackieControlProtocol::master_fader_touch_release);
1536 }
1537
1538 void
1539 MackieControlProtocol::handle_button_event (Surface& surface, Button& button, ButtonState bs)
1540 {
1541         Button::ID button_id = button.bid();
1542
1543         if  (bs != press && bs != release) {
1544                 update_led (surface, button, none);
1545                 return;
1546         }
1547
1548         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2 (%3)\n", (bs == press ? "press" : "release"), button.id(),
1549                                                            Button::id_to_name (button.bid())));
1550
1551         /* check profile first */
1552
1553         string action = _device_profile.get_button_action (button.bid(), _modifier_state);
1554
1555         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("device profile returned [%1] for that button\n", action));
1556
1557         if (!action.empty()) {
1558
1559                 if (action.find ('/') != string::npos) { /* good chance that this is really an action */
1560
1561                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Looked up action for button %1 with modifier %2, got [%3]\n",
1562                                                                            button.bid(), _modifier_state, action));
1563
1564                         /* if there is a bound action for this button, and this is a press event,
1565                            carry out the action. If its a release event, do nothing since we
1566                            don't bind to them at all but don't want any other handling to
1567                            occur either.
1568                         */
1569                         if (bs == press) {
1570                                 update_led (surface, button, on);
1571                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("executing action %1\n", action));
1572                                 access_action (action);
1573                         } else {
1574                                 update_led (surface, button, off);
1575                         }
1576                         return;
1577
1578                 } else {
1579
1580                         /* "action" is more likely to be a button name. We use this to
1581                          * allow remapping buttons to different (builtin) functionality
1582                          * associated with an existing button. This is similar to the
1583                          * way that (for example) Nuendo moves the "Shift" function to
1584                          * the "Enter" key of the MCU Pro.
1585                          */
1586
1587                         int bid = Button::name_to_id (action);
1588
1589                         if (bid < 0) {
1590                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("apparent button name %1 not found\n", action));
1591                                 return;
1592                         }
1593
1594                         button_id = (Button::ID) bid;
1595                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("handling button %1 as if it was %2 (%3)\n", Button::id_to_name (button.bid()), button_id, Button::id_to_name (button_id)));
1596                 }
1597         }
1598
1599         /* Now that we have the correct (maybe remapped) button ID, do these
1600          * checks on it.
1601          */
1602
1603         if ((button_id != Button::Marker) && (modifier_state() & MODIFIER_MARKER)) {
1604                 marker_modifier_consumed_by_button = true;
1605         }
1606
1607         if ((button_id != Button::Nudge) && (modifier_state() & MODIFIER_NUDGE)) {
1608                 nudge_modifier_consumed_by_button = true;
1609         }
1610
1611         /* lookup using the device-INDEPENDENT button ID */
1612
1613         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("now looking up button ID %1\n", button_id));
1614
1615         ButtonMap::iterator b = button_map.find (button_id);
1616
1617         if (b != button_map.end()) {
1618
1619                 ButtonHandlers& bh (b->second);
1620
1621                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("button found in map, now invoking %1\n", (bs == press ? "press" : "release")));
1622
1623                 switch  (bs) {
1624                 case press:
1625                         surface.write (button.set_state ((this->*(bh.press)) (button)));
1626                         break;
1627                 case release:
1628                         surface.write (button.set_state ((this->*(bh.release)) (button)));
1629                         break;
1630                 default:
1631                         break;
1632                 }
1633         } else {
1634                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("no button handlers for button ID %1 (device ID %2)\n",
1635                                                                    button.bid(), button.id()));
1636                 error << string_compose ("no button handlers for button ID %1 (device ID %2)\n",
1637                                          button.bid(), button.id()) << endmsg;
1638         }
1639 }
1640
1641 bool
1642 MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port)
1643 {
1644         if (ioc & ~IO_IN) {
1645                 DEBUG_TRACE (DEBUG::MackieControl, "MIDI port closed\n");
1646                 return false;
1647         }
1648
1649         if (ioc & IO_IN) {
1650
1651                 // DEBUG_TRACE (DEBUG::MackieControl, string_compose ("something happend on  %1\n", port->name()));
1652
1653                 /* Devices using regular JACK MIDI ports will need to have
1654                    the x-thread FIFO drained to avoid burning endless CPU.
1655
1656                    Devices using ipMIDI have port->selectable() as the same
1657                    file descriptor that data arrives on, so doing this
1658                    for them will simply throw all incoming data away.
1659                 */
1660
1661                 if (!_device_info.uses_ipmidi()) {
1662                         AsyncMIDIPort* asp = dynamic_cast<AsyncMIDIPort*>(port);
1663                         if (asp) {
1664                                 asp->clear ();
1665                         }
1666                 }
1667
1668                 // DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name()));
1669                 samplepos_t now = session->engine().sample_time();
1670                 port->parse (now);
1671         }
1672
1673         return true;
1674 }
1675
1676 void
1677 MackieControlProtocol::clear_ports ()
1678 {
1679         if (_input_bundle) {
1680                 _input_bundle->remove_channels ();
1681                 _output_bundle->remove_channels ();
1682         }
1683 }
1684
1685 void
1686 MackieControlProtocol::notify_subview_stripable_deleted ()
1687 {
1688         /* return to global/mixer view */
1689         _subview_stripable.reset ();
1690         set_view_mode (Mixer);
1691 }
1692
1693 bool
1694 MackieControlProtocol::subview_mode_would_be_ok (SubViewMode mode, boost::shared_ptr<Stripable> r)
1695 {
1696         switch (mode) {
1697         case None:
1698                 return true;
1699                 break;
1700
1701         case Sends:
1702                 if (r && r->send_level_controllable (0)) {
1703                         return true;
1704                 }
1705                 break;
1706
1707         case EQ:
1708                 if (r && r->eq_band_cnt() > 0) {
1709                         return true;
1710                 }
1711                 break;
1712
1713         case Dynamics:
1714                 if (r && r->comp_enable_controllable()) {
1715                         return true;
1716                 }
1717                 break;
1718
1719         case TrackView:
1720                 if (r) {
1721                         return true;
1722                 }
1723         }
1724
1725         return false;
1726 }
1727
1728 bool
1729 MackieControlProtocol::redisplay_subview_mode ()
1730 {
1731         Surfaces copy; /* can't hold surfaces lock while calling Strip::subview_mode_changed */
1732
1733         {
1734                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
1735                 copy = surfaces;
1736         }
1737
1738         for (Surfaces::iterator s = copy.begin(); s != copy.end(); ++s) {
1739                 (*s)->subview_mode_changed ();
1740         }
1741
1742         /* don't call this again from a timeout */
1743         return false;
1744 }
1745
1746 int
1747 MackieControlProtocol::set_subview_mode (SubViewMode sm, boost::shared_ptr<Stripable> r)
1748 {
1749         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("set subview mode %1 with stripable %2, current flip mode %3\n", sm, (r ? r->name() : string ("null")), _flip_mode));
1750
1751         if (_flip_mode != Normal) {
1752                 set_flip_mode (Normal);
1753         }
1754
1755         if (!subview_mode_would_be_ok (sm, r)) {
1756
1757                 DEBUG_TRACE (DEBUG::MackieControl, "subview mode not OK\n");
1758
1759                 if (r) {
1760
1761                         Glib::Threads::Mutex::Lock lm (surfaces_lock);
1762
1763                         if (!surfaces.empty()) {
1764
1765                                 string msg;
1766
1767                                 switch (sm) {
1768                                 case Sends:
1769                                         msg = _("no sends for selected track/bus");
1770                                         break;
1771                                 case EQ:
1772                                         msg = _("no EQ in the track/bus");
1773                                         break;
1774                                 case Dynamics:
1775                                         msg = _("no dynamics in selected track/bus");
1776                                         break;
1777                                 case TrackView:
1778                                         msg = _("no track view possible");
1779                                 default:
1780                                         break;
1781                                 }
1782                                 if (!msg.empty()) {
1783                                         surfaces.front()->display_message_for (msg, 1000);
1784                                         if (_subview_mode != None) {
1785                                                 /* redisplay current subview mode after
1786                                                    that message goes away.
1787                                                 */
1788                                                 Glib::RefPtr<Glib::TimeoutSource> redisplay_timeout = Glib::TimeoutSource::create (1000); // milliseconds
1789                                                 redisplay_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::redisplay_subview_mode));
1790                                                 redisplay_timeout->attach (main_loop()->get_context());
1791                                         }
1792                                 }
1793                         }
1794                 }
1795
1796                 return -1;
1797         }
1798
1799         boost::shared_ptr<Stripable> old_stripable = _subview_stripable;
1800
1801         _subview_mode = sm;
1802         _subview_stripable = r;
1803
1804         if (_subview_stripable != old_stripable) {
1805                 subview_stripable_connections.drop_connections ();
1806
1807                 /* Catch the current subview stripable going away */
1808                 if (_subview_stripable) {
1809                         _subview_stripable->DropReferences.connect (subview_stripable_connections, MISSING_INVALIDATOR,
1810                                                                     boost::bind (&MackieControlProtocol::notify_subview_stripable_deleted, this),
1811                                                                     this);
1812                 }
1813         }
1814
1815         redisplay_subview_mode ();
1816
1817         /* turn buttons related to vpot mode on or off as required */
1818
1819         switch (_subview_mode) {
1820         case MackieControlProtocol::None:
1821                 update_global_button (Button::Send, off);
1822                 update_global_button (Button::Plugin, off);
1823                 update_global_button (Button::Eq, off);
1824                 update_global_button (Button::Dyn, off);
1825                 update_global_button (Button::Track, off);
1826                 update_global_button (Button::Pan, on);
1827                 break;
1828         case MackieControlProtocol::EQ:
1829                 update_global_button (Button::Send, off);
1830                 update_global_button (Button::Plugin, off);
1831                 update_global_button (Button::Eq, on);
1832                 update_global_button (Button::Dyn, off);
1833                 update_global_button (Button::Track, off);
1834                 update_global_button (Button::Pan, off);
1835                 break;
1836         case MackieControlProtocol::Dynamics:
1837                 update_global_button (Button::Send, off);
1838                 update_global_button (Button::Plugin, off);
1839                 update_global_button (Button::Eq, off);
1840                 update_global_button (Button::Dyn, on);
1841                 update_global_button (Button::Track, off);
1842                 update_global_button (Button::Pan, off);
1843                 break;
1844         case MackieControlProtocol::Sends:
1845                 update_global_button (Button::Send, on);
1846                 update_global_button (Button::Plugin, off);
1847                 update_global_button (Button::Eq, off);
1848                 update_global_button (Button::Dyn, off);
1849                 update_global_button (Button::Track, off);
1850                 update_global_button (Button::Pan, off);
1851                 break;
1852         case MackieControlProtocol::TrackView:
1853                 update_global_button (Button::Send, off);
1854                 update_global_button (Button::Plugin, off);
1855                 update_global_button (Button::Eq, off);
1856                 update_global_button (Button::Dyn, off);
1857                 update_global_button (Button::Track, on);
1858                 update_global_button (Button::Pan, off);
1859                 break;
1860         }
1861
1862         return 0;
1863 }
1864
1865 void
1866 MackieControlProtocol::set_view_mode (ViewMode m)
1867 {
1868         if (_flip_mode != Normal) {
1869                 set_flip_mode (Normal);
1870         }
1871         ViewMode old_view_mode = _view_mode;
1872
1873         _view_mode = m;
1874         _last_bank[old_view_mode] = _current_initial_bank;
1875
1876         if (switch_banks(_last_bank[m], true)) {
1877                 _view_mode = old_view_mode;
1878                 return;
1879         }
1880
1881         /* leave subview mode, whatever it was */
1882         set_subview_mode (None, boost::shared_ptr<Stripable>());
1883         display_view_mode ();
1884 }
1885
1886 void
1887 MackieControlProtocol::display_view_mode ()
1888 {
1889         Glib::Threads::Mutex::Lock lm (surfaces_lock);
1890
1891         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
1892                 (*s)->update_view_mode_display (true);
1893         }
1894 }
1895
1896 void
1897 MackieControlProtocol::set_flip_mode (FlipMode fm)
1898 {
1899         if (fm == Normal) {
1900                 update_global_button (Button::Flip, off);
1901         } else {
1902                 update_global_button (Button::Flip, on);
1903         }
1904
1905         Glib::Threads::Mutex::Lock lm (surfaces_lock);
1906
1907         _flip_mode = fm;
1908
1909         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
1910                 (*s)->update_flip_mode_display ();
1911         }
1912 }
1913
1914 void
1915 MackieControlProtocol::set_master_on_surface_strip (uint32_t surface, uint32_t strip_number)
1916 {
1917         force_special_stripable_to_strip (session->master_out(), surface, strip_number);
1918 }
1919
1920 void
1921 MackieControlProtocol::set_monitor_on_surface_strip (uint32_t surface, uint32_t strip_number)
1922 {
1923         force_special_stripable_to_strip (session->monitor_out(), surface, strip_number);
1924 }
1925
1926 void
1927 MackieControlProtocol::force_special_stripable_to_strip (boost::shared_ptr<Stripable> r, uint32_t surface, uint32_t strip_number)
1928 {
1929         if (!r) {
1930                 return;
1931         }
1932
1933         Glib::Threads::Mutex::Lock lm (surfaces_lock);
1934
1935         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
1936                 if ((*s)->number() == surface) {
1937                         Strip* strip = (*s)->nth_strip (strip_number);
1938                         if (strip) {
1939                                 strip->set_stripable (session->master_out());
1940                                 strip->lock_controls ();
1941                         }
1942                 }
1943         }
1944 }
1945
1946 void
1947 MackieControlProtocol::check_fader_automation_state ()
1948 {
1949         fader_automation_connections.drop_connections ();
1950
1951         boost::shared_ptr<Stripable> r = first_selected_stripable ();
1952
1953         if (!r) {
1954                 update_global_button (Button::Read, off);
1955                 update_global_button (Button::Write, off);
1956                 update_global_button (Button::Touch, off);
1957                 update_global_button (Button::Trim, off);
1958                 update_global_button (Button::Latch, off);
1959                 update_global_button (Button::Grp, on);
1960                 return;
1961         }
1962
1963         r->gain_control()->alist()->automation_state_changed.connect (fader_automation_connections,
1964                                                                       MISSING_INVALIDATOR,
1965                                                                       boost::bind (&MackieControlProtocol::update_fader_automation_state, this),
1966                                                                       this);
1967
1968         update_fader_automation_state ();
1969 }
1970
1971 void
1972 MackieControlProtocol::update_fader_automation_state ()
1973 {
1974         boost::shared_ptr<Stripable> r = first_selected_stripable ();
1975
1976         if (!r) {
1977                 update_global_button (Button::Read, off);
1978                 update_global_button (Button::Write, off);
1979                 update_global_button (Button::Touch, off);
1980                 update_global_button (Button::Trim, off);
1981                 update_global_button (Button::Latch, off);
1982                 update_global_button (Button::Grp, on);
1983                 return;
1984         }
1985
1986         switch (r->gain_control()->automation_state()) {
1987         case Off:
1988                 update_global_button (Button::Read, off);
1989                 update_global_button (Button::Write, off);
1990                 update_global_button (Button::Touch, off);
1991                 update_global_button (Button::Trim, off);
1992                 update_global_button (Button::Latch, off);
1993                 update_global_button (Button::Grp, on);
1994                 break;
1995         case Play:
1996                 update_global_button (Button::Read, on);
1997                 update_global_button (Button::Write, off);
1998                 update_global_button (Button::Touch, off);
1999                 update_global_button (Button::Trim, off);
2000                 update_global_button (Button::Latch, off);
2001                 update_global_button (Button::Grp, off);
2002                 break;
2003         case Write:
2004                 update_global_button (Button::Read, off);
2005                 update_global_button (Button::Write, on);
2006                 update_global_button (Button::Touch, off);
2007                 update_global_button (Button::Trim, off);
2008                 update_global_button (Button::Latch, off);
2009                 update_global_button (Button::Grp, off);
2010                 break;
2011         case Touch:
2012                 update_global_button (Button::Read, off);
2013                 update_global_button (Button::Write, off);
2014                 update_global_button (Button::Touch, on);
2015                 update_global_button (Button::Trim, off);
2016                 update_global_button (Button::Latch, off);
2017                 update_global_button (Button::Grp, off);
2018                 break;
2019         }
2020 }
2021
2022 samplepos_t
2023 MackieControlProtocol::transport_sample() const
2024 {
2025         return session->transport_sample();
2026 }
2027
2028 void
2029 MackieControlProtocol::add_down_select_button (int surface, int strip)
2030 {
2031         _down_select_buttons.insert ((surface<<8)|(strip&0xf));
2032 }
2033
2034 void
2035 MackieControlProtocol::remove_down_select_button (int surface, int strip)
2036 {
2037         DownButtonList::iterator x = find (_down_select_buttons.begin(), _down_select_buttons.end(), (uint32_t) (surface<<8)|(strip&0xf));
2038         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("removing surface %1 strip %2 from down select buttons\n", surface, strip));
2039         if (x != _down_select_buttons.end()) {
2040                 _down_select_buttons.erase (x);
2041         } else {
2042                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface %1 strip %2 not found in down select buttons\n",
2043                                                                    surface, strip));
2044         }
2045 }
2046
2047 void
2048 MackieControlProtocol::select_range (uint32_t pressed)
2049 {
2050         StripableList stripables;
2051
2052         pull_stripable_range (_down_select_buttons, stripables, pressed);
2053
2054         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("select range: found %1 stripables, first = %2\n", stripables.size(),
2055                                                            (stripables.empty() ? "null" : stripables.front()->name())));
2056
2057         if (stripables.empty()) {
2058                 return;
2059         }
2060
2061         if (stripables.size() == 1 && ControlProtocol::last_selected().size() == 1 && stripables.front()->is_selected()) {
2062                 /* cancel selection for one and only selected stripable */
2063                 ToggleStripableSelection (stripables.front());
2064         } else {
2065                 for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) {
2066
2067                         if (main_modifier_state() == MODIFIER_SHIFT) {
2068                                 ToggleStripableSelection (*s);
2069                         } else {
2070                                 if (s == stripables.begin()) {
2071                                         SetStripableSelection (*s);
2072                                 } else {
2073                                         AddStripableToSelection (*s);
2074                                 }
2075                         }
2076                 }
2077         }
2078 }
2079
2080 void
2081 MackieControlProtocol::add_down_button (AutomationType a, int surface, int strip)
2082 {
2083         DownButtonMap::iterator m = _down_buttons.find (a);
2084
2085         if (m == _down_buttons.end()) {
2086                 _down_buttons[a] = DownButtonList();
2087         }
2088
2089         _down_buttons[a].insert ((surface<<8)|(strip&0xf));
2090 }
2091
2092 void
2093 MackieControlProtocol::remove_down_button (AutomationType a, int surface, int strip)
2094 {
2095         DownButtonMap::iterator m = _down_buttons.find (a);
2096
2097         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("removing surface %1 strip %2 from down buttons for %3\n", surface, strip, (int) a));
2098
2099         if (m == _down_buttons.end()) {
2100                 return;
2101         }
2102
2103         DownButtonList& l (m->second);
2104         DownButtonList::iterator x = find (l.begin(), l.end(), (surface<<8)|(strip&0xf));
2105
2106         if (x != l.end()) {
2107                 l.erase (x);
2108         } else {
2109                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface %1 strip %2 not found in down buttons for %3\n",
2110                                                                    surface, strip, (int) a));
2111         }
2112 }
2113
2114 MackieControlProtocol::ControlList
2115 MackieControlProtocol::down_controls (AutomationType p, uint32_t pressed)
2116 {
2117         ControlList controls;
2118         StripableList stripables;
2119
2120         DownButtonMap::iterator m = _down_buttons.find (p);
2121
2122         if (m == _down_buttons.end()) {
2123                 return controls;
2124         }
2125
2126         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("looking for down buttons for %1, got %2\n",
2127                                                            p, m->second.size()));
2128
2129         pull_stripable_range (m->second, stripables, pressed);
2130
2131         switch (p) {
2132         case GainAutomation:
2133                 for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) {
2134                         controls.push_back ((*s)->gain_control());
2135                 }
2136                 break;
2137         case SoloAutomation:
2138                 for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) {
2139                         controls.push_back ((*s)->solo_control());
2140                 }
2141                 break;
2142         case MuteAutomation:
2143                 for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) {
2144                         controls.push_back ((*s)->mute_control());
2145                 }
2146                 break;
2147         case RecEnableAutomation:
2148                 for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) {
2149                         boost::shared_ptr<AutomationControl> ac = (*s)->rec_enable_control();
2150                         if (ac) {
2151                                 controls.push_back (ac);
2152                         }
2153                 }
2154                 break;
2155         default:
2156                 break;
2157         }
2158
2159         return controls;
2160
2161 }
2162
2163 struct ButtonRangeSorter {
2164     bool operator() (const uint32_t& a, const uint32_t& b) {
2165             return (a>>8) < (b>>8) // a.surface < b.surface
2166                     ||
2167                     ((a>>8) == (b>>8) && (a&0xf) < (b&0xf)); // a.surface == b.surface && a.strip < b.strip
2168     }
2169 };
2170
2171 void
2172 MackieControlProtocol::pull_stripable_range (DownButtonList& down, StripableList& selected, uint32_t pressed)
2173 {
2174         ButtonRangeSorter cmp;
2175
2176         if (down.empty()) {
2177                 return;
2178         }
2179
2180         list<uint32_t> ldown;
2181         ldown.insert (ldown.end(), down.begin(), down.end());
2182         ldown.sort (cmp);
2183
2184         uint32_t first = ldown.front();
2185         uint32_t last = ldown.back ();
2186
2187         uint32_t first_surface = first>>8;
2188         uint32_t first_strip = first&0xf;
2189
2190         uint32_t last_surface = last>>8;
2191         uint32_t last_strip = last&0xf;
2192
2193         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("PRR %5 in list %1.%2 - %3.%4\n", first_surface, first_strip, last_surface, last_strip,
2194                                                            down.size()));
2195
2196         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2197
2198         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
2199
2200                 if ((*s)->number() >= first_surface && (*s)->number() <= last_surface) {
2201
2202                         uint32_t fs;
2203                         uint32_t ls;
2204
2205                         if ((*s)->number() == first_surface) {
2206                                 fs = first_strip;
2207                         } else {
2208                                 fs = 0;
2209                         }
2210
2211                         if ((*s)->number() == last_surface) {
2212                                 ls = last_strip;
2213                                 ls += 1;
2214                         } else {
2215                                 ls = (*s)->n_strips ();
2216                         }
2217
2218                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("adding strips for surface %1 (%2 .. %3)\n",
2219                                                                            (*s)->number(), fs, ls));
2220
2221                         for (uint32_t n = fs; n < ls; ++n) {
2222                                 Strip* strip = (*s)->nth_strip (n);
2223                                 boost::shared_ptr<Stripable> r = strip->stripable();
2224                                 if (r) {
2225                                         if (global_index_locked (*strip) == pressed) {
2226                                                 selected.push_front (r);
2227                                         } else {
2228                                                 selected.push_back (r);
2229                                         }
2230                                 }
2231                         }
2232                 }
2233         }
2234
2235 }
2236
2237 void
2238 MackieControlProtocol::set_ipmidi_base (int16_t portnum)
2239 {
2240         /* this will not be saved without a session save, so .. */
2241
2242         session->set_dirty ();
2243
2244         _ipmidi_base = portnum;
2245
2246         /* if the current device uses ipMIDI we need
2247            to restart.
2248         */
2249
2250         if (active() && _device_info.uses_ipmidi()) {
2251                 needs_ipmidi_restart = true;
2252         }
2253 }
2254
2255 int
2256 MackieControlProtocol::ipmidi_restart ()
2257 {
2258         clear_surfaces ();
2259         if (create_surfaces ()) {
2260                 return -1;
2261         }
2262         (void) switch_banks (_current_initial_bank, true);
2263         needs_ipmidi_restart = false;
2264         return 0;
2265 }
2266
2267 void
2268 MackieControlProtocol::clear_surfaces ()
2269 {
2270         clear_ports ();
2271
2272         {
2273                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
2274                 _master_surface.reset ();
2275                 surfaces.clear ();
2276         }
2277 }
2278
2279 void
2280 MackieControlProtocol::set_touch_sensitivity (int sensitivity)
2281 {
2282         sensitivity = min (9, sensitivity);
2283         sensitivity = max (0, sensitivity);
2284
2285         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2286
2287         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
2288                 (*s)->set_touch_sensitivity (sensitivity);
2289         }
2290 }
2291
2292 void
2293 MackieControlProtocol::recalibrate_faders ()
2294 {
2295         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2296
2297         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
2298                 (*s)->recalibrate_faders ();
2299         }
2300 }
2301
2302 void
2303 MackieControlProtocol::toggle_backlight ()
2304 {
2305         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2306
2307         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
2308                 (*s)->toggle_backlight ();
2309         }
2310 }
2311
2312 boost::shared_ptr<Surface>
2313 MackieControlProtocol::get_surface_by_raw_pointer (void* ptr) const
2314 {
2315         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2316
2317         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
2318                 if ((*s).get() == (Surface*) ptr) {
2319                         return *s;
2320                 }
2321         }
2322
2323         return boost::shared_ptr<Surface> ();
2324 }
2325
2326 boost::shared_ptr<Surface>
2327 MackieControlProtocol::nth_surface (uint32_t n) const
2328 {
2329         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2330
2331         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s, --n) {
2332                 if (n == 0) {
2333                         return *s;
2334                 }
2335         }
2336
2337         return boost::shared_ptr<Surface> ();
2338 }
2339
2340 void
2341 MackieControlProtocol::connection_handler (boost::weak_ptr<ARDOUR::Port> wp1, std::string name1, boost::weak_ptr<ARDOUR::Port> wp2, std::string name2, bool yn)
2342 {
2343         Surfaces scopy;
2344         {
2345                 Glib::Threads::Mutex::Lock lm (surfaces_lock);
2346                 scopy = surfaces;
2347         }
2348
2349         for (Surfaces::const_iterator s = scopy.begin(); s != scopy.end(); ++s) {
2350                 if ((*s)->connection_handler (wp1, name1, wp2, name2, yn)) {
2351                         ConnectionChange (*s);
2352                         break;
2353                 }
2354         }
2355 }
2356
2357 bool
2358 MackieControlProtocol::is_track (boost::shared_ptr<Stripable> r) const
2359 {
2360         return boost::dynamic_pointer_cast<Track>(r) != 0;
2361 }
2362
2363 bool
2364 MackieControlProtocol::is_audio_track (boost::shared_ptr<Stripable> r) const
2365 {
2366         return boost::dynamic_pointer_cast<AudioTrack>(r) != 0;
2367 }
2368
2369 bool
2370 MackieControlProtocol::is_midi_track (boost::shared_ptr<Stripable> r) const
2371 {
2372         return boost::dynamic_pointer_cast<MidiTrack>(r) != 0;
2373 }
2374
2375 bool
2376 MackieControlProtocol::is_mapped (boost::shared_ptr<Stripable> r) const
2377 {
2378         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2379
2380         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
2381                 if ((*s)->stripable_is_mapped (r)) {
2382                         return true;
2383                 }
2384         }
2385
2386         return false;
2387 }
2388
2389 void
2390 MackieControlProtocol::stripable_selection_changed ()
2391 {
2392         //this function is called after the stripable selection is "stable", so this is the place to check surface selection state
2393         for (Surfaces::iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
2394                 (*si)->update_strip_selection ();
2395         }
2396
2397         boost::shared_ptr<Stripable> s = first_selected_stripable ();
2398         if (s) {
2399                 check_fader_automation_state ();
2400
2401                 /* It is possible that first_selected_route() may return null if we
2402                  * are no longer displaying/mapping that route. In that case,
2403                  * we will exit subview mode. If first_selected_route() is
2404                  * null, and subview mode is not None, then the first call to
2405                  * set_subview_mode() will fail, and we will reset to None.
2406                  */
2407
2408                 if (set_subview_mode (_subview_mode, s)) {
2409                         set_subview_mode (None, boost::shared_ptr<Stripable>());
2410                 }
2411
2412         }
2413 }
2414
2415 boost::shared_ptr<Stripable>
2416 MackieControlProtocol::first_selected_stripable () const
2417 {
2418         boost::shared_ptr<Stripable> s = ControlProtocol::first_selected_stripable();
2419
2420         if (s) {
2421                 /* check it is on one of our surfaces */
2422
2423                 if (is_mapped (s)) {
2424                         return s;
2425                 }
2426
2427                 /* stripable is not mapped. thus, the currently selected stripable is
2428                  * not on the surfaces, and so from our perspective, there is
2429                  * no currently selected stripable.
2430                  */
2431
2432                 s.reset ();
2433         }
2434
2435         return s; /* may be null */
2436 }
2437
2438 boost::shared_ptr<Stripable>
2439 MackieControlProtocol::subview_stripable () const
2440 {
2441         return _subview_stripable;
2442 }
2443
2444 uint32_t
2445 MackieControlProtocol::global_index (Strip& strip)
2446 {
2447         Glib::Threads::Mutex::Lock lm (surfaces_lock);
2448         return global_index_locked (strip);
2449 }
2450
2451 uint32_t
2452 MackieControlProtocol::global_index_locked (Strip& strip)
2453 {
2454         uint32_t global = 0;
2455
2456         for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
2457                 if ((*s).get() == strip.surface()) {
2458                         return global + strip.index();
2459                 }
2460                 global += (*s)->n_strips ();
2461         }
2462
2463         return global;
2464 }
2465
2466 void*
2467 MackieControlProtocol::request_factory (uint32_t num_requests)
2468 {
2469         /* AbstractUI<T>::request_buffer_factory() is a template method only
2470            instantiated in this source module. To provide something visible for
2471            use in the interface/descriptor, we have this static method that is
2472            template-free.
2473         */
2474         return request_buffer_factory (num_requests);
2475 }
2476
2477 void
2478 MackieControlProtocol::set_automation_state (AutoState as)
2479 {
2480         boost::shared_ptr<Stripable> r = first_selected_stripable ();
2481
2482         if (!r) {
2483                 return;
2484         }
2485
2486         boost::shared_ptr<AutomationControl> ac = r->gain_control();
2487
2488         if (!ac) {
2489                 return;
2490         }
2491
2492         ac->set_automation_state (as);
2493 }