1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008, 2009 Nedko Arnaudov <nedko@arnaudov.name>
6 * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
8 **************************************************************************
9 * This file contains the code that implements main() and other top-level functionality
10 **************************************************************************
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.
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.
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.
31 #include "graph_canvas.h"
32 #include "../jack_proxy.h"
33 #include "dbus_helpers.h"
34 #include "control_proxy.h"
42 Gtk::Window
* window() { return _main_win
.get(); }
44 void quit() { _main_win
->hide(); }
51 void set_studio_availability(bool available
);
53 void set_a2j_status(unsigned int status
);
55 void load_project_ask();
56 void load_project(const std::string
& project_name
);
57 void save_all_projects();
58 void save_project(const std::string
& project_name
);
59 void close_project(const std::string
& project_name
);
60 void close_all_projects();
64 void connect_widgets();
69 void on_show_projects();
70 void on_view_toolbar();
71 bool on_scroll(GdkEventScroll
* ev
);
76 void update_toolbar();
78 void jack_status_changed(bool started
);
80 void buffer_size_changed();
85 boost::shared_ptr
<PatchagePort
> port
,
86 std::string
& jack_client_name
,
87 std::string
& jack_port_name
);
89 boost::shared_ptr
<PatchagePort
>
91 const char * jack_client_name
,
92 const char * jack_port_name
);
98 //project_list * _project_list;
100 Gtk::Main
* _gtk_main
;
104 Widget
<Gtk::AboutDialog
> _about_win
;
105 Widget
<Gtk::ComboBox
> _buffer_size_combo
;
106 Widget
<Gtk::ToolButton
> _clear_load_but
;
107 Widget
<Gtk::ScrolledWindow
> _main_scrolledwin
;
108 Widget
<Gtk::Window
> _main_win
;
109 Widget
<Gtk::ProgressBar
> _main_xrun_progress
;
110 Widget
<Gtk::Label
> _main_a2j_status_label
;
111 Widget
<Gtk::MenuItem
> _menu_file_quit
;
112 Widget
<Gtk::MenuItem
> _menu_help_about
;
113 Widget
<Gtk::MenuItem
> _menu_jack_start
;
114 Widget
<Gtk::MenuItem
> _menu_jack_stop
;
115 Widget
<Gtk::MenuItem
> _menu_a2j_start
;
116 Widget
<Gtk::MenuItem
> _menu_a2j_stop
;
117 Widget
<Gtk::MenuItem
> _menu_load_project
;
118 Widget
<Gtk::MenuItem
> _menu_save_all_projects
;
119 Widget
<Gtk::MenuItem
> _menu_close_all_projects
;
120 Widget
<Gtk::MenuItem
> _menu_store_positions
;
121 Widget
<Gtk::MenuItem
> _menu_view_arrange
;
122 Widget
<Gtk::CheckMenuItem
> _menu_view_projects
;
123 Widget
<Gtk::MenuItem
> _menu_view_refresh
;
124 Widget
<Gtk::CheckMenuItem
> _menu_view_toolbar
;
125 Widget
<Gtk::Viewport
> _project_list_viewport
;
126 Widget
<Gtk::Label
> _sample_rate_label
;
127 Widget
<Gtk::Toolbar
> _toolbar
;
128 Widget
<Gtk::ToolButton
> _zoom_full_but
;
129 Widget
<Gtk::ToolButton
> _zoom_normal_but
;
132 #include "globals.hpp"
135 #include "Widget.hpp"
142 #include <libgnomecanvasmm.h>
143 #include <libglademm/xml.h>
144 #include <gtk/gtkwindow.h>
145 #include <boost/format.hpp>
147 #include "project_list.hpp"
148 #include "session.hpp"
149 #include "globals.hpp"
150 //#include "load_projects_dialog.hpp"
151 #include "graph_canvas.h"
152 #include "../jack_proxy.h"
157 //#define LOG_TO_STATUS
159 /* Gtk helpers (resize combo boxes) */
162 gtkmm_get_ink_pixel_size (Glib::RefPtr
<Pango::Layout
> layout
,
166 Pango::Rectangle ink_rect
= layout
->get_ink_extents ();
168 width
= (ink_rect
.get_width() + PANGO_SCALE
/ 2) / PANGO_SCALE
;
169 height
= (ink_rect
.get_height() + PANGO_SCALE
/ 2) / PANGO_SCALE
;
173 gtkmm_set_width_for_given_text (Gtk::Widget
&w
, const gchar
*text
,
174 gint hpadding
/*, gint vpadding*/)
177 int old_width
, old_height
;
178 w
.get_size_request(old_width
, old_height
);
183 gtkmm_get_ink_pixel_size (w
.create_pango_layout (text
), width
, height
);
184 w
.set_size_request(width
+ hpadding
, old_height
);//height + vpadding);
187 /* end Gtk helpers */
190 #define INIT_WIDGET(x) x(g_xml, ((const char*)#x) + 1)
195 , INIT_WIDGET(_about_win
)
196 , INIT_WIDGET(_buffer_size_combo
)
197 , INIT_WIDGET(_clear_load_but
)
198 , INIT_WIDGET(_main_scrolledwin
)
199 , INIT_WIDGET(_main_win
)
200 , INIT_WIDGET(_main_xrun_progress
)
201 , INIT_WIDGET(_main_a2j_status_label
)
202 , INIT_WIDGET(_menu_file_quit
)
203 , INIT_WIDGET(_menu_help_about
)
204 , INIT_WIDGET(_menu_jack_start
)
205 , INIT_WIDGET(_menu_jack_stop
)
206 , INIT_WIDGET(_menu_a2j_start
)
207 , INIT_WIDGET(_menu_a2j_stop
)
208 , INIT_WIDGET(_menu_load_project
)
209 , INIT_WIDGET(_menu_save_all_projects
)
210 , INIT_WIDGET(_menu_close_all_projects
)
211 , INIT_WIDGET(_menu_store_positions
)
212 , INIT_WIDGET(_menu_view_arrange
)
213 , INIT_WIDGET(_menu_view_projects
)
214 , INIT_WIDGET(_menu_view_refresh
)
215 , INIT_WIDGET(_menu_view_toolbar
)
216 , INIT_WIDGET(_project_list_viewport
)
217 , INIT_WIDGET(_sample_rate_label
)
218 , INIT_WIDGET(_toolbar
)
219 , INIT_WIDGET(_zoom_full_but
)
220 , INIT_WIDGET(_zoom_normal_but
)
225 patchage_dbus_init();
227 graph_create(JACKDBUS_SERVICE
, JACKDBUS_OBJECT
, &g_jack_graph
);
228 graph_canvas_create(1600 * 2, 1200 * 2, &g_jack_graph_canvas
);
229 graph_canvas_attach(g_jack_graph_canvas
, g_jack_graph
);
230 graph_activate(g_jack_graph
);
232 Glib::set_application_name("Patchage");
233 _about_win
->property_program_name() = "Patchage";
234 _about_win
->property_logo_icon_name() = "gladish";
235 gtk_window_set_default_icon_name("gladish");
237 gtkmm_set_width_for_given_text(*_buffer_size_combo
, "4096 frames", 40);
239 _main_scrolledwin
->add(*Glib::wrap(canvas_get_widget(graph_canvas_get_canvas(g_jack_graph_canvas
))));
241 // _canvas->scroll_to(static_cast<int>(_canvas->width()/2 - 320),
242 // static_cast<int>(_canvas->height()/2 - 240)); // FIXME: hardcoded
244 _main_scrolledwin
->property_hadjustment().get_value()->set_step_increment(10);
245 _main_scrolledwin
->property_vadjustment().get_value()->set_step_increment(10);
247 _main_scrolledwin
->signal_scroll_event().connect(
248 sigc::mem_fun(this, &Patchage::on_scroll
));
250 _buffer_size_combo
->signal_changed().connect(
251 sigc::mem_fun(this, &Patchage::buffer_size_changed
));
252 _clear_load_but
->signal_clicked().connect(
253 sigc::mem_fun(this, &Patchage::clear_load
));
254 _zoom_normal_but
->signal_clicked().connect(sigc::bind(
255 sigc::mem_fun(this, &Patchage::zoom
), 1.0));
256 // _zoom_full_but->signal_clicked().connect(sigc::mem_fun(_canvas.get(), &PatchageCanvas::zoom_full));
258 // _menu_load_project->signal_activate().connect(sigc::mem_fun(this, &Patchage::load_project_ask));
259 // _menu_save_all_projects->signal_activate().connect(sigc::mem_fun(this, &Patchage::save_all_projects));
260 // _menu_close_all_projects->signal_activate().connect(sigc::mem_fun(this, &Patchage::close_all_projects));
262 _menu_file_quit
->signal_activate().connect(
263 sigc::mem_fun(this, &Patchage::on_quit
));
264 _menu_view_refresh
->signal_activate().connect(
265 sigc::mem_fun(this, &Patchage::refresh
));
266 _menu_view_arrange
->signal_activate().connect(
267 sigc::mem_fun(this, &Patchage::on_arrange
));
268 _menu_view_toolbar
->signal_activate().connect(
269 sigc::mem_fun(this, &Patchage::on_view_toolbar
));
270 _menu_view_projects
->signal_toggled().connect(
271 sigc::mem_fun(this, &Patchage::on_show_projects
));
272 _menu_help_about
->signal_activate().connect(
273 sigc::mem_fun(this, &Patchage::on_help_about
));
275 Glib::wrap(canvas_get_widget(graph_canvas_get_canvas(g_jack_graph_canvas
)))->show();
276 _main_win
->present();
278 _about_win
->set_transient_for(*_main_win
);
280 // _a2j = new a2j_proxy;
282 //info_msg(str(boost::format("a2j jack client name is '%s'") % _a2j->get_jack_client_name()));
284 // _session = new session();
286 // _project_list = new project_list(this, _session);
287 // _project_list_viewport->hide();
289 // _lash = new lash_proxy(_session);
291 //_menu_jack_start->signal_activate().connect(sigc::mem_fun(_jack, &jack_proxy::start_server));
292 //_menu_jack_stop->signal_activate().connect(sigc::mem_fun(_jack, &jack_proxy::stop_server));
294 // _menu_a2j_start->signal_activate().connect(sigc::mem_fun(_a2j, &a2j_proxy::start_bridge));
295 // _menu_a2j_stop->signal_activate().connect(sigc::mem_fun(_a2j, &a2j_proxy::stop_bridge));
297 //jack_status_changed(_jack->is_started());
302 // _canvas->grab_focus();
304 // Idle callback, check if we need to refresh
305 Glib::signal_timeout().connect(
306 sigc::mem_fun(this, &Patchage::idle_callback
), 100);
309 Patchage::~Patchage()
312 //delete _project_list;
316 _about_win
.destroy();
317 //_main_win.destroy();
319 patchage_dbus_uninit();
323 Patchage::idle_callback()
331 Patchage::update_toolbar()
336 started
= _jack
->is_started();
338 _buffer_size_combo
->set_sensitive(started
);
342 _buffer_size_combo
->set_active((int)log2f(_jack
->buffer_size()) - 5);
348 Patchage::update_load()
351 if (!_jack
->is_started())
353 _main_xrun_progress
->set_text("JACK stopped");
358 snprintf(tmp_buf
, 8, "%zd", _jack
->xruns());
360 _main_xrun_progress
->set_text(std::string(tmp_buf
) + " Dropouts");
362 float load
= _jack
->get_dsp_load();
364 load
/= 100.0; // dbus returns it in percents, we use 0..1
366 if (load
> _max_dsp_load
)
368 _max_dsp_load
= load
;
369 _main_xrun_progress
->set_fraction(load
);
376 Patchage::zoom(double z
)
378 // _canvas->set_zoom(z);
387 // _canvas->destroy();
392 // for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) {
398 Patchage::clear_load()
401 _main_xrun_progress
->set_fraction(0.0);
402 _jack
->reset_xruns();
408 Patchage::update_state()
410 // for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) {
411 // shared_ptr<Module> module = dynamic_pointer_cast<Module>(*i);
413 // module->load_location();
418 /** Update the sensitivity status of menus to reflect the present.
420 * (eg. disable "Connect to Jack" when Patchage is already connected to Jack)
423 Patchage::connect_widgets()
425 //_jack->signal_started.connect(sigc::bind(sigc::mem_fun(this, &Patchage::jack_status_changed), true));
426 //_jack->signal_stopped.connect(sigc::bind(sigc::mem_fun(this, &Patchage::jack_status_changed), false));
430 Patchage::jack_status_changed(
435 _menu_jack_start
->set_sensitive(!started
);
436 _menu_jack_stop
->set_sensitive(started
);
437 _clear_load_but
->set_sensitive(started
);
440 _main_xrun_progress
->set_fraction(0.0);
445 Patchage::on_arrange()
449 // _canvas->arrange();
454 Patchage::on_help_about()
468 Patchage::on_show_projects()
470 if (_menu_view_projects
->get_active())
471 _project_list_viewport
->show();
473 _project_list_viewport
->hide();
477 Patchage::on_view_toolbar()
479 if (_menu_view_toolbar
->get_active())
487 Patchage::on_scroll(GdkEventScroll
* ev
)
489 lash_debug("ON SCROLL");
495 Patchage::buffer_size_changed()
498 const int selected
= _buffer_size_combo
->get_active_row_number();
506 uint32_t buffer_size
= 1 << (selected
+5);
508 // this check is temporal workaround for jack bug
509 // we skip setting buffer size if it same as acutal one
510 // proper place for such check is in jack
511 if (_jack
->buffer_size() != buffer_size
)
513 if (!_jack
->set_buffer_size(buffer_size
))
515 update_toolbar(); // reset combo box to actual value
523 Patchage::set_studio_availability(
528 _main_win
->set_title("Active Studio - LADI Session Handler");
532 _main_win
->set_title("LADI Session Handler");
534 //_project_list->set_lash_availability(available);
535 _menu_view_projects
->set_active(available
);
540 Patchage::set_a2j_status(
543 const char * status_text
;
547 case A2J_STATUS_NO_RESPONSE
:
548 status_text
= "A2J N/A";
549 _menu_a2j_start
->set_sensitive(false);
550 _menu_a2j_stop
->set_sensitive(false);
552 case A2J_STATUS_BRIDGE_STOPPED
:
553 status_text
= "A2J bridge stopped";
554 _menu_a2j_start
->set_sensitive(true);
555 _menu_a2j_stop
->set_sensitive(false);
557 case A2J_STATUS_BRIDGE_STARTED
:
558 status_text
= "A2J bridge started";
559 _menu_a2j_start
->set_sensitive(false);
560 _menu_a2j_stop
->set_sensitive(true);
563 error_msg(str(boost::format("Unknown A2J status %u") % status
));
564 status_text
= "Unknown A2J status";
565 _menu_a2j_start
->set_sensitive(true);
566 _menu_a2j_stop
->set_sensitive(true);
570 _main_a2j_status_label
->set_text(status_text
);
574 Patchage::load_project_ask()
576 std::list
<lash_project_info
> projects
;
578 _lash
->get_available_projects(projects
);
579 run_load_project_dialog(projects
);
583 Patchage::load_project(
584 const std::string
& project_name
)
586 _lash
->load_project(project_name
);
590 Patchage::save_all_projects()
592 _lash
->save_all_projects();
596 Patchage::save_project(
597 const std::string
& project_name
)
599 _lash
->save_project(project_name
);
603 Patchage::close_project(
604 const std::string
& project_name
)
606 _lash
->close_project(project_name
);
610 Patchage::close_all_projects()
612 _lash
->close_all_projects();
616 Patchage::on_port_added(
617 const char * jack_client_name
,
618 const char * jack_port_name
,
624 std::string canvas_client_name
;
625 std::string canvas_port_name
;
626 uint32_t alsa_client_id
;
627 boost::shared_ptr
<PatchageModule
> module
;
629 is_a2j_mapped
= strcmp(_a2j
->get_jack_client_name(), jack_client_name
) == 0;
632 if (!_a2j
->map_jack_port(jack_port_name
, canvas_client_name
, canvas_port_name
, alsa_client_id
))
637 canvas_port_name
= str(boost::format(canvas_port_name
+ " [a2j:%u]") % alsa_client_id
);
641 canvas_client_name
= jack_client_name
;
642 canvas_port_name
= jack_port_name
;
645 ModuleType module_type
= InputOutput
;
646 if (_state_manager
->get_module_split(canvas_client_name
, is_terminal
&& !is_a2j_mapped
)) {
650 module_type
= Output
;
654 module
= _canvas
->find_module(canvas_client_name
, module_type
);
656 module
= boost::shared_ptr
<PatchageModule
>(new PatchageModule(this, canvas_client_name
, module_type
));
657 module
->load_location();
658 _canvas
->add_item(module
);
661 if (module
->get_port(canvas_port_name
)) {
665 boost::shared_ptr
<PatchagePort
> port
= boost::shared_ptr
<PatchagePort
>(
670 _state_manager
->get_port_color(port_type
)));
672 port
->type
= port_type
;
673 port
->is_a2j_mapped
= is_a2j_mapped
;
676 port
->a2j_jack_port_name
= jack_port_name
;
679 module
->add_port(port
);
684 boost::shared_ptr
<PatchagePort
>
685 Patchage::lookup_port(
686 const char * jack_client_name
,
687 const char * jack_port_name
)
689 if (strcmp(_a2j
->get_jack_client_name(), jack_client_name
) == 0)
691 return _canvas
->lookup_port_by_a2j_jack_port_name(jack_port_name
);
694 return _canvas
->get_port(jack_client_name
, jack_port_name
);
698 Patchage::on_port_removed(
699 const char * jack_client_name
,
700 const char * jack_port_name
)
702 boost::shared_ptr
<PatchagePort
> port
= lookup_port(jack_client_name
, jack_port_name
);
704 error_msg(str(boost::format("Unable to remove unknown port '%s':'%s'") % jack_client_name
% jack_port_name
));
708 boost::shared_ptr
<PatchageModule
> module
= dynamic_pointer_cast
<PatchageModule
>(port
->module().lock());
710 module
->remove_port(port
);
713 // No empty modules (for now)
714 if (module
->num_ports() == 0) {
715 _canvas
->remove_item(module
);
723 Patchage::on_ports_connected(
724 const char * jack_client1_name
,
725 const char * jack_port1_name
,
726 const char * jack_client2_name
,
727 const char * jack_port2_name
)
729 boost::shared_ptr
<PatchagePort
> port1
= lookup_port(jack_client1_name
, jack_port1_name
);
731 error_msg((std::string
)"Unable to connect unknown port '" + jack_port1_name
+ "' of client '" + jack_client1_name
+ "'");
735 boost::shared_ptr
<PatchagePort
> port2
= lookup_port(jack_client2_name
, jack_port2_name
);
737 error_msg((std::string
)"Unable to connect unknown port '" + jack_port2_name
+ "' of client '" + jack_client2_name
+ "'");
741 _canvas
->add_connection(port1
, port2
, port1
->color() + 0x22222200);
745 Patchage::on_ports_disconnected(
746 const char * jack_client1_name
,
747 const char * jack_port1_name
,
748 const char * jack_client2_name
,
749 const char * jack_port2_name
)
751 boost::shared_ptr
<PatchagePort
> port1
= lookup_port(jack_client1_name
, jack_port1_name
);
753 error_msg((std::string
)"Unable to disconnect unknown port '" + jack_port1_name
+ "' of client '" + jack_client1_name
+ "'");
757 boost::shared_ptr
<PatchagePort
> port2
= lookup_port(jack_client2_name
, jack_port2_name
);
759 error_msg((std::string
)"Unable to disconnect unknown port '" + jack_port2_name
+ "' of client '" + jack_client2_name
+ "'");
763 _canvas
->remove_connection(port1
, port2
);
769 boost::shared_ptr
<PatchagePort
> port1
,
770 boost::shared_ptr
<PatchagePort
> port2
)
772 return port1
->type
== port2
->type
;
776 Patchage::get_port_jack_names(
777 boost::shared_ptr
<PatchagePort
> port
,
778 std::string
& jack_client_name
,
779 std::string
& jack_port_name
)
781 if (port
->is_a2j_mapped
)
783 jack_client_name
= _a2j
->get_jack_client_name();
784 jack_port_name
= port
->a2j_jack_port_name
;
788 jack_client_name
= port
->module().lock()->name();
789 jack_port_name
= port
->name();
795 boost::shared_ptr
<PatchagePort
> port1
,
796 boost::shared_ptr
<PatchagePort
> port2
)
798 std::string jack_client1_name
;
799 std::string jack_port1_name
;
800 std::string jack_client2_name
;
801 std::string jack_port2_name
;
803 if (port_type_match(port1
, port2
))
805 get_port_jack_names(port1
, jack_client1_name
, jack_port1_name
);
806 get_port_jack_names(port2
, jack_client2_name
, jack_port2_name
);
809 jack_client1_name
.c_str(),
810 jack_port1_name
.c_str(),
811 jack_client2_name
.c_str(),
812 jack_port2_name
.c_str());
816 status_msg("ERROR: Attempt to connect ports with mismatched types");
821 Patchage::disconnect(
822 boost::shared_ptr
<PatchagePort
> port1
,
823 boost::shared_ptr
<PatchagePort
> port2
)
825 std::string jack_client1_name
;
826 std::string jack_port1_name
;
827 std::string jack_client2_name
;
828 std::string jack_port2_name
;
830 if (port_type_match(port1
, port2
))
832 get_port_jack_names(port1
, jack_client1_name
, jack_port1_name
);
833 get_port_jack_names(port2
, jack_client2_name
, jack_port2_name
);
836 jack_client1_name
.c_str(),
837 jack_port1_name
.c_str(),
838 jack_client2_name
.c_str(),
839 jack_port2_name
.c_str());
843 status_msg("ERROR: Attempt to disconnect ports with mismatched types");
848 Patchage::is_canvas_empty()
850 return _canvas
->items().empty();
855 GtkScrolledWindow
* g_main_scrolledwin
;
860 graph_canvas_handle graph_canvas
;
862 GtkWidget
* canvas_widget
;
865 struct view
* create_view(const char * name
, const char * service
, const char * object
)
867 struct view
* view_ptr
;
869 view_ptr
= malloc(sizeof(struct view
));
870 if (view_ptr
== NULL
)
872 lash_error("malloc() failed for struct view");
876 view_ptr
->name
= strdup(name
);
877 if (view_ptr
->name
== NULL
)
879 lash_error("strdup() failed for \"%s\"", name
);
883 if (!graph_create(JACKDBUS_SERVICE
, JACKDBUS_OBJECT
, &view_ptr
->graph
))
888 if (!graph_canvas_create(1600 * 2, 1200 * 2, &view_ptr
->graph_canvas
))
893 if (!graph_canvas_attach(view_ptr
->graph_canvas
, view_ptr
->graph
))
895 goto destroy_graph_canvas
;
898 if (!graph_activate(view_ptr
->graph
))
900 goto detach_graph_canvas
;
903 view_ptr
->canvas_widget
= canvas_get_widget(graph_canvas_get_canvas(view_ptr
->graph_canvas
));
905 gtk_widget_show(view_ptr
->canvas_widget
);
910 graph_canvas_detach(view_ptr
->graph_canvas
);
911 destroy_graph_canvas
:
912 graph_canvas_destroy(view_ptr
->graph_canvas
);
914 graph_destroy(view_ptr
->graph
);
916 free(view_ptr
->name
);
923 void destroy_view(struct view
* view_ptr
)
925 graph_canvas_detach(view_ptr
->graph_canvas
);
926 graph_canvas_destroy(view_ptr
->graph_canvas
);
927 graph_destroy(view_ptr
->graph
);
928 free(view_ptr
->name
);
932 struct view
* g_jack_view
;
934 void control_proxy_on_studio_appeared(void)
936 g_jack_view
= create_view("Raw JACK", JACKDBUS_SERVICE
, JACKDBUS_OBJECT
);
938 gtk_container_add(GTK_CONTAINER(g_main_scrolledwin
), g_jack_view
->canvas_widget
);
940 //_canvas->scroll_to(static_cast<int>(_canvas->width()/2 - 320), static_cast<int>(_canvas->height()/2 - 240)); // FIXME: hardcoded
941 //_main_scrolledwin->property_hadjustment().get_value()->set_step_increment(10);
942 //_main_scrolledwin->property_vadjustment().get_value()->set_step_increment(10);
945 void control_proxy_on_studio_disappeared(void)
947 gtk_container_remove(GTK_CONTAINER(g_main_scrolledwin
), g_jack_view
->canvas_widget
);
948 destroy_view(g_jack_view
);
951 int main(int argc
, char** argv
)
953 GtkWidget
* main_win
;
955 gtk_init(&argc
, &argv
);
959 lash_error("Canvas initialization failed.");
968 /* Obtain widgets that we need */
969 main_win
= get_glade_widget("main_win");
970 g_main_scrolledwin
= GTK_SCROLLED_WINDOW(get_glade_widget("main_scrolledwin"));
972 patchage_dbus_init();
974 if (!control_proxy_init())
979 //gtkmm_set_width_for_given_text(*_buffer_size_combo, "4096 frames", 40);
981 g_signal_connect(G_OBJECT(main_win
), "destroy", G_CALLBACK(gtk_main_quit
), NULL
);
982 g_signal_connect(G_OBJECT(get_glade_widget("menu_file_quit")), "activate", G_CALLBACK(gtk_main_quit
), NULL
);
984 gtk_widget_show(main_win
);
986 //_about_win->set_transient_for(*_main_win);
990 control_proxy_uninit();