aboutsummaryrefslogtreecommitdiff
path: root/src/main/gnunet-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/gnunet-gtk.c')
-rw-r--r--src/main/gnunet-gtk.c378
1 files changed, 0 insertions, 378 deletions
diff --git a/src/main/gnunet-gtk.c b/src/main/gnunet-gtk.c
deleted file mode 100644
index 68029152..00000000
--- a/src/main/gnunet-gtk.c
+++ /dev/null
@@ -1,378 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2012-2014 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file src/main/gnunet-gtk.c
23 * @author Christian Grothoff
24 * @brief Gtk user interface for GNUnet
25 */
26#include "gnunet_gtk.h"
27#if HAVE_GTK_GTKX_H
28#include <gtk/gtkx.h>
29#endif
30
31/**
32 * Handle for a plugged in process.
33 */
34struct Plug
35{
36
37 /**
38 * Kept in a DLL.
39 */
40 struct Plug *prev;
41
42 /**
43 * Kept in a DLL.
44 */
45 struct Plug *next;
46
47 /**
48 * The socket.
49 */
50 GtkWidget *s;
51
52 /**
53 * Name of the binary.
54 */
55 const char *binary;
56
57 /**
58 * Environment variable we set.
59 */
60 const char *env_var;
61
62 /**
63 * Handle to the child process.
64 */
65 struct GNUNET_OS_Process *proc;
66
67 /**
68 * How long do we wait on restarts?
69 */
70 struct GNUNET_TIME_Relative backoff;
71
72 /**
73 * Task to restart process after crash.
74 */
75 struct GNUNET_SCHEDULER_Task * restart_task;
76
77 /**
78 * ID of the signal associated with the window.
79 */
80 gulong sig_id;
81
82};
83
84
85/**
86 * Main loop handle.
87 */
88static struct GNUNET_GTK_MainLoop *ml;
89
90/**
91 * Our configuration.
92 */
93static const struct GNUNET_CONFIGURATION_Handle *cfg;
94
95/**
96 * Global return value (for success/failure of gnunet-gtk).
97 */
98static int gret;
99
100/**
101 * Head of plugs.
102 */
103static struct Plug *p_head;
104
105/**
106 * Tail of plugs.
107 */
108static struct Plug *p_tail;
109
110
111/**
112 * Get an object from the main window.
113 *
114 * @param name name of the object
115 * @return NULL on error, otherwise the object
116 */
117static GObject *
118get_object (const char *name)
119{
120 if (NULL == ml)
121 return NULL;
122 return GNUNET_GTK_main_loop_get_object (ml, name);
123}
124
125
126/**
127 * Actual main to tear down the system.
128 *
129 * @param cls the main loop handle
130 */
131static void
132cleanup_task (void *cls)
133{
134 struct Plug *p;
135
136 while (NULL != (p = p_head))
137 {
138 if (NULL != p->proc)
139 {
140 (void) GNUNET_OS_process_kill (p->proc,
141 SIGTERM);
142 GNUNET_break (GNUNET_OK ==
143 GNUNET_OS_process_wait (p->proc));
144 GNUNET_OS_process_destroy (p->proc);
145 p->proc = NULL;
146 }
147 if (NULL != p->restart_task)
148 {
149 GNUNET_SCHEDULER_cancel (p->restart_task);
150 p->restart_task = NULL;
151 }
152 /* This object is long gone, as part of the cleanup
153 of the window from gtk_window_dispose that is
154 triggered with the shutdown; so we should not
155 do it here. (Keeping commented out to show
156 that there is symmetry with initialization --
157 kind-of) */
158 /* g_signal_handler_disconnect (p->s, p->sig_id); */
159 GNUNET_CONTAINER_DLL_remove (p_head,
160 p_tail,
161 p);
162 GNUNET_free (p);
163 }
164 if (NULL == ml)
165 {
166 GNUNET_break (0);
167 return;
168 }
169 GNUNET_GTK_main_loop_quit (ml);
170}
171
172
173/**
174 * Callback invoked if the application is supposed to exit.
175 */
176void
177gnunet_gtk_quit_cb (GObject * object,
178 gpointer user_data)
179{
180 GNUNET_SCHEDULER_shutdown ();
181}
182
183
184#ifdef GDK_WINDOWING_X11
185/**
186 * Start the child process for the plug.
187 *
188 * @param p plug identification
189 */
190static void
191start_process (struct Plug *p)
192{
193 char window_id[128];
194 Window w;
195
196 w = gtk_socket_get_id (GTK_SOCKET (p->s));
197 GNUNET_snprintf (window_id,
198 sizeof (window_id),
199 "%llu",
200 (unsigned long long) w);
201 setenv (p->env_var, window_id, 1);
202 p->proc = GNUNET_OS_start_process (GNUNET_NO,
203 GNUNET_OS_INHERIT_STD_ALL,
204 NULL, NULL, NULL,
205 p->binary,
206 p->binary,
207 NULL);
208}
209
210
211/**
212 * Restart crashed plugin process.
213 *
214 * @param cls the `struct Plug` of the plugin
215 */
216static void
217restart_process (void *cls)
218{
219 struct Plug *p = cls;
220
221 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
222 _("Restarting crashed plugin `%s'\n"),
223 p->binary);
224 p->restart_task = NULL;
225 start_process (p);
226}
227
228
229/**
230 * The window got detached, restart the child.
231 *
232 * @param sock socket the plug got detached from
233 * @param userdata our `struct Plug *`
234 * @return TRUE (keep socket open)
235 */
236static gboolean
237handle_remove (GtkSocket *sock,
238 gpointer userdata)
239{
240 struct Plug *p = userdata;
241
242 if (NULL != p->proc)
243 {
244 (void) GNUNET_OS_process_kill (p->proc, SIGTERM);
245 GNUNET_OS_process_destroy (p->proc);
246 p->proc = NULL;
247 }
248 p->backoff = GNUNET_TIME_STD_BACKOFF (p->backoff);
249 p->restart_task = GNUNET_SCHEDULER_add_delayed (p->backoff,
250 &restart_process,
251 p);
252 return TRUE;
253}
254
255
256/**
257 * Embed process in our GUI.
258 *
259 * @param container where to embed
260 * @param binary name of the binary to embed
261 * @param env_var name of the environment variable to set
262 */
263static void
264plug (const char *container,
265 const char *binary,
266 const char *env_var)
267{
268 GtkWidget *v;
269 GtkWidget *l;
270 struct Plug *p;
271 GtkNotebook *n;
272
273 p = GNUNET_new (struct Plug);
274 p->s = gtk_socket_new ();
275 gtk_widget_set_events (p->s,
276 GDK_ALL_EVENTS_MASK);
277 n = GTK_NOTEBOOK (get_object ("gnunet_gtk_notebook"));
278 v = GTK_WIDGET (get_object (container));
279 l = gtk_notebook_get_tab_label (n, v);
280 /* remove old tab, replace with new tab; effectively,
281 we preserve the label; but GtkNotebook does not
282 allow us to directly substitute the body of the tab */
283 g_object_ref (l);
284 gtk_notebook_remove_page (n,
285 gtk_notebook_page_num (n, v));
286 gtk_notebook_append_page (n, p->s, l);
287 g_object_unref (l);
288 p->binary = binary;
289 p->env_var = env_var;
290 p->sig_id = g_signal_connect (p->s,
291 "plug-removed",
292 G_CALLBACK (handle_remove),
293 p);
294 start_process (p);
295 gtk_widget_show (p->s);
296 GNUNET_CONTAINER_DLL_insert (p_head,
297 p_tail,
298 p);
299}
300#endif
301
302
303/**
304 * Actual main method that sets up the configuration window.
305 *
306 * @param cls the main loop handle
307 */
308static void
309run (void *cls)
310{
311 GtkWidget *main_window;
312
313 ml = cls;
314 cfg = GNUNET_GTK_main_loop_get_configuration (ml);
315 if (GNUNET_OK != GNUNET_GTK_main_loop_build_window (ml, NULL))
316 return;
317 GNUNET_GTK_set_icon_search_path ();
318 GNUNET_GTK_setup_nls ();
319 main_window = GTK_WIDGET (get_object ("gnunet_gtk_window"));
320 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL);
321#ifdef GDK_WINDOWING_X11
322 plug ("gnunet_statistics_hbox",
323 "gnunet-statistics-gtk",
324 "GNUNET_STATISTICS_GTK_PLUG");
325 plug ("gnunet_peerinfo_hbox",
326 "gnunet-peerinfo-gtk",
327 "GNUNET_PEERINFO_GTK_PLUG");
328 plug ("gnunet_namestore_hbox",
329 "gnunet-namestore-gtk",
330 "GNUNET_NAMESTORE_GTK_PLUG");
331 plug ("gnunet_fs_hbox",
332 "gnunet-fs-gtk",
333 "GNUNET_FS_GTK_PLUG");
334 plug ("gnunet_identity_hbox",
335 "gnunet-identity-gtk",
336 "GNUNET_IDENTITY_GTK_PLUG");
337 plug ("gnunet_conversation_hbox",
338 "gnunet-conversation-gtk",
339 "GNUNET_CONVERSATION_GTK_PLUG");
340#if 0
341 plug ("gnunet_setup_hbox",
342 "gnunet-setup",
343 "GNUNET_SETUP_PLUG");
344#endif
345#endif
346 gtk_widget_show (main_window);
347 gtk_window_present (GTK_WINDOW (main_window));
348}
349
350
351/**
352 * Main function for gnunet-gtk.
353 *
354 * @param argc number of arguments
355 * @param argv arguments
356 * @return 0 on success
357 */
358int
359main (int argc, char *const *argv)
360{
361 struct GNUNET_GETOPT_CommandLineOption options[] = {
362 GNUNET_GETOPT_OPTION_END
363 };
364 int ret;
365
366 if (GNUNET_OK ==
367 GNUNET_GTK_main_loop_start ("gnunet-gtk",
368 "gnunet-gtk", argc, argv,
369 options, "gnunet_gtk.glade",
370 &run))
371 ret = gret;
372 else
373 ret = 1;
374 return ret;
375}
376
377
378/* end of gnunet-gtk.c */