+
+bool
+MackieControlProtocol::is_mapped (boost::shared_ptr<Stripable> r) const
+{
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ if ((*s)->stripable_is_mapped (r)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+MackieControlProtocol::update_selected (boost::shared_ptr<Stripable> s, bool became_selected)
+{
+ if (became_selected) {
+
+ check_fader_automation_state ();
+
+ /* It is possible that first_selected_route() may return null if we
+ * are no longer displaying/mapping that route. In that case,
+ * we will exit subview mode. If first_selected_route() is
+ * null, and subview mode is not None, then the first call to
+ * set_subview_mode() will fail, and we will reset to None.
+ */
+
+ if (set_subview_mode (_subview_mode, first_selected_stripable())) {
+ set_subview_mode (None, boost::shared_ptr<Stripable>());
+ }
+
+ }
+}
+
+boost::shared_ptr<Stripable>
+MackieControlProtocol::first_selected_stripable () const
+{
+ boost::shared_ptr<Stripable> s = ControlProtocol::first_selected_stripable();
+
+ if (s) {
+ /* check it is on one of our surfaces */
+
+ if (is_mapped (s)) {
+ return s;
+ }
+
+ /* stripable is not mapped. thus, the currently selected stripable is
+ * not on the surfaces, and so from our perspective, there is
+ * no currently selected stripable.
+ */
+
+ s.reset ();
+ }
+
+ return s; /* may be null */
+}
+
+boost::shared_ptr<Stripable>
+MackieControlProtocol::subview_stripable () const
+{
+ return _subview_stripable;
+}
+
+uint32_t
+MackieControlProtocol::global_index (Strip& strip)
+{
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ return global_index_locked (strip);
+}
+
+uint32_t
+MackieControlProtocol::global_index_locked (Strip& strip)
+{
+ uint32_t global = 0;
+
+ for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ if ((*s).get() == strip.surface()) {
+ return global + strip.index();
+ }
+ global += (*s)->n_strips ();
+ }
+
+ return global;
+}
+
+void*
+MackieControlProtocol::request_factory (uint32_t num_requests)
+{
+ /* AbstractUI<T>::request_buffer_factory() is a template method only
+ instantiated in this source module. To provide something visible for
+ use in the interface/descriptor, we have this static method that is
+ template-free.
+ */
+ return request_buffer_factory (num_requests);
+}
+
+void
+MackieControlProtocol::set_automation_state (AutoState as)
+{
+ boost::shared_ptr<Stripable> r = first_selected_stripable ();
+
+ if (!r) {
+ return;
+ }
+
+ boost::shared_ptr<AutomationControl> ac = r->gain_control();
+
+ if (!ac) {
+ return;
+ }
+
+ ac->set_automation_state (as);
+}