aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-25 14:33:37 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-25 14:33:37 +0000
commit5631caa73d4a0e43edc1e0320062b6337f64f25a (patch)
tree043f00ccb77eec11715964a1d203d88d8dff29f7 /src/main
parent8bbf657962c8861fd5548ad8983fee008b84b0fb (diff)
downloadgnunet-gtk-5631caa73d4a0e43edc1e0320062b6337f64f25a.tar.gz
gnunet-gtk-5631caa73d4a0e43edc1e0320062b6337f64f25a.zip
-basics for pluggable GUIs
Diffstat (limited to 'src/main')
-rw-r--r--src/main/Makefile.am23
-rw-r--r--src/main/gnunet-gtk.c278
2 files changed, 301 insertions, 0 deletions
diff --git a/src/main/Makefile.am b/src/main/Makefile.am
new file mode 100644
index 00000000..d8f46af7
--- /dev/null
+++ b/src/main/Makefile.am
@@ -0,0 +1,23 @@
1SUBDIRS = .
2
3AM_CPPFLAGS = \
4 -I$(top_srcdir)/ \
5 -I$(top_srcdir)/src/include
6
7bin_PROGRAMS = gnunet-gtk
8
9gnunet_gtk_SOURCES = \
10 gnunet-gtk.c
11
12gnunet_gtk_LDADD = \
13 $(top_builddir)/src/lib/libgnunetgtk.la \
14 @GTK_LIBS@ @GNUNET_LIBS@ @GLADE_LIBS@ \
15 $(WINLIBS) \
16 -lgnunetutil \
17 $(INTLLIBS)
18gnunet_gtk_CFLAGS = \
19 @GTK_CFLAGS@ \
20 @GNUNET_CFLAGS@ \
21 @GLADE_CFLAGS@
22gnunet_gtk_LDFLAGS = \
23 -export-dynamic
diff --git a/src/main/gnunet-gtk.c b/src/main/gnunet-gtk.c
new file mode 100644
index 00000000..af4e092c
--- /dev/null
+++ b/src/main/gnunet-gtk.c
@@ -0,0 +1,278 @@
1/*
2 This file is part of GNUnet
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, 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#include <gtk/gtkx.h>
28
29/**
30 * Main loop handle.
31 */
32static struct GNUNET_GTK_MainLoop *ml;
33
34/**
35 * Our configuration.
36 */
37static const struct GNUNET_CONFIGURATION_Handle *cfg;
38
39/**
40 * Global return value (for success/failure of gnunet-gtk).
41 */
42static int gret;
43
44
45/**
46 * Get an object from the main window.
47 *
48 * @param name name of the object
49 * @return NULL on error, otherwise the object
50 */
51static GObject *
52get_object (const char *name)
53{
54 if (NULL == ml)
55 return NULL;
56 return GNUNET_GTK_main_loop_get_object (ml, name);
57}
58
59
60/**
61 * Actual main to tear down the system.
62 *
63 * @param cls the main loop handle
64 * @param tc scheduler context
65 */
66static void
67cleanup_task (void *cls,
68 const struct GNUNET_SCHEDULER_TaskContext *tc)
69{
70 if (NULL == ml)
71 {
72 GNUNET_break (0);
73 return;
74 }
75 GNUNET_GTK_main_loop_quit (ml);
76}
77
78
79/**
80 * Callback invoked if the application is supposed to exit.
81 */
82void
83gnunet_gtk_quit_cb (GObject * object,
84 gpointer user_data)
85{
86 GNUNET_SCHEDULER_shutdown ();
87}
88
89
90/**
91 * Handle for a plugged in process.
92 */
93struct Plug
94{
95 /**
96 * The socket.
97 */
98 GtkWidget *s;
99
100 /**
101 * Name of the binary.
102 */
103 const char *binary;
104
105 /**
106 * Environment variable we set.
107 */
108 const char *env_var;
109
110 /**
111 * Handle to the child process.
112 */
113 struct GNUNET_OS_Process *proc;
114};
115
116
117/**
118 * Start the child process for the plug.
119 *
120 * @param p plug identification
121 */
122static void
123start_process (struct Plug *p)
124{
125 char window_id[128];
126 Window w;
127
128 w = gtk_socket_get_id (GTK_SOCKET (p->s));
129 GNUNET_snprintf (window_id,
130 sizeof (window_id),
131 "%llu",
132 (unsigned long long) w);
133 setenv (p->env_var, window_id, 1);
134 p->proc = GNUNET_OS_start_process (GNUNET_NO,
135 GNUNET_OS_INHERIT_STD_ALL,
136 NULL, NULL,
137 p->binary,
138 p->binary,
139 NULL);
140}
141
142
143/**
144 * The window got detached, restart the child.
145 *
146 * @param sock socket the plug got detached from
147 * @param userdata our `struct Plug *`
148 * @return TRUE (keep socket open)
149 */
150static gboolean
151handle_remove (GtkSocket *sock,
152 gpointer userdata)
153{
154 struct Plug *p = userdata;
155
156 (void) GNUNET_OS_process_kill (p->proc, SIGTERM);
157 GNUNET_OS_process_destroy (p->proc);
158 p->proc = NULL;
159 start_process (p);
160 return TRUE;
161}
162
163
164/**
165 * The socket widget is being deleted, clean up child process.
166 *
167 * @param sock the widget
168 * @param userdata our `struct Plug *`
169 * @return FALSE (continue event processing)
170 */
171static gboolean
172handle_delete (GtkSocket *sock,
173 gpointer userdata)
174{
175 struct Plug *p = userdata;
176
177 (void) GNUNET_OS_process_kill (p->proc, SIGTERM);
178 GNUNET_break (GNUNET_OK ==
179 GNUNET_OS_process_wait (p->proc));
180 GNUNET_OS_process_destroy (p->proc);
181 p->proc = NULL;
182 GNUNET_free (p);
183 return FALSE;
184}
185
186
187/**
188 * Embed process in our GUI.
189 *
190 * @param container where to embed
191 * @param binary name of the binary to embed
192 * @param env_var name of the environment variable to set
193 */
194static void
195plug (const char *container,
196 const char *binary,
197 const char *env_var)
198{
199 GtkContainer *v;
200 struct Plug *p;
201
202 p = GNUNET_new (struct Plug);
203 p->s = gtk_socket_new ();
204 gtk_widget_set_events (p->s,
205 GDK_ALL_EVENTS_MASK);
206 v = GTK_CONTAINER (get_object (container));
207 gtk_container_add (v, p->s);
208 p->binary = binary;
209 p->env_var = env_var;
210 g_signal_connect (p->s,
211 "plug-removed",
212 G_CALLBACK (handle_remove),
213 p);
214 g_signal_connect (p->s,
215 "delete-event",
216 G_CALLBACK (handle_delete),
217 p);
218 start_process (p);
219 gtk_widget_show (p->s);
220}
221
222
223/**
224 * Actual main method that sets up the configuration window.
225 *
226 * @param cls the main loop handle
227 * @param tc scheduler context
228 */
229static void
230run (void *cls,
231 const struct GNUNET_SCHEDULER_TaskContext *tc)
232{
233 GtkWidget *main_window;
234
235 ml = cls;
236 cfg = GNUNET_GTK_main_loop_get_configuration (ml);
237 if (GNUNET_OK != GNUNET_GTK_main_loop_build_window (ml, NULL))
238 return;
239 main_window = GTK_WIDGET (get_object ("gnunet_gtk_window"));
240 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
241 &cleanup_task, NULL);
242 plug ("hbox1",
243 "gnunet-statistics-gtk",
244 "GNUNET_STATISTICS_GTK_PLUG");
245 gtk_widget_show (main_window);
246 gtk_window_present (GTK_WINDOW (main_window));
247}
248
249
250/**
251 * Main function for gnunet-gtk.
252 *
253 * @param argc number of arguments
254 * @param argv arguments
255 * @return 0 on success
256 */
257int
258main (int argc, char *const *argv)
259{
260 struct GNUNET_GETOPT_CommandLineOption options[] = {
261 GNUNET_GETOPT_OPTION_END
262 };
263 int ret;
264
265 if (GNUNET_OK ==
266 GNUNET_GTK_main_loop_start ("gnunet-gtk",
267 "gnunet-gtk", argc, argv,
268 options, "gnunet_gtk.glade",
269 &run))
270 ret = gret;
271 else
272 ret = 1;
273 return ret;
274}
275
276
277
278/* end of gnunet-gtk.c */