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