ardour
io_selector.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2007 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <stdint.h>
21 
22 #include <glibmm/objectbase.h>
23 
24 #include <gtkmm2ext/doi.h>
25 
26 #include "ardour/audioengine.h"
27 #include "ardour/bundle.h"
28 #include "ardour/data_type.h"
29 #include "ardour/io.h"
30 #include "ardour/port.h"
31 #include "ardour/session.h"
32 
33 #include "io_selector.h"
34 #include "utils.h"
35 #include "gui_thread.h"
36 #include "i18n.h"
37 
38 using namespace ARDOUR;
39 using namespace ARDOUR_UI_UTILS;
40 using namespace Gtk;
41 
43  : PortMatrix (p, session, DataType::NIL)
44  , _io (io)
45 {
46  setup_type ();
47 
48  /* signal flow from 0 to 1 */
49 
50  _find_inputs_for_io_outputs = (_io->direction() == IO::Output);
51 
53  _other = 1;
54  _ours = 0;
55  } else {
56  _other = 0;
57  _ours = 1;
58  }
59 
60  _port_group.reset (new PortGroup (io->name()));
62 
63  io->changed.connect (_io_connection, invalidator (*this), boost::bind (&IOSelector::io_changed_proxy, this), gui_context ());
64 
65  setup_all_ports ();
66  init ();
67 }
68 
69 void
71 {
72  /* set type according to what's in the IO */
73 
74  int N = 0;
75  DataType type_with_ports = DataType::NIL;
76  for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) {
77  if (_io->ports().num_ports (*i)) {
78  type_with_ports = *i;
79  ++N;
80  }
81  }
82 
83  if (N <= 1) {
84  set_type (type_with_ports);
85  } else {
86  set_type (DataType::NIL);
87  }
88 }
89 
90 void
92 {
93  /* The IO's changed signal is emitted from code that holds its route's processor lock,
94  so we can't call setup_all_ports (which results in a call to Route::foreach_processor)
95  without a deadlock unless we break things up with this idle handler.
96  */
97 
98  Glib::signal_idle().connect_once (sigc::mem_fun (*this, &IOSelector::io_changed));
99 }
100 
101 void
103 {
104  setup_type ();
105  setup_all_ports ();
106 }
107 
108 void
110 {
111  if (!_session) {
112  return;
113  }
114 
115  _ports[dim].suspend_signals ();
116 
117  if (dim == _other) {
118 
120 
121  } else {
122 
123  _port_group->clear ();
125  }
126 
127  _ports[dim].resume_signals ();
128 }
129 
130 void
132 {
133  ARDOUR::Bundle::PortList const & our_ports = c[_ours].bundle->channel_ports (c[_ours].channel);
134  ARDOUR::Bundle::PortList const & other_ports = c[_other].bundle->channel_ports (c[_other].channel);
135 
136  for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
137  for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
138 
140  if (!f) {
141  return;
142  }
143 
144  if (s) {
145  if (!f->connected_to (*j)) {
146  _io->connect (f, *j, 0);
147  }
148  } else {
149  if (f->connected_to (*j)) {
150  _io->disconnect (f, *j, 0);
151  }
152  }
153  }
154  }
155 }
156 
159 {
160  if (c[0].bundle->nchannels() == ChanCount::ZERO || c[1].bundle->nchannels() == ChanCount::ZERO) {
162  }
163 
164  ARDOUR::Bundle::PortList const & our_ports = c[_ours].bundle->channel_ports (c[_ours].channel);
165  ARDOUR::Bundle::PortList const & other_ports = c[_other].bundle->channel_ports (c[_other].channel);
166 
167  if (!_session || our_ports.empty() || other_ports.empty()) {
168  /* we're looking at a bundle with no parts associated with this channel,
169  so nothing to connect */
171  }
172 
173  for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
174  for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
175 
177 
178  /* since we are talking about an IO, our ports should all have an associated Port *,
179  so the above call should never fail */
180  assert (f);
181 
182  if (!f->connected_to (*j)) {
183  /* if any one thing is not connected, all bets are off */
185  }
186  }
187  }
188 
190 }
191 
192 uint32_t
194 {
196  return _io->n_ports().get (_io->default_type());
197  } else {
198  return _io->n_ports().get (_io->default_type());
199  }
200 }
201 
202 bool
204 {
205  return (dim == _other);
206 }
207 
208 std::string
210 {
211  return _("Disconnect");
212 }
213 
214 std::string
216 {
217  return _("port");
218 }
219 
221  : ArdourWindow (_("I/O selector"))
222  , _selector (this, session, io)
223 {
224  set_name ("IOSelectorWindow2");
225 
226  add (_selector);
227 
228  io_name_changed (this);
229 
230  show_all ();
231 
232  signal_delete_event().connect (sigc::mem_fun (*this, &IOSelectorWindow::wm_delete));
233 }
234 
235 bool
236 IOSelectorWindow::wm_delete (GdkEventAny* /*event*/)
237 {
239  return false;
240 }
241 
242 
243 void
245 {
247  Window::on_map ();
248 }
249 
250 void
252 {
253  Gtk::Window::on_show ();
254  std::pair<uint32_t, uint32_t> const pm_max = _selector.max_size ();
255  resize_window_to_proportion_of_monitor (this, pm_max.first, pm_max.second);
256 }
257 
258 void
260 {
262 
263  std::string title;
264 
266  title = string_compose(_("%1 input"), _selector.io()->name());
267  } else {
268  title = string_compose(_("%1 output"), _selector.io()->name());
269  }
270 
271  set_title (title);
272 }
273 
void resize_window_to_proportion_of_monitor(Gtk::Window *, int, int)
Definition: utils.cc:831
void setup_all_ports()
Definition: port_matrix.cc:642
uint32_t n_io_ports() const
Definition: io_selector.cc:193
void suspend_signals()
Definition: port_group.cc:758
IOSelector _selector
Definition: io_selector.h:82
void resume_signals()
Definition: port_group.cc:764
the ports are not associated
bool connected_to(std::string const &) const
Definition: port.cc:147
void gather(ARDOUR::Session *, ARDOUR::DataType, bool, bool, bool)
Definition: port_group.cc:329
PortMatrixNode::State get_state(ARDOUR::BundleChannel c[2]) const
Definition: io_selector.cc:158
Definition: ardour_ui.h:130
std::vector< std::string > PortList
Definition: bundle.h:50
Direction direction() const
Definition: io.h:82
PortSet & ports()
Definition: io.h:117
static int N
Definition: signals_test.cc:27
void clear()
Definition: port_group.cc:160
tuple f
Definition: signals.py:35
void setup_type()
Definition: io_selector.cc:70
boost::shared_ptr< PortGroup > _port_group
Definition: io_selector.h:65
IOSelectorWindow(ARDOUR::Session *, boost::shared_ptr< ARDOUR::IO >, bool can_cancel=false)
Definition: io_selector.cc:220
void add_group(boost::shared_ptr< PortGroup >)
Definition: port_group.cc:718
#define ENSURE_GUI_THREAD(obj, method,...)
Definition: gui_thread.h:34
#define invalidator(x)
Definition: gui_thread.h:40
size_t num_ports() const
Definition: port_set.cc:123
the ports are associated
#define _(Text)
Definition: i18n.h:11
void io_name_changed(void *src)
Definition: io_selector.cc:259
void io_changed()
Definition: io_selector.cc:102
bool _find_inputs_for_io_outputs
Definition: io_selector.h:66
const ChanCount & n_ports() const
Definition: io.h:135
void add_bundle(boost::shared_ptr< ARDOUR::Bundle >, bool allow_dups=false)
Definition: port_group.cc:73
boost::shared_ptr< Bundle > bundle()
Definition: io.h:102
Definition: amp.h:29
DataType default_type() const
Definition: io.h:84
std::string channel_noun() const
Definition: io_selector.cc:215
#define gui_context()
Definition: gui_thread.h:36
bool find_inputs_for_io_outputs() const
Definition: io_selector.h:44
PBD::Signal2< void, IOChange, void * > changed
Definition: io.h:141
void set_type(ARDOUR::DataType)
Definition: port_matrix.cc:229
void set_state(ARDOUR::BundleChannel c[2], bool)
Definition: io_selector.cc:131
bool show_only_bundles() const
Definition: port_matrix.h:94
bool wm_delete(GdkEventAny *)
Definition: io_selector.cc:236
ARDOUR::DataType type() const
Definition: port_matrix.h:68
std::pair< uint32_t, uint32_t > max_size() const
Definition: port_matrix.cc:672
uint32_t get(DataType t) const
Definition: chan_count.h:59
int connect(boost::shared_ptr< Port > our_port, std::string other_port, void *src)
Definition: io.cc:224
boost::shared_ptr< Port > get_port_by_name(const std::string &)
boost::shared_ptr< Bundle > bundle
Definition: bundle.h:168
boost::shared_ptr< ARDOUR::IO > const io()
Definition: io_selector.h:40
std::string name() const
PBD::ScopedConnection _io_connection
Definition: io_selector.h:67
sigc::signal< void, Result > Finished
Definition: port_matrix.h:164
int disconnect(boost::shared_ptr< Port > our_port, std::string other_port, void *src)
void io_changed_proxy()
Definition: io_selector.cc:91
bool list_is_global(int) const
Definition: io_selector.cc:203
std::string disassociation_verb() const
Definition: io_selector.cc:209
ARDOUR::Session * _session
void setup_ports(int)
Definition: io_selector.cc:109
IOSelector(Gtk::Window *, ARDOUR::Session *, boost::shared_ptr< ARDOUR::IO >)
Definition: io_selector.cc:42
AudioEngine & engine()
Definition: session.h:546
void init()
Definition: port_matrix.cc:122
boost::shared_ptr< ARDOUR::IO > _io
Definition: io_selector.h:64
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
PortGroupList _ports[2]
Definition: port_matrix.h:176