3 * Copyright (C) 2004 Jan Kratochvil <project-udpgate@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "ui-gnome.h" /* self */
23 #include <glib/gmessages.h>
25 #include <libgnomeui/gnome-app.h>
26 #include <sys/types.h>
30 #include <libgnomeui/gnome-appbar.h>
31 #include <gtk/gtkbutton.h>
34 #include <gtk/gtkentry.h>
35 #include <gtk/gtktogglebutton.h>
37 #include <gtk/gtkmain.h>
38 #include <libgnomeui/gnome-app-util.h>
39 #include <gtk/gtklabel.h>
40 #include <gtk/gtkcheckbutton.h>
44 #include "static-startup.h"
48 #define DAEMON_CHECK_INTERVAL_MS 100
49 #define EXTERNAL_STARTUP_CHECK_INTERVAL_MS 1000
50 #define PORT_RANGE_BEGIN 2048
51 #define PORT_RANGE_END 10240
52 #define UI_GNOME_PROBE_TIMEOUT_SEC 10
56 static GtkButton *ButtonStart;
57 static GtkButton *ButtonStop;
58 static GtkHBox *PortHBox;
59 static GnomeAppBar *AppBar;
60 static GtkEntry *PortEntry;
61 static GtkEntry *HostIPEntry;
62 static GtkLabel *AutostartLabel;
63 static GtkCheckButton *AutostartCheckButton;
66 static void state_start_stop(void)
69 gboolean daemon_running;
70 static gboolean last_daemon_running,last_daemon_running_set=FALSE;
72 daemon_pid=is_daemon_running();
73 daemon_running=((pid_t)-1!=daemon_pid);
75 /* Cache the result; maybe not needed. */
76 if (last_daemon_running_set && last_daemon_running==daemon_running)
78 last_daemon_running=daemon_running;
79 last_daemon_running_set=TRUE;
81 gtk_widget_set_sensitive(GTK_WIDGET(ButtonStart),!daemon_running);
82 gtk_widget_set_sensitive(GTK_WIDGET(ButtonStop) , daemon_running);
83 gtk_widget_set_sensitive(GTK_WIDGET(PortHBox) ,!daemon_running);
85 gnome_appbar_set_status(AppBar,
86 udpgate_printf_alloca(_("udpgate daemon running as PID %d."),(int)daemon_pid));
88 gnome_appbar_set_status(AppBar,_("No udpgate daemon currently running."));
91 static gboolean daemon_check_timeout_func(gpointer data /* unused */)
93 if (!App) /* Quitting? */
94 return FALSE; /* stop running */
97 return TRUE; /* continue running */
100 static gboolean external_startup_check_timeout_func(gpointer data /* unused */)
102 gboolean state_startup_is_on;
104 if (!App) /* Quitting? */
105 return FALSE; /* stop running */
107 if (static_startup_query(&state_startup_is_on))
108 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(AutostartCheckButton),state_startup_is_on);
109 return TRUE; /* continue running */
112 static void buttonstart(void)
114 if (!optarg_port_set_string(gtk_entry_get_text(PortEntry)))
116 network_start(optarg_port);
119 void on_PortButtonRandom_clicked(GtkButton *button,gpointer user_data)
121 g_return_if_fail(GTK_IS_BUTTON(button));
124 if ((pid_t)-1!=is_daemon_running())
126 gtk_entry_set_text(PortEntry,
127 udpgate_printf_alloca("%d",(int)g_random_int_range(PORT_RANGE_BEGIN,PORT_RANGE_END)));
131 void on_AutostartCheckButton_toggled(GtkToggleButton *togglebutton,gpointer user_data)
133 static gint inside=0;
135 g_return_if_fail(GTK_IS_TOGGLE_BUTTON(togglebutton));
137 /* Avoid reentrancy to prevent segfault during failed registration.
138 * FIXME: Who knows why? Some forbidden GTK recursion occurs.
145 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AutostartCheckButton)))
148 static_startup_off();
149 external_startup_check_timeout_func(NULL); /* data; unused */
155 void on_ButtonStart_clicked(GtkButton *button,gpointer user_data)
157 g_return_if_fail(GTK_IS_BUTTON(button));
162 void on_ButtonStop_clicked(GtkButton *button,gpointer user_data)
164 g_return_if_fail(GTK_IS_BUTTON(button));
169 void on_ButtonHide_clicked(GtkButton *button,gpointer user_data)
173 g_return_if_fail(GTK_IS_BUTTON(button));
175 /* update config file */
176 optarg_port_set_string(gtk_entry_get_text(PortEntry));
178 /* Do not: gtk_main_quit();
179 * as 'App' widget will quit our gtk_main() automatically.
181 /* Do not: gtk_widget_destroy(App); App=NULL;
182 * as it would race with g_timeout_add()ed function which check
183 * 'if (!App)' first and expect there fully valid tree afterwards.
187 gtk_widget_destroy(GTK_WIDGET(App_local));
190 static void ui_gnome_network_notify_hostip(guint32 hostip_guint32)
192 if (!App) /* Quitting? */
195 if (!hostip_guint32) {
198 daemon_pid=is_daemon_running();
199 if ((pid_t)-1==daemon_pid)
200 gtk_entry_set_text(HostIPEntry,_("(unknown; Start the daemon)"));
201 else if (getpid()==daemon_pid)
202 gtk_entry_set_text(HostIPEntry,_("(unknown; detecting...)"));
204 gtk_entry_set_text(HostIPEntry,_("(unknown; Kill the daemon and start your own)"));
207 gtk_entry_set_text(HostIPEntry,HOSTIP_GUINT32_TO_STRING(hostip_guint32));
211 static guint ui_gnome_g_log_handler_handler_id;
212 static void ui_gnome_g_log_handler(const gchar *log_domain,GLogLevelFlags log_level,const gchar *message,gpointer user_data)
216 if (!App) /* Quitting? */
219 /**/ if (log_level & G_LOG_LEVEL_ERROR)
220 dialog=gnome_app_error(App,message);
221 else if (log_level & (G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING))
222 dialog=gnome_app_warning(App,message);
224 dialog=gnome_app_message(App,message);
226 /* Do not set it modal as ... who knows. At least in the fully static
227 * build during on_AutostartCheckButton_toggled() we get reported
228 * the messages twice and application immediately gtk_main_quit()
229 * even the second (toplevel) gtk_main().
232 gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
233 g_signal_connect((gpointer)dialog,"close",G_CALLBACK(gtk_main_quit),NULL);
235 /* 'dialog' gets destroyed automatically */
239 static void ui_gnome_interactive(void)
241 probe_timeout_sec_max=UI_GNOME_PROBE_TIMEOUT_SEC;
243 network_notify_hostip=NULL;
244 g_log_remove_handler(
245 G_LOG_DOMAIN, /* log_domain; "Captive" */
246 ui_gnome_g_log_handler_handler_id); /* handler_id */
250 /* of "ui-gnome-interface.h": */
251 GtkWidget *create_App(void);
252 /* of "ui-gnome-support.h": */
253 GtkWidget *lookup_widget(GtkWidget *widget,const gchar *widget_name);
255 gboolean ui_gnome_init(void)
257 App=GNOME_APP(create_App());
259 ButtonStart=GTK_BUTTON(lookup_widget(GTK_WIDGET(App),"ButtonStart"));
260 ButtonStop=GTK_BUTTON(lookup_widget(GTK_WIDGET(App),"ButtonStop"));
261 PortHBox=GTK_HBOX(lookup_widget(GTK_WIDGET(App),"PortHBox"));
262 AppBar=GNOME_APPBAR(lookup_widget(GTK_WIDGET(App),"AppBar"));
263 PortEntry=GTK_ENTRY(lookup_widget(GTK_WIDGET(App),"PortEntry"));
264 HostIPEntry=GTK_ENTRY(lookup_widget(GTK_WIDGET(App),"HostIPEntry"));
265 AutostartLabel=GTK_LABEL(lookup_widget(GTK_WIDGET(App),"AutostartLabel"));
266 AutostartCheckButton=GTK_CHECK_BUTTON(lookup_widget(GTK_WIDGET(App),"AutostartCheckButton"));
268 /* ui_gnome_g_log_handler() needs 'App'. */
269 ui_gnome_g_log_handler_handler_id=g_log_set_handler(
270 G_LOG_DOMAIN, /* log_domain; "Captive" */
271 (G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL)&~(0
274 |G_LOG_LEVEL_DEBUG), /* log_levels */
275 ui_gnome_g_log_handler, /* log_func */
276 NULL); /* user_data */
278 ui_gnome_network_notify_hostip(0);
279 gtk_entry_set_text(PortEntry,udpgate_printf_alloca("%d",(int)optarg_port));
280 if (!static_startup_supported()) {
281 gtk_widget_set_sensitive(GTK_WIDGET(AutostartLabel),FALSE);
282 gtk_widget_set_sensitive(GTK_WIDGET(AutostartCheckButton),FALSE);
284 if (!static_startup_query(NULL))
285 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(AutostartCheckButton),TRUE);
286 daemon_check_timeout_func(NULL); /* data; unused */
287 external_startup_check_timeout_func(NULL); /* data; unused */
289 gtk_widget_show_all(GTK_WIDGET(App));
291 DAEMON_CHECK_INTERVAL_MS, /* interval */
292 daemon_check_timeout_func, /* function */
293 NULL); /* data; unused */
295 EXTERNAL_STARTUP_CHECK_INTERVAL_MS, /* interval */
296 external_startup_check_timeout_func, /* function */
297 NULL); /* data; unused */
299 network_notify_hostip=ui_gnome_network_notify_hostip;
301 ui_interactive=ui_gnome_interactive;