2007-02-07 07:57:53 +02:00
|
|
|
/* This file is part of Patchage.
|
|
|
|
* Copyright (C) 2007 Dave Robillard <http://drobilla.net>
|
2008-06-15 11:50:12 +03:00
|
|
|
* Copyright (C) 2008 Nedko Arnaudov <nedko@arnaudov.name>
|
2006-06-09 05:18:57 +03:00
|
|
|
*
|
2006-10-02 23:56:28 +03:00
|
|
|
* Patchage is free software; you can redistribute it and/or modify it under the
|
2006-06-09 05:18:57 +03:00
|
|
|
* terms of the GNU General Public License as published by the Free Software
|
|
|
|
* Foundation; either version 2 of the License, or (at your option) any later
|
|
|
|
* version.
|
|
|
|
*
|
2006-10-02 23:56:28 +03:00
|
|
|
* Patchage is distributed in the hope that it will be useful, but WITHOUT ANY
|
2006-06-09 05:18:57 +03:00
|
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
2007-04-06 07:29:27 +03:00
|
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2006-06-09 05:18:57 +03:00
|
|
|
*/
|
|
|
|
|
2008-07-16 10:14:15 +03:00
|
|
|
#include <string.h>
|
2007-01-01 08:30:55 +02:00
|
|
|
#include <cmath>
|
2007-01-14 06:55:22 +02:00
|
|
|
#include <sstream>
|
2006-06-09 05:18:57 +03:00
|
|
|
#include <fstream>
|
2007-12-20 01:24:51 +02:00
|
|
|
#include <libgnomecanvasmm.h>
|
|
|
|
#include <libglademm/xml.h>
|
2008-01-06 04:49:24 +02:00
|
|
|
#include <gtk/gtkwindow.h>
|
2008-06-12 01:34:07 +03:00
|
|
|
#include <boost/format.hpp>
|
2007-12-20 01:24:51 +02:00
|
|
|
|
2008-10-03 04:10:58 +03:00
|
|
|
#include "config.h"
|
2008-07-03 23:27:11 +03:00
|
|
|
#include "common.hpp"
|
2008-06-18 04:05:03 +03:00
|
|
|
#include "jack_proxy.hpp"
|
2007-07-24 22:26:47 +03:00
|
|
|
#include "Patchage.hpp"
|
2007-12-20 02:52:10 +02:00
|
|
|
#include "PatchageCanvas.hpp"
|
2007-07-24 22:26:47 +03:00
|
|
|
#include "StateManager.hpp"
|
2008-06-13 03:30:22 +03:00
|
|
|
#include "lash_proxy.hpp"
|
2008-06-15 11:50:12 +03:00
|
|
|
#include "project_list.hpp"
|
2008-07-03 22:55:43 +03:00
|
|
|
#include "session.hpp"
|
2008-07-04 22:47:59 +03:00
|
|
|
#include "globals.hpp"
|
2008-08-02 12:54:14 +03:00
|
|
|
#include "a2j_proxy.hpp"
|
2008-08-02 15:31:43 +03:00
|
|
|
#include "PatchageModule.hpp"
|
2008-09-08 05:47:27 +03:00
|
|
|
#include "dbus_helpers.h"
|
2008-10-19 06:35:19 +03:00
|
|
|
#include "load_projects_dialog.hpp"
|
2006-06-09 05:18:57 +03:00
|
|
|
|
2008-07-04 23:36:25 +03:00
|
|
|
Patchage * g_app;
|
|
|
|
|
2008-06-12 22:36:28 +03:00
|
|
|
//#define LOG_TO_STD
|
|
|
|
#define LOG_TO_STATUS
|
|
|
|
|
2007-12-20 01:46:11 +02:00
|
|
|
using namespace std;
|
|
|
|
|
2007-01-01 08:30:55 +02:00
|
|
|
/* Gtk helpers (resize combo boxes) */
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtkmm_get_ink_pixel_size (Glib::RefPtr<Pango::Layout> layout,
|
|
|
|
int& width,
|
|
|
|
int& height)
|
|
|
|
{
|
|
|
|
Pango::Rectangle ink_rect = layout->get_ink_extents ();
|
|
|
|
|
|
|
|
width = (ink_rect.get_width() + PANGO_SCALE / 2) / PANGO_SCALE;
|
|
|
|
height = (ink_rect.get_height() + PANGO_SCALE / 2) / PANGO_SCALE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtkmm_set_width_for_given_text (Gtk::Widget &w, const gchar *text,
|
|
|
|
gint hpadding/*, gint vpadding*/)
|
|
|
|
|
|
|
|
{
|
|
|
|
int old_width, old_height;
|
|
|
|
w.get_size_request(old_width, old_height);
|
|
|
|
|
|
|
|
int width, height;
|
|
|
|
w.ensure_style ();
|
|
|
|
|
|
|
|
gtkmm_get_ink_pixel_size (w.create_pango_layout (text), width, height);
|
|
|
|
w.set_size_request(width + hpadding, old_height);//height + vpadding);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* end Gtk helpers */
|
|
|
|
|
|
|
|
|
2008-07-04 22:47:59 +03:00
|
|
|
#define INIT_WIDGET(x) x(g_xml, ((const char*)#x) + 1)
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2006-06-09 05:18:57 +03:00
|
|
|
Patchage::Patchage(int argc, char** argv)
|
2008-09-08 05:47:27 +03:00
|
|
|
: _max_dsp_load(0.0)
|
2007-12-20 04:04:55 +02:00
|
|
|
, INIT_WIDGET(_about_win)
|
|
|
|
, INIT_WIDGET(_buffer_size_combo)
|
|
|
|
, INIT_WIDGET(_clear_load_but)
|
|
|
|
, INIT_WIDGET(_main_scrolledwin)
|
|
|
|
, INIT_WIDGET(_main_win)
|
|
|
|
, INIT_WIDGET(_main_xrun_progress)
|
2008-09-13 12:20:38 +03:00
|
|
|
, INIT_WIDGET(_main_a2j_status_label)
|
|
|
|
, INIT_WIDGET(_main_lash_status_label)
|
2007-12-20 04:04:55 +02:00
|
|
|
, INIT_WIDGET(_menu_file_quit)
|
|
|
|
, INIT_WIDGET(_menu_help_about)
|
2008-06-11 23:53:35 +03:00
|
|
|
, INIT_WIDGET(_menu_jack_start)
|
|
|
|
, INIT_WIDGET(_menu_jack_stop)
|
2008-09-13 15:26:22 +03:00
|
|
|
, INIT_WIDGET(_menu_a2j_start)
|
|
|
|
, INIT_WIDGET(_menu_a2j_stop)
|
2008-09-13 22:12:40 +03:00
|
|
|
, INIT_WIDGET(_menu_lash_activate)
|
|
|
|
, INIT_WIDGET(_menu_lash_deactivate)
|
2008-09-08 05:47:27 +03:00
|
|
|
, INIT_WIDGET(_menu_load_project)
|
|
|
|
, INIT_WIDGET(_menu_save_all_projects)
|
|
|
|
, INIT_WIDGET(_menu_close_all_projects)
|
2007-12-20 04:04:55 +02:00
|
|
|
, INIT_WIDGET(_menu_store_positions)
|
|
|
|
, INIT_WIDGET(_menu_view_arrange)
|
|
|
|
, INIT_WIDGET(_menu_view_messages)
|
2008-08-22 06:26:33 +03:00
|
|
|
, INIT_WIDGET(_menu_view_projects)
|
2007-12-20 04:04:55 +02:00
|
|
|
, INIT_WIDGET(_menu_view_refresh)
|
|
|
|
, INIT_WIDGET(_menu_view_toolbar)
|
2008-01-06 00:50:01 +02:00
|
|
|
, INIT_WIDGET(_messages_clear_but)
|
|
|
|
, INIT_WIDGET(_messages_close_but)
|
2008-08-22 06:26:33 +03:00
|
|
|
, INIT_WIDGET(_messages_win)
|
|
|
|
, INIT_WIDGET(_project_list_viewport)
|
2007-12-20 04:04:55 +02:00
|
|
|
, INIT_WIDGET(_sample_rate_label)
|
|
|
|
, INIT_WIDGET(_status_text)
|
|
|
|
, INIT_WIDGET(_toolbar)
|
|
|
|
, INIT_WIDGET(_zoom_full_but)
|
|
|
|
, INIT_WIDGET(_zoom_normal_but)
|
2006-06-09 05:18:57 +03:00
|
|
|
{
|
2008-07-04 23:36:25 +03:00
|
|
|
g_app = this;
|
|
|
|
|
2007-02-07 05:22:42 +02:00
|
|
|
_settings_filename = getenv("HOME");
|
2008-10-28 00:05:01 +02:00
|
|
|
_settings_filename += "/." PATCHAGE_APPNAME "rc";
|
2007-02-07 05:22:42 +02:00
|
|
|
_state_manager = new StateManager();
|
2007-06-06 05:51:08 +03:00
|
|
|
_canvas = boost::shared_ptr<PatchageCanvas>(new PatchageCanvas(this, 1600*2, 1200*2));
|
2007-12-20 04:04:55 +02:00
|
|
|
|
2008-02-17 19:17:10 +02:00
|
|
|
while (argc > 0) {
|
|
|
|
if (!strcmp(*argv, "--help")) {
|
|
|
|
cout << "Usage: patchage [OPTIONS]\nOptions: --no-alsa" << endl;
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
argv++;
|
|
|
|
argc--;
|
|
|
|
}
|
|
|
|
|
2008-09-08 05:47:27 +03:00
|
|
|
patchage_dbus_init();
|
2008-06-13 01:08:44 +03:00
|
|
|
|
2008-01-06 04:23:58 +02:00
|
|
|
Glib::set_application_name("Patchage");
|
2007-12-20 04:04:55 +02:00
|
|
|
_about_win->property_program_name() = "Patchage";
|
2008-10-28 00:05:01 +02:00
|
|
|
_about_win->property_logo_icon_name() = PATCHAGE_APPNAME;
|
|
|
|
gtk_window_set_default_icon_name(PATCHAGE_APPNAME);
|
2006-06-09 05:18:57 +03:00
|
|
|
|
2007-04-06 06:10:35 +03:00
|
|
|
gtkmm_set_width_for_given_text(*_buffer_size_combo, "4096 frames", 40);
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2007-12-20 04:04:55 +02:00
|
|
|
_main_scrolledwin->add(*_canvas);
|
2007-02-07 05:22:42 +02:00
|
|
|
_canvas->scroll_to(static_cast<int>(_canvas->width()/2 - 320),
|
2007-12-20 01:46:11 +02:00
|
|
|
static_cast<int>(_canvas->height()/2 - 240)); // FIXME: hardcoded
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2008-01-02 19:53:38 +02:00
|
|
|
_main_scrolledwin->property_hadjustment().get_value()->set_step_increment(10);
|
|
|
|
_main_scrolledwin->property_vadjustment().get_value()->set_step_increment(10);
|
|
|
|
|
2008-06-09 18:54:13 +03:00
|
|
|
_main_scrolledwin->signal_scroll_event().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::on_scroll));
|
|
|
|
|
2007-12-20 01:46:11 +02:00
|
|
|
_buffer_size_combo->signal_changed().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::buffer_size_changed));
|
2007-12-20 04:04:55 +02:00
|
|
|
_clear_load_but->signal_clicked().connect(
|
2007-12-20 01:46:11 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::clear_load));
|
2007-12-20 04:04:55 +02:00
|
|
|
_zoom_normal_but->signal_clicked().connect(sigc::bind(
|
2007-12-20 01:46:11 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::zoom), 1.0));
|
2007-12-20 04:04:55 +02:00
|
|
|
_zoom_full_but->signal_clicked().connect(
|
2007-12-20 01:46:11 +02:00
|
|
|
sigc::mem_fun(_canvas.get(), &PatchageCanvas::zoom_full));
|
2006-10-02 23:56:28 +03:00
|
|
|
|
2008-09-08 05:47:27 +03:00
|
|
|
_menu_load_project->signal_activate().connect(
|
2008-06-18 22:54:06 +03:00
|
|
|
sigc::mem_fun(this, &Patchage::load_project_ask));
|
2008-09-08 05:47:27 +03:00
|
|
|
_menu_save_all_projects->signal_activate().connect(
|
2008-06-18 22:54:06 +03:00
|
|
|
sigc::mem_fun(this, &Patchage::save_all_projects));
|
2008-09-08 05:47:27 +03:00
|
|
|
_menu_close_all_projects->signal_activate().connect(
|
2008-06-18 22:54:06 +03:00
|
|
|
sigc::mem_fun(this, &Patchage::close_all_projects));
|
2007-12-20 01:46:11 +02:00
|
|
|
|
|
|
|
_menu_store_positions->signal_activate().connect(
|
2007-12-20 04:04:55 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::on_store_positions));
|
2007-12-20 01:46:11 +02:00
|
|
|
_menu_file_quit->signal_activate().connect(
|
2007-12-20 04:04:55 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::on_quit));
|
2007-12-20 01:46:11 +02:00
|
|
|
_menu_view_refresh->signal_activate().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::refresh));
|
|
|
|
_menu_view_arrange->signal_activate().connect(
|
2007-12-20 04:04:55 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::on_arrange));
|
2007-12-20 01:46:11 +02:00
|
|
|
_menu_view_toolbar->signal_activate().connect(
|
2007-12-20 04:04:55 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::on_view_toolbar));
|
2007-12-20 01:46:11 +02:00
|
|
|
_menu_view_messages->signal_toggled().connect(
|
2007-12-20 04:04:55 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::on_show_messages));
|
2008-08-22 06:26:33 +03:00
|
|
|
_menu_view_projects->signal_toggled().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::on_show_projects));
|
2007-12-20 01:46:11 +02:00
|
|
|
_menu_help_about->signal_activate().connect(
|
2007-12-20 04:04:55 +02:00
|
|
|
sigc::mem_fun(this, &Patchage::on_help_about));
|
2008-01-06 00:50:01 +02:00
|
|
|
|
|
|
|
_messages_clear_but->signal_clicked().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::on_messages_clear));
|
|
|
|
_messages_close_but->signal_clicked().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::on_messages_close));
|
|
|
|
_messages_win->signal_delete_event().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::on_messages_delete));
|
2006-06-09 05:18:57 +03:00
|
|
|
|
2007-02-07 05:22:42 +02:00
|
|
|
_canvas->show();
|
2008-02-22 22:24:56 +02:00
|
|
|
_main_win->present();
|
|
|
|
|
2008-02-22 22:33:15 +02:00
|
|
|
_state_manager->load(_settings_filename);
|
|
|
|
|
2008-01-02 19:10:26 +02:00
|
|
|
_main_win->resize(
|
|
|
|
static_cast<int>(_state_manager->get_window_size().x),
|
|
|
|
static_cast<int>(_state_manager->get_window_size().y));
|
|
|
|
|
|
|
|
_main_win->move(
|
|
|
|
static_cast<int>(_state_manager->get_window_location().x),
|
|
|
|
static_cast<int>(_state_manager->get_window_location().y));
|
2008-02-22 20:41:10 +02:00
|
|
|
|
|
|
|
_about_win->set_transient_for(*_main_win);
|
2008-06-13 03:30:22 +03:00
|
|
|
|
2008-08-02 12:54:14 +03:00
|
|
|
_a2j = new a2j_proxy;
|
|
|
|
|
|
|
|
//info_msg(str(boost::format("a2j jack client name is '%s'") % _a2j->get_jack_client_name()));
|
|
|
|
|
2008-07-03 22:55:43 +03:00
|
|
|
_session = new session();
|
2008-06-15 11:50:12 +03:00
|
|
|
|
2008-07-04 22:47:59 +03:00
|
|
|
_project_list = new project_list(this, _session);
|
2008-07-03 22:55:43 +03:00
|
|
|
|
2008-07-04 23:36:25 +03:00
|
|
|
_lash = new lash_proxy(_session);
|
2008-06-15 11:50:12 +03:00
|
|
|
|
2008-06-18 04:05:03 +03:00
|
|
|
_jack = new jack_proxy(this);
|
2008-06-11 23:53:35 +03:00
|
|
|
|
|
|
|
_menu_jack_start->signal_activate().connect(
|
2008-06-18 04:05:03 +03:00
|
|
|
sigc::mem_fun(_jack, &jack_proxy::start_server));
|
2008-06-11 23:53:35 +03:00
|
|
|
_menu_jack_stop->signal_activate().connect(
|
2008-06-18 04:05:03 +03:00
|
|
|
sigc::mem_fun(_jack, &jack_proxy::stop_server));
|
2008-06-11 23:53:35 +03:00
|
|
|
|
2008-09-13 15:26:22 +03:00
|
|
|
_menu_a2j_start->signal_activate().connect(
|
|
|
|
sigc::mem_fun(_a2j, &a2j_proxy::start_bridge));
|
|
|
|
_menu_a2j_stop->signal_activate().connect(
|
|
|
|
sigc::mem_fun(_a2j, &a2j_proxy::stop_bridge));
|
|
|
|
|
2008-09-13 22:12:40 +03:00
|
|
|
_menu_lash_activate->signal_activate().connect(
|
|
|
|
sigc::mem_fun(_lash, &lash_proxy::try_activate));
|
|
|
|
_menu_lash_deactivate->signal_activate().connect(
|
|
|
|
sigc::mem_fun(_lash, &lash_proxy::deactivate));
|
|
|
|
|
2008-06-18 04:05:03 +03:00
|
|
|
jack_status_changed(_jack->is_started());
|
2008-06-11 23:53:35 +03:00
|
|
|
|
2008-02-22 20:41:10 +02:00
|
|
|
connect_widgets();
|
|
|
|
update_state();
|
|
|
|
|
2008-06-09 18:54:13 +03:00
|
|
|
_canvas->grab_focus();
|
|
|
|
|
2008-02-22 20:41:10 +02:00
|
|
|
// Idle callback, check if we need to refresh
|
|
|
|
Glib::signal_timeout().connect(
|
|
|
|
sigc::mem_fun(this, &Patchage::idle_callback), 100);
|
2006-06-09 05:18:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
Patchage::~Patchage()
|
|
|
|
{
|
2008-06-18 04:05:03 +03:00
|
|
|
delete _jack;
|
2008-06-13 03:30:22 +03:00
|
|
|
delete _lash;
|
2008-06-15 11:50:12 +03:00
|
|
|
delete _project_list;
|
2008-07-03 22:55:43 +03:00
|
|
|
delete _session;
|
2007-02-07 05:22:42 +02:00
|
|
|
delete _state_manager;
|
2008-08-02 12:54:14 +03:00
|
|
|
delete _a2j;
|
2008-02-23 21:51:43 +02:00
|
|
|
|
|
|
|
_about_win.destroy();
|
|
|
|
_messages_win.destroy();
|
2008-08-22 06:26:33 +03:00
|
|
|
//_main_win.destroy();
|
2007-08-05 05:32:10 +03:00
|
|
|
|
2008-09-08 05:47:27 +03:00
|
|
|
patchage_dbus_uninit();
|
2006-06-09 05:18:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
Patchage::idle_callback()
|
|
|
|
{
|
2007-01-01 08:30:55 +02:00
|
|
|
update_load();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::update_toolbar()
|
|
|
|
{
|
2008-06-11 23:53:35 +03:00
|
|
|
bool started;
|
|
|
|
|
2008-06-18 04:05:03 +03:00
|
|
|
started = _jack->is_started();
|
2008-06-11 23:53:35 +03:00
|
|
|
|
|
|
|
_buffer_size_combo->set_sensitive(started);
|
|
|
|
|
|
|
|
if (started)
|
|
|
|
{
|
2008-06-18 04:05:03 +03:00
|
|
|
_buffer_size_combo->set_active((int)log2f(_jack->buffer_size()) - 5);
|
2008-06-11 23:53:35 +03:00
|
|
|
}
|
2007-01-01 08:30:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-11 23:53:35 +03:00
|
|
|
void
|
2007-01-01 08:30:55 +02:00
|
|
|
Patchage::update_load()
|
|
|
|
{
|
2008-06-18 04:05:03 +03:00
|
|
|
if (!_jack->is_started())
|
2008-06-11 23:53:35 +03:00
|
|
|
{
|
|
|
|
_main_xrun_progress->set_text("JACK stopped");
|
|
|
|
return;
|
|
|
|
}
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2008-03-16 19:01:28 +02:00
|
|
|
char tmp_buf[8];
|
2008-06-18 04:05:03 +03:00
|
|
|
snprintf(tmp_buf, 8, "%zd", _jack->xruns());
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2008-03-16 19:01:28 +02:00
|
|
|
_main_xrun_progress->set_text(string(tmp_buf) + " Dropouts");
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2008-06-18 04:05:03 +03:00
|
|
|
float load = _jack->get_dsp_load();
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2008-06-12 22:08:48 +03:00
|
|
|
load /= 100.0; // dbus returns it in percents, we use 0..1
|
|
|
|
|
|
|
|
if (load > _max_dsp_load)
|
|
|
|
{
|
|
|
|
_max_dsp_load = load;
|
|
|
|
_main_xrun_progress->set_fraction(load);
|
2007-01-01 08:30:55 +02:00
|
|
|
}
|
2006-06-09 05:18:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2006-10-02 23:56:28 +03:00
|
|
|
Patchage::zoom(double z)
|
2006-06-09 05:18:57 +03:00
|
|
|
{
|
2007-02-07 05:22:42 +02:00
|
|
|
_state_manager->set_zoom(z);
|
|
|
|
_canvas->set_zoom(z);
|
2006-06-09 05:18:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2007-12-20 04:04:55 +02:00
|
|
|
Patchage::refresh()
|
2006-06-09 05:18:57 +03:00
|
|
|
{
|
2007-12-20 04:04:55 +02:00
|
|
|
assert(_canvas);
|
|
|
|
|
2008-06-11 23:53:35 +03:00
|
|
|
_canvas->destroy();
|
2007-12-20 04:04:55 +02:00
|
|
|
|
2008-06-18 04:05:03 +03:00
|
|
|
if (_jack)
|
|
|
|
_jack->refresh();
|
2007-12-20 04:04:55 +02:00
|
|
|
|
2008-06-11 23:53:35 +03:00
|
|
|
for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) {
|
|
|
|
(*i)->resize();
|
2007-02-08 05:56:42 +02:00
|
|
|
}
|
2006-06-09 05:18:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-02 19:10:26 +02:00
|
|
|
/** Update the stored window location and size in the StateManager (in memory).
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
Patchage::store_window_location()
|
|
|
|
{
|
|
|
|
int loc_x, loc_y, size_x, size_y;
|
|
|
|
_main_win->get_position(loc_x, loc_y);
|
|
|
|
_main_win->get_size(size_x, size_y);
|
|
|
|
Coord window_location;
|
|
|
|
window_location.x = loc_x;
|
|
|
|
window_location.y = loc_y;
|
|
|
|
Coord window_size;
|
|
|
|
window_size.x = size_x;
|
|
|
|
window_size.y = size_y;
|
|
|
|
_state_manager->set_window_location(window_location);
|
|
|
|
_state_manager->set_window_size(window_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-20 04:04:55 +02:00
|
|
|
void
|
|
|
|
Patchage::clear_load()
|
|
|
|
{
|
|
|
|
_main_xrun_progress->set_fraction(0.0);
|
2008-06-18 04:05:03 +03:00
|
|
|
_jack->reset_xruns();
|
2008-06-12 22:08:48 +03:00
|
|
|
_max_dsp_load = 0.0;
|
2007-12-20 04:04:55 +02:00
|
|
|
}
|
|
|
|
|
2008-01-06 00:50:01 +02:00
|
|
|
|
2006-06-09 05:18:57 +03:00
|
|
|
void
|
2008-08-22 06:26:33 +03:00
|
|
|
Patchage::error_msg(const std::string& msg)
|
|
|
|
{
|
|
|
|
#if defined(LOG_TO_STATUS)
|
|
|
|
status_msg(msg);
|
|
|
|
#endif
|
|
|
|
#if defined(LOG_TO_STD)
|
|
|
|
cerr << msg << endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::info_msg(const std::string& msg)
|
|
|
|
{
|
|
|
|
#if defined(LOG_TO_STATUS)
|
|
|
|
status_msg(msg);
|
|
|
|
#endif
|
|
|
|
#if defined(LOG_TO_STD)
|
|
|
|
cerr << msg << endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::status_msg(const string& msg)
|
2006-06-09 05:18:57 +03:00
|
|
|
{
|
2007-02-07 05:22:42 +02:00
|
|
|
if (_status_text->get_buffer()->size() > 0)
|
|
|
|
_status_text->get_buffer()->insert(_status_text->get_buffer()->end(), "\n");
|
2006-06-09 05:18:57 +03:00
|
|
|
|
2007-02-07 05:22:42 +02:00
|
|
|
_status_text->get_buffer()->insert(_status_text->get_buffer()->end(), msg);
|
|
|
|
_status_text->scroll_to_mark(_status_text->get_buffer()->get_insert(), 0);
|
2006-10-02 23:56:28 +03:00
|
|
|
}
|
2006-06-09 05:18:57 +03:00
|
|
|
|
|
|
|
|
2007-12-20 04:04:55 +02:00
|
|
|
void
|
|
|
|
Patchage::update_state()
|
|
|
|
{
|
|
|
|
for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) {
|
2008-07-31 18:55:46 +03:00
|
|
|
shared_ptr<Module> module = dynamic_pointer_cast<Module>(*i);
|
2007-12-20 04:04:55 +02:00
|
|
|
if (module)
|
|
|
|
module->load_location();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-09 05:18:57 +03:00
|
|
|
/** Update the sensitivity status of menus to reflect the present.
|
|
|
|
*
|
|
|
|
* (eg. disable "Connect to Jack" when Patchage is already connected to Jack)
|
|
|
|
*/
|
|
|
|
void
|
2007-01-01 08:30:55 +02:00
|
|
|
Patchage::connect_widgets()
|
2006-06-09 05:18:57 +03:00
|
|
|
{
|
2008-06-18 04:05:03 +03:00
|
|
|
_jack->signal_started.connect(
|
2008-06-11 23:53:35 +03:00
|
|
|
sigc::bind(sigc::mem_fun(this, &Patchage::jack_status_changed), true));
|
2006-10-02 23:56:28 +03:00
|
|
|
|
2008-06-18 04:05:03 +03:00
|
|
|
_jack->signal_stopped.connect(
|
2008-06-11 23:53:35 +03:00
|
|
|
sigc::bind(sigc::mem_fun(this, &Patchage::jack_status_changed), false));
|
2006-06-09 05:18:57 +03:00
|
|
|
}
|
|
|
|
|
2008-06-11 23:53:35 +03:00
|
|
|
void
|
|
|
|
Patchage::jack_status_changed(
|
|
|
|
bool started)
|
|
|
|
{
|
|
|
|
update_toolbar();
|
|
|
|
|
|
|
|
_menu_jack_start->set_sensitive(!started);
|
|
|
|
_menu_jack_stop->set_sensitive(started);
|
|
|
|
_clear_load_but->set_sensitive(started);
|
2008-06-14 23:03:42 +03:00
|
|
|
if (!started)
|
|
|
|
{
|
|
|
|
_main_xrun_progress->set_fraction(0.0);
|
|
|
|
}
|
2008-06-11 23:53:35 +03:00
|
|
|
}
|
2006-06-09 05:18:57 +03:00
|
|
|
|
2006-10-14 19:05:09 +03:00
|
|
|
void
|
2008-01-06 00:50:01 +02:00
|
|
|
Patchage::on_arrange()
|
2006-10-14 19:05:09 +03:00
|
|
|
{
|
2008-01-06 00:50:01 +02:00
|
|
|
assert(_canvas);
|
|
|
|
|
|
|
|
_canvas->arrange();
|
2006-10-16 07:55:16 +03:00
|
|
|
}
|
2006-10-14 19:05:09 +03:00
|
|
|
|
2008-01-06 00:50:01 +02:00
|
|
|
|
2006-10-16 07:55:16 +03:00
|
|
|
void
|
2008-01-06 00:50:01 +02:00
|
|
|
Patchage::on_help_about()
|
2006-10-16 07:55:16 +03:00
|
|
|
{
|
2008-01-06 00:50:01 +02:00
|
|
|
_about_win->run();
|
|
|
|
_about_win->hide();
|
2006-10-16 07:55:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2008-01-06 00:50:01 +02:00
|
|
|
Patchage::on_messages_clear()
|
2006-10-16 07:55:16 +03:00
|
|
|
{
|
2008-01-06 00:50:01 +02:00
|
|
|
_status_text->get_buffer()->erase(
|
|
|
|
_status_text->get_buffer()->begin(),
|
|
|
|
_status_text->get_buffer()->end());
|
2006-10-14 19:05:09 +03:00
|
|
|
}
|
|
|
|
|
2007-12-20 04:04:55 +02:00
|
|
|
|
2006-06-09 05:18:57 +03:00
|
|
|
void
|
2008-01-06 00:50:01 +02:00
|
|
|
Patchage::on_messages_close()
|
2006-06-09 05:18:57 +03:00
|
|
|
{
|
2008-01-06 00:50:01 +02:00
|
|
|
_menu_view_messages->set_active(false);
|
2007-12-20 04:04:55 +02:00
|
|
|
}
|
2006-06-09 05:18:57 +03:00
|
|
|
|
2008-01-06 00:50:01 +02:00
|
|
|
|
|
|
|
bool
|
|
|
|
Patchage::on_messages_delete(GdkEventAny*)
|
|
|
|
{
|
|
|
|
_menu_view_messages->set_active(false);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-20 04:04:55 +02:00
|
|
|
void
|
|
|
|
Patchage::on_quit()
|
|
|
|
{
|
|
|
|
_main_win->hide();
|
2006-06-09 05:18:57 +03:00
|
|
|
}
|
|
|
|
|
2008-01-06 00:50:01 +02:00
|
|
|
|
2007-04-07 03:52:22 +03:00
|
|
|
void
|
2007-12-20 04:04:55 +02:00
|
|
|
Patchage::on_show_messages()
|
2007-04-07 03:52:22 +03:00
|
|
|
{
|
2008-01-06 00:50:01 +02:00
|
|
|
if (_menu_view_messages->get_active())
|
|
|
|
_messages_win->present();
|
|
|
|
else
|
|
|
|
_messages_win->hide();
|
2007-12-20 04:04:55 +02:00
|
|
|
}
|
|
|
|
|
2008-08-22 06:26:33 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::on_show_projects()
|
|
|
|
{
|
|
|
|
if (_menu_view_projects->get_active())
|
|
|
|
_project_list_viewport->show();
|
|
|
|
else
|
|
|
|
_project_list_viewport->hide();
|
|
|
|
}
|
|
|
|
|
2007-04-07 03:52:22 +03:00
|
|
|
|
2007-12-20 04:04:55 +02:00
|
|
|
void
|
|
|
|
Patchage::on_store_positions()
|
|
|
|
{
|
2008-01-02 19:10:26 +02:00
|
|
|
store_window_location();
|
2007-12-20 04:04:55 +02:00
|
|
|
_state_manager->save(_settings_filename);
|
2007-04-07 03:52:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-15 22:35:42 +02:00
|
|
|
void
|
2007-12-20 04:04:55 +02:00
|
|
|
Patchage::on_view_toolbar()
|
2007-02-15 22:35:42 +02:00
|
|
|
{
|
2007-04-06 06:10:35 +03:00
|
|
|
if (_menu_view_toolbar->get_active())
|
2008-02-23 20:59:05 +02:00
|
|
|
_toolbar->show();
|
2007-02-15 22:35:42 +02:00
|
|
|
else
|
2008-02-23 20:59:05 +02:00
|
|
|
_toolbar->hide();
|
2007-02-15 22:35:42 +02:00
|
|
|
}
|
|
|
|
|
2008-06-09 18:54:13 +03:00
|
|
|
|
|
|
|
bool
|
|
|
|
Patchage::on_scroll(GdkEventScroll* ev)
|
|
|
|
{
|
|
|
|
cout << "ON SCROLL" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-02-15 22:35:42 +02:00
|
|
|
|
2007-01-01 08:30:55 +02:00
|
|
|
void
|
|
|
|
Patchage::buffer_size_changed()
|
|
|
|
{
|
2007-02-07 05:22:42 +02:00
|
|
|
const int selected = _buffer_size_combo->get_active_row_number();
|
2007-01-01 08:30:55 +02:00
|
|
|
|
|
|
|
if (selected == -1) {
|
|
|
|
update_toolbar();
|
|
|
|
} else {
|
2008-09-10 01:33:49 +03:00
|
|
|
uint32_t buffer_size = 1 << (selected+5);
|
2007-01-01 08:30:55 +02:00
|
|
|
|
2008-06-12 22:08:48 +03:00
|
|
|
// this check is temporal workaround for jack bug
|
|
|
|
// we skip setting buffer size if it same as acutal one
|
|
|
|
// proper place for such check is in jack
|
2008-06-18 04:05:03 +03:00
|
|
|
if (_jack->buffer_size() != buffer_size)
|
2008-06-12 22:08:48 +03:00
|
|
|
{
|
2008-06-18 04:05:03 +03:00
|
|
|
if (!_jack->set_buffer_size(buffer_size))
|
2008-06-12 22:08:48 +03:00
|
|
|
{
|
|
|
|
update_toolbar(); // reset combo box to actual value
|
|
|
|
}
|
|
|
|
}
|
2007-01-01 08:30:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-15 16:24:12 +03:00
|
|
|
void
|
|
|
|
Patchage::set_lash_availability(
|
|
|
|
bool lash_active)
|
|
|
|
{
|
|
|
|
_project_list->set_lash_availability(lash_active);
|
2008-09-13 15:01:26 +03:00
|
|
|
_menu_view_projects->set_active(lash_active);
|
2008-09-13 22:12:40 +03:00
|
|
|
_menu_lash_activate->set_sensitive(!lash_active);
|
|
|
|
_menu_lash_deactivate->set_sensitive(lash_active);
|
2008-07-06 19:44:47 +03:00
|
|
|
if (!lash_active)
|
|
|
|
{
|
|
|
|
_session->clear();
|
2008-09-13 12:20:38 +03:00
|
|
|
_main_lash_status_label->set_text("LASH N/A");
|
|
|
|
_project_list_viewport->hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_main_lash_status_label->set_text("LASH active");
|
|
|
|
_project_list_viewport->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-09-13 12:41:35 +03:00
|
|
|
Patchage::set_a2j_status(
|
|
|
|
unsigned int status)
|
2008-09-13 12:20:38 +03:00
|
|
|
{
|
2008-09-13 12:41:35 +03:00
|
|
|
const char * status_text;
|
|
|
|
|
|
|
|
switch (status)
|
2008-09-13 12:20:38 +03:00
|
|
|
{
|
2008-09-13 12:41:35 +03:00
|
|
|
case A2J_STATUS_NO_RESPONSE:
|
|
|
|
status_text = "A2J N/A";
|
2008-09-13 15:26:22 +03:00
|
|
|
_menu_a2j_start->set_sensitive(false);
|
|
|
|
_menu_a2j_stop->set_sensitive(false);
|
2008-09-13 12:41:35 +03:00
|
|
|
break;
|
|
|
|
case A2J_STATUS_BRIDGE_STOPPED:
|
|
|
|
status_text = "A2J bridge stopped";
|
2008-09-13 15:26:22 +03:00
|
|
|
_menu_a2j_start->set_sensitive(true);
|
|
|
|
_menu_a2j_stop->set_sensitive(false);
|
2008-09-13 12:41:35 +03:00
|
|
|
break;
|
|
|
|
case A2J_STATUS_BRIDGE_STARTED:
|
|
|
|
status_text = "A2J bridge started";
|
2008-09-13 15:26:22 +03:00
|
|
|
_menu_a2j_start->set_sensitive(false);
|
|
|
|
_menu_a2j_stop->set_sensitive(true);
|
2008-09-13 12:41:35 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error_msg(str(boost::format("Unknown A2J status %u") % status));
|
|
|
|
status_text = "Unknown A2J status";
|
2008-09-13 15:26:22 +03:00
|
|
|
_menu_a2j_start->set_sensitive(true);
|
|
|
|
_menu_a2j_stop->set_sensitive(true);
|
2008-09-13 12:41:35 +03:00
|
|
|
break;
|
2008-07-06 19:44:47 +03:00
|
|
|
}
|
2008-09-13 12:41:35 +03:00
|
|
|
|
|
|
|
_main_a2j_status_label->set_text(status_text);
|
2008-06-15 16:24:12 +03:00
|
|
|
}
|
|
|
|
|
2008-06-17 00:59:30 +03:00
|
|
|
void
|
2008-06-18 22:54:06 +03:00
|
|
|
Patchage::load_project_ask()
|
2008-06-17 00:59:30 +03:00
|
|
|
{
|
2008-06-18 22:21:24 +03:00
|
|
|
std::list<lash_project_info> projects;
|
2008-06-17 00:59:30 +03:00
|
|
|
|
|
|
|
_lash->get_available_projects(projects);
|
2008-10-19 06:35:19 +03:00
|
|
|
run_load_project_dialog(projects);
|
2008-06-16 05:00:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::load_project(
|
|
|
|
const std::string& project_name)
|
|
|
|
{
|
|
|
|
_lash->load_project(project_name);
|
2008-06-15 23:55:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::save_all_projects()
|
|
|
|
{
|
|
|
|
_lash->save_all_projects();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::save_project(
|
|
|
|
const std::string& project_name)
|
|
|
|
{
|
|
|
|
_lash->save_project(project_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::close_project(
|
|
|
|
const std::string& project_name)
|
|
|
|
{
|
|
|
|
_lash->close_project(project_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::close_all_projects()
|
|
|
|
{
|
|
|
|
_lash->close_all_projects();
|
|
|
|
}
|
2008-06-18 04:05:03 +03:00
|
|
|
|
2008-08-02 15:31:43 +03:00
|
|
|
void
|
|
|
|
Patchage::on_port_added(
|
2008-08-02 17:13:39 +03:00
|
|
|
const char * jack_client_name,
|
|
|
|
const char * jack_port_name,
|
2008-08-02 15:31:43 +03:00
|
|
|
PortType port_type,
|
|
|
|
bool is_input,
|
|
|
|
bool is_terminal)
|
|
|
|
{
|
2008-08-02 17:13:39 +03:00
|
|
|
bool is_a2j_mapped;
|
|
|
|
string canvas_client_name;
|
|
|
|
string canvas_port_name;
|
2008-10-28 00:09:16 +02:00
|
|
|
uint32_t alsa_client_id;
|
|
|
|
boost::shared_ptr<PatchageModule> module;
|
2008-08-02 17:13:39 +03:00
|
|
|
|
2008-08-02 20:07:04 +03:00
|
|
|
is_a2j_mapped = strcmp(_a2j->get_jack_client_name(), jack_client_name) == 0;
|
|
|
|
if (is_a2j_mapped)
|
2008-08-02 17:13:39 +03:00
|
|
|
{
|
2008-10-28 00:09:16 +02:00
|
|
|
if (!_a2j->map_jack_port(jack_port_name, canvas_client_name, canvas_port_name, alsa_client_id))
|
2008-08-02 20:07:04 +03:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2008-10-28 00:09:16 +02:00
|
|
|
|
|
|
|
canvas_port_name = str(boost::format(canvas_port_name + " [a2j:%u]") % alsa_client_id);
|
2008-08-02 20:07:04 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
canvas_client_name = jack_client_name;
|
|
|
|
canvas_port_name = jack_port_name;
|
2008-08-02 17:13:39 +03:00
|
|
|
}
|
|
|
|
|
2008-08-02 15:31:43 +03:00
|
|
|
ModuleType module_type = InputOutput;
|
2008-08-02 20:25:31 +03:00
|
|
|
if (_state_manager->get_module_split(canvas_client_name, is_terminal && !is_a2j_mapped)) {
|
2008-08-02 15:31:43 +03:00
|
|
|
if (is_input) {
|
|
|
|
module_type = Input;
|
|
|
|
} else {
|
|
|
|
module_type = Output;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-28 00:09:16 +02:00
|
|
|
module = _canvas->find_module(canvas_client_name, module_type);
|
2008-08-02 15:31:43 +03:00
|
|
|
if (!module) {
|
2008-08-02 17:13:39 +03:00
|
|
|
module = boost::shared_ptr<PatchageModule>(new PatchageModule(this, canvas_client_name, module_type));
|
2008-08-02 15:31:43 +03:00
|
|
|
module->load_location();
|
|
|
|
_canvas->add_item(module);
|
|
|
|
}
|
|
|
|
|
2008-08-02 17:13:39 +03:00
|
|
|
if (module->get_port(canvas_port_name)) {
|
2008-08-02 15:31:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-08-02 17:13:39 +03:00
|
|
|
boost::shared_ptr<PatchagePort> port = boost::shared_ptr<PatchagePort>(
|
|
|
|
new PatchagePort(
|
|
|
|
module,
|
|
|
|
canvas_port_name,
|
|
|
|
is_input,
|
|
|
|
_state_manager->get_port_color(port_type)));
|
|
|
|
|
|
|
|
port->type = port_type;
|
|
|
|
port->is_a2j_mapped = is_a2j_mapped;
|
|
|
|
if (is_a2j_mapped)
|
|
|
|
{
|
|
|
|
port->a2j_jack_port_name = jack_port_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
module->add_port(port);
|
2008-08-02 15:31:43 +03:00
|
|
|
|
|
|
|
module->resize();
|
|
|
|
}
|
|
|
|
|
2008-08-02 20:07:04 +03:00
|
|
|
boost::shared_ptr<PatchagePort>
|
|
|
|
Patchage::lookup_port(
|
2008-08-02 17:13:39 +03:00
|
|
|
const char * jack_client_name,
|
|
|
|
const char * jack_port_name)
|
2008-08-02 15:31:43 +03:00
|
|
|
{
|
2008-08-02 20:07:04 +03:00
|
|
|
if (strcmp(_a2j->get_jack_client_name(), jack_client_name) == 0)
|
2008-08-02 17:13:39 +03:00
|
|
|
{
|
2008-08-02 20:07:04 +03:00
|
|
|
return _canvas->lookup_port_by_a2j_jack_port_name(jack_port_name);
|
2008-08-02 17:13:39 +03:00
|
|
|
}
|
|
|
|
|
2008-08-02 20:07:04 +03:00
|
|
|
return _canvas->get_port(jack_client_name, jack_port_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::on_port_removed(
|
|
|
|
const char * jack_client_name,
|
|
|
|
const char * jack_port_name)
|
|
|
|
{
|
|
|
|
boost::shared_ptr<PatchagePort> port = lookup_port(jack_client_name, jack_port_name);
|
2008-08-02 15:31:43 +03:00
|
|
|
if (!port) {
|
2008-08-02 20:07:04 +03:00
|
|
|
error_msg(str(boost::format("Unable to remove unknown port '%s':'%s'") % jack_client_name % jack_port_name));
|
2008-08-02 15:31:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
boost::shared_ptr<PatchageModule> module = dynamic_pointer_cast<PatchageModule>(port->module().lock());
|
|
|
|
|
|
|
|
module->remove_port(port);
|
|
|
|
port.reset();
|
|
|
|
|
|
|
|
// No empty modules (for now)
|
|
|
|
if (module->num_ports() == 0) {
|
|
|
|
_canvas->remove_item(module);
|
|
|
|
module.reset();
|
|
|
|
} else {
|
|
|
|
module->resize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::on_ports_connected(
|
2008-08-02 17:13:39 +03:00
|
|
|
const char * jack_client1_name,
|
|
|
|
const char * jack_port1_name,
|
|
|
|
const char * jack_client2_name,
|
|
|
|
const char * jack_port2_name)
|
2008-08-02 15:31:43 +03:00
|
|
|
{
|
2008-08-02 20:07:04 +03:00
|
|
|
boost::shared_ptr<PatchagePort> port1 = lookup_port(jack_client1_name, jack_port1_name);
|
2008-08-02 15:31:43 +03:00
|
|
|
if (!port1) {
|
2008-08-02 20:07:04 +03:00
|
|
|
error_msg((string)"Unable to connect unknown port '" + jack_port1_name + "' of client '" + jack_client1_name + "'");
|
2008-08-02 15:31:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-08-02 20:07:04 +03:00
|
|
|
boost::shared_ptr<PatchagePort> port2 = lookup_port(jack_client2_name, jack_port2_name);
|
2008-08-02 15:31:43 +03:00
|
|
|
if (!port2) {
|
2008-08-02 20:07:04 +03:00
|
|
|
error_msg((string)"Unable to connect unknown port '" + jack_port2_name + "' of client '" + jack_client2_name + "'");
|
2008-08-02 15:31:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_canvas->add_connection(port1, port2, port1->color() + 0x22222200);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::on_ports_disconnected(
|
2008-08-02 17:13:39 +03:00
|
|
|
const char * jack_client1_name,
|
|
|
|
const char * jack_port1_name,
|
|
|
|
const char * jack_client2_name,
|
|
|
|
const char * jack_port2_name)
|
2008-08-02 15:31:43 +03:00
|
|
|
{
|
2008-08-02 20:07:04 +03:00
|
|
|
boost::shared_ptr<PatchagePort> port1 = lookup_port(jack_client1_name, jack_port1_name);
|
2008-08-02 15:31:43 +03:00
|
|
|
if (!port1) {
|
2008-08-02 20:07:04 +03:00
|
|
|
error_msg((string)"Unable to disconnect unknown port '" + jack_port1_name + "' of client '" + jack_client1_name + "'");
|
2008-08-02 15:31:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-08-02 20:07:04 +03:00
|
|
|
boost::shared_ptr<PatchagePort> port2 = lookup_port(jack_client2_name, jack_port2_name);
|
2008-08-02 15:31:43 +03:00
|
|
|
if (!port2) {
|
2008-08-02 20:07:04 +03:00
|
|
|
error_msg((string)"Unable to disconnect unknown port '" + jack_port2_name + "' of client '" + jack_client2_name + "'");
|
2008-08-02 15:31:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_canvas->remove_connection(port1, port2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
bool
|
|
|
|
port_type_match(
|
|
|
|
boost::shared_ptr<PatchagePort> port1,
|
|
|
|
boost::shared_ptr<PatchagePort> port2)
|
|
|
|
{
|
2008-08-02 17:13:39 +03:00
|
|
|
return port1->type == port2->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::get_port_jack_names(
|
|
|
|
boost::shared_ptr<PatchagePort> port,
|
|
|
|
string& jack_client_name,
|
|
|
|
string& jack_port_name)
|
|
|
|
{
|
|
|
|
if (port->is_a2j_mapped)
|
|
|
|
{
|
|
|
|
jack_client_name = _a2j->get_jack_client_name();
|
|
|
|
jack_port_name = port->a2j_jack_port_name;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
jack_client_name = port->module().lock()->name();
|
|
|
|
jack_port_name = port->name();
|
|
|
|
}
|
2008-08-02 15:31:43 +03:00
|
|
|
}
|
|
|
|
|
2008-06-18 04:05:03 +03:00
|
|
|
void
|
|
|
|
Patchage::connect(
|
2008-08-02 15:31:43 +03:00
|
|
|
boost::shared_ptr<PatchagePort> port1,
|
|
|
|
boost::shared_ptr<PatchagePort> port2)
|
2008-06-18 04:05:03 +03:00
|
|
|
{
|
2008-08-02 17:13:39 +03:00
|
|
|
string jack_client1_name;
|
|
|
|
string jack_port1_name;
|
|
|
|
string jack_client2_name;
|
|
|
|
string jack_port2_name;
|
2008-08-02 15:31:43 +03:00
|
|
|
|
|
|
|
if (port_type_match(port1, port2))
|
2008-06-18 04:05:03 +03:00
|
|
|
{
|
2008-08-02 17:13:39 +03:00
|
|
|
get_port_jack_names(port1, jack_client1_name, jack_port1_name);
|
|
|
|
get_port_jack_names(port2, jack_client2_name, jack_port2_name);
|
2008-08-02 15:31:43 +03:00
|
|
|
|
|
|
|
_jack->connect(
|
2008-08-02 17:13:39 +03:00
|
|
|
jack_client1_name.c_str(),
|
|
|
|
jack_port1_name.c_str(),
|
|
|
|
jack_client2_name.c_str(),
|
|
|
|
jack_port2_name.c_str());
|
2008-06-18 04:05:03 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-09-08 05:47:27 +03:00
|
|
|
status_msg("ERROR: Attempt to connect ports with mismatched types");
|
2008-06-18 04:05:03 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Patchage::disconnect(
|
2008-08-02 15:31:43 +03:00
|
|
|
boost::shared_ptr<PatchagePort> port1,
|
|
|
|
boost::shared_ptr<PatchagePort> port2)
|
2008-06-18 04:05:03 +03:00
|
|
|
{
|
2008-08-02 17:13:39 +03:00
|
|
|
string jack_client1_name;
|
|
|
|
string jack_port1_name;
|
|
|
|
string jack_client2_name;
|
|
|
|
string jack_port2_name;
|
2008-08-02 15:31:43 +03:00
|
|
|
|
|
|
|
if (port_type_match(port1, port2))
|
2008-06-18 04:05:03 +03:00
|
|
|
{
|
2008-08-02 17:13:39 +03:00
|
|
|
get_port_jack_names(port1, jack_client1_name, jack_port1_name);
|
|
|
|
get_port_jack_names(port2, jack_client2_name, jack_port2_name);
|
2008-08-02 15:31:43 +03:00
|
|
|
|
|
|
|
_jack->disconnect(
|
2008-08-02 17:13:39 +03:00
|
|
|
jack_client1_name.c_str(),
|
|
|
|
jack_port1_name.c_str(),
|
|
|
|
jack_client2_name.c_str(),
|
|
|
|
jack_port2_name.c_str());
|
2008-06-18 04:05:03 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-09-08 05:47:27 +03:00
|
|
|
status_msg("ERROR: Attempt to disconnect ports with mismatched types");
|
2008-06-18 04:05:03 +03:00
|
|
|
}
|
|
|
|
}
|
2008-08-02 15:31:43 +03:00
|
|
|
|
|
|
|
/** Destroy all JACK (canvas) ports.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
Patchage::clear_canvas()
|
|
|
|
{
|
|
|
|
ItemList modules = _canvas->items(); // copy
|
|
|
|
for (ItemList::iterator m = modules.begin(); m != modules.end(); ++m) {
|
|
|
|
shared_ptr<Module> module = dynamic_pointer_cast<Module>(*m);
|
|
|
|
if (!module)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
PortVector ports = module->ports(); // copy
|
|
|
|
for (PortVector::iterator p = ports.begin(); p != ports.end(); ++p) {
|
|
|
|
boost::shared_ptr<PatchagePort> port = boost::dynamic_pointer_cast<PatchagePort>(*p);
|
2008-08-02 17:13:39 +03:00
|
|
|
if (port)
|
|
|
|
{
|
2008-08-02 15:31:43 +03:00
|
|
|
module->remove_port(port);
|
|
|
|
port->hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (module->ports().empty())
|
|
|
|
_canvas->remove_item(module);
|
|
|
|
else
|
|
|
|
module->resize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Patchage::is_canvas_empty()
|
|
|
|
{
|
|
|
|
return _canvas->items().empty();
|
|
|
|
}
|