Remove warnings
[dhcpcd-ui] / 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 #include "menu.h"
29
30 static const char *copyright = "Copyright (c) 2009 Roy Marples";
31
32 static const char *authors[] = {
33         "Roy Marples <roy@marples.name>",
34         NULL
35 };
36 static const char *license =
37         "Licensed under the 2 clause BSD license.\n"
38         "\n"
39         "Redistribution and use in source and binary forms, with or without\n"
40         "modification, are permitted provided that the following conditions\n"
41         "are met:\n"
42         "1. Redistributions of source code must retain the above copyright\n"
43         "   notice, this list of conditions and the following disclaimer.\n"
44         "2. Redistributions in binary form must reproduce the above copyright\n"
45         "   notice, this list of conditions and the following disclaimer in the\n"
46         "   documentation and/or other materials provided with the distribution.\n"
47         "\n"
48         "THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n"
49         "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
50         "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
51         "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n"
52         "FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
53         "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
54         "OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
55         "HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"
56         "LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"
57         "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"
58         "SUCH DAMAGE.";
59
60 static void
61 on_quit(_unused GtkMenuItem *item, _unused gpointer data)
62 {
63         gtk_main_quit();
64 }
65
66 static void
67 on_help(_unused GtkMenuItem *item, _unused gpointer data)
68 {
69 }
70
71 static void
72 url_show(GtkAboutDialog *dialog, const char *url)
73 {
74         GdkScreen *screen;
75
76         screen = gtk_widget_get_screen(GTK_WIDGET(dialog));
77         gtk_show_uri(screen, url, GDK_CURRENT_TIME, NULL);
78 }
79
80 static void
81 email_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer p)
82 {
83         char *address;
84
85         address = g_strdup_printf("mailto:%s", url);
86         url_show(dialog, address);
87         g_free(address);
88 }
89
90 static void
91 url_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer p)
92 {
93         url_show(dialog, url);
94 }
95
96 static void
97 on_about(_unused GtkMenuItem *item, _unused gpointer data)
98 {
99         gtk_window_set_default_icon_name(GTK_STOCK_NETWORK);
100         gtk_about_dialog_set_email_hook(email_hook, NULL, NULL);
101         gtk_about_dialog_set_url_hook(url_hook, NULL, NULL);
102         gtk_show_about_dialog(NULL,
103                               "version", VERSION,
104                               "copyright", copyright,
105                               "license", license,
106                               "website-label", "dhcpcd Website",
107                               "website", "http://roy.marples.name/projects/dhcpcd",
108                               "authors", authors,
109                               "wrap-license", TRUE,
110                               "logo-icon-name", GTK_STOCK_NETWORK,
111                               NULL);
112 }
113
114 static void
115 add_scan_results(GtkMenu *menu, const struct if_msg *ifm)
116 {
117         GList *gl;
118         const struct if_ap *ifa;
119         GtkWidget *item, *image;
120
121         for (gl = ifm->scan_results; gl; gl = gl->next) {
122                 ifa = (const struct if_ap *)gl->data;
123                 item = gtk_image_menu_item_new_with_label(ifa->ssid);
124                 image = gtk_image_new_from_icon_name("network-wireless",
125                                                      GTK_ICON_SIZE_MENU);
126                 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
127                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
128         }
129 }
130
131 static void
132 on_activate(GtkStatusIcon *icon, _unused guint button, _unused guint32 atime, _unused gpointer data)
133 {
134         GtkMenu *menu;
135         const struct if_msg *ifm;
136         GList *gl;
137         size_t n;
138
139         notify_close();
140
141         n = 0;
142         for (gl = interfaces; gl; gl = gl->next) {
143                 ifm = (const struct if_msg *)gl->data;
144                 if (ifm->wireless)
145                         if (++n > 1)
146                                 break;
147         }
148         if (n == 0)
149                 return;
150
151         menu = (GtkMenu *)gtk_menu_new();
152
153         for (gl = interfaces; gl; gl = gl->next) {
154                 ifm = (const struct if_msg *)gl->data;
155                 if (!ifm->wireless)
156                         continue;
157                 if (n == 1) {
158                         add_scan_results(menu, ifm);
159                         break;
160                 }
161 #if 0
162                 item = gtk_image_menu_item_new_with_label(ifm->name);
163                 image = gtk_image_new_from_icon_name("network-wireless",
164                                                      GTK_ICON_SIZE_MENU);
165                 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
166
167                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
168 #endif
169         }
170         gtk_widget_show_all(GTK_WIDGET(menu));
171         gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
172                        gtk_status_icon_position_menu, icon,
173                        1, gtk_get_current_event_time());
174 }
175
176 static void
177 on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
178 {
179         GtkMenu *menu;
180         GtkWidget *item, *image;
181
182         notify_close();
183
184         menu = (GtkMenu *)gtk_menu_new();
185
186         item = gtk_image_menu_item_new_with_mnemonic("_Quit");
187         image = gtk_image_new_from_icon_name(GTK_STOCK_QUIT,
188                                              GTK_ICON_SIZE_MENU);
189         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
190         g_signal_connect(G_OBJECT(item), "activate",
191                          G_CALLBACK(on_quit), icon);
192         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
193
194         item = gtk_separator_menu_item_new();
195         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
196
197         item = gtk_image_menu_item_new_with_mnemonic("_Help");
198         image = gtk_image_new_from_icon_name(GTK_STOCK_HELP,
199                                              GTK_ICON_SIZE_MENU);
200         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
201         g_signal_connect(G_OBJECT(item), "activate",
202                          G_CALLBACK(on_help), icon);
203         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
204
205         item = gtk_image_menu_item_new_with_mnemonic("_About");
206         image = gtk_image_new_from_icon_name(GTK_STOCK_ABOUT,
207                                              GTK_ICON_SIZE_MENU);
208         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
209         g_signal_connect(G_OBJECT(item), "activate",
210                          G_CALLBACK(on_about), icon);
211         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
212
213         gtk_widget_show_all(GTK_WIDGET(menu));
214         gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
215                        gtk_status_icon_position_menu, data, button, atime);
216         if (button == 0)
217                 gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), FALSE);
218 }
219
220 void
221 menu_init(GtkStatusIcon *icon)
222 {
223         g_signal_connect_object(G_OBJECT(icon), "activate",
224                                 G_CALLBACK(on_activate), icon, 0);
225         g_signal_connect_object(G_OBJECT(icon), "popup_menu",
226                                 G_CALLBACK(on_popup), icon, 0);
227 }