Guitarix
gx_portmap.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3  * Copyright (C) 2011 Pete Shorthose
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  * ---------------------------------------------------------------------------
19  *
20  * gx_head portmap window
21  *
22  * ----------------------------------------------------------------------------
23  */
24 
25 #include "guitarix.h" // NOLINT
26 
27 #include <cstring> // NOLINT
28 #include <list> // NOLINT
29 #include <string> // NOLINT
30 
31 /****************************************************************
32  ** PortMapWindow
33  */
34 
35 namespace gx_portmap {
36 
37 static PortAttr gx_head_ports[] = {
38  // client_num, is_insert, port_name, is_input, port_type
39  { 0, false, "in_0", true, JACK_DEFAULT_AUDIO_TYPE },
40  { 1, false, "out_0", false, JACK_DEFAULT_AUDIO_TYPE },
41  { 1, false, "out_1", false, JACK_DEFAULT_AUDIO_TYPE },
42  { 0, false, "midi_in_1", true, JACK_DEFAULT_MIDI_TYPE },
43  { 0, false, "midi_out_1", false, JACK_DEFAULT_MIDI_TYPE },
44  { 1, true, "in_0", true, JACK_DEFAULT_AUDIO_TYPE },
45  { 0, true, "out_0", false, JACK_DEFAULT_AUDIO_TYPE },
46 };
47 
48 #define ALSA_PCM "alsa_pcm" // special alsa sequencer gxjack.client
49 #define ALSA_PCM_LEN_1 9
50 
51 /****************************************************************
52 ** ClientList
53 **
54 ** (helper to convert the jack port list into a sorted list with sub-lists)
55 */
56 
57 struct ClientPortList {
58  const char *client;
59  int len;
60  list<const char*> ports;
61  explicit ClientPortList(const char *p);
62  inline void add(const char *p) { ports.push_back(p); }
63  inline bool sameclient(const char *p) { return strncmp(client, p, len) == 0; }
64  string clientname() { return string(*ports.begin()).substr(0, len-1); }
65 };
66 
67 ClientPortList::ClientPortList(const char *p) {
68  client = p;
69  const char *q = strchr(p, ':');
70  if (q) {
71  len = (q - p) + 1;
72  if (strncmp(p, (ALSA_PCM ":"), ALSA_PCM_LEN_1) == 0) {
73  q = strchr(p+len, '/');
74  if (q) {
75  len = (q - p) + 1;
76  } else {
77  len = strlen(p);
78  }
79  }
80  } else { // should not happen
81  len = strlen(p);
82  }
83 }
84 
85 struct ClientList: list<ClientPortList*> {
86  static bool str_compare(const char *a, const char *b);
87  explicit ClientList(const char**);
88  ~ClientList();
89  void remove(string excl);
90 };
91 
92 bool ClientList::str_compare(const char *a, const char *b) {
93  return strcmp(b, a) > 0;
94 }
95 
96 ClientList::ClientList(const char **ports) {
97  list<const char*> l;
98  for (int i = 0; ports[i]; ++i) {
99  l.push_back(ports[i]);
100  }
101  l.sort(str_compare);
102  if (l.empty()) {
103  return;
104  }
105  ClientPortList *cp = new ClientPortList(*l.begin());
106  for (list<const char*>::iterator j = l.begin(); j != l.end(); ++j) {
107  if (!cp->sameclient(*j)) {
108  push_back(cp);
109  cp = new ClientPortList(*j);
110  }
111  cp->add(*j);
112  }
113  push_back(cp);
114 }
115 
117  for (list<ClientPortList*>::iterator i = begin(); i != end(); ++i) {
118  delete *i;
119  }
120 }
121 
122 void ClientList::remove(string excl) {
123  for (list<ClientPortList*>::iterator i = begin(); i != end();) {
124  if ((*i)->sameclient(excl.c_str())) {
125  list<ClientPortList*>::iterator n = i++;
126  delete *n;
127  erase(n);
128  break;
129  } else {
130  ++i;
131  }
132  }
133 }
134 
135 
136 /****************************************************************
137 ** PortMapWindow
138 */
139 
140 /*
141 ** port registration / removal
142 */
143 
144 static string client_from_port(const string& port) {
145  size_t pos = port.find_first_of(':');
146  if (pos == string::npos) {
147  return port;
148  }
149  string s = port.substr(0, pos);
150  if (s.compare(ALSA_PCM) != 0) {
151  return s;
152  }
153  size_t p2 = port.find_first_of('/', ALSA_PCM_LEN_1);
154  if (p2 == string::npos) {
155  return port;
156  }
157  return port.substr(0, p2);
158 }
159 
160 static bool compare_client(const string& name, const string& p) {
161  if (name.compare(0, name.size(), p, 0, name.size()) == 0) {
162  if (p[name.size()] == ':' || p.size() == name.size()) {
163  return true;
164  }
165  }
166  if (p.compare(0, ALSA_PCM_LEN_1, (ALSA_PCM ":"))) {
167  if (name.compare(0, name.size(), p, ALSA_PCM_LEN_1, name.size()) == 0) {
168  if (p[ALSA_PCM_LEN_1+name.size()] == '/' || p.size() == ALSA_PCM_LEN_1+name.size()) {
169  return true;
170  }
171  }
172  }
173  return false;
174 }
175 
176 static bool compare_port(const string& name, const char *p) {
177  return name.compare(p) == 0;
178 }
179 
180 bool PortMapWindow::walk_remove(Glib::RefPtr<Gtk::TreeStore> ts, bool (*compare) // NOLINT
181  (const string&, const char*), string data) {
182  bool changed = false;
183  Gtk::TreeIter i(ts->children().begin());
184  while (i) {
185  if ((*i)[columns.is_port]) {
186  if (data == (*i)[columns.port]) {
187  changed = true;
188  i = ts->erase(i);
189  continue;
190  }
191  } else {
192  Gtk::TreeIter j(i->children().begin());
193  while (j) {
194  if (data == (*j)[columns.port]) {
195  changed = true;
196  j = ts->erase(j);
197  continue;
198  }
199  ++j;
200  }
201  }
202  ++i;
203  }
204  return changed;
205 }
206 
207 void PortMapWindow::walk_insert(Glib::RefPtr<Gtk::TreeStore> ts, string name) {
208  // clients and ports on top level
209  for (Gtk::TreeIter i(ts->children().begin()); i; ++i) {
210  Glib::ustring p = (*i)[columns.port];
211  if (name == p) {
212  return;
213  }
214  if (!(*i)[columns.is_port] && compare_client(client_from_port(name), p)) {
215  // ports of a gxjack.client, 2nd level
216  for (Gtk::TreeIter j(i->children().begin()); j; ++j) {
217  // if we already have the port get out
218  if (name == (*j)[columns.port]) {
219  return;
220  }
221  }
222  Gtk::TreeRow row = *ts->append(i->children());
223  row[columns.port] = name;
224  row[columns.connected] = false;
225  row[columns.is_port] = true;
226  return;
227  }
228  }
229  Gtk::TreeRow row = *ts->append();
230  row[columns.port] = name;
231  row[columns.connected] = false;
232  row[columns.is_port] = true;
233 }
234 
235 void PortMapWindow::port_changed(string name, const char *tp, int flags, bool reg) {
236  if (reg == 0) {
237  for (int i = 0; i < number_of_ports; ++i) {
238  PortSection& p = portsection[i];
239  if (walk_remove(p.treestore, compare_port, name)) {
240  update_summary(p);
241  }
242  }
243  } else {
244  for (list<string>::iterator j = excluded_clients.begin();
245  j != excluded_clients.end(); ++j) {
246  if (name.compare(0, j->size(), *j) == 0) {
247  return;
248  }
249  }
250  for (int i = 0; i < number_of_ports; ++i) {
251  PortSection *p = &portsection[i];
252  if (strcmp(p->port_attr->port_type, tp) != 0) {
253  continue;
254  }
255  if (p->port_attr->is_input) {
256  if (!(flags & JackPortIsOutput)) {
257  continue;
258  }
259  } else {
260  if (!(flags & JackPortIsInput)) {
261  continue;
262  }
263  }
264  walk_insert(p->treestore, name);
265  }
266  }
267 }
268 
269 
270 /*
271 ** port connection change
272 */
273 
274 list<string> PortMapWindow::walk(Glib::RefPtr<Gtk::TreeStore> ts, string *port, int connect) {
275  list<string> l;
276  for (Gtk::TreeIter i(ts->children().begin()); i; ++i) {
277  Glib::ustring p = (*i)[columns.port];
278  bool is_connected = (*i)[columns.connected];
279  if ((*i)[columns.is_port]) {
280  if (port && port->compare(p) == 0) {
281  is_connected = connect;
282  (*i)[columns.connected] = connect;
283  }
284  if (is_connected) {
285  l.push_back(p);
286  }
287  } else {
288  for (Gtk::TreeIter j(i->children().begin()); j; ++j) {
289  Glib::ustring p = (*j)[columns.port];
290  bool is_connected = (*j)[columns.connected];
291  if (port && port->compare(p) == 0) {
292  is_connected = connect;
293  (*j)[columns.connected] = connect;
294  }
295  if (is_connected) {
296  l.push_back(p);
297  }
298  }
299  }
300  }
301  return l;
302 }
303 
304 void PortMapWindow::update_summary(PortSection& p, string *port, bool conn) {
305  list<string> l = walk(p.treestore, port, conn);
306  if (!p.expander) {
307  return;
308  }
309  string q;
310  list<string>::iterator i = l.begin();
311  if (i != l.end()) {
312  q = *i++;
313  }
314  for (; i != l.end(); ++i) {
315  q += "\n" + *i;
316  }
317  p.label->set_text(q);
318  Glib::signal_idle().connect_once(
319  sigc::bind(
320  sigc::mem_fun(*this, &PortMapWindow::redraw_expander), p.expander));
321 }
322 
323 void PortMapWindow::connection_changed(string port1, string port2, bool conn) {
324  for (int i = 0; i < number_of_ports; ++i) {
325  PortSection& p = portsection[i];
326 
327  string s = (p.port_attr->client_num == 0 ?
328  jack.client_name : jack.client_insert_name)
329  + ":" + p.port_attr->port_name;
330  if (s.compare(port1) == 0) {
331  update_summary(p, &port2, conn);
332  } else if (s.compare(port2) == 0) {
333  update_summary(p, &port1, conn);
334  }
335  }
336 }
337 
338 
339 /*
340 ** gtk callback functions
341 */
342 
343 void PortMapWindow::on_check_resize() {
344  // cf. comment at the end of on_expander()
345  if (monitored_expander_child &&
346  !monitored_expander_child->get_child_visible()) {
347  monitored_expander_child = 0;
348  int x, y, width, height, depth;
349  window->get_window()->get_geometry(x, y, width, height, depth);
350  window->resize(width, 1);
351  }
352 }
353 
354 void PortMapWindow::on_expander(Gtk::Expander& expander) {
355  gboolean expanded = expander.get_expanded();
356  if (expanded) {
357  // close all other expanders and unset their expand child property
358  for (int i = 0; i < number_of_ports; ++i) {
359  Gtk::Expander *w = portsection[i].expander;
360  if (&expander != w) {
361  /*
362  GValue v = {0};
363  g_value_init(&v, G_TYPE_BOOLEAN);
364  g_value_set_boolean(&v, FALSE);
365  w->get_parent()->child_set_property(w, "expand", &v);
366  */
367  w->set_expanded(false);
368  }
369  }
370  }
371  // set the expand child property of the current expander if its expanded
372  /*
373  GValue value = {0};
374  g_value_init(&value, G_TYPE_BOOLEAN);
375  g_value_set_boolean(&value, expanded);
376  expander.get_parent().child_set_property(expander, "expand", &value);
377  */
378  expander.set_expanded(expanded);
379  if (!expanded) {
380  // when the expander is explicitely closed (so all expanders are
381  // closed now) we want to shrink the portmap window with
382  // gtk_window_resize().
383  // But GtkExpander uses a timer before the child is made
384  // unvisible and a resize of the window is triggered.
385  // So we defer resizing to the "check-resize"-signal handler
386  monitored_expander_child = expander.get_child();
387  }
388 }
389 
390 void PortMapWindow::redraw_expander(Gtk::Expander* ex) {
391  ex->queue_draw();
392 }
393 
394 void PortMapWindow::on_cell_toggle(Glib::ustring path, PortSection& p) {
395  Gtk::TreeIter iter(p.treestore->get_iter(path));
396  Glib::ustring q1 = (*iter)[columns.port];
397  bool v = (*iter)[columns.connected];
398  string gcln;
399  jack_client_t *gcl;
400  if (p.port_attr->client_num == 0) {
401  gcl = jack.client;
402  gcln = jack.client_name;
403  } else {
404  gcl = jack.client_insert;
405  gcln = jack.client_insert_name;
406  }
407  Glib::ustring q2(gcln + ":" + p.port_attr->port_name);
408  if (!p.port_attr->is_input) {
409  Glib::ustring sw = q1;
410  q1 = q2;
411  q2 = sw;
412  }
413 
414  v = !v;
415  int ret;
416 
417  if (v) {
418  ret = jack_connect(gcl, q1.c_str(), q2.c_str());
419  } else {
420  ret = jack_disconnect(gcl, q1.c_str(), q2.c_str());
421  }
422 
423  if (ret != 0) {
424  ostringstream buf;
425  buf << "couldn't " << (v ? "" : "dis") << "connect " << q2 << " -> " << q1;
426  gx_print_error("port connection", buf.str());
427  return;
428  }
429  (*iter)[columns.connected] = v;
430  update_summary(p);
431 }
432 
433 /*
434 ** constuctor / destructor
435 */
436 
437 inline bool getnumber(const Glib::ustring& p, long *pi) { // NOLINT
438  char *q;
439  *pi = strtol(p.c_str(), &q, 10);
440  return !*q;
441 }
442 
443 int PortMapWindow::sort_func(const Gtk::TreeModel::iterator& a, const Gtk::TreeModel::iterator& b) {
444  Glib::ustring pa((*a)[columns.port]), pb((*b)[columns.port]);
445  int i = 0;
446  for (; ; ++i) {
447  if (pa[i] != pb[i]) {
448  break;
449  }
450  if (!pa[i]) {
451  return 0;
452  }
453  }
454  long ia = 0, ib = 0; // initialize to silence compiler warning...
455  if (getnumber(pa.substr(i), &ia) && getnumber(pb.substr(i), &ib)) {
456  return ia - ib;
457  }
458  return pa.compare(pb);
459 }
460 
461 void PortMapWindow::load(int sect, jack_port_t *jack_port) {
462  if (jack.client) {
463  const unsigned int max_items_unfolded = 1;
464  PortSection& ps = portsection[sect];
465  Glib::RefPtr<Gtk::TreeStore> tree = ps.treestore;
466  assert(tree);
467  tree->set_sort_func(0, sigc::mem_fun(*this, &PortMapWindow::sort_func));
468  tree->set_sort_column_id(0, Gtk::SORT_ASCENDING);
469  tree->clear();
470  const char **ports;
471 
472  jack_client_t *gcl = (ps.port_attr->client_num == 0 ? jack.client
473  : jack.client_insert);
474  if (jack.single_client) {
475  gcl = jack.client;
476  }
477 
478  ports = jack_get_ports(gcl, NULL, ps.port_attr->port_type,
479  (ps.port_attr->is_input ? JackPortIsOutput : JackPortIsInput));
480  if (!ports) {
481  return;
482  }
483  const char** conn_ports = jack_port_get_connections(jack_port);
484  ClientList cl(ports);
485  // the following loop depends on the first 2 entries being
486  // gxjack.client_name and gxjack.client_insert_name
487  int idx = 0;
488  for (list<string>::iterator j = excluded_clients.begin(); j !=
489  excluded_clients.end(); ++j, idx++) {
490  if (!ps.port_attr->is_insert || ps.port_attr->client_num != idx) {
491  cl.remove(*j);
492  }
493  }
494  Gtk::TreeIter iter, parent, *parentp;
495  for (ClientList::iterator i = cl.begin(); i != cl.end(); ++i) {
496  ClientPortList *p = *i;
497  if (cl.size() > 1 && p->ports.size() > max_items_unfolded) {
498  parent = tree->append();
499  (*parent)[columns.port] = p->clientname();
500  (*parent)[columns.connected] = false;
501  (*parent)[columns.is_port] = false;
502  parentp = &parent;
503  } else {
504  parentp = 0;
505  }
506  //printf("Client: %s\n", p->clientname().c_str());
507  for (list<const char*>::iterator j = p->ports.begin(); j != p->ports.end(); ++j) {
508  //printf("Port: %s\n", *j);
509  bool conn = false;
510  if (conn_ports) {
511  for (const char** q = conn_ports; *q; q++) {
512  if (strcmp(*q, *j) == 0) {
513  conn = true;
514  break;
515  }
516  }
517  }
518  if (parentp) {
519  iter = tree->append((*parentp)->children());
520  } else {
521  iter = tree->append();
522  }
523  (*iter)[columns.port] = *j;
524  (*iter)[columns.connected] = conn;
525  (*iter)[columns.is_port] = true;
526  }
527  }
528  free(conn_ports);
529  free(ports);
530  update_summary(portsection[sect]);
531  }
532 }
533 
534 void PortMapWindow::load_all() {
535 #define uslp() usleep(10); // prevents xruns?? (bug in jackd?)
536  load(0, jack.ports.input.port);
537  uslp();
538  load(1, jack.ports.output1.port);
539  uslp();
540  load(2, jack.ports.output2.port);
541  uslp();
542  load(3, jack.ports.midi_input.port);
543  uslp();
544 #if defined(USE_MIDI_OUT) || defined(USE_MIDI_CC_OUT)
545  load(4, jack.ports.midi_output.port);
546  uslp();
547 #endif
548  if (!jack.single_client) {
549  load(5, jack.ports.insert_in.port);
550  uslp();
551  load(6, jack.ports.insert_out.port);
552  }
553 #undef uslp
554 }
555 
556 PortMapWindow* PortMapWindow::create(gx_engine::GxMachineBase& machine, Glib::RefPtr<Gtk::AccelGroup> ag) {
557  gx_jack::GxJack *jack = machine.get_jack();
558  if (!jack) {
559  return 0;
560  }
561  Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(
562  gx_system::get_options().get_builder_filepath("ports.glade"), &machine);
563  return new PortMapWindow(bld, *jack, ag);
564 }
565 
566 PortMapWindow::PortMapWindow(Glib::RefPtr<gx_gui::GxBuilder> bld, gx_jack::GxJack& jack_, Glib::RefPtr<Gtk::AccelGroup> ag)
567  : portsection(),
568  excluded_clients(),
569  jack(jack_),
570  monitored_expander_child(0) {
571  bld->get_toplevel("PortMapWindow", window);
572  monitored_expander_child = 0;
573 
574  // order of first 2 entries is important (check load())
575  excluded_clients.push_back(string(jack.client_insert_name) + ":");
576  excluded_clients.push_back(string(jack.client_name) + ":");
577  excluded_clients.push_back(string(jack.get_instancename()) + "_meterbridge:");
578  excluded_clients.push_back(string("jack_capture:"));
579 
580  // no need to set, its transient window
581  //window->set_icon(Glib::wrap(GDK_PIXBUF(gx_gui::gw.ib),true));
582  Gtk::Widget *b;
583  bld->find_widget("button1",b);
584  assert(b);
585  b->set_name("rack_button");
586  //Gtk::VBox *vbox1;
587  //bld->find_widget("dialog-vbox1", vbox1);
588  //g_signal_connect(GTK_WIDGET(vbox1->gobj()), "expose-event",
589  //G_CALLBACK(gx_cairo::rectangle_skin_color_expose), NULL);
590  // vbox1->signal_expose_event().connect(
591  //sigc::group(&gx_cairo::rectangle_skin_color_expose,GTK_WIDGET(vbox1->gobj()),sigc::_1,(void*)0),false);
592  //Gtk::VBox *vbox2;
593  //bld->find_widget("dialog-vbox2", vbox2);
594  //g_signal_connect(GTK_WIDGET(vbox2->gobj()), "expose-event",
595  //G_CALLBACK(gx_cairo::rectangle_skin_color_expose), NULL);
596  // vbox2->signal_expose_event().connect(
597 // sigc::group(&gx_cairo::rectangle_skin_color_expose,GTK_WIDGET(vbox2->gobj()),sigc::_1,(void*)0),false);
598  //vbox1->set_redraw_on_allocate(true);
599  //vbox2->set_redraw_on_allocate(true);
600  for (int i = 0; i < number_of_ports; ++i) {
601  portsection[i].port_attr = &gx_head_ports[i];
602  char name[30];
603  snprintf(name, sizeof(name), "scrolledwindow%d", i+1);
604  bld->find_widget(name, portsection[i].scrolled_window);
605  snprintf(name, sizeof(name), "treeview%d", i+1);
606  Gtk::TreeView *view;
607  bld->find_widget(name, view);
608  Gtk::TreeViewColumn *col = view->get_column(0);
609  // get_first_cell_renderer is decprecated, but only available after gtkmm 2.20
610  // --> we can also use view->get_column_cell_renderer(0) instead
611  //Gtk::CellRendererToggle *cell = dynamic_cast<Gtk::CellRendererToggle*>(col->get_first_cell());
612  Gtk::CellRendererToggle *cell = dynamic_cast<Gtk::CellRendererToggle*>(col->get_first_cell_renderer());
613  //Gtk::CellRendererToggle *cell = dynamic_cast<Gtk::CellRendererToggle*>(view->get_column_cell_renderer(0));
614  portsection[i].treestore = Gtk::TreeStore::create(columns);
615  view->set_model(portsection[i].treestore);
616  //snprintf(name, sizeof(name), "treestore%d", i+1);
617  //bld->find_widget(name, portsection[i].treestore);
618  //snprintf(name, sizeof(name), "cellrenderertoggle%d", i+1);
619  //Gtk::CellRendererToggle *tg;
620  //bld->find_widget(name, tg);
621  cell->signal_toggled().connect(
622  sigc::bind(
623  sigc::mem_fun(*this, &PortMapWindow::on_cell_toggle),
624  sigc::ref(portsection[i])));
625  snprintf(name, sizeof(name), "expander%d", i+1);
626  //bld->find_widget(name, portsection[i].expander);
627  if (portsection[i].expander) {
628  portsection[i].expander->property_expanded().signal_changed().connect(
629  sigc::bind(
630  sigc::mem_fun(*this, &PortMapWindow::on_expander),
631  sigc::ref(*portsection[i].expander)));
632  snprintf(name, sizeof(name), "port%d", i+1);
633  bld->find_widget(name, portsection[i].label);
634  }
635  }
636 
637  load_all();
638 
639  window->add_accel_group(ag);
640  window->signal_check_resize().connect(sigc::mem_fun(*this, &PortMapWindow::on_check_resize),true);
641  window->show();
642  Gtk::Notebook *n;
643  bld->find_widget("notebook1",n);
644  Gtk::Widget *t;
645  t = n->get_nth_page(1);
646  if (jack.single_client) t->hide();
647  jack.signal_portchange().connect(sigc::mem_fun(*this, &PortMapWindow::refresh));
648  jack.signal_connection_changed().connect(sigc::mem_fun(*this, &PortMapWindow::connection_changed));
649  jack.send_connection_changes(true);
650 }
651 
652 // refresh portmap widget when connect/disconnect with jack server
653 void PortMapWindow::refresh() {
654  if (!jack.client) {
655  for (int i = 0; i< number_of_ports; ++i) {
656  PortSection& ps = portsection[i];
657  Glib::RefPtr<Gtk::TreeStore> tree = ps.treestore;
658  assert(tree);
659  tree->set_sort_func(0, sigc::mem_fun(*this, &PortMapWindow::sort_func));
660  tree->set_sort_column_id(0, Gtk::SORT_ASCENDING);
661  tree->clear();
662  update_summary(portsection[i]);
663  }
664  } else {
665  load_all();
666  }
667 }
668 
670  jack.send_connection_changes(false);
671  delete window;
672 }
673 
674 } // namespace gui
gx_portmap::PortMapWindow::~PortMapWindow
~PortMapWindow()
Definition: gx_portmap.cpp:671
gx_portmap::PortAttr::client_num
const int client_num
Definition: gx_portmap.h:45
uslp
#define uslp()
gx_portmap::PortSection::treestore
Glib::RefPtr< Gtk::TreeStore > treestore
Definition: gx_portmap.h:51
gx_portmap::ClientPortList::len
int len
Definition: gx_portmap.cpp:65
gx_portmap::PortAttr::port_name
const char * port_name
Definition: gx_portmap.h:47
gx_jack::GxJack::client
jack_client_t * client
Definition: gx_jack.h:171
gx_jack::GxJack::signal_connection_changed
sigc::signal< void, string, string, bool > & signal_connection_changed()
Definition: gx_jack.h:212
gx_portmap::ClientList::remove
void remove(string excl)
Definition: gx_portmap.cpp:124
gx_portmap::ClientList::ClientList
ClientList(const char **)
Definition: gx_portmap.cpp:98
gx_engine::GxMachineBase
Definition: machine.h:53
gx_jack::GxJack::ports
JackPorts ports
Definition: gx_jack.h:169
gx_jack::JackPorts::insert_out
PortConnection insert_out
Definition: gx_jack.h:86
gx_portmap::PortSection
Definition: gx_portmap.h:50
gx_portmap::ClientPortList::sameclient
bool sameclient(const char *p)
Definition: gx_portmap.cpp:69
gx_portmap::getnumber
bool getnumber(const Glib::ustring &p, long *pi)
Definition: gx_portmap.cpp:439
gx_jack::GxJack::client_insert_name
string client_insert_name
Definition: gx_jack.h:204
gx_portmap::ClientList::str_compare
static bool str_compare(const char *a, const char *b)
Definition: gx_portmap.cpp:94
gx_jack::JackPorts::midi_output
PortConnection midi_output
Definition: gx_jack.h:87
gx_jack::JackPorts::output1
PortConnection output1
Definition: gx_jack.h:89
gx_portmap::ClientPortList::ClientPortList
ClientPortList(const char *p)
Definition: gx_portmap.cpp:69
gx_system::get_options
BasicOptions & get_options()
Definition: gx_system.h:515
gx_portmap::ClientList::~ClientList
~ClientList()
Definition: gx_portmap.cpp:118
gx_jack::PortConnection::port
jack_port_t * port
Definition: gx_jack.h:80
gx_portmap::PortSection::expander
Gtk::Expander * expander
Definition: gx_portmap.h:53
gx_jack::JackPorts::output2
PortConnection output2
Definition: gx_jack.h:90
gx_portmap::ClientPortList::clientname
string clientname()
Definition: gx_portmap.cpp:70
gx_jack::GxJack
Definition: gx_jack.h:111
gx_portmap::PortMapWindow
Definition: gx_portmap.h:58
gx_jack::GxJack::send_connection_changes
void send_connection_changes(bool v)
Definition: gx_jack.h:215
gx_jack::JackPorts::input
PortConnection input
Definition: gx_jack.h:84
gx_portmap::PortMapWindow::create
static PortMapWindow * create(gx_engine::GxMachineBase &machine, Glib::RefPtr< Gtk::AccelGroup > ag)
Definition: gx_portmap.cpp:558
gx_print_error
void gx_print_error(const char *, const std::string &)
Definition: gx_logging.cpp:166
gx_jack::JackPorts::insert_in
PortConnection insert_in
Definition: gx_jack.h:88
gx_portmap::PortMapWindow::refresh
void refresh()
Definition: gx_portmap.cpp:655
gx_portmap::ClientPortList::client
const char * client
Definition: gx_portmap.cpp:64
gx_portmap::PortMapWindow::connection_changed
void connection_changed(string port1, string port2, bool conn)
Definition: gx_portmap.cpp:325
gx_jack::GxJack::get_instancename
const string & get_instancename()
Definition: gx_jack.h:202
gx_jack::GxJack::client_name
string client_name
Definition: gx_jack.h:203
gx_jack::JackPorts::midi_input
PortConnection midi_input
Definition: gx_jack.h:85
gx_engine::GxMachineBase::get_jack
virtual gx_jack::GxJack * get_jack()=0
end
CmdConnection::msg_type end
Definition: jsonrpc.cpp:258
gx_jack::GxJack::client_insert
jack_client_t * client_insert
Definition: gx_jack.h:172
gx_jack::GxJack::signal_portchange
Glib::Dispatcher & signal_portchange()
Definition: gx_jack.h:213
gx_portmap::ClientPortList::add
void add(const char *p)
Definition: gx_portmap.cpp:68
gx_portmap::ClientPortList::ports
list< const char * > ports
Definition: gx_portmap.cpp:66
gx_portmap
Definition: gx_portmap.h:36
guitarix.h
ALSA_PCM_LEN_1
#define ALSA_PCM_LEN_1
Definition: gx_portmap.cpp:51
ALSA_PCM
#define ALSA_PCM
Definition: gx_portmap.cpp:50
gx_portmap::PortSection::port_attr
PortAttr * port_attr
Definition: gx_portmap.h:55