28 #include <gtkmm/main.h>
29 #include <gxwmm/init.h>
53 void signal_helper_thread();
55 void gx_ladi_handler();
58 static void relay_sigchld(
int);
71 sigemptyset(&waitset);
76 sigaddset(&waitset, SIGUSR1);
77 sigaddset(&waitset, SIGCHLD);
78 sigaddset(&waitset, SIGINT);
79 sigaddset(&waitset, SIGQUIT);
80 sigaddset(&waitset, SIGTERM);
81 sigaddset(&waitset, SIGHUP);
82 sigaddset(&waitset, SIGKILL);
88 sigprocmask(SIG_BLOCK, &waitset, NULL);
90 signal(SIGCHLD, relay_sigchld);
96 pthread_kill(pthr, SIGINT);
99 sigprocmask(SIG_UNBLOCK, &waitset, NULL);
102 void PosixSignals::create_thread() {
104 thread = Glib::Thread::create(
105 sigc::mem_fun(*
this, &PosixSignals::signal_helper_thread),
true);
106 }
catch (Glib::ThreadError& e) {
108 boost::format(_(
"Thread create failed (signal): %1%")) % e.what());
112 void PosixSignals::quit_slot() {
116 void PosixSignals::gx_ladi_handler() {
118 _(
"signal_handler"), _(
"signal USR1 received, save settings"));
119 if (gx_preset::GxSettings::instance) {
127 void PosixSignals::relay_sigchld(
int) {
128 kill(getpid(), SIGCHLD);
131 bool PosixSignals::gtk_level() {
135 return Gtk::Main::level();
140 void PosixSignals::signal_helper_thread() {
141 pthr = pthread_self();
143 guint source_id_usr1 = 0;
144 pthread_sigmask(SIG_BLOCK, &waitset, NULL);
148 int ret = sigwait(&waitset, &sig);
153 assert(errno == EINTR);
158 if (gtk_level() < 1) {
160 _(
"signal usr1 skipped"));
164 if (source_id_usr1 == 0 ||
165 g_main_context_find_source_by_id(NULL, source_id_usr1) == NULL) {
166 const Glib::RefPtr<Glib::IdleSource> idle_source = Glib::IdleSource::create();
167 idle_source->connect(
168 sigc::bind_return<bool>(
169 sigc::mem_fun(*
this, &PosixSignals::gx_ladi_handler),
false));
170 idle_source->attach();
171 source_id_usr1 = idle_source->get_id();
175 Glib::signal_idle().connect_once(
184 signame = _(
"ctrl-c");
196 if (!seen && gtk_level() == 1) {
197 printf(
"\nquit (%s)\n", signame);
198 Glib::signal_idle().connect_once(sigc::mem_fun(*
this, &PosixSignals::quit_slot));
201 (boost::format(
"\nQUIT (%1%)\n") % signame).str());
221 Gtk::MessageDialog *dialog;
223 void on_response(
int);
247 if (msg.size() > 1000) {
248 msg.substr(msg.size()-1000);
251 dialog->set_message(msg);
261 void ErrorPopup::on_response(
int) {
267 void ErrorPopup::show_msg() {
268 dialog =
new Gtk::MessageDialog(msg,
false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE);
269 dialog->set_keep_above(
true);
272 Gtk::VBox *ma =
dynamic_cast<Gtk::VBox*
>(
273 *(++
dynamic_cast<Gtk::HBox*
>(
274 *dialog->get_vbox()->get_children().begin())->get_children().begin()));
277 Gtk::Alignment *align =
new Gtk::Alignment();
279 dynamic_cast<Gtk::Label*
>(*ma->get_children().begin())->reparent(*align);
280 ma->pack_start(*manage(align));
281 align->set_padding(50,20,0,10);
282 Gtk::VBox *vbox =
dynamic_cast<Gtk::VBox *
>(dialog->get_child());
283 vbox->set_redraw_on_allocate(
true);
284 g_signal_connect(GTK_WIDGET(vbox->gobj()),
"expose-event",
288 dialog->set_title(_(
"GUITARIX ERROR"));
289 dialog->signal_response().connect(
290 sigc::mem_fun(*
this, &ErrorPopup::on_response));
309 : Gtk::Window(Gtk::WINDOW_POPUP) {
310 set_redraw_on_allocate(
true);
312 g_signal_connect(GTK_WIDGET(gobj()),
"expose-event",
317 set_decorated(
false);
318 set_type_hint(Gdk::WINDOW_TYPE_HINT_SPLASHSCREEN);
319 set_position(Gtk::WIN_POS_CENTER );
320 set_default_size(613, 180);
329 Gtk::Widget::on_show();
330 while(Gtk::Main::events_pending())
331 Gtk::Main::iteration(
false);
344 gtk_rc_parse(rcfile.c_str());
345 gtk_rc_reset_styles(gtk_settings_get_default());
349 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(fname, &machine);
350 w = bld->get_first_window();
351 gx_ui::GxUI::updateAllGuis(
true);
363 static void null_handler(
const char *log_domain, GLogLevelFlags log_level,
364 const gchar *msg, gpointer user_data ) {
369 static void mainHeadless(
int argc,
char *argv[]) {
375 options.parse(argc, argv);
378 bool need_new_preset;
381 _(
"old config directory found (.gx_head)."
382 " state file and standard presets file have been copied to"
383 " the new directory (.config/guitarix).\n"
384 " Additional old preset files can be imported into the"
385 " new bank scheme by mouse drag and drop with a file"
398 if (! machine.get_jack()->gx_jack_connection(
true,
true, 0, options)) {
399 cerr <<
"can't connect to jack\n";
402 if (need_new_preset) {
403 machine.create_default_scratch_preset();
406 cout <<
"Ctrl-C to quit\n";
407 Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create();
408 machine.get_jack()->shutdown.connect(sigc::mem_fun(loop.operator->(),&Glib::MainLoop::quit));
415 machine.start_socket(sigc::mem_fun(loop.operator->(),&Glib::MainLoop::quit), options.
get_rpcaddress(), port);
423 static void exception_handler() {
427 cerr << error.
what() << endl;
429 }
catch (
const Glib::OptionError &error) {
430 cerr << error.what() << endl;
431 cerr << _(
"use \"guitarix -h\" to get a help text") << endl;
433 Glib::ustring::compose(
436 _(
"use \"guitarix -h\" to get a help text")));
437 }
catch (
const Glib::Error& error) {
438 const GError *perr = error.gobj();
439 Glib::ustring msg = Glib::ustring::compose(
440 "Glib::Error[%1/%2]: %3",
441 g_quark_to_string(perr->domain),
443 (perr->message) ? perr->message :
"(null)");
446 }
catch (
const std::exception& except) {
447 Glib::ustring msg = Glib::ustring::compose(
448 "std::exception: %1", except.what());
452 cerr << _(
"unknown error") << endl;
457 static void mainGtk(
int argc,
char *argv[]) {
462 Glib::add_exception_handler(sigc::ptr_fun(exception_handler));
464 Gtk::Main
main(argc, argv, options);
471 g_log_set_handler(
"Gtk",G_LOG_LEVEL_WARNING,null_handler,NULL);
479 bool need_new_preset;
481 Gtk::MessageDialog dialog(
482 _(
"old config directory found (.gx_head)."
483 " state file and standard presets file have been copied to"
484 " the new directory (.config/guitarix).\n"
485 " Additional old preset files can be imported into the"
486 " new bank scheme by mouse drag and drop with a file"
487 " manager"),
false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE,
true);
488 dialog.set_title(
"Guitarix");
497 debug_display_glade(engine, options, gx_engine::parameter_map, argv[1]);
504 if (need_new_preset) {
505 gui.create_default_scratch_preset();
514 static void mainFront(
int argc,
char *argv[]) {
519 Glib::add_exception_handler(sigc::ptr_fun(exception_handler));
521 Gtk::Main
main(argc, argv, options);
526 g_log_set_handler(
"Gtk",G_LOG_LEVEL_WARNING,null_handler,NULL);
534 bool need_new_preset;
536 Gtk::MessageDialog dialog(
537 _(
"old config directory found (.gx_head)."
538 " state file and standard presets file have been copied to"
539 " the new directory (.config/guitarix).\n"
540 " Additional old preset files can be imported into the"
541 " new bank scheme by mouse drag and drop with a file"
542 " manager"),
false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE,
true);
543 dialog.set_title(
"Guitarix");
558 if (!si.get_address_port(a, port, name, host)) {
559 cerr <<
"Failed to get address" << endl;
564 title = Glib::ustring::compose(
"%1 / %2:%3", name, host, port);
579 MainWindow gui(machine, options, Splash, title);
580 if (need_new_preset) {
581 gui.create_default_scratch_preset();
585 machine.set_init_values();
589 static bool is_headless(
int argc,
char *argv[]) {
590 for (
int i = 0; i < argc; ++i) {
591 if (strcmp(argv[i],
"-N") == 0 || strcmp(argv[i],
"--nogui") == 0) {
598 static bool is_frontend(
int argc,
char *argv[]) {
599 for (
int i = 0; i < argc; ++i) {
600 if (strcmp(argv[i],
"-G") == 0 || strcmp(argv[i],
"--onlygui") == 0) {
607 int main(
int argc,
char *argv[]) {
610 #elif defined(IS_MACOSX)
613 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
614 bind_textdomain_codeset(GETTEXT_PACKAGE,
"UTF-8");
615 textdomain(GETTEXT_PACKAGE);
620 #ifndef G_DISABLE_DEPRECATED
621 if (!g_thread_supported ()) {
625 if (is_headless(argc, argv)) {
626 mainHeadless(argc, argv);
627 }
else if (is_frontend(argc, argv)) {
628 mainFront(argc, argv);