24f24426ef021011a045bba32cd698b73471762c
[strongswan.git] / src / frontends / maemo / src / strongswan-status.c
1 /*
2 * Copyright (C) 2010 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <hildon/hildon.h>
17 #include <libosso.h>
18
19 #include "strongswan-status.h"
20 #include "strongswan-connections.h"
21
22 #define STRONGSWAN_STATUS_GET_PRIVATE(object) \
23 (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
24 STRONGSWAN_TYPE_STATUS, \
25 StrongswanStatusPrivate))
26
27 #define OSSO_CHARON_NAME "charon"
28 #define OSSO_CHARON_SERVICE "org.strongswan."OSSO_CHARON_NAME
29 #define OSSO_CHARON_OBJECT "/org/strongswan/"OSSO_CHARON_NAME
30 #define OSSO_CHARON_IFACE "org.strongswan."OSSO_CHARON_NAME
31
32 #define ICON_SIZE_STATUS 18
33 #define ICON_SIZE_BUTTON 48
34
35 struct _StrongswanStatusPrivate
36 {
37 struct {
38 GdkPixbuf *status_open;
39 GdkPixbuf *status_close;
40 GdkPixbuf *button_open;
41 GdkPixbuf *button_close;
42 } icons;
43
44 GtkWidget *dialog;
45 GtkWidget *button;
46 GtkWidget *image;
47 GtkWidget *selector;
48 GtkWidget *box;
49
50 osso_context_t *context;
51
52 StrongswanConnections *conns;
53
54 gchar *current;
55 };
56
57 HD_DEFINE_PLUGIN_MODULE_EXTENDED (StrongswanStatus, strongswan_status, \
58 HD_TYPE_STATUS_MENU_ITEM, {}, { \
59 strongswan_connection_register (G_TYPE_MODULE (plugin)); \
60 strongswan_connections_register (G_TYPE_MODULE (plugin)); }, {});
61
62 static void
63 dialog_response (GtkDialog *dialog, gint response_id, StrongswanStatus *plugin)
64 {
65 StrongswanStatusPrivate *priv = plugin->priv;
66 gtk_widget_destroy (priv->dialog);
67 priv->dialog = NULL;
68 }
69
70 static void
71 connect_clicked (HildonButton *button, StrongswanStatus *plugin)
72 {
73 StrongswanStatusPrivate *priv = plugin->priv;
74 gtk_dialog_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK);
75 }
76
77 static void
78 disconnect_clicked (HildonButton *button, StrongswanStatus *plugin)
79 {
80 StrongswanStatusPrivate *priv = plugin->priv;
81 gtk_dialog_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK);
82 }
83
84 static void
85 button_clicked (HildonButton *button, StrongswanStatus *plugin)
86 {
87 StrongswanStatusPrivate *priv = plugin->priv;
88
89 priv->dialog = gtk_dialog_new ();
90 gtk_window_set_title (GTK_WINDOW (priv->dialog), "strongSwan VPN");
91 g_signal_connect (priv->dialog, "response",
92 G_CALLBACK (dialog_response), plugin);
93
94 GtkWidget *vbox = GTK_DIALOG (priv->dialog)->vbox;
95
96 if (priv->current)
97 {
98 /* connected case */
99 GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
100 priv->box = hbox;
101 GtkWidget *button = hildon_button_new_with_text (
102 HILDON_SIZE_FINGER_HEIGHT |
103 HILDON_SIZE_AUTO_WIDTH,
104 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
105 "Disconnect", priv->current);
106 hildon_button_set_style (HILDON_BUTTON (button),
107 HILDON_BUTTON_STYLE_PICKER);
108 g_signal_connect (button, "clicked", G_CALLBACK (disconnect_clicked),
109 plugin);
110 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
111 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
112 }
113 else
114 {
115 /* unconnected case */
116 GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
117 priv->box = hbox;
118 GtkWidget *button = hildon_picker_button_new (
119 HILDON_SIZE_FINGER_HEIGHT |
120 HILDON_SIZE_AUTO_WIDTH,
121 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
122 hildon_button_set_title (HILDON_BUTTON (button), "Connection:");
123 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
124
125 GtkWidget *selector = hildon_touch_selector_new ();
126 priv->selector = selector;
127 GtkTreeModel *model = strongswan_connections_get_model (priv->conns);
128 hildon_touch_selector_append_text_column (
129 HILDON_TOUCH_SELECTOR (selector),
130 model,
131 TRUE);
132 hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
133 HILDON_TOUCH_SELECTOR (selector));
134
135 button = hildon_button_new_with_text (
136 HILDON_SIZE_FINGER_HEIGHT |
137 HILDON_SIZE_AUTO_WIDTH,
138 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
139 "Connect", NULL);
140 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
141 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
142 g_signal_connect (button, "clicked", G_CALLBACK (connect_clicked),
143 plugin);
144 }
145
146 gtk_widget_show_all (priv->dialog);
147 }
148
149 static GdkPixbuf*
150 load_icon (GtkIconTheme *theme, const gchar *name, gint size)
151 {
152 GdkPixbuf *icon = NULL;
153 GdkPixbuf *loaded = gtk_icon_theme_load_icon (theme, name, size,
154 GTK_ICON_LOOKUP_NO_SVG, NULL);
155 if (loaded)
156 { /* so we don't have to listen for theme changes, we copy the icon */
157 icon = gdk_pixbuf_copy (loaded);
158 g_object_unref (loaded);
159 }
160 return icon;
161 }
162
163 static void
164 load_icons (StrongswanStatusPrivate *priv)
165 {
166 GtkIconTheme *theme = gtk_icon_theme_get_default ();
167 priv->icons.status_open = load_icon (theme, "strongswan_lock_open",
168 ICON_SIZE_STATUS);
169 priv->icons.status_close = load_icon (theme, "strongswan_lock_close",
170 ICON_SIZE_STATUS);
171 priv->icons.button_open = load_icon (theme, "strongswan_lock_open",
172 ICON_SIZE_BUTTON);
173 priv->icons.button_close = load_icon (theme, "strongswan_lock_close",
174 ICON_SIZE_BUTTON);
175 if (!priv->icons.status_open || !priv->icons.button_open)
176 {
177 hildon_banner_show_information (NULL, NULL, "failed to load icons");
178 }
179 }
180
181 static void
182 strongswan_status_init (StrongswanStatus *plugin)
183 {
184 StrongswanStatusPrivate *priv = STRONGSWAN_STATUS_GET_PRIVATE (plugin);
185 plugin->priv = priv;
186
187 priv->context = osso_initialize (OSSO_STATUS_SERVICE, "0.0.1", TRUE, NULL);
188 if (!priv->context)
189 {
190 return;
191 }
192
193 priv->conns = strongswan_connections_new ();
194
195 load_icons(priv);
196
197 hd_status_plugin_item_set_status_area_icon (HD_STATUS_PLUGIN_ITEM (plugin),
198 priv->icons.status_open);
199
200 GtkWidget *button = hildon_button_new_with_text (
201 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
202 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
203 "strongSwan VPN", "Not connected");
204 hildon_button_set_style (HILDON_BUTTON (button),
205 HILDON_BUTTON_STYLE_PICKER);
206 priv->button = button;
207 gtk_container_add (GTK_CONTAINER (plugin), button);
208
209 GtkWidget *image = gtk_image_new_from_pixbuf (priv->icons.button_open);
210 priv->image = image;
211 hildon_button_set_image (HILDON_BUTTON (button), image);
212
213 gtk_button_set_alignment (GTK_BUTTON (button), 0.0, 0.5);
214
215 g_signal_connect (button, "clicked", G_CALLBACK (button_clicked), plugin);
216
217 gtk_widget_show_all (GTK_WIDGET (plugin));
218 }
219
220 static void
221 strongswan_status_dispose (GObject *object)
222 {
223 StrongswanStatusPrivate *priv = STRONGSWAN_STATUS (object)->priv;
224 if (priv->conns)
225 {
226 priv->conns = (g_object_unref (priv->conns), NULL);
227 }
228 if (priv->icons.status_open)
229 {
230 g_object_unref (priv->icons.status_open);
231 priv->icons.status_open = NULL;
232 }
233 if (priv->icons.status_close)
234 {
235 g_object_unref (priv->icons.status_close);
236 priv->icons.status_close = NULL;
237 }
238 if (priv->icons.button_open)
239 {
240 g_object_unref (priv->icons.button_open);
241 priv->icons.button_open = NULL;
242 }
243 if (priv->icons.button_close)
244 {
245 g_object_unref (priv->icons.button_close);
246 priv->icons.button_close = NULL;
247 }
248 G_OBJECT_CLASS (strongswan_status_parent_class)->dispose (object);
249 }
250
251 static void
252 strongswan_status_finalize (GObject *object)
253 {
254 StrongswanStatusPrivate *priv = STRONGSWAN_STATUS (object)->priv;
255 priv->current = (g_free (priv->current), NULL);
256 G_OBJECT_CLASS (strongswan_status_parent_class)->finalize (object);
257 }
258
259 static void
260 strongswan_status_class_finalize (StrongswanStatusClass *klass)
261 {
262 }
263
264 static void
265 strongswan_status_class_init (StrongswanStatusClass *klass)
266 {
267 GObjectClass *object_class = G_OBJECT_CLASS (klass);
268
269 object_class->dispose = strongswan_status_dispose;
270 object_class->finalize = strongswan_status_finalize;
271
272 g_type_class_add_private (klass, sizeof (StrongswanStatusPrivate));
273 }