| 1 | /* -*- Mode: C ; c-basic-offset: 2 -*- */ |
|---|
| 2 | /* |
|---|
| 3 | * LADI Session Handler (ladish) |
|---|
| 4 | * |
|---|
| 5 | * Copyright (C) 2008, 2009 Nedko Arnaudov <nedko@arnaudov.name> |
|---|
| 6 | * Copyright (C) 2007 Dave Robillard <http://drobilla.net> |
|---|
| 7 | * |
|---|
| 8 | ************************************************************************** |
|---|
| 9 | * This file contains the code that implements main() and other top-level functionality |
|---|
| 10 | ************************************************************************** |
|---|
| 11 | * |
|---|
| 12 | * LADI Session Handler is free software; you can redistribute it and/or modify |
|---|
| 13 | * it under the terms of the GNU General Public License as published by |
|---|
| 14 | * the Free Software Foundation; either version 2 of the License, or |
|---|
| 15 | * (at your option) any later version. |
|---|
| 16 | * |
|---|
| 17 | * LADI Session Handler is distributed in the hope that it will be useful, |
|---|
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 20 | * GNU General Public License for more details. |
|---|
| 21 | * |
|---|
| 22 | * You should have received a copy of the GNU General Public License |
|---|
| 23 | * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/> |
|---|
| 24 | * or write to the Free Software Foundation, Inc., |
|---|
| 25 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|---|
| 26 | */ |
|---|
| 27 | |
|---|
| 28 | #include "common.h" |
|---|
| 29 | #include "glade.h" |
|---|
| 30 | #include "canvas.h" |
|---|
| 31 | #include "graph_canvas.h" |
|---|
| 32 | #include "../jack_proxy.h" |
|---|
| 33 | #include "dbus_helpers.h" |
|---|
| 34 | #include "control_proxy.h" |
|---|
| 35 | #include "../dbus_constants.h" |
|---|
| 36 | |
|---|
| 37 | #if 0 |
|---|
| 38 | class Patchage { |
|---|
| 39 | public: |
|---|
| 40 | Patchage(); |
|---|
| 41 | ~Patchage(); |
|---|
| 42 | |
|---|
| 43 | Gtk::Window* window() { return _main_win.get(); } |
|---|
| 44 | |
|---|
| 45 | void quit() { _main_win->hide(); } |
|---|
| 46 | |
|---|
| 47 | void refresh(); |
|---|
| 48 | |
|---|
| 49 | void clear_load(); |
|---|
| 50 | void update_state(); |
|---|
| 51 | |
|---|
| 52 | void set_studio_availability(bool available); |
|---|
| 53 | #if 0 |
|---|
| 54 | void set_a2j_status(unsigned int status); |
|---|
| 55 | |
|---|
| 56 | void load_project_ask(); |
|---|
| 57 | void load_project(const std::string& project_name); |
|---|
| 58 | void save_all_projects(); |
|---|
| 59 | void save_project(const std::string& project_name); |
|---|
| 60 | void close_project(const std::string& project_name); |
|---|
| 61 | void close_all_projects(); |
|---|
| 62 | #endif |
|---|
| 63 | |
|---|
| 64 | protected: |
|---|
| 65 | void connect_widgets(); |
|---|
| 66 | |
|---|
| 67 | void on_arrange(); |
|---|
| 68 | void on_help_about(); |
|---|
| 69 | void on_quit(); |
|---|
| 70 | void on_show_projects(); |
|---|
| 71 | void on_view_toolbar(); |
|---|
| 72 | bool on_scroll(GdkEventScroll* ev); |
|---|
| 73 | |
|---|
| 74 | void zoom(double z); |
|---|
| 75 | bool idle_callback(); |
|---|
| 76 | void update_load(); |
|---|
| 77 | void update_toolbar(); |
|---|
| 78 | |
|---|
| 79 | void jack_status_changed(bool started); |
|---|
| 80 | |
|---|
| 81 | void buffer_size_changed(); |
|---|
| 82 | |
|---|
| 83 | #if 0 |
|---|
| 84 | void |
|---|
| 85 | get_port_jack_names( |
|---|
| 86 | boost::shared_ptr<PatchagePort> port, |
|---|
| 87 | std::string& jack_client_name, |
|---|
| 88 | std::string& jack_port_name); |
|---|
| 89 | |
|---|
| 90 | boost::shared_ptr<PatchagePort> |
|---|
| 91 | lookup_port( |
|---|
| 92 | const char * jack_client_name, |
|---|
| 93 | const char * jack_port_name); |
|---|
| 94 | #endif |
|---|
| 95 | |
|---|
| 96 | //a2j_proxy * _a2j; |
|---|
| 97 | //session * _session; |
|---|
| 98 | //lash_proxy * _lash; |
|---|
| 99 | //project_list * _project_list; |
|---|
| 100 | |
|---|
| 101 | Gtk::Main* _gtk_main; |
|---|
| 102 | |
|---|
| 103 | float _max_dsp_load; |
|---|
| 104 | |
|---|
| 105 | Widget<Gtk::AboutDialog> _about_win; |
|---|
| 106 | Widget<Gtk::ComboBox> _buffer_size_combo; |
|---|
| 107 | Widget<Gtk::ToolButton> _clear_load_but; |
|---|
| 108 | Widget<Gtk::ScrolledWindow> _main_scrolledwin; |
|---|
| 109 | Widget<Gtk::Window> _main_win; |
|---|
| 110 | Widget<Gtk::ProgressBar> _main_xrun_progress; |
|---|
| 111 | Widget<Gtk::Label> _main_a2j_status_label; |
|---|
| 112 | Widget<Gtk::MenuItem> _menu_file_quit; |
|---|
| 113 | Widget<Gtk::MenuItem> _menu_help_about; |
|---|
| 114 | Widget<Gtk::MenuItem> _menu_jack_start; |
|---|
| 115 | Widget<Gtk::MenuItem> _menu_jack_stop; |
|---|
| 116 | Widget<Gtk::MenuItem> _menu_a2j_start; |
|---|
| 117 | Widget<Gtk::MenuItem> _menu_a2j_stop; |
|---|
| 118 | Widget<Gtk::MenuItem> _menu_load_project; |
|---|
| 119 | Widget<Gtk::MenuItem> _menu_save_all_projects; |
|---|
| 120 | Widget<Gtk::MenuItem> _menu_close_all_projects; |
|---|
| 121 | Widget<Gtk::MenuItem> _menu_store_positions; |
|---|
| 122 | Widget<Gtk::MenuItem> _menu_view_arrange; |
|---|
| 123 | Widget<Gtk::CheckMenuItem> _menu_view_projects; |
|---|
| 124 | Widget<Gtk::MenuItem> _menu_view_refresh; |
|---|
| 125 | Widget<Gtk::CheckMenuItem> _menu_view_toolbar; |
|---|
| 126 | Widget<Gtk::Viewport> _project_list_viewport; |
|---|
| 127 | Widget<Gtk::Label> _sample_rate_label; |
|---|
| 128 | Widget<Gtk::Toolbar> _toolbar; |
|---|
| 129 | Widget<Gtk::ToolButton> _zoom_full_but; |
|---|
| 130 | Widget<Gtk::ToolButton> _zoom_normal_but; |
|---|
| 131 | }; |
|---|
| 132 | |
|---|
| 133 | #include "globals.hpp" |
|---|
| 134 | |
|---|
| 135 | #include "common.h" |
|---|
| 136 | #include "Widget.hpp" |
|---|
| 137 | #include <gtkmm.h> |
|---|
| 138 | |
|---|
| 139 | #include "common.h" |
|---|
| 140 | |
|---|
| 141 | #include <string.h> |
|---|
| 142 | #include <cmath> |
|---|
| 143 | #include <libgnomecanvasmm.h> |
|---|
| 144 | #include <libglademm/xml.h> |
|---|
| 145 | #include <gtk/gtkwindow.h> |
|---|
| 146 | #include <boost/format.hpp> |
|---|
| 147 | |
|---|
| 148 | #include "project_list.hpp" |
|---|
| 149 | #include "session.hpp" |
|---|
| 150 | #include "globals.hpp" |
|---|
| 151 | //#include "load_projects_dialog.hpp" |
|---|
| 152 | #include "graph_canvas.h" |
|---|
| 153 | #include "../jack_proxy.h" |
|---|
| 154 | |
|---|
| 155 | Patchage * g_app; |
|---|
| 156 | |
|---|
| 157 | #define LOG_TO_STD |
|---|
| 158 | //#define LOG_TO_STATUS |
|---|
| 159 | |
|---|
| 160 | /* Gtk helpers (resize combo boxes) */ |
|---|
| 161 | |
|---|
| 162 | static void |
|---|
| 163 | gtkmm_get_ink_pixel_size (Glib::RefPtr<Pango::Layout> layout, |
|---|
| 164 | int& width, |
|---|
| 165 | int& height) |
|---|
| 166 | { |
|---|
| 167 | Pango::Rectangle ink_rect = layout->get_ink_extents (); |
|---|
| 168 | |
|---|
| 169 | width = (ink_rect.get_width() + PANGO_SCALE / 2) / PANGO_SCALE; |
|---|
| 170 | height = (ink_rect.get_height() + PANGO_SCALE / 2) / PANGO_SCALE; |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | static void |
|---|
| 174 | gtkmm_set_width_for_given_text (Gtk::Widget &w, const gchar *text, |
|---|
| 175 | gint hpadding/*, gint vpadding*/) |
|---|
| 176 | |
|---|
| 177 | { |
|---|
| 178 | int old_width, old_height; |
|---|
| 179 | w.get_size_request(old_width, old_height); |
|---|
| 180 | |
|---|
| 181 | int width, height; |
|---|
| 182 | w.ensure_style (); |
|---|
| 183 | |
|---|
| 184 | gtkmm_get_ink_pixel_size (w.create_pango_layout (text), width, height); |
|---|
| 185 | w.set_size_request(width + hpadding, old_height);//height + vpadding); |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | /* end Gtk helpers */ |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | #define INIT_WIDGET(x) x(g_xml, ((const char*)#x) + 1) |
|---|
| 192 | |
|---|
| 193 | Patchage::Patchage() |
|---|
| 194 | : _max_dsp_load(0.0) |
|---|
| 195 | #if 0 |
|---|
| 196 | , INIT_WIDGET(_about_win) |
|---|
| 197 | , INIT_WIDGET(_buffer_size_combo) |
|---|
| 198 | , INIT_WIDGET(_clear_load_but) |
|---|
| 199 | , INIT_WIDGET(_main_scrolledwin) |
|---|
| 200 | , INIT_WIDGET(_main_win) |
|---|
| 201 | , INIT_WIDGET(_main_xrun_progress) |
|---|
| 202 | , INIT_WIDGET(_main_a2j_status_label) |
|---|
| 203 | , INIT_WIDGET(_menu_file_quit) |
|---|
| 204 | , INIT_WIDGET(_menu_help_about) |
|---|
| 205 | , INIT_WIDGET(_menu_jack_start) |
|---|
| 206 | , INIT_WIDGET(_menu_jack_stop) |
|---|
| 207 | , INIT_WIDGET(_menu_a2j_start) |
|---|
| 208 | , INIT_WIDGET(_menu_a2j_stop) |
|---|
| 209 | , INIT_WIDGET(_menu_load_project) |
|---|
| 210 | , INIT_WIDGET(_menu_save_all_projects) |
|---|
| 211 | , INIT_WIDGET(_menu_close_all_projects) |
|---|
| 212 | , INIT_WIDGET(_menu_store_positions) |
|---|
| 213 | , INIT_WIDGET(_menu_view_arrange) |
|---|
| 214 | , INIT_WIDGET(_menu_view_projects) |
|---|
| 215 | , INIT_WIDGET(_menu_view_refresh) |
|---|
| 216 | , INIT_WIDGET(_menu_view_toolbar) |
|---|
| 217 | , INIT_WIDGET(_project_list_viewport) |
|---|
| 218 | , INIT_WIDGET(_sample_rate_label) |
|---|
| 219 | , INIT_WIDGET(_toolbar) |
|---|
| 220 | , INIT_WIDGET(_zoom_full_but) |
|---|
| 221 | , INIT_WIDGET(_zoom_normal_but) |
|---|
| 222 | #endif |
|---|
| 223 | { |
|---|
| 224 | g_app = this; |
|---|
| 225 | |
|---|
| 226 | patchage_dbus_init(); |
|---|
| 227 | |
|---|
| 228 | graph_create(JACKDBUS_SERVICE, JACKDBUS_OBJECT, &g_jack_graph); |
|---|
| 229 | graph_canvas_create(1600 * 2, 1200 * 2, &g_jack_graph_canvas); |
|---|
| 230 | graph_canvas_attach(g_jack_graph_canvas, g_jack_graph); |
|---|
| 231 | graph_activate(g_jack_graph); |
|---|
| 232 | |
|---|
| 233 | Glib::set_application_name("Patchage"); |
|---|
| 234 | _about_win->property_program_name() = "Patchage"; |
|---|
| 235 | _about_win->property_logo_icon_name() = "gladish"; |
|---|
| 236 | gtk_window_set_default_icon_name("gladish"); |
|---|
| 237 | |
|---|
| 238 | gtkmm_set_width_for_given_text(*_buffer_size_combo, "4096 frames", 40); |
|---|
| 239 | |
|---|
| 240 | _main_scrolledwin->add(*Glib::wrap(canvas_get_widget(graph_canvas_get_canvas(g_jack_graph_canvas)))); |
|---|
| 241 | |
|---|
| 242 | // _canvas->scroll_to(static_cast<int>(_canvas->width()/2 - 320), |
|---|
| 243 | // static_cast<int>(_canvas->height()/2 - 240)); // FIXME: hardcoded |
|---|
| 244 | |
|---|
| 245 | _main_scrolledwin->property_hadjustment().get_value()->set_step_increment(10); |
|---|
| 246 | _main_scrolledwin->property_vadjustment().get_value()->set_step_increment(10); |
|---|
| 247 | |
|---|
| 248 | _main_scrolledwin->signal_scroll_event().connect( |
|---|
| 249 | sigc::mem_fun(this, &Patchage::on_scroll)); |
|---|
| 250 | |
|---|
| 251 | _buffer_size_combo->signal_changed().connect( |
|---|
| 252 | sigc::mem_fun(this, &Patchage::buffer_size_changed)); |
|---|
| 253 | _clear_load_but->signal_clicked().connect( |
|---|
| 254 | sigc::mem_fun(this, &Patchage::clear_load)); |
|---|
| 255 | _zoom_normal_but->signal_clicked().connect(sigc::bind( |
|---|
| 256 | sigc::mem_fun(this, &Patchage::zoom), 1.0)); |
|---|
| 257 | // _zoom_full_but->signal_clicked().connect(sigc::mem_fun(_canvas.get(), &PatchageCanvas::zoom_full)); |
|---|
| 258 | |
|---|
| 259 | // _menu_load_project->signal_activate().connect(sigc::mem_fun(this, &Patchage::load_project_ask)); |
|---|
| 260 | // _menu_save_all_projects->signal_activate().connect(sigc::mem_fun(this, &Patchage::save_all_projects)); |
|---|
| 261 | // _menu_close_all_projects->signal_activate().connect(sigc::mem_fun(this, &Patchage::close_all_projects)); |
|---|
| 262 | |
|---|
| 263 | _menu_file_quit->signal_activate().connect( |
|---|
| 264 | sigc::mem_fun(this, &Patchage::on_quit)); |
|---|
| 265 | _menu_view_refresh->signal_activate().connect( |
|---|
| 266 | sigc::mem_fun(this, &Patchage::refresh)); |
|---|
| 267 | _menu_view_arrange->signal_activate().connect( |
|---|
| 268 | sigc::mem_fun(this, &Patchage::on_arrange)); |
|---|
| 269 | _menu_view_toolbar->signal_activate().connect( |
|---|
| 270 | sigc::mem_fun(this, &Patchage::on_view_toolbar)); |
|---|
| 271 | _menu_view_projects->signal_toggled().connect( |
|---|
| 272 | sigc::mem_fun(this, &Patchage::on_show_projects)); |
|---|
| 273 | _menu_help_about->signal_activate().connect( |
|---|
| 274 | sigc::mem_fun(this, &Patchage::on_help_about)); |
|---|
| 275 | |
|---|
| 276 | Glib::wrap(canvas_get_widget(graph_canvas_get_canvas(g_jack_graph_canvas)))->show(); |
|---|
| 277 | _main_win->present(); |
|---|
| 278 | |
|---|
| 279 | _about_win->set_transient_for(*_main_win); |
|---|
| 280 | |
|---|
| 281 | // _a2j = new a2j_proxy; |
|---|
| 282 | |
|---|
| 283 | //info_msg(str(boost::format("a2j jack client name is '%s'") % _a2j->get_jack_client_name())); |
|---|
| 284 | |
|---|
| 285 | // _session = new session(); |
|---|
| 286 | |
|---|
| 287 | // _project_list = new project_list(this, _session); |
|---|
| 288 | // _project_list_viewport->hide(); |
|---|
| 289 | |
|---|
| 290 | // _lash = new lash_proxy(_session); |
|---|
| 291 | |
|---|
| 292 | //_menu_jack_start->signal_activate().connect(sigc::mem_fun(_jack, &jack_proxy::start_server)); |
|---|
| 293 | //_menu_jack_stop->signal_activate().connect(sigc::mem_fun(_jack, &jack_proxy::stop_server)); |
|---|
| 294 | |
|---|
| 295 | // _menu_a2j_start->signal_activate().connect(sigc::mem_fun(_a2j, &a2j_proxy::start_bridge)); |
|---|
| 296 | // _menu_a2j_stop->signal_activate().connect(sigc::mem_fun(_a2j, &a2j_proxy::stop_bridge)); |
|---|
| 297 | |
|---|
| 298 | //jack_status_changed(_jack->is_started()); |
|---|
| 299 | |
|---|
| 300 | connect_widgets(); |
|---|
| 301 | update_state(); |
|---|
| 302 | |
|---|
| 303 | // _canvas->grab_focus(); |
|---|
| 304 | |
|---|
| 305 | // Idle callback, check if we need to refresh |
|---|
| 306 | Glib::signal_timeout().connect( |
|---|
| 307 | sigc::mem_fun(this, &Patchage::idle_callback), 100); |
|---|
| 308 | } |
|---|
| 309 | |
|---|
| 310 | Patchage::~Patchage() |
|---|
| 311 | { |
|---|
| 312 | //delete _lash; |
|---|
| 313 | //delete _project_list; |
|---|
| 314 | //delete _session; |
|---|
| 315 | //delete _a2j; |
|---|
| 316 | |
|---|
| 317 | _about_win.destroy(); |
|---|
| 318 | //_main_win.destroy(); |
|---|
| 319 | |
|---|
| 320 | patchage_dbus_uninit(); |
|---|
| 321 | } |
|---|
| 322 | |
|---|
| 323 | bool |
|---|
| 324 | Patchage::idle_callback() |
|---|
| 325 | { |
|---|
| 326 | update_load(); |
|---|
| 327 | |
|---|
| 328 | return true; |
|---|
| 329 | } |
|---|
| 330 | |
|---|
| 331 | void |
|---|
| 332 | Patchage::update_toolbar() |
|---|
| 333 | { |
|---|
| 334 | #if 0 |
|---|
| 335 | bool started; |
|---|
| 336 | |
|---|
| 337 | started = _jack->is_started(); |
|---|
| 338 | |
|---|
| 339 | _buffer_size_combo->set_sensitive(started); |
|---|
| 340 | |
|---|
| 341 | if (started) |
|---|
| 342 | { |
|---|
| 343 | _buffer_size_combo->set_active((int)log2f(_jack->buffer_size()) - 5); |
|---|
| 344 | } |
|---|
| 345 | #endif |
|---|
| 346 | } |
|---|
| 347 | |
|---|
| 348 | void |
|---|
| 349 | Patchage::update_load() |
|---|
| 350 | { |
|---|
| 351 | #if 0 |
|---|
| 352 | if (!_jack->is_started()) |
|---|
| 353 | { |
|---|
| 354 | _main_xrun_progress->set_text("JACK stopped"); |
|---|
| 355 | return; |
|---|
| 356 | } |
|---|
| 357 | |
|---|
| 358 | char tmp_buf[8]; |
|---|
| 359 | snprintf(tmp_buf, 8, "%zd", _jack->xruns()); |
|---|
| 360 | |
|---|
| 361 | _main_xrun_progress->set_text(std::string(tmp_buf) + " Dropouts"); |
|---|
| 362 | |
|---|
| 363 | float load = _jack->get_dsp_load(); |
|---|
| 364 | |
|---|
| 365 | load /= 100.0; // dbus returns it in percents, we use 0..1 |
|---|
| 366 | |
|---|
| 367 | if (load > _max_dsp_load) |
|---|
| 368 | { |
|---|
| 369 | _max_dsp_load = load; |
|---|
| 370 | _main_xrun_progress->set_fraction(load); |
|---|
| 371 | } |
|---|
| 372 | #endif |
|---|
| 373 | } |
|---|
| 374 | |
|---|
| 375 | |
|---|
| 376 | void |
|---|
| 377 | Patchage::zoom(double z) |
|---|
| 378 | { |
|---|
| 379 | // _canvas->set_zoom(z); |
|---|
| 380 | } |
|---|
| 381 | |
|---|
| 382 | |
|---|
| 383 | void |
|---|
| 384 | Patchage::refresh() |
|---|
| 385 | { |
|---|
| 386 | // assert(_canvas); |
|---|
| 387 | |
|---|
| 388 | // _canvas->destroy(); |
|---|
| 389 | |
|---|
| 390 | // if (_jack) |
|---|
| 391 | // _jack->refresh(); |
|---|
| 392 | |
|---|
| 393 | // for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) { |
|---|
| 394 | // (*i)->resize(); |
|---|
| 395 | // } |
|---|
| 396 | } |
|---|
| 397 | |
|---|
| 398 | void |
|---|
| 399 | Patchage::clear_load() |
|---|
| 400 | { |
|---|
| 401 | #if 0 |
|---|
| 402 | _main_xrun_progress->set_fraction(0.0); |
|---|
| 403 | _jack->reset_xruns(); |
|---|
| 404 | _max_dsp_load = 0.0; |
|---|
| 405 | #endif |
|---|
| 406 | } |
|---|
| 407 | |
|---|
| 408 | void |
|---|
| 409 | Patchage::update_state() |
|---|
| 410 | { |
|---|
| 411 | // for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) { |
|---|
| 412 | // shared_ptr<Module> module = dynamic_pointer_cast<Module>(*i); |
|---|
| 413 | // if (module) |
|---|
| 414 | // module->load_location(); |
|---|
| 415 | // } |
|---|
| 416 | } |
|---|
| 417 | |
|---|
| 418 | |
|---|
| 419 | /** Update the sensitivity status of menus to reflect the present. |
|---|
| 420 | * |
|---|
| 421 | * (eg. disable "Connect to Jack" when Patchage is already connected to Jack) |
|---|
| 422 | */ |
|---|
| 423 | void |
|---|
| 424 | Patchage::connect_widgets() |
|---|
| 425 | { |
|---|
| 426 | //_jack->signal_started.connect(sigc::bind(sigc::mem_fun(this, &Patchage::jack_status_changed), true)); |
|---|
| 427 | //_jack->signal_stopped.connect(sigc::bind(sigc::mem_fun(this, &Patchage::jack_status_changed), false)); |
|---|
| 428 | } |
|---|
| 429 | |
|---|
| 430 | void |
|---|
| 431 | Patchage::jack_status_changed( |
|---|
| 432 | bool started) |
|---|
| 433 | { |
|---|
| 434 | update_toolbar(); |
|---|
| 435 | |
|---|
| 436 | _menu_jack_start->set_sensitive(!started); |
|---|
| 437 | _menu_jack_stop->set_sensitive(started); |
|---|
| 438 | _clear_load_but->set_sensitive(started); |
|---|
| 439 | if (!started) |
|---|
| 440 | { |
|---|
| 441 | _main_xrun_progress->set_fraction(0.0); |
|---|
| 442 | } |
|---|
| 443 | } |
|---|
| 444 | |
|---|
| 445 | void |
|---|
| 446 | Patchage::on_arrange() |
|---|
| 447 | { |
|---|
| 448 | // assert(_canvas); |
|---|
| 449 | |
|---|
| 450 | // _canvas->arrange(); |
|---|
| 451 | } |
|---|
| 452 | |
|---|
| 453 | |
|---|
| 454 | void |
|---|
| 455 | Patchage::on_help_about() |
|---|
| 456 | { |
|---|
| 457 | _about_win->run(); |
|---|
| 458 | _about_win->hide(); |
|---|
| 459 | } |
|---|
| 460 | |
|---|
| 461 | |
|---|
| 462 | void |
|---|
| 463 | Patchage::on_quit() |
|---|
| 464 | { |
|---|
| 465 | _main_win->hide(); |
|---|
| 466 | } |
|---|
| 467 | |
|---|
| 468 | void |
|---|
| 469 | Patchage::on_show_projects() |
|---|
| 470 | { |
|---|
| 471 | if (_menu_view_projects->get_active()) |
|---|
| 472 | _project_list_viewport->show(); |
|---|
| 473 | else |
|---|
| 474 | _project_list_viewport->hide(); |
|---|
| 475 | } |
|---|
| 476 | |
|---|
| 477 | void |
|---|
| 478 | Patchage::on_view_toolbar() |
|---|
| 479 | { |
|---|
| 480 | if (_menu_view_toolbar->get_active()) |
|---|
| 481 | _toolbar->show(); |
|---|
| 482 | else |
|---|
| 483 | _toolbar->hide(); |
|---|
| 484 | } |
|---|
| 485 | |
|---|
| 486 | |
|---|
| 487 | bool |
|---|
| 488 | Patchage::on_scroll(GdkEventScroll* ev) |
|---|
| 489 | { |
|---|
| 490 | lash_debug("ON SCROLL"); |
|---|
| 491 | return false; |
|---|
| 492 | } |
|---|
| 493 | |
|---|
| 494 | |
|---|
| 495 | void |
|---|
| 496 | Patchage::buffer_size_changed() |
|---|
| 497 | { |
|---|
| 498 | #if 0 |
|---|
| 499 | const int selected = _buffer_size_combo->get_active_row_number(); |
|---|
| 500 | |
|---|
| 501 | if (selected == -1) |
|---|
| 502 | { |
|---|
| 503 | update_toolbar(); |
|---|
| 504 | } |
|---|
| 505 | else |
|---|
| 506 | { |
|---|
| 507 | uint32_t buffer_size = 1 << (selected+5); |
|---|
| 508 | |
|---|
| 509 | // this check is temporal workaround for jack bug |
|---|
| 510 | // we skip setting buffer size if it same as acutal one |
|---|
| 511 | // proper place for such check is in jack |
|---|
| 512 | if (_jack->buffer_size() != buffer_size) |
|---|
| 513 | { |
|---|
| 514 | if (!_jack->set_buffer_size(buffer_size)) |
|---|
| 515 | { |
|---|
| 516 | update_toolbar(); // reset combo box to actual value |
|---|
| 517 | } |
|---|
| 518 | } |
|---|
| 519 | } |
|---|
| 520 | #endif |
|---|
| 521 | } |
|---|
| 522 | |
|---|
| 523 | void |
|---|
| 524 | Patchage::set_studio_availability( |
|---|
| 525 | bool available) |
|---|
| 526 | { |
|---|
| 527 | if (available) |
|---|
| 528 | { |
|---|
| 529 | _main_win->set_title("Active Studio - LADI Session Handler"); |
|---|
| 530 | } |
|---|
| 531 | else |
|---|
| 532 | { |
|---|
| 533 | _main_win->set_title("LADI Session Handler"); |
|---|
| 534 | } |
|---|
| 535 | //_project_list->set_lash_availability(available); |
|---|
| 536 | _menu_view_projects->set_active(available); |
|---|
| 537 | } |
|---|
| 538 | |
|---|
| 539 | #if 0 |
|---|
| 540 | void |
|---|
| 541 | Patchage::set_a2j_status( |
|---|
| 542 | unsigned int status) |
|---|
| 543 | { |
|---|
| 544 | const char * status_text; |
|---|
| 545 | |
|---|
| 546 | switch (status) |
|---|
| 547 | { |
|---|
| 548 | case A2J_STATUS_NO_RESPONSE: |
|---|
| 549 | status_text = "A2J N/A"; |
|---|
| 550 | _menu_a2j_start->set_sensitive(false); |
|---|
| 551 | _menu_a2j_stop->set_sensitive(false); |
|---|
| 552 | break; |
|---|
| 553 | case A2J_STATUS_BRIDGE_STOPPED: |
|---|
| 554 | status_text = "A2J bridge stopped"; |
|---|
| 555 | _menu_a2j_start->set_sensitive(true); |
|---|
| 556 | _menu_a2j_stop->set_sensitive(false); |
|---|
| 557 | break; |
|---|
| 558 | case A2J_STATUS_BRIDGE_STARTED: |
|---|
| 559 | status_text = "A2J bridge started"; |
|---|
| 560 | _menu_a2j_start->set_sensitive(false); |
|---|
| 561 | _menu_a2j_stop->set_sensitive(true); |
|---|
| 562 | break; |
|---|
| 563 | default: |
|---|
| 564 | error_msg(str(boost::format("Unknown A2J status %u") % status)); |
|---|
| 565 | status_text = "Unknown A2J status"; |
|---|
| 566 | _menu_a2j_start->set_sensitive(true); |
|---|
| 567 | _menu_a2j_stop->set_sensitive(true); |
|---|
| 568 | break; |
|---|
| 569 | } |
|---|
| 570 | |
|---|
| 571 | _main_a2j_status_label->set_text(status_text); |
|---|
| 572 | } |
|---|
| 573 | |
|---|
| 574 | void |
|---|
| 575 | Patchage::load_project_ask() |
|---|
| 576 | { |
|---|
| 577 | std::list<lash_project_info> projects; |
|---|
| 578 | |
|---|
| 579 | _lash->get_available_projects(projects); |
|---|
| 580 | run_load_project_dialog(projects); |
|---|
| 581 | } |
|---|
| 582 | |
|---|
| 583 | void |
|---|
| 584 | Patchage::load_project( |
|---|
| 585 | const std::string& project_name) |
|---|
| 586 | { |
|---|
| 587 | _lash->load_project(project_name); |
|---|
| 588 | } |
|---|
| 589 | |
|---|
| 590 | void |
|---|
| 591 | Patchage::save_all_projects() |
|---|
| 592 | { |
|---|
| 593 | _lash->save_all_projects(); |
|---|
| 594 | } |
|---|
| 595 | |
|---|
| 596 | void |
|---|
| 597 | Patchage::save_project( |
|---|
| 598 | const std::string& project_name) |
|---|
| 599 | { |
|---|
| 600 | _lash->save_project(project_name); |
|---|
| 601 | } |
|---|
| 602 | |
|---|
| 603 | void |
|---|
| 604 | Patchage::close_project( |
|---|
| 605 | const std::string& project_name) |
|---|
| 606 | { |
|---|
| 607 | _lash->close_project(project_name); |
|---|
| 608 | } |
|---|
| 609 | |
|---|
| 610 | void |
|---|
| 611 | Patchage::close_all_projects() |
|---|
| 612 | { |
|---|
| 613 | _lash->close_all_projects(); |
|---|
| 614 | } |
|---|
| 615 | |
|---|
| 616 | void |
|---|
| 617 | Patchage::on_port_added( |
|---|
| 618 | const char * jack_client_name, |
|---|
| 619 | const char * jack_port_name, |
|---|
| 620 | PortType port_type, |
|---|
| 621 | bool is_input, |
|---|
| 622 | bool is_terminal) |
|---|
| 623 | { |
|---|
| 624 | bool is_a2j_mapped; |
|---|
| 625 | std::string canvas_client_name; |
|---|
| 626 | std::string canvas_port_name; |
|---|
| 627 | uint32_t alsa_client_id; |
|---|
| 628 | boost::shared_ptr<PatchageModule> module; |
|---|
| 629 | |
|---|
| 630 | is_a2j_mapped = strcmp(_a2j->get_jack_client_name(), jack_client_name) == 0; |
|---|
| 631 | if (is_a2j_mapped) |
|---|
| 632 | { |
|---|
| 633 | if (!_a2j->map_jack_port(jack_port_name, canvas_client_name, canvas_port_name, alsa_client_id)) |
|---|
| 634 | { |
|---|
| 635 | return; |
|---|
| 636 | } |
|---|
| 637 | |
|---|
| 638 | canvas_port_name = str(boost::format(canvas_port_name + " [a2j:%u]") % alsa_client_id); |
|---|
| 639 | } |
|---|
| 640 | else |
|---|
| 641 | { |
|---|
| 642 | canvas_client_name = jack_client_name; |
|---|
| 643 | canvas_port_name = jack_port_name; |
|---|
| 644 | } |
|---|
| 645 | |
|---|
| 646 | ModuleType module_type = InputOutput; |
|---|
| 647 | if (_state_manager->get_module_split(canvas_client_name, is_terminal && !is_a2j_mapped)) { |
|---|
| 648 | if (is_input) { |
|---|
| 649 | module_type = Input; |
|---|
| 650 | } else { |
|---|
| 651 | module_type = Output; |
|---|
| 652 | } |
|---|
| 653 | } |
|---|
| 654 | |
|---|
| 655 | module = _canvas->find_module(canvas_client_name, module_type); |
|---|
| 656 | if (!module) { |
|---|
| 657 | module = boost::shared_ptr<PatchageModule>(new PatchageModule(this, canvas_client_name, module_type)); |
|---|
| 658 | module->load_location(); |
|---|
| 659 | _canvas->add_item(module); |
|---|
| 660 | } |
|---|
| 661 | |
|---|
| 662 | if (module->get_port(canvas_port_name)) { |
|---|
| 663 | return; |
|---|
| 664 | } |
|---|
| 665 | |
|---|
| 666 | boost::shared_ptr<PatchagePort> port = boost::shared_ptr<PatchagePort>( |
|---|
| 667 | new PatchagePort( |
|---|
| 668 | module, |
|---|
| 669 | canvas_port_name, |
|---|
| 670 | is_input, |
|---|
| 671 | _state_manager->get_port_color(port_type))); |
|---|
| 672 | |
|---|
| 673 | port->type = port_type; |
|---|
| 674 | port->is_a2j_mapped = is_a2j_mapped; |
|---|
| 675 | if (is_a2j_mapped) |
|---|
| 676 | { |
|---|
| 677 | port->a2j_jack_port_name = jack_port_name; |
|---|
| 678 | } |
|---|
| 679 | |
|---|
| 680 | module->add_port(port); |
|---|
| 681 | |
|---|
| 682 | module->resize(); |
|---|
| 683 | } |
|---|
| 684 | |
|---|
| 685 | boost::shared_ptr<PatchagePort> |
|---|
| 686 | Patchage::lookup_port( |
|---|
| 687 | const char * jack_client_name, |
|---|
| 688 | const char * jack_port_name) |
|---|
| 689 | { |
|---|
| 690 | if (strcmp(_a2j->get_jack_client_name(), jack_client_name) == 0) |
|---|
| 691 | { |
|---|
| 692 | return _canvas->lookup_port_by_a2j_jack_port_name(jack_port_name); |
|---|
| 693 | } |
|---|
| 694 | |
|---|
| 695 | return _canvas->get_port(jack_client_name, jack_port_name); |
|---|
| 696 | } |
|---|
| 697 | |
|---|
| 698 | void |
|---|
| 699 | Patchage::on_port_removed( |
|---|
| 700 | const char * jack_client_name, |
|---|
| 701 | const char * jack_port_name) |
|---|
| 702 | { |
|---|
| 703 | boost::shared_ptr<PatchagePort> port = lookup_port(jack_client_name, jack_port_name); |
|---|
| 704 | if (!port) { |
|---|
| 705 | error_msg(str(boost::format("Unable to remove unknown port '%s':'%s'") % jack_client_name % jack_port_name)); |
|---|
| 706 | return; |
|---|
| 707 | } |
|---|
| 708 | |
|---|
| 709 | boost::shared_ptr<PatchageModule> module = dynamic_pointer_cast<PatchageModule>(port->module().lock()); |
|---|
| 710 | |
|---|
| 711 | module->remove_port(port); |
|---|
| 712 | port.reset(); |
|---|
| 713 | |
|---|
| 714 | // No empty modules (for now) |
|---|
| 715 | if (module->num_ports() == 0) { |
|---|
| 716 | _canvas->remove_item(module); |
|---|
| 717 | module.reset(); |
|---|
| 718 | } else { |
|---|
| 719 | module->resize(); |
|---|
| 720 | } |
|---|
| 721 | } |
|---|
| 722 | |
|---|
| 723 | void |
|---|
| 724 | Patchage::on_ports_connected( |
|---|
| 725 | const char * jack_client1_name, |
|---|
| 726 | const char * jack_port1_name, |
|---|
| 727 | const char * jack_client2_name, |
|---|
| 728 | const char * jack_port2_name) |
|---|
| 729 | { |
|---|
| 730 | boost::shared_ptr<PatchagePort> port1 = lookup_port(jack_client1_name, jack_port1_name); |
|---|
| 731 | if (!port1) { |
|---|
| 732 | error_msg((std::string)"Unable to connect unknown port '" + jack_port1_name + "' of client '" + jack_client1_name + "'"); |
|---|
| 733 | return; |
|---|
| 734 | } |
|---|
| 735 | |
|---|
| 736 | boost::shared_ptr<PatchagePort> port2 = lookup_port(jack_client2_name, jack_port2_name); |
|---|
| 737 | if (!port2) { |
|---|
| 738 | error_msg((std::string)"Unable to connect unknown port '" + jack_port2_name + "' of client '" + jack_client2_name + "'"); |
|---|
| 739 | return; |
|---|
| 740 | } |
|---|
| 741 | |
|---|
| 742 | _canvas->add_connection(port1, port2, port1->color() + 0x22222200); |
|---|
| 743 | } |
|---|
| 744 | |
|---|
| 745 | void |
|---|
| 746 | Patchage::on_ports_disconnected( |
|---|
| 747 | const char * jack_client1_name, |
|---|
| 748 | const char * jack_port1_name, |
|---|
| 749 | const char * jack_client2_name, |
|---|
| 750 | const char * jack_port2_name) |
|---|
| 751 | { |
|---|
| 752 | boost::shared_ptr<PatchagePort> port1 = lookup_port(jack_client1_name, jack_port1_name); |
|---|
| 753 | if (!port1) { |
|---|
| 754 | error_msg((std::string)"Unable to disconnect unknown port '" + jack_port1_name + "' of client '" + jack_client1_name + "'"); |
|---|
| 755 | return; |
|---|
| 756 | } |
|---|
| 757 | |
|---|
| 758 | boost::shared_ptr<PatchagePort> port2 = lookup_port(jack_client2_name, jack_port2_name); |
|---|
| 759 | if (!port2) { |
|---|
| 760 | error_msg((std::string)"Unable to disconnect unknown port '" + jack_port2_name + "' of client '" + jack_client2_name + "'"); |
|---|
| 761 | return; |
|---|
| 762 | } |
|---|
| 763 | |
|---|
| 764 | _canvas->remove_connection(port1, port2); |
|---|
| 765 | } |
|---|
| 766 | |
|---|
| 767 | static |
|---|
| 768 | bool |
|---|
| 769 | port_type_match( |
|---|
| 770 | boost::shared_ptr<PatchagePort> port1, |
|---|
| 771 | boost::shared_ptr<PatchagePort> port2) |
|---|
| 772 | { |
|---|
| 773 | return port1->type == port2->type; |
|---|
| 774 | } |
|---|
| 775 | |
|---|
| 776 | void |
|---|
| 777 | Patchage::get_port_jack_names( |
|---|
| 778 | boost::shared_ptr<PatchagePort> port, |
|---|
| 779 | std::string& jack_client_name, |
|---|
| 780 | std::string& jack_port_name) |
|---|
| 781 | { |
|---|
| 782 | if (port->is_a2j_mapped) |
|---|
| 783 | { |
|---|
| 784 | jack_client_name = _a2j->get_jack_client_name(); |
|---|
| 785 | jack_port_name = port->a2j_jack_port_name; |
|---|
| 786 | } |
|---|
| 787 | else |
|---|
| 788 | { |
|---|
| 789 | jack_client_name = port->module().lock()->name(); |
|---|
| 790 | jack_port_name = port->name(); |
|---|
| 791 | } |
|---|
| 792 | } |
|---|
| 793 | |
|---|
| 794 | void |
|---|
| 795 | Patchage::connect( |
|---|
| 796 | boost::shared_ptr<PatchagePort> port1, |
|---|
| 797 | boost::shared_ptr<PatchagePort> port2) |
|---|
| 798 | { |
|---|
| 799 | std::string jack_client1_name; |
|---|
| 800 | std::string jack_port1_name; |
|---|
| 801 | std::string jack_client2_name; |
|---|
| 802 | std::string jack_port2_name; |
|---|
| 803 | |
|---|
| 804 | if (port_type_match(port1, port2)) |
|---|
| 805 | { |
|---|
| 806 | get_port_jack_names(port1, jack_client1_name, jack_port1_name); |
|---|
| 807 | get_port_jack_names(port2, jack_client2_name, jack_port2_name); |
|---|
| 808 | |
|---|
| 809 | _jack->connect( |
|---|
| 810 | jack_client1_name.c_str(), |
|---|
| 811 | jack_port1_name.c_str(), |
|---|
| 812 | jack_client2_name.c_str(), |
|---|
| 813 | jack_port2_name.c_str()); |
|---|
| 814 | } |
|---|
| 815 | else |
|---|
| 816 | { |
|---|
| 817 | status_msg("ERROR: Attempt to connect ports with mismatched types"); |
|---|
| 818 | } |
|---|
| 819 | } |
|---|
| 820 | |
|---|
| 821 | void |
|---|
| 822 | Patchage::disconnect( |
|---|
| 823 | boost::shared_ptr<PatchagePort> port1, |
|---|
| 824 | boost::shared_ptr<PatchagePort> port2) |
|---|
| 825 | { |
|---|
| 826 | std::string jack_client1_name; |
|---|
| 827 | std::string jack_port1_name; |
|---|
| 828 | std::string jack_client2_name; |
|---|
| 829 | std::string jack_port2_name; |
|---|
| 830 | |
|---|
| 831 | if (port_type_match(port1, port2)) |
|---|
| 832 | { |
|---|
| 833 | get_port_jack_names(port1, jack_client1_name, jack_port1_name); |
|---|
| 834 | get_port_jack_names(port2, jack_client2_name, jack_port2_name); |
|---|
| 835 | |
|---|
| 836 | _jack->disconnect( |
|---|
| 837 | jack_client1_name.c_str(), |
|---|
| 838 | jack_port1_name.c_str(), |
|---|
| 839 | jack_client2_name.c_str(), |
|---|
| 840 | jack_port2_name.c_str()); |
|---|
| 841 | } |
|---|
| 842 | else |
|---|
| 843 | { |
|---|
| 844 | status_msg("ERROR: Attempt to disconnect ports with mismatched types"); |
|---|
| 845 | } |
|---|
| 846 | } |
|---|
| 847 | |
|---|
| 848 | bool |
|---|
| 849 | Patchage::is_canvas_empty() |
|---|
| 850 | { |
|---|
| 851 | return _canvas->items().empty(); |
|---|
| 852 | } |
|---|
| 853 | #endif |
|---|
| 854 | #endif |
|---|
| 855 | |
|---|
| 856 | GtkScrolledWindow * g_main_scrolledwin; |
|---|
| 857 | |
|---|
| 858 | struct view |
|---|
| 859 | { |
|---|
| 860 | char * name; |
|---|
| 861 | graph_canvas_handle graph_canvas; |
|---|
| 862 | graph_handle graph; |
|---|
| 863 | GtkWidget * canvas_widget; |
|---|
| 864 | }; |
|---|
| 865 | |
|---|
| 866 | struct view * create_view(const char * name, const char * service, const char * object) |
|---|
| 867 | { |
|---|
| 868 | struct view * view_ptr; |
|---|
| 869 | |
|---|
| 870 | view_ptr = malloc(sizeof(struct view)); |
|---|
| 871 | if (view_ptr == NULL) |
|---|
| 872 | { |
|---|
| 873 | lash_error("malloc() failed for struct view"); |
|---|
| 874 | goto fail; |
|---|
| 875 | } |
|---|
| 876 | |
|---|
| 877 | view_ptr->name = strdup(name); |
|---|
| 878 | if (view_ptr->name == NULL) |
|---|
| 879 | { |
|---|
| 880 | lash_error("strdup() failed for \"%s\"", name); |
|---|
| 881 | goto free_view; |
|---|
| 882 | } |
|---|
| 883 | |
|---|
| 884 | if (!graph_create(service, object, &view_ptr->graph)) |
|---|
| 885 | { |
|---|
| 886 | goto free_name; |
|---|
| 887 | } |
|---|
| 888 | |
|---|
| 889 | if (!graph_canvas_create(1600 * 2, 1200 * 2, &view_ptr->graph_canvas)) |
|---|
| 890 | { |
|---|
| 891 | goto destroy_graph; |
|---|
| 892 | } |
|---|
| 893 | |
|---|
| 894 | if (!graph_canvas_attach(view_ptr->graph_canvas, view_ptr->graph)) |
|---|
| 895 | { |
|---|
| 896 | goto destroy_graph_canvas; |
|---|
| 897 | } |
|---|
| 898 | |
|---|
| 899 | if (!graph_activate(view_ptr->graph)) |
|---|
| 900 | { |
|---|
| 901 | goto detach_graph_canvas; |
|---|
| 902 | } |
|---|
| 903 | |
|---|
| 904 | view_ptr->canvas_widget = canvas_get_widget(graph_canvas_get_canvas(view_ptr->graph_canvas)); |
|---|
| 905 | |
|---|
| 906 | gtk_widget_show(view_ptr->canvas_widget); |
|---|
| 907 | |
|---|
| 908 | return view_ptr; |
|---|
| 909 | |
|---|
| 910 | detach_graph_canvas: |
|---|
| 911 | graph_canvas_detach(view_ptr->graph_canvas); |
|---|
| 912 | destroy_graph_canvas: |
|---|
| 913 | graph_canvas_destroy(view_ptr->graph_canvas); |
|---|
| 914 | destroy_graph: |
|---|
| 915 | graph_destroy(view_ptr->graph); |
|---|
| 916 | free_name: |
|---|
| 917 | free(view_ptr->name); |
|---|
| 918 | free_view: |
|---|
| 919 | free(view_ptr); |
|---|
| 920 | fail: |
|---|
| 921 | return NULL; |
|---|
| 922 | } |
|---|
| 923 | |
|---|
| 924 | void destroy_view(struct view * view_ptr) |
|---|
| 925 | { |
|---|
| 926 | graph_canvas_detach(view_ptr->graph_canvas); |
|---|
| 927 | graph_canvas_destroy(view_ptr->graph_canvas); |
|---|
| 928 | graph_destroy(view_ptr->graph); |
|---|
| 929 | free(view_ptr->name); |
|---|
| 930 | free(view_ptr); |
|---|
| 931 | } |
|---|
| 932 | |
|---|
| 933 | void attach_view(struct view * view_ptr) |
|---|
| 934 | { |
|---|
| 935 | GtkWidget * child; |
|---|
| 936 | |
|---|
| 937 | child = gtk_bin_get_child(GTK_BIN(g_main_scrolledwin)); |
|---|
| 938 | if (child != NULL) |
|---|
| 939 | { |
|---|
| 940 | gtk_container_remove(GTK_CONTAINER(g_main_scrolledwin), child); |
|---|
| 941 | } |
|---|
| 942 | |
|---|
| 943 | gtk_container_add(GTK_CONTAINER(g_main_scrolledwin), view_ptr->canvas_widget); |
|---|
| 944 | |
|---|
| 945 | //_canvas->scroll_to(static_cast<int>(_canvas->width()/2 - 320), static_cast<int>(_canvas->height()/2 - 240)); // FIXME: hardcoded |
|---|
| 946 | //_main_scrolledwin->property_hadjustment().get_value()->set_step_increment(10); |
|---|
| 947 | //_main_scrolledwin->property_vadjustment().get_value()->set_step_increment(10); |
|---|
| 948 | } |
|---|
| 949 | |
|---|
| 950 | void detach_view(struct view * view_ptr) |
|---|
| 951 | { |
|---|
| 952 | GtkWidget * child; |
|---|
| 953 | |
|---|
| 954 | child = gtk_bin_get_child(GTK_BIN(g_main_scrolledwin)); |
|---|
| 955 | if (child == view_ptr->canvas_widget) |
|---|
| 956 | { |
|---|
| 957 | gtk_container_remove(GTK_CONTAINER(g_main_scrolledwin), view_ptr->canvas_widget); |
|---|
| 958 | } |
|---|
| 959 | } |
|---|
| 960 | |
|---|
| 961 | struct view * g_jack_view; |
|---|
| 962 | struct view * g_studio_view; |
|---|
| 963 | |
|---|
| 964 | void control_proxy_on_studio_appeared(void) |
|---|
| 965 | { |
|---|
| 966 | g_studio_view = create_view("Studio", SERVICE_NAME, STUDIO_OBJECT_PATH); |
|---|
| 967 | attach_view(g_studio_view); |
|---|
| 968 | g_jack_view = create_view("Raw JACK", JACKDBUS_SERVICE_NAME, JACKDBUS_OBJECT_PATH); |
|---|
| 969 | attach_view(g_jack_view); |
|---|
| 970 | } |
|---|
| 971 | |
|---|
| 972 | void control_proxy_on_studio_disappeared(void) |
|---|
| 973 | { |
|---|
| 974 | detach_view(g_jack_view); |
|---|
| 975 | destroy_view(g_jack_view); |
|---|
| 976 | detach_view(g_studio_view); |
|---|
| 977 | destroy_view(g_studio_view); |
|---|
| 978 | } |
|---|
| 979 | |
|---|
| 980 | int main(int argc, char** argv) |
|---|
| 981 | { |
|---|
| 982 | GtkWidget * main_win; |
|---|
| 983 | |
|---|
| 984 | gtk_init(&argc, &argv); |
|---|
| 985 | |
|---|
| 986 | if (!canvas_init()) |
|---|
| 987 | { |
|---|
| 988 | lash_error("Canvas initialization failed."); |
|---|
| 989 | return 1; |
|---|
| 990 | } |
|---|
| 991 | |
|---|
| 992 | if (!init_glade()) |
|---|
| 993 | { |
|---|
| 994 | return 1; |
|---|
| 995 | } |
|---|
| 996 | |
|---|
| 997 | /* Obtain widgets that we need */ |
|---|
| 998 | main_win = get_glade_widget("main_win"); |
|---|
| 999 | g_main_scrolledwin = GTK_SCROLLED_WINDOW(get_glade_widget("main_scrolledwin")); |
|---|
| 1000 | |
|---|
| 1001 | patchage_dbus_init(); |
|---|
| 1002 | |
|---|
| 1003 | if (!control_proxy_init()) |
|---|
| 1004 | { |
|---|
| 1005 | return 1; |
|---|
| 1006 | } |
|---|
| 1007 | |
|---|
| 1008 | //gtkmm_set_width_for_given_text(*_buffer_size_combo, "4096 frames", 40); |
|---|
| 1009 | |
|---|
| 1010 | g_signal_connect(G_OBJECT(main_win), "destroy", G_CALLBACK(gtk_main_quit), NULL); |
|---|
| 1011 | g_signal_connect(G_OBJECT(get_glade_widget("menu_file_quit")), "activate", G_CALLBACK(gtk_main_quit), NULL); |
|---|
| 1012 | |
|---|
| 1013 | gtk_widget_show(main_win); |
|---|
| 1014 | |
|---|
| 1015 | //_about_win->set_transient_for(*_main_win); |
|---|
| 1016 | |
|---|
| 1017 | gtk_main(); |
|---|
| 1018 | |
|---|
| 1019 | control_proxy_uninit(); |
|---|
| 1020 | uninit_glade(); |
|---|
| 1021 | |
|---|
| 1022 | return 0; |
|---|
| 1023 | } |
|---|