X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Fui-gnome.c;h=75182f9ec4757a89f2c26f38a318a56e3b637d67;hb=4e21ae021fecaa14f68c61324d66a374f0f3038f;hp=f706abc6d4d8e094f6072f050550e96eff27fb95;hpb=755a54d546c01f396c179cc954582b5b8fa89a82;p=udpgate.git diff --git a/src/ui-gnome.c b/src/ui-gnome.c index f706abc..75182f9 100644 --- a/src/ui-gnome.c +++ b/src/ui-gnome.c @@ -41,7 +41,7 @@ #include "network.h" #include "packet.h" -#include "startup.h" +#include "static-startup.h" /* Config: */ @@ -49,6 +49,7 @@ #define EXTERNAL_STARTUP_CHECK_INTERVAL_MS 1000 #define PORT_RANGE_BEGIN 2048 #define PORT_RANGE_END 10240 +#define UI_GNOME_PROBE_TIMEOUT_SEC 10 static GnomeApp *App; @@ -89,6 +90,9 @@ static gboolean last_daemon_running,last_daemon_running_set=FALSE; static gboolean daemon_check_timeout_func(gpointer data /* unused */) { + if (!App) /* Quitting? */ + return FALSE; /* stop running */ + state_start_stop(); return TRUE; /* continue running */ } @@ -97,11 +101,21 @@ static gboolean external_startup_check_timeout_func(gpointer data /* unused */) { gboolean state_startup_is_on; - if (startup_query(&state_startup_is_on)) + if (!App) /* Quitting? */ + return FALSE; /* stop running */ + + if (static_startup_query(&state_startup_is_on)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(AutostartCheckButton),state_startup_is_on); return TRUE; /* continue running */ } +static void buttonstart(void) +{ + if (!optarg_port_set_string(gtk_entry_get_text(PortEntry))) + return; + network_start(optarg_port); +} + void on_PortButtonRandom_clicked(GtkButton *button,gpointer user_data) { g_return_if_fail(GTK_IS_BUTTON(button)); @@ -111,26 +125,38 @@ void on_PortButtonRandom_clicked(GtkButton *button,gpointer user_data) return; gtk_entry_set_text(PortEntry, udpgate_printf_alloca("%d",(int)g_random_int_range(PORT_RANGE_BEGIN,PORT_RANGE_END))); + buttonstart(); } void on_AutostartCheckButton_toggled(GtkToggleButton *togglebutton,gpointer user_data) { +static gint inside=0; + g_return_if_fail(GTK_IS_TOGGLE_BUTTON(togglebutton)); + /* Avoid reentrancy to prevent segfault during failed registration. + * FIXME: Who knows why? Some forbidden GTK recursion occurs. + */ + g_assert(inside>=0); + if (inside) + return; + inside++; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AutostartCheckButton))) - startup_on(); + static_startup_on(); else - startup_off(); + static_startup_off(); external_startup_check_timeout_func(NULL); /* data; unused */ + + g_assert(inside==1); + inside--; } void on_ButtonStart_clicked(GtkButton *button,gpointer user_data) { g_return_if_fail(GTK_IS_BUTTON(button)); - if (!optarg_port_set_string(gtk_entry_get_text(PortEntry))) - return; - network_start(optarg_port); + buttonstart(); } void on_ButtonStop_clicked(GtkButton *button,gpointer user_data) @@ -142,6 +168,8 @@ void on_ButtonStop_clicked(GtkButton *button,gpointer user_data) void on_ButtonHide_clicked(GtkButton *button,gpointer user_data) { +GnomeApp *App_local; + g_return_if_fail(GTK_IS_BUTTON(button)); /* update config file */ @@ -150,16 +178,30 @@ void on_ButtonHide_clicked(GtkButton *button,gpointer user_data) /* Do not: gtk_main_quit(); * as 'App' widget will quit our gtk_main() automatically. */ - gtk_widget_destroy(GTK_WIDGET(App)); + /* Do not: gtk_widget_destroy(App); App=NULL; + * as it would race with g_timeout_add()ed function which check + * 'if (!App)' first and expect there fully valid tree afterwards. + */ + App_local=App; + App=NULL; + gtk_widget_destroy(GTK_WIDGET(App_local)); } static void ui_gnome_network_notify_hostip(guint32 hostip_guint32) { + if (!App) /* Quitting? */ + return; + if (!hostip_guint32) { - if (is_daemon_running()==(pid_t)-1) +pid_t daemon_pid; + + daemon_pid=is_daemon_running(); + if ((pid_t)-1==daemon_pid) gtk_entry_set_text(HostIPEntry,_("(unknown; Start the daemon)")); - else + else if (getpid()==daemon_pid) gtk_entry_set_text(HostIPEntry,_("(unknown; detecting...)")); + else + gtk_entry_set_text(HostIPEntry,_("(unknown; Kill the daemon and start your own)")); } else { gtk_entry_set_text(HostIPEntry,HOSTIP_GUINT32_TO_STRING(hostip_guint32)); @@ -171,6 +213,9 @@ static void ui_gnome_g_log_handler(const gchar *log_domain,GLogLevelFlags log_le { GtkWidget *dialog; + if (!App) /* Quitting? */ + return; + /**/ if (log_level & G_LOG_LEVEL_ERROR) dialog=gnome_app_error(App,message); else if (log_level & (G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING)) @@ -178,14 +223,22 @@ GtkWidget *dialog; else dialog=gnome_app_message(App,message); + /* Do not set it modal as ... who knows. At least in the fully static + * build during on_AutostartCheckButton_toggled() we get reported + * the messages twice and application immediately gtk_main_quit() + * even the second (toplevel) gtk_main(). + */ +#if 0 gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); g_signal_connect((gpointer)dialog,"close",G_CALLBACK(gtk_main_quit),NULL); gtk_main(); /* 'dialog' gets destroyed automatically */ +#endif } static void ui_gnome_interactive(void) { + probe_timeout_sec_max=UI_GNOME_PROBE_TIMEOUT_SEC; gtk_main(); network_notify_hostip=NULL; g_log_remove_handler( @@ -224,11 +277,12 @@ gboolean ui_gnome_init(void) ui_gnome_network_notify_hostip(0); gtk_entry_set_text(PortEntry,udpgate_printf_alloca("%d",(int)optarg_port)); - if (!startup_init()) { - gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(AutostartCheckButton),TRUE); + if (!static_startup_supported()) { gtk_widget_set_sensitive(GTK_WIDGET(AutostartLabel),FALSE); gtk_widget_set_sensitive(GTK_WIDGET(AutostartCheckButton),FALSE); } + if (!static_startup_query(NULL)) + gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(AutostartCheckButton),TRUE); daemon_check_timeout_func(NULL); /* data; unused */ external_startup_check_timeout_func(NULL); /* data; unused */