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));
303 virtual void on_show();
308 : Gtk::Window(Gtk::WINDOW_POPUP) {
309 set_redraw_on_allocate(
true);
311 g_signal_connect(GTK_WIDGET(gobj()),
"expose-event",
316 set_decorated(
false);
317 set_type_hint(Gdk::WINDOW_TYPE_HINT_SPLASHSCREEN);
318 set_position(Gtk::WIN_POS_CENTER );
319 set_default_size(613, 180);
324 Gtk::Widget::on_show();
325 while(Gtk::Main::events_pending())
326 Gtk::Main::iteration(
false);
339 gtk_rc_parse(rcfile.c_str());
340 gtk_rc_reset_styles(gtk_settings_get_default());
344 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(fname, &machine);
345 w = bld->get_first_window();
346 gx_ui::GxUI::updateAllGuis(
true);
358 static void null_handler(
const char *log_domain, GLogLevelFlags log_level,
359 const gchar *msg, gpointer user_data ) {
364 static void mainHeadless(
int argc,
char *argv[]) {
370 options.parse(argc, argv);
373 bool need_new_preset;
376 _(
"old config directory found (.gx_head)." 377 " state file and standard presets file have been copied to" 378 " the new directory (.config/guitarix).\n" 379 " Additional old preset files can be imported into the" 380 " new bank scheme by mouse drag and drop with a file" 394 cerr <<
"can't connect to jack\n";
397 if (need_new_preset) {
401 cout <<
"Ctrl-C to quit\n";
402 Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create();
403 machine.
get_jack()->
shutdown.connect(sigc::mem_fun(loop.operator->(),&Glib::MainLoop::quit));
417 static void exception_handler() {
421 cerr << error.
what() << endl;
423 }
catch (
const Glib::OptionError &error) {
424 cerr << error.what() << endl;
425 cerr << _(
"use \"guitarix -h\" to get a help text") << endl;
427 Glib::ustring::compose(
430 _(
"use \"guitarix -h\" to get a help text")));
431 }
catch (
const Glib::Error& error) {
432 const GError *perr = error.gobj();
433 Glib::ustring msg = Glib::ustring::compose(
434 "Glib::Error[%1/%2]: %3",
435 g_quark_to_string(perr->domain),
437 (perr->message) ? perr->message :
"(null)");
440 }
catch (
const std::exception& except) {
441 Glib::ustring msg = Glib::ustring::compose(
442 "std::exception: %1", except.what());
446 cerr << _(
"unknown error") << endl;
451 static void mainGtk(
int argc,
char *argv[]) {
456 Glib::add_exception_handler(sigc::ptr_fun(exception_handler));
458 Gtk::Main
main(argc, argv, options);
463 g_log_set_handler(
"Gtk",G_LOG_LEVEL_WARNING,null_handler,NULL);
471 bool need_new_preset;
473 Gtk::MessageDialog dialog(
474 _(
"old config directory found (.gx_head)." 475 " state file and standard presets file have been copied to" 476 " the new directory (.config/guitarix).\n" 477 " Additional old preset files can be imported into the" 478 " new bank scheme by mouse drag and drop with a file" 479 " manager"),
false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE,
true);
480 dialog.set_title(
"Guitarix");
489 debug_display_glade(engine, options, gx_engine::parameter_map, argv[1]);
496 if (need_new_preset) {
505 static void mainFront(
int argc,
char *argv[]) {
510 Glib::add_exception_handler(sigc::ptr_fun(exception_handler));
512 Gtk::Main
main(argc, argv, options);
517 g_log_set_handler(
"Gtk",G_LOG_LEVEL_WARNING,null_handler,NULL);
525 bool need_new_preset;
527 Gtk::MessageDialog dialog(
528 _(
"old config directory found (.gx_head)." 529 " state file and standard presets file have been copied to" 530 " the new directory (.config/guitarix).\n" 531 " Additional old preset files can be imported into the" 532 " new bank scheme by mouse drag and drop with a file" 533 " manager"),
false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE,
true);
534 dialog.set_title(
"Guitarix");
550 cerr <<
"Failed to get address" << endl;
555 title = Glib::ustring::compose(
"%1 / %2:%3", name, host, port);
570 MainWindow gui(machine, options, Splash, title);
571 if (need_new_preset) {
576 machine.set_init_values();
580 static bool is_headless(
int argc,
char *argv[]) {
581 for (
int i = 0; i < argc; ++i) {
582 if (strcmp(argv[i],
"-N") == 0 || strcmp(argv[i],
"--nogui") == 0) {
589 static bool is_frontend(
int argc,
char *argv[]) {
590 for (
int i = 0; i < argc; ++i) {
591 if (strcmp(argv[i],
"-G") == 0 || strcmp(argv[i],
"--onlygui") == 0) {
598 int main(
int argc,
char *argv[]) {
604 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
605 bind_textdomain_codeset(GETTEXT_PACKAGE,
"UTF-8");
606 textdomain(GETTEXT_PACKAGE);
611 #ifndef G_DISABLE_DEPRECATED 612 if (!g_thread_supported ()) {
616 if (is_headless(argc, argv)) {
617 mainHeadless(argc, argv);
618 }
else if (is_frontend(argc, argv)) {
619 mainFront(argc, argv);
void gx_print_info(const char *, const std::string &)
virtual void start_socket(sigc::slot< void > quit_mainloop, const Glib::ustring &host, int port)
bool get_address_port(Glib::ustring &address, int &port, Glib::ustring &name, Glib::ustring &host)
int get_idle_thread_timeout() const
void disable_autosave(bool v)
sigc::signal< void, std::string > & signal_msg()
static void rt_watchdog_set_limit(int limit)
void set_rpcaddress(const Glib::ustring &address)
gboolean error_box_expose(GtkWidget *wi, GdkEventExpose *ev, gpointer user_data)
static bool check_settings_dir(gx_system::CmdlineOptions &opt, bool *need_new_preset)
void gx_print_fatal(const char *, const std::string &)
const Glib::ustring & get_rpcaddress()
std::string get_style_filepath(const std::string &basename) const
void gx_sigchld_handler()
static GxLogger & get_logger()
void create_default_scratch_preset()
void process(int argc, char **argv)
const Glib::ustring & get_rcset() const
static GxExit & get_instance()
msg_signal & signal_message()
gboolean splash_expose(GtkWidget *wi, GdkEventExpose *ev, gpointer user_data)
bool get_auto_save_state()
virtual void create_default_scratch_preset()
void set_rpcport(int port)
void gx_print_warning(const char *, const std::string &)
void exit_program(std::string msg="", int errcode=1)
int main(int argc, char *argv[])
void show_error_msg(const string &msg)
Glib::Dispatcher shutdown
bool gx_jack_connection(bool connect, bool startserver, int wait_after_connect, const gx_system::CmdlineOptions &opt)
virtual const char * what() const
virtual gx_jack::GxJack * get_jack()