Remove dbus-glib dependency and create libdhcpcd.
[dhcpcd-ui] / src / dhcpcd-gtk / menu.c
1 /*
2  * dhcpcd-gtk
3  * Copyright 2009 Roy Marples <roy@marples.name>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "dhcpcd-gtk.h"
28
29 static const char *copyright = "Copyright (c) 2009 Roy Marples";
30 static const char *authors[] = { "Roy Marples <roy@marples.name>", NULL };
31
32 static void
33 on_pref(_unused GtkObject *o, gpointer data)
34 {
35         dhcpcd_prefs_show((DHCPCD_CONNECTION *)data);
36 }
37
38 static void
39 on_quit(void)
40 {
41         gtk_main_quit();
42 }
43
44 static void
45 url_show(GtkAboutDialog *dialog, const char *url)
46 {
47         GdkScreen *screen;
48
49         screen = gtk_widget_get_screen(GTK_WIDGET(dialog));
50         gtk_show_uri(screen, url, GDK_CURRENT_TIME, NULL);
51 }
52
53 static void
54 email_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer data)
55 {
56         char *address;
57
58         address = g_strdup_printf("mailto:%s", url);
59         url_show(dialog, address);
60         g_free(address);
61 }
62
63 static void
64 url_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer data)
65 {
66         url_show(dialog, url);
67 }
68
69 static void
70 ssid_hook(_unused GtkMenuItem *item, gpointer data)
71 {
72         DHCPCD_WI_SCAN *scan;
73         WI_SCAN *wi;
74
75         scan = (DHCPCD_WI_SCAN *)data;
76         wi = wi_scan_find(scan);
77         if (wi)
78                 wpa_configure(wi->connection, wi->interface, scan);
79 }
80
81 static void
82 on_about(_unused GtkMenuItem *item)
83 {
84         gtk_window_set_default_icon_name("network-transmit-receive");
85         gtk_about_dialog_set_email_hook(email_hook, NULL, NULL);
86         gtk_about_dialog_set_url_hook(url_hook, NULL, NULL);
87         gtk_show_about_dialog(NULL,
88             "version", VERSION,
89             "copyright", copyright,
90             "website-label", "dhcpcd Website",
91             "website", "http://roy.marples.name/projects/dhcpcd",
92             "authors", authors,
93             "logo-icon-name", "network-transmit-receive",
94             "comments", "Part of the dhcpcd project",
95             NULL);
96 }
97
98 static GtkWidget *
99 add_scans(WI_SCAN *scan)
100 {
101         DHCPCD_WI_SCAN *wis;
102         GtkWidget *menu, *item, *image, *box, *label, *bar;
103         double perc;
104         int strength;
105         const char *icon;
106         char *tip;
107
108         menu = gtk_menu_new();
109         for (wis = scan->scans; wis; wis = wis->next) {
110                 item = gtk_check_menu_item_new();
111                 gtk_check_menu_item_set_draw_as_radio(
112                         GTK_CHECK_MENU_ITEM(item), true); 
113                 box = gtk_hbox_new(false, 6);
114                 gtk_container_add(GTK_CONTAINER(item), box); 
115                 label = gtk_label_new(wis->ssid);
116                 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);
117
118                 if (g_strcmp0(wis->ssid, scan->interface->ssid) == 0)
119                         gtk_check_menu_item_set_active(
120                                 GTK_CHECK_MENU_ITEM(item), true);
121                 if (wis->flags == NULL)
122                         icon = "network-wireless";
123                 else
124                         icon = "network-wireless-encrypted";
125                 image = gtk_image_new_from_icon_name(icon,
126                     GTK_ICON_SIZE_MENU);
127                 gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
128
129                 bar = gtk_progress_bar_new();
130                 gtk_widget_set_size_request(bar, 100, -1);
131                 gtk_box_pack_end(GTK_BOX(box), bar, FALSE, TRUE, 0);
132                 strength = CLAMP(wis->quality, 0, 100);
133                 perc = strength / 100.0;
134                 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar), perc);
135
136                 tip = g_strconcat(wis->bssid, " ", wis->flags, NULL);
137                 gtk_widget_set_tooltip_text(item, tip);
138                 g_free(tip);
139
140                 gtk_widget_show(label);
141                 gtk_widget_show(bar);
142                 gtk_widget_show(image);
143                 gtk_widget_show(box);
144                 g_signal_connect(G_OBJECT(item), "activate",
145                     G_CALLBACK(ssid_hook), wis);
146                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
147         }
148         return menu;
149 }
150
151 static void
152 on_activate(GtkStatusIcon *icon)
153 {
154         WI_SCAN *w;
155         GtkWidget *menu, *imenu, *item, *image;
156
157         notify_close();
158         if (wi_scans == NULL)
159                 return;
160         if (wi_scans->next) {
161                 menu = gtk_menu_new();
162                 for (w = wi_scans; w; w = w->next) {
163                         imenu = gtk_menu_new();
164                         item = gtk_image_menu_item_new_with_label(
165                                 w->interface->ifname);
166                         image = gtk_image_new_from_icon_name(
167                                 "network-wireless", GTK_ICON_SIZE_MENU);
168                         gtk_image_menu_item_set_image(
169                                 GTK_IMAGE_MENU_ITEM(item), image);
170                         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
171                         gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),
172                             add_scans(w));
173                 }
174         } else
175                 menu = add_scans(wi_scans);
176         
177         gtk_widget_show_all(GTK_WIDGET(menu));
178         gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
179             gtk_status_icon_position_menu, icon,
180             1, gtk_get_current_event_time());
181 }
182
183 static void
184 on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
185 {
186         DHCPCD_CONNECTION *con;
187         GtkMenu *menu;
188         GtkWidget *item, *image;
189
190         notify_close();
191
192         con = (DHCPCD_CONNECTION *)data;
193         menu = (GtkMenu *)gtk_menu_new();
194
195         item = gtk_image_menu_item_new_with_mnemonic(_("_Preferences"));
196         image = gtk_image_new_from_icon_name(GTK_STOCK_PREFERENCES,
197             GTK_ICON_SIZE_MENU);
198         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
199         if (g_strcmp0(dhcpcd_status(con), "down") == 0)
200                 gtk_widget_set_sensitive(item, false);
201         else
202                 g_signal_connect(G_OBJECT(item), "activate",
203                     G_CALLBACK(on_pref), data);
204         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
205
206         item = gtk_separator_menu_item_new();
207         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
208
209         item = gtk_image_menu_item_new_with_mnemonic(_("_About"));
210         image = gtk_image_new_from_icon_name(GTK_STOCK_ABOUT,
211             GTK_ICON_SIZE_MENU);
212         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
213         g_signal_connect(G_OBJECT(item), "activate",
214             G_CALLBACK(on_about), icon);
215         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
216
217         item = gtk_image_menu_item_new_with_mnemonic(_("_Quit"));
218         image = gtk_image_new_from_icon_name(GTK_STOCK_QUIT,
219             GTK_ICON_SIZE_MENU);
220         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
221         g_signal_connect(G_OBJECT(item), "activate",
222             G_CALLBACK(on_quit), icon);
223         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
224
225         gtk_widget_show_all(GTK_WIDGET(menu));
226         gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
227             gtk_status_icon_position_menu, icon, button, atime);
228         if (button == 0)
229                 gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), FALSE);
230 }
231
232 void
233 menu_init(GtkStatusIcon *icon, DHCPCD_CONNECTION *con)
234 {
235         g_signal_connect(G_OBJECT(icon), "activate",
236             G_CALLBACK(on_activate), con);
237         g_signal_connect(G_OBJECT(icon), "popup_menu",
238             G_CALLBACK(on_popup), con);
239 }