X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Fui-gnome.c;h=75182f9ec4757a89f2c26f38a318a56e3b637d67;hb=4e21ae021fecaa14f68c61324d66a374f0f3038f;hp=99bdd90061cdd9d11096a60631f292ec1fcf6105;hpb=fad5c58128094d8d4146ea2435d4c9b85313175a;p=udpgate.git diff --git a/src/ui-gnome.c b/src/ui-gnome.c index 99bdd90..75182f9 100644 --- a/src/ui-gnome.c +++ b/src/ui-gnome.c @@ -36,14 +36,20 @@ #include #include #include +#include +#include #include "network.h" +#include "packet.h" +#include "static-startup.h" /* Config: */ #define DAEMON_CHECK_INTERVAL_MS 100 +#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; @@ -52,14 +58,26 @@ static GtkButton *ButtonStop; static GtkHBox *PortHBox; static GnomeAppBar *AppBar; static GtkEntry *PortEntry; +static GtkEntry *HostIPEntry; +static GtkLabel *AutostartLabel; +static GtkCheckButton *AutostartCheckButton; static void state_start_stop(void) { pid_t daemon_pid; +gboolean daemon_running; +static gboolean last_daemon_running,last_daemon_running_set=FALSE; daemon_pid=is_daemon_running(); - gboolean daemon_running=((pid_t)-1!=daemon_pid); + daemon_running=((pid_t)-1!=daemon_pid); + + /* Cache the result; maybe not needed. */ + if (last_daemon_running_set && last_daemon_running==daemon_running) + return; + last_daemon_running=daemon_running; + last_daemon_running_set=TRUE; + gtk_widget_set_sensitive(GTK_WIDGET(ButtonStart),!daemon_running); gtk_widget_set_sensitive(GTK_WIDGET(ButtonStop) , daemon_running); gtk_widget_set_sensitive(GTK_WIDGET(PortHBox) ,!daemon_running); @@ -72,10 +90,32 @@ pid_t daemon_pid; static gboolean daemon_check_timeout_func(gpointer data /* unused */) { + if (!App) /* Quitting? */ + return FALSE; /* stop running */ + state_start_stop(); return TRUE; /* continue running */ } +static gboolean external_startup_check_timeout_func(gpointer data /* unused */) +{ +gboolean 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)); @@ -85,32 +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))) + static_startup_on(); + else + 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) { -const gchar *port_string; -char *endp; -long port_long; - g_return_if_fail(GTK_IS_BUTTON(button)); - port_string=gtk_entry_get_text(PortEntry); - port_long=strtol(port_string,&endp,0); - if (endp && *endp) { - g_warning(_("Invalid port specification, offending string: %s"),endp); - return; - } - if (port_long<1 || port_long>=G_MAXINT || (endp && *endp)) { - g_warning(_("Invalid port integer number specification (%ld)"),port_long); - return; - } - network_start(port_long); + buttonstart(); } void on_ButtonStop_clicked(GtkButton *button,gpointer user_data) @@ -122,18 +168,54 @@ 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 */ + optarg_port_set_string(gtk_entry_get_text(PortEntry)); + /* 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) { +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 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)); + } +} + +static guint ui_gnome_g_log_handler_handler_id; static void ui_gnome_g_log_handler(const gchar *log_domain,GLogLevelFlags log_level,const gchar *message,gpointer user_data) { 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)) @@ -141,10 +223,28 @@ 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( + G_LOG_DOMAIN, /* log_domain; "Captive" */ + ui_gnome_g_log_handler_handler_id); /* handler_id */ + network_detach(); } /* of "ui-gnome-interface.h": */ @@ -161,9 +261,12 @@ gboolean ui_gnome_init(void) PortHBox=GTK_HBOX(lookup_widget(GTK_WIDGET(App),"PortHBox")); AppBar=GNOME_APPBAR(lookup_widget(GTK_WIDGET(App),"AppBar")); PortEntry=GTK_ENTRY(lookup_widget(GTK_WIDGET(App),"PortEntry")); + HostIPEntry=GTK_ENTRY(lookup_widget(GTK_WIDGET(App),"HostIPEntry")); + AutostartLabel=GTK_LABEL(lookup_widget(GTK_WIDGET(App),"AutostartLabel")); + AutostartCheckButton=GTK_CHECK_BUTTON(lookup_widget(GTK_WIDGET(App),"AutostartCheckButton")); /* ui_gnome_g_log_handler() needs 'App'. */ - g_log_set_handler( + ui_gnome_g_log_handler_handler_id=g_log_set_handler( G_LOG_DOMAIN, /* log_domain; "Captive" */ (G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL)&~(0 |G_LOG_LEVEL_MESSAGE @@ -172,15 +275,30 @@ gboolean ui_gnome_init(void) ui_gnome_g_log_handler, /* log_func */ NULL); /* user_data */ + ui_gnome_network_notify_hostip(0); + gtk_entry_set_text(PortEntry,udpgate_printf_alloca("%d",(int)optarg_port)); + 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 */ + gtk_widget_show_all(GTK_WIDGET(App)); g_timeout_add( DAEMON_CHECK_INTERVAL_MS, /* interval */ daemon_check_timeout_func, /* function */ NULL); /* data; unused */ - return TRUE; -} + g_timeout_add( + EXTERNAL_STARTUP_CHECK_INTERVAL_MS, /* interval */ + external_startup_check_timeout_func, /* function */ + NULL); /* data; unused */ -void ui_gnome_interactive(void) -{ - gtk_main(); + network_notify_hostip=ui_gnome_network_notify_hostip; + + ui_interactive=ui_gnome_interactive; + + return TRUE; }