1
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
2
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
4
* Dan Williams <dcbw@redhat.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
* This applet used the GNOME Wireless Applet as a skeleton to build from.
22
* GNOME Wireless Applet Authors:
23
* Eskil Heyn Olsen <eskil@eskil.dk>
24
* Bastien Nocera <hadess@hadess.net> (Gnome2 port)
26
* (C) Copyright 2004-2005 Red Hat, Inc.
27
* (C) Copyright 2001, 2002 Free Software Foundation
36
#include <glib/gi18n.h>
37
#include <libgnomeui/libgnomeui.h>
39
#if !GTK_CHECK_VERSION(2,6,0)
43
#include <glade/glade.h>
44
#include <gconf/gconf-client.h>
47
#include <libnotify/notify.h>
51
#include "applet-compat.h"
52
#include "applet-dbus.h"
53
#include "applet-dbus-devices.h"
54
#include "applet-dbus-vpn.h"
55
#include "applet-dbus-info.h"
56
#include "applet-notifications.h"
57
#include "other-network-dialog.h"
58
#include "passphrase-dialog.h"
59
#include "menu-items.h"
60
#include "vpn-password-dialog.h"
61
#include "vpn-connection.h"
63
#include "dbus-method-dispatcher.h"
65
/* Compat for GTK 2.4 and lower... */
66
#if (GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 6)
67
#define GTK_STOCK_MEDIA_PAUSE GTK_STOCK_STOP
68
#define GTK_STOCK_MEDIA_PLAY GTK_STOCK_REFRESH
69
#define GTK_STOCK_ABOUT GTK_STOCK_DIALOG_INFO
70
#define GTK_STOCK_INFO GTK_STOCK_DIALOG_INFO
73
/* Compat for GTK 2.6 */
74
#if (GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION == 6)
75
#define GTK_STOCK_INFO GTK_STOCK_DIALOG_INFO
78
static GObject * nma_constructor (GType type, guint n_props, GObjectConstructParam *construct_props);
79
static gboolean nma_icons_init (NMApplet *applet);
80
static void nma_icons_free (NMApplet *applet);
81
static void nma_context_menu_update (NMApplet *applet);
82
static GtkWidget * nma_get_instance (NMApplet *applet);
83
static void nma_update_state (NMApplet *applet);
84
static void nma_dropdown_menu_deactivate_cb (GtkWidget *menu, NMApplet *applet);
85
static G_GNUC_NORETURN void nma_destroy (NMApplet *applet);
86
static GType nma_get_type (void); /* for G_DEFINE_TYPE */
88
G_DEFINE_TYPE(NMApplet, nma, EGG_TYPE_TRAY_ICON)
93
* Doesn't freaking segfault if s1/s2 are NULL
96
int nm_null_safe_strcmp (const char *s1, const char *s2)
105
return (strcmp (s1, s2));
110
* nma_get_first_active_device
112
* Return the first device marked as "active".
115
NetworkDevice * nma_get_first_active_device (GSList *dev_list)
119
for (elt = dev_list; elt; elt = g_slist_next (elt))
121
NetworkDevice *dev = (NetworkDevice *)(elt->data);
122
if (network_device_get_active (dev))
130
static void nma_init (NMApplet *applet)
132
applet->animation_id = 0;
133
applet->animation_step = 0;
136
if (!nma_icons_init (applet))
139
/* gtk_window_set_default_icon_from_file (ICONDIR"/NMApplet/wireless-applet.png", NULL); */
140
gtk_widget_show (nma_get_instance (applet));
143
static void nma_class_init (NMAppletClass *klass)
145
GObjectClass *gobject_class;
147
gobject_class = G_OBJECT_CLASS (klass);
148
gobject_class->constructor = nma_constructor;
151
static GObject *nma_constructor (GType type, guint n_props, GObjectConstructParam *construct_props)
155
NMAppletClass *klass;
157
klass = NM_APPLET_CLASS (g_type_class_peek (type));
158
obj = G_OBJECT_CLASS (nma_parent_class)->constructor (type, n_props, construct_props);
159
applet = NM_APPLET (obj);
164
static GtkWidget * get_label (GtkWidget *info_dialog, GladeXML *xml, const char *name)
170
label = glade_xml_get_widget (xml, name);
171
g_object_set_data (G_OBJECT (info_dialog), name, label);
174
label = g_object_get_data (G_OBJECT (info_dialog), name);
179
static void nma_show_socket_err (GtkWidget *info_dialog, const char *err)
181
GtkWidget *error_dialog;
183
error_dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (info_dialog), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
184
"<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s", _("Error displaying connection information:"), err);
185
gtk_window_present (GTK_WINDOW (error_dialog));
186
g_signal_connect_swapped (error_dialog, "response", G_CALLBACK (gtk_widget_destroy), error_dialog);
189
static gboolean nma_update_info (NMApplet *applet)
191
GtkWidget *info_dialog;
192
char *addr = NULL, *broadcast = NULL, *primary_dns = NULL, *secondary_dns = NULL;
193
char *mac = NULL, *iface_and_type = NULL, *route = NULL, *mask = NULL, *speed = NULL;
196
const char *iface = NULL, *driver = NULL;
199
info_dialog = glade_xml_get_widget (applet->info_dialog_xml, "info_dialog");
202
char *err = g_strdup (_("Could not find some required resources (the glade file)!"));
203
nma_show_socket_err (info_dialog, err);
208
if ((dev = nma_get_first_active_device (applet->device_list)))
209
iface = network_device_get_iface (dev);
213
char *err = g_strdup (_("No active connections!"));
214
nma_show_socket_err (info_dialog, err);
219
if (!(driver = network_device_get_driver (dev)))
220
driver = "(unknown)";
221
mac = (char*) network_device_get_address (dev);
222
broadcast = (char*) network_device_get_broadcast (dev);
223
addr = (char*) network_device_get_ip4_address (dev);
224
mask = (char*) network_device_get_netmask (dev);
225
route = (char*) network_device_get_route (dev);
226
primary_dns = (char*) network_device_get_primary_dns (dev);
227
secondary_dns = (char*) network_device_get_secondary_dns (dev);
229
mbs = network_device_get_speed (dev);
231
speed = g_strdup_printf ("%d Mb/s", mbs);
233
if (network_device_is_wired (dev))
234
iface_and_type = g_strdup_printf (_("Wired Ethernet (%s)"), iface);
236
iface_and_type = g_strdup_printf (_("Wireless Ethernet (%s)"), iface);
238
label = get_label (info_dialog, applet->info_dialog_xml, "label-interface");
239
gtk_label_set_text (GTK_LABEL (label), iface_and_type);
241
label = get_label (info_dialog, applet->info_dialog_xml, "label-speed");
242
gtk_label_set_text (GTK_LABEL (label), mbs ? speed : "Unknown");
244
label = get_label (info_dialog, applet->info_dialog_xml, "label-driver");
245
gtk_label_set_text (GTK_LABEL (label), driver);
247
label = get_label (info_dialog, applet->info_dialog_xml, "label-ip-address");
248
gtk_label_set_text (GTK_LABEL (label), addr);
250
label = get_label (info_dialog, applet->info_dialog_xml, "label-broadcast-address");
251
gtk_label_set_text (GTK_LABEL (label), broadcast);
253
label = get_label (info_dialog, applet->info_dialog_xml, "label-subnet-mask");
254
gtk_label_set_text (GTK_LABEL (label), mask);
256
label = get_label (info_dialog, applet->info_dialog_xml, "label-default-route");
257
gtk_label_set_text (GTK_LABEL (label), route);
259
label = get_label (info_dialog, applet->info_dialog_xml, "label-primary-dns");
260
gtk_label_set_text (GTK_LABEL (label), primary_dns);
262
label = get_label (info_dialog, applet->info_dialog_xml, "label-secondary-dns");
263
gtk_label_set_text (GTK_LABEL (label), secondary_dns);
265
label = get_label (info_dialog, applet->info_dialog_xml, "label-hardware-address");
266
gtk_label_set_text (GTK_LABEL (label), mac);
268
g_free (iface_and_type);
274
static void nma_show_info_cb (GtkMenuItem *mi, NMApplet *applet)
276
GtkWidget *info_dialog;
278
info_dialog = glade_xml_get_widget (applet->info_dialog_xml, "info_dialog");
280
if (nma_update_info (applet))
282
gtk_window_present (GTK_WINDOW (info_dialog));
283
g_signal_connect_swapped (info_dialog, "response", G_CALLBACK (gtk_widget_hide), info_dialog);
287
static void about_dialog_activate_link_cb (GtkAboutDialog *about,
291
gnome_url_show (url, NULL);
294
static void nma_about_cb (GtkMenuItem *mi, NMApplet *applet)
296
static const gchar *authors[] =
298
"The Red Hat Desktop Team, including:\n",
299
"Christopher Aillon <caillon@redhat.com>",
300
"Jonathan Blandford <jrb@redhat.com>",
301
"John Palmieri <johnp@redhat.com>",
302
"Ray Strode <rstrode@redhat.com>",
303
"Colin Walters <walters@redhat.com>",
304
"Dan Williams <dcbw@redhat.com>",
305
"David Zeuthen <davidz@redhat.com>",
306
"\nAnd others, including:\n",
307
"Bill Moss <bmoss@clemson.edu>",
310
"Peter Jones <pjones@redhat.com>",
311
"Robert Love <rml@novell.com>",
312
"Tim Niemueller <tim@niemueller.de>",
316
static const gchar *artists[] =
318
"Diana Fong <dfong@redhat.com>",
322
#if !GTK_CHECK_VERSION(2,6,0)
325
GtkWidget *about_dialog;
327
/* GTK 2.4 and earlier, have to use libgnome for about dialog */
328
file = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_PIXMAP, "gnome-networktool.png", FALSE, NULL);
329
pixbuf = gdk_pixbuf_new_from_file (file, NULL);
332
about_dialog = gnome_about_new (_("NetworkManager Applet"),
334
_("Copyright \xc2\xa9 2004-2006 Red Hat, Inc.\n"
335
"Copyright \xc2\xa9 2005-2006 Novell, Inc."),
336
_("Notification area applet for managing your network devices and connections."),
339
_("translator-credits"),
341
g_object_unref (pixbuf);
343
gtk_window_set_screen (GTK_WINDOW (about_dialog), gtk_widget_get_screen (GTK_WIDGET (applet)));
344
g_signal_connect (about_dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &about_dialog);
345
gtk_widget_show (about_dialog);
349
static gboolean been_here = FALSE;
353
gtk_about_dialog_set_url_hook (about_dialog_activate_link_cb, NULL, NULL);
356
/* GTK 2.6 and later code */
357
gtk_show_about_dialog (NULL,
358
"name", _("NetworkManager Applet"),
360
"copyright", _("Copyright \xc2\xa9 2004-2005 Red Hat, Inc.\n"
361
"Copyright \xc2\xa9 2005-2006 Novell, Inc."),
362
"comments", _("Notification area applet for managing your network devices and connections."),
363
"website", "http://www.gnome.org/projects/NetworkManager/",
366
"translator-credits", _("translator-credits"),
367
"logo-icon-name", GTK_STOCK_NETWORK,
373
#ifndef ENABLE_NOTIFY
375
* nma_show_vpn_failure_dialog
377
* Present the VPN failure dialog.
381
nma_show_vpn_failure_dialog (const char *title,
386
g_return_if_fail (title != NULL);
387
g_return_if_fail (msg != NULL);
389
dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_ERROR,
390
GTK_BUTTONS_OK, msg, NULL);
391
gtk_window_set_title (GTK_WINDOW (dialog), title);
392
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
393
g_signal_connect (dialog, "close", G_CALLBACK (gtk_widget_destroy), NULL);
395
/* Bash focus-stealing prevention in the face */
396
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
397
gtk_widget_realize (dialog);
398
gdk_x11_window_set_user_time (dialog->window, gtk_get_current_event_time ());
399
gtk_widget_show_all (dialog);
405
* nma_schedule_vpn_failure_alert
407
* Schedule display of a VPN failure message.
410
void nma_show_vpn_failure_alert (NMApplet *applet, const char *member, const char *vpn_name, const char *error_msg)
415
g_return_if_fail (applet != NULL);
416
g_return_if_fail (member != NULL);
417
g_return_if_fail (vpn_name != NULL);
418
g_return_if_fail (error_msg != NULL);
420
if (!strcmp (member, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED))
422
title = g_strdup (_("VPN Login Failure"));
423
desc = g_strdup_printf (_("Could not start the VPN connection '%s' due to a login failure."), vpn_name);
425
else if (!strcmp (member, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED))
427
title = g_strdup (_("VPN Start Failure"));
428
desc = g_strdup_printf (_("Could not start the VPN connection '%s' due to a failure launching the VPN program."), vpn_name);
430
else if (!strcmp (member, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED))
432
title = g_strdup (_("VPN Connect Failure"));
433
desc = g_strdup_printf (_("Could not start the VPN connection '%s' due to a connection error."), vpn_name);
435
else if (!strcmp (member, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD))
437
title = g_strdup (_("VPN Configuration Error"));
438
desc = g_strdup_printf (_("The VPN connection '%s' was not correctly configured."), vpn_name);
440
else if (!strcmp (member, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
442
title = g_strdup (_("VPN Connect Failure"));
443
desc = g_strdup_printf (_("Could not start the VPN connection '%s' because the VPN server did not return an adequate network configuration."), vpn_name);
451
msg = g_strdup_printf ("\n%s\n%s", desc, error_msg);
452
nma_send_event_notification (applet, NOTIFY_URGENCY_CRITICAL,
453
title, msg, "gnome-lockscreen");
455
msg = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n"
456
"%s\n\n%s", title, desc, error_msg);
457
nma_show_vpn_failure_dialog (title, msg);
467
#ifndef ENABLE_NOTIFY
469
* nma_show_vpn_login_banner_dialog
471
* Present the VPN login banner dialog.
475
nma_show_vpn_login_banner_dialog (const char *title,
480
g_return_if_fail (title != NULL);
481
g_return_if_fail (msg != NULL);
483
dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_INFO,
484
GTK_BUTTONS_OK, msg, NULL);
485
gtk_window_set_title (GTK_WINDOW (dialog), title);
486
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
487
g_signal_connect (dialog, "close", G_CALLBACK (gtk_widget_destroy), NULL);
489
/* Bash focus-stealing prevention in the face */
490
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
491
gtk_widget_realize (dialog);
492
gdk_x11_window_set_user_time (dialog->window, gtk_get_current_event_time ());
493
gtk_widget_show_all (dialog);
499
* nma_schedule_vpn_login_banner
501
* Schedule a display of the VPN banner
504
void nma_show_vpn_login_banner (NMApplet *applet, const char *vpn_name, const char *banner)
509
g_return_if_fail (applet != NULL);
510
g_return_if_fail (vpn_name != NULL);
511
g_return_if_fail (banner != NULL);
513
title = _("VPN Login Message");
515
msg = g_strdup_printf ("\n%s", banner);
516
nma_send_event_notification (applet, NOTIFY_URGENCY_LOW,
517
title, msg, "gnome-lockscreen");
519
msg = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s",
521
nma_show_vpn_login_banner_dialog (title, msg);
528
* nma_driver_notify_get_ignored_list
530
* Return list of devices for which we are supposed to ignore driver
531
* notifications for from GConf.
534
static GSList *nma_driver_notify_get_ignored_list (NMApplet *applet)
538
GSList *mac_list = NULL;
540
g_return_val_if_fail (applet != NULL, NULL);
541
g_return_val_if_fail (applet->gconf_client != NULL, NULL);
543
/* Get current list of access point MAC addresses for this AP from GConf */
544
key = g_strdup_printf ("%s/non_notify_cards", GCONF_PATH_PREFS);
545
value = gconf_client_get (applet->gconf_client, key, NULL);
547
if (value && (value->type == GCONF_VALUE_LIST) && (gconf_value_get_list_type (value) == GCONF_VALUE_STRING))
548
mac_list = gconf_client_get_list (applet->gconf_client, key, GCONF_VALUE_STRING, NULL);
551
gconf_value_free (value);
559
* nma_driver_notify_is_device_ignored
561
* Look in GConf and determine whether or not we are supposed to
562
* ignore driver notifications for a particular device.
565
static gboolean nma_driver_notify_is_device_ignored (NMApplet *applet, NetworkDevice *dev)
567
gboolean found = FALSE;
568
GSList * mac_list = NULL;
570
const char * dev_addr;
572
g_return_val_if_fail (applet != NULL, TRUE);
573
g_return_val_if_fail (applet->gconf_client != NULL, TRUE);
574
g_return_val_if_fail (dev != NULL, TRUE);
576
dev_addr = network_device_get_address (dev);
577
g_return_val_if_fail (dev_addr != NULL, TRUE);
578
g_return_val_if_fail (strlen (dev_addr) > 0, TRUE);
580
mac_list = nma_driver_notify_get_ignored_list (applet);
582
/* Ensure that the MAC isn't already in the list */
583
for (elt = mac_list; elt; elt = g_slist_next (elt))
585
if (elt->data && !strcmp (dev_addr, elt->data))
592
/* Free the list, since gconf_client_set_list deep-copies it */
593
g_slist_foreach (mac_list, (GFunc)g_free, NULL);
594
g_slist_free (mac_list);
601
* nma_driver_notify_ignore_device
603
* Add a device's MAC address to the list of ones that we ignore
604
* in GConf. Stores user's pref for "Don't remind me".
607
static void nma_driver_notify_ignore_device (NMApplet *applet, NetworkDevice *dev)
609
gboolean found = FALSE;
610
GSList * new_mac_list = NULL;
612
const char * dev_addr;
614
g_return_if_fail (applet != NULL);
615
g_return_if_fail (applet->gconf_client != NULL);
616
g_return_if_fail (dev != NULL);
618
dev_addr = network_device_get_address (dev);
619
g_return_if_fail (dev_addr != NULL);
620
g_return_if_fail (strlen (dev_addr) > 0);
622
new_mac_list = nma_driver_notify_get_ignored_list (applet);
624
/* Ensure that the MAC isn't already in the list */
625
for (elt = new_mac_list; elt; elt = g_slist_next (elt))
627
if (elt->data && !strcmp (dev_addr, elt->data))
634
/* Add the new MAC address to the end of the list */
637
char *key = g_strdup_printf ("%s/non_notify_cards", GCONF_PATH_PREFS);
639
new_mac_list = g_slist_append (new_mac_list, g_strdup (dev_addr));
640
gconf_client_set_list (applet->gconf_client, key, GCONF_VALUE_STRING, new_mac_list, NULL);
644
/* Free the list, since gconf_client_set_list deep-copies it */
645
g_slist_foreach (new_mac_list, (GFunc)g_free, NULL);
646
g_slist_free (new_mac_list);
649
static gboolean nma_driver_notify_dialog_delete_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
651
gtk_widget_destroy (widget);
655
static gboolean nma_driver_notify_dialog_destroy_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
657
DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data);
660
g_return_val_if_fail (cb_data != NULL, FALSE);
661
g_return_val_if_fail (cb_data->xml != NULL, FALSE);
664
g_return_val_if_fail (dev != NULL, FALSE);
666
network_device_unref (dev);
668
g_object_unref (cb_data->xml);
675
static gboolean nma_driver_notify_ok_cb (GtkButton *button, gpointer user_data)
677
DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data);
683
g_return_val_if_fail (cb_data != NULL, FALSE);
684
g_return_val_if_fail (cb_data->xml != NULL, FALSE);
687
g_return_val_if_fail (dev != NULL, FALSE);
689
applet = cb_data->applet;
690
g_return_val_if_fail (applet != NULL, FALSE);
692
checkbox = glade_xml_get_widget (cb_data->xml, "dont_remind_checkbox");
693
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)))
694
nma_driver_notify_ignore_device (applet, dev);
696
dialog = glade_xml_get_widget (cb_data->xml, "driver_sucks_dialog");
697
gtk_widget_destroy (dialog);
706
* Notify the user if there's some problem with the driver
707
* of a specific network device.
710
gboolean nma_driver_notify (gpointer user_data)
712
DriverNotifyCBData * cb_data = (DriverNotifyCBData *)(user_data);
717
char * label_text = NULL;
721
g_return_val_if_fail (cb_data != NULL, FALSE);
724
g_return_val_if_fail (dev != NULL, FALSE);
726
if (!(applet = cb_data->applet) || !applet->glade_file)
729
/* If the user has already requested that we ignore notifications for
730
* this device, don't do anything.
732
if (nma_driver_notify_is_device_ignored (applet, dev))
735
if (!(cb_data->xml = glade_xml_new (applet->glade_file, "driver_sucks_dialog", NULL)))
737
nma_schedule_warning_dialog (applet, _("The NetworkManager Applet could not find some required resources (the glade file was not found)."));
741
dialog = glade_xml_get_widget (cb_data->xml, "driver_sucks_dialog");
742
g_signal_connect (G_OBJECT (dialog), "destroy-event", GTK_SIGNAL_FUNC (nma_driver_notify_dialog_destroy_cb), cb_data);
743
g_signal_connect (G_OBJECT (dialog), "delete-event", GTK_SIGNAL_FUNC (nma_driver_notify_dialog_delete_cb), cb_data);
745
label = GTK_LABEL (glade_xml_get_widget (cb_data->xml, "driver_sucks_label"));
747
if (network_device_is_wireless (dev) && !(network_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN))
749
temp = g_strdup_printf (_("The network device \"%s (%s)\" does not support wireless scanning."),
750
network_device_get_desc (dev), network_device_get_iface (dev));
751
label_text = g_strdup_printf (gtk_label_get_label (label), temp);
755
if (network_device_is_wired (dev) && !(network_device_get_capabilities (dev) & NM_DEVICE_CAP_CARRIER_DETECT))
757
temp = g_strdup_printf (_("The network device \"%s (%s)\" does not support link detection."),
758
network_device_get_desc (dev), network_device_get_iface (dev));
759
label_text = g_strdup_printf (gtk_label_get_label (label), temp);
764
gtk_label_set_markup (label, label_text);
766
button = GTK_BUTTON (glade_xml_get_widget (cb_data->xml, "ok_button"));
767
g_signal_connect (G_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (nma_driver_notify_ok_cb), cb_data);
769
/* Bash focus-stealing prevention in the face */
770
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
771
gtk_widget_realize (dialog);
772
gdk_x11_window_set_user_time (dialog->window, gtk_get_current_event_time ());
773
gtk_widget_show_all (dialog);
776
network_device_unref (cb_data->dev);
782
* nma_get_first_active_vpn_connection
784
* Return the first active VPN connection, if any.
787
VPNConnection *nma_get_first_active_vpn_connection (NMApplet *applet)
790
NMVPNActStage vpn_state;
793
for (elt = applet->vpn_connections; elt; elt = g_slist_next (elt))
795
vpn = (VPNConnection*) elt->data;
796
vpn_state = nma_vpn_connection_get_stage (vpn);
797
if (vpn_state == NM_VPN_ACT_STAGE_ACTIVATED)
804
static VPNConnection *nma_get_first_activating_vpn_connection (NMApplet *applet)
809
for (elt = applet->vpn_connections; elt; elt = g_slist_next (elt))
811
vpn = (VPNConnection*) elt->data;
812
if (nma_vpn_connection_is_activating (vpn))
820
static void nma_set_icon (NMApplet *applet, GdkPixbuf *link_icon, GdkPixbuf *vpn_icon)
822
GtkRequisition requisition;
823
GdkPixbuf *composite;
826
g_return_if_fail (applet != NULL);
827
g_return_if_fail (link_icon != NULL);
829
composite = gdk_pixbuf_copy (link_icon);
831
vpn = nma_get_first_active_vpn_connection (applet);
833
vpn = nma_get_first_activating_vpn_connection (applet);
836
gdk_pixbuf_composite (vpn_icon, composite, 0, 0, gdk_pixbuf_get_width (vpn_icon),
837
gdk_pixbuf_get_height (vpn_icon), 0, 0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
839
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), composite);
841
/* Add some padding to the applet to ensure the
842
* highlight has some space.
844
gtk_widget_set_size_request (GTK_WIDGET (applet), -1, -1);
845
gtk_widget_size_request (GTK_WIDGET (applet), &requisition);
846
gtk_widget_set_size_request (GTK_WIDGET (applet), requisition.width + 6, requisition.height + 2);
848
g_object_unref (composite);
852
static GdkPixbuf *nma_get_connected_icon (NMApplet *applet, NetworkDevice *dev)
855
GdkPixbuf *pixbuf = NULL;
857
g_return_val_if_fail (applet != NULL, NULL);
858
g_return_val_if_fail (dev != NULL, NULL);
860
if (network_device_is_wireless (dev))
862
if (applet->is_adhoc)
863
pixbuf = applet->adhoc_icon;
866
strength = CLAMP ((int)network_device_get_strength (dev), 0, 100);
868
pixbuf = applet->wireless_100_icon;
869
else if (strength > 55)
870
pixbuf = applet->wireless_75_icon;
871
else if (strength > 30)
872
pixbuf = applet->wireless_50_icon;
873
else if (strength > 5)
874
pixbuf = applet->wireless_25_icon;
876
pixbuf = applet->wireless_00_icon;
880
pixbuf = applet->wired_icon;
886
static GdkPixbuf * nma_act_stage_to_pixbuf (NMApplet *applet, NetworkDevice *dev, WirelessNetwork *net, char **tip)
890
gint connecting_stage = -1;
891
GdkPixbuf *pixbuf = NULL;
893
g_return_val_if_fail (applet != NULL, NULL);
894
g_return_val_if_fail (dev != NULL, NULL);
895
g_return_val_if_fail (tip != NULL, NULL);
897
iface = network_device_get_iface (dev);
898
essid = net ? wireless_network_get_essid (net) : NULL;
899
switch (network_device_get_act_stage (dev))
901
case NM_ACT_STAGE_DEVICE_PREPARE:
903
if (network_device_is_wired (dev))
904
*tip = g_strdup_printf (_("Preparing device %s for the wired network..."), iface);
905
else if (network_device_is_wireless (dev))
906
*tip = g_strdup_printf (_("Preparing device %s for the wireless network '%s'..."), iface, essid);
907
connecting_stage = 0;
911
case NM_ACT_STAGE_DEVICE_CONFIG:
913
if (network_device_is_wired (dev))
914
*tip = g_strdup_printf (_("Configuring device %s for the wired network..."), iface);
915
else if (network_device_is_wireless (dev))
916
*tip = g_strdup_printf (_("Attempting to join the wireless network '%s'..."), essid);
917
connecting_stage = 0;
921
case NM_ACT_STAGE_NEED_USER_KEY:
923
if (network_device_is_wireless (dev))
924
*tip = g_strdup_printf (_("Waiting for Network Key for the wireless network '%s'..."), essid);
925
connecting_stage = 0;
929
case NM_ACT_STAGE_IP_CONFIG_START:
931
if (network_device_is_wired (dev))
932
*tip = g_strdup_printf (_("Requesting a network address from the wired network..."));
933
else if (network_device_is_wireless (dev))
934
*tip = g_strdup_printf (_("Requesting a network address from the wireless network '%s'..."), essid);
935
connecting_stage = 1;
939
case NM_ACT_STAGE_IP_CONFIG_GET:
941
if (network_device_is_wired (dev))
942
*tip = g_strdup_printf (_("Requesting a network address from the wired network..."));
943
else if (network_device_is_wireless (dev))
944
*tip = g_strdup_printf (_("Requesting a network address from the wireless network '%s'..."), essid);
945
connecting_stage = 2;
949
case NM_ACT_STAGE_IP_CONFIG_COMMIT:
951
if (network_device_is_wired (dev))
952
*tip = g_strdup_printf (_("Finishing connection to the wired network..."));
953
else if (network_device_is_wireless (dev))
954
*tip = g_strdup_printf (_("Finishing connection to the wireless network '%s'..."), essid);
955
connecting_stage = 2;
960
case NM_ACT_STAGE_ACTIVATED:
961
case NM_ACT_STAGE_FAILED:
962
case NM_ACT_STAGE_CANCELLED:
963
case NM_ACT_STAGE_UNKNOWN:
967
if (connecting_stage >= 0 && connecting_stage < NUM_CONNECTING_STAGES)
969
if (applet->animation_step >= NUM_CONNECTING_FRAMES)
970
applet->animation_step = 0;
972
pixbuf = applet->network_connecting_icons[connecting_stage][applet->animation_step];
982
* Jump to the next frame of the applets icon if the icon
983
* is supposed to be animated.
986
static gboolean animation_timeout (NMApplet *applet)
988
NetworkDevice *act_dev;
991
g_return_val_if_fail (applet != NULL, FALSE);
993
if (!applet->nm_running)
995
applet->animation_step = 0;
996
applet->animation_id = 0;
1000
act_dev = nma_get_first_active_device (applet->device_list);
1003
applet->animation_step = 0;
1004
applet->animation_id = 0;
1008
if (applet->nm_state == NM_STATE_CONNECTING)
1013
pixbuf = nma_act_stage_to_pixbuf (applet, act_dev, NULL, &tip);
1017
nma_set_icon (applet, pixbuf, NULL);
1019
applet->animation_step ++;
1021
else if (nma_get_first_activating_vpn_connection (applet) != NULL)
1023
pixbuf = nma_get_connected_icon (applet, act_dev);
1025
if (applet->animation_step >= NUM_VPN_CONNECTING_FRAMES)
1026
applet->animation_step = 0;
1028
nma_set_icon (applet, pixbuf, applet->vpn_connecting_icons[applet->animation_step]);
1029
applet->animation_step ++;
1033
applet->animation_step = 0;
1034
nma_update_state (applet);
1045
* Figure out what the currently active device is from NetworkManager, its type,
1046
* and what our icon on the panel should look like for each type.
1049
static void nma_update_state (NMApplet *applet)
1051
gboolean show_applet = TRUE;
1052
gboolean need_animation = FALSE;
1053
GdkPixbuf * pixbuf = NULL;
1056
char * vpntip = NULL;
1057
WirelessNetwork * active_network = NULL;
1058
NetworkDevice * act_dev = NULL;
1061
act_dev = nma_get_first_active_device (applet->device_list);
1062
if (act_dev && network_device_is_wireless (act_dev))
1064
active_network = network_device_get_active_wireless_network (act_dev);
1065
strength = CLAMP ((int)network_device_get_strength (act_dev), 0, 100);
1068
if (!applet->nm_running)
1070
show_applet = FALSE;
1071
tip = g_strdup (_("NetworkManager is not running"));
1075
switch (applet->nm_state)
1077
case NM_STATE_ASLEEP:
1078
pixbuf = applet->no_connection_icon;
1079
tip = g_strdup (_("Networking disabled"));
1082
case NM_STATE_DISCONNECTED:
1083
pixbuf = applet->no_connection_icon;
1084
tip = g_strdup (_("No network connection"));
1087
case NM_STATE_CONNECTED:
1088
if (network_device_is_wired (act_dev))
1089
tip = g_strdup (_("Wired network connection"));
1090
else if (network_device_is_wireless (act_dev))
1092
if (applet->is_adhoc)
1093
tip = g_strdup (_("Connected to an Ad-Hoc wireless network"));
1095
tip = g_strdup_printf (_("Wireless network connection to '%s' (%d%%)"),
1096
active_network ? wireless_network_get_essid (active_network) : "(unknown)", strength);
1098
pixbuf = nma_get_connected_icon (applet, act_dev);
1101
case NM_STATE_CONNECTING:
1104
pixbuf = nma_act_stage_to_pixbuf (applet, act_dev, active_network, &tip);
1105
need_animation = TRUE;
1113
vpn = nma_get_first_active_vpn_connection (applet);
1116
vpntip = g_strdup_printf (_("VPN connection to '%s'"), nma_vpn_connection_get_name (vpn));
1120
vpn = nma_get_first_activating_vpn_connection (applet);
1123
need_animation = TRUE;
1124
vpntip = g_strdup_printf (_("VPN connecting to '%s'"), nma_vpn_connection_get_name (vpn));
1131
newtip = g_strconcat (tip, "\n", vpntip, NULL);
1138
if (!applet->tooltips)
1139
applet->tooltips = gtk_tooltips_new ();
1141
gtk_tooltips_set_tip (applet->tooltips, applet->event_box, tip, NULL);
1144
applet->animation_step = 0;
1145
if (need_animation && applet->animation_id == 0)
1146
applet->animation_id = g_timeout_add (100, (GSourceFunc) animation_timeout, applet);
1147
else if (!need_animation)
1149
if (applet->animation_id)
1151
g_source_remove (applet->animation_id);
1152
applet->animation_id = 0;
1156
nma_set_icon (applet, pixbuf, applet->vpn_lock_icon);
1158
show_applet = FALSE;
1161
/* determine if we should hide the notification icon */
1163
gtk_widget_show (GTK_WIDGET (applet));
1165
gtk_widget_hide (GTK_WIDGET (applet));
1170
* nma_redraw_timeout
1172
* Called regularly to update the applet's state and icon in the panel
1175
static int nma_redraw_timeout (NMApplet *applet)
1177
if (!applet->animation_id)
1178
nma_update_state (applet);
1185
* show_warning_dialog
1187
* pop up a warning or error dialog with certain text
1190
static gboolean show_warning_dialog (char *mesg)
1194
dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, mesg, NULL);
1196
/* Bash focus-stealing prevention in the face */
1197
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
1198
gtk_widget_realize (dialog);
1199
gdk_x11_window_set_user_time (dialog->window, gtk_get_current_event_time ());
1200
gtk_window_present (GTK_WINDOW (dialog));
1202
g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
1210
* nma_schedule_warning_dialog
1212
* Run a warning dialog in the main event loop.
1215
void nma_schedule_warning_dialog (NMApplet *applet, const char *msg)
1219
g_return_if_fail (applet != NULL);
1220
g_return_if_fail (msg != NULL);
1222
lcl_msg = g_strdup (msg);
1223
g_idle_add ((GSourceFunc) show_warning_dialog, lcl_msg);
1228
* nma_get_device_for_nm_device
1230
* Searches the device list for a device that matches the
1231
* NetworkManager ID given.
1234
NetworkDevice *nma_get_device_for_nm_path (GSList *dev_list, const char *nm_path)
1236
NetworkDevice *found_dev = NULL;
1239
g_return_val_if_fail (nm_path != NULL, NULL);
1240
g_return_val_if_fail (strlen (nm_path), NULL);
1242
for (elt = dev_list; elt; elt = g_slist_next (elt))
1244
NetworkDevice *dev = (NetworkDevice *)(elt->data);
1245
if (dev && (strcmp (network_device_get_nm_path (dev), nm_path) == 0))
1257
* nma_menu_item_activate
1259
* Signal function called when user clicks on a menu item
1262
static void nma_menu_item_activate (GtkMenuItem *item, gpointer user_data)
1264
NMApplet *applet = (NMApplet *)user_data;
1265
NetworkDevice *dev = NULL;
1266
WirelessNetwork *net = NULL;
1269
g_return_if_fail (item != NULL);
1270
g_return_if_fail (applet != NULL);
1272
if (!(tag = g_object_get_data (G_OBJECT (item), "device")))
1275
if ((dev = nma_get_device_for_nm_path (applet->device_list, tag)))
1276
network_device_ref (dev);
1281
if ((tag = g_object_get_data (G_OBJECT (item), "network")))
1282
net = network_device_get_wireless_network_by_essid (dev, tag);
1284
nma_dbus_set_device (applet->connection, dev, net ? wireless_network_get_essid (net) : NULL, NULL);
1285
network_device_unref (dev);
1287
nmi_dbus_signal_user_interface_activated (applet->connection);
1292
* nma_menu_vpn_item_activate
1294
* Signal function called when user clicks on a VPN menu item
1297
static void nma_menu_vpn_item_activate (GtkMenuItem *item, gpointer user_data)
1299
NMApplet *applet = (NMApplet *)user_data;
1302
g_return_if_fail (item != NULL);
1303
g_return_if_fail (applet != NULL);
1305
if ((tag = g_object_get_data (G_OBJECT (item), "vpn")))
1307
VPNConnection *vpn = (VPNConnection *)tag;
1308
const char *name = nma_vpn_connection_get_name (vpn);
1310
VPNConnection *active_vpn = nma_get_first_active_vpn_connection (applet);
1312
if (vpn != active_vpn)
1316
gboolean last_attempt_success;
1319
escaped_name = gconf_escape_key (name, strlen (name));
1320
gconf_key = g_strdup_printf ("%s/%s/last_attempt_success", GCONF_PATH_VPN_CONNECTIONS, escaped_name);
1321
last_attempt_success = gconf_client_get_bool (applet->gconf_client, gconf_key, NULL);
1323
g_free (escaped_name);
1325
reprompt = ! last_attempt_success; /* it's obvious, but.. */
1327
if ((passwords = nma_vpn_request_password (applet,
1329
nma_vpn_connection_get_service (vpn),
1332
nma_dbus_vpn_activate_connection (applet->connection, name, passwords);
1334
g_slist_foreach (passwords, (GFunc)g_free, NULL);
1335
g_slist_free (passwords);
1340
nmi_dbus_signal_user_interface_activated (applet->connection);
1345
* nma_menu_connect_item_activate
1347
* Signal function called when user clicks on a dialup menu item
1350
static void nma_menu_dialup_connect_item_activate (GtkMenuItem *item, gpointer user_data)
1352
NMApplet *applet = (NMApplet *) user_data;
1355
g_return_if_fail (item != NULL);
1356
g_return_if_fail (applet != NULL);
1358
dialup = g_object_get_data (G_OBJECT (item), "dialup");
1362
nma_dbus_dialup_activate_connection (applet, dialup);
1364
nmi_dbus_signal_user_interface_activated (applet->connection);
1369
* nma_menu_dialup_hangup_activate
1371
* Signal function called when user clicks on a dialup menu item
1374
static void nma_menu_dialup_disconnect_item_activate (GtkMenuItem *item, gpointer user_data)
1376
NMApplet *applet = (NMApplet *) user_data;
1379
g_return_if_fail (item != NULL);
1380
g_return_if_fail (applet != NULL);
1382
dialup = g_object_get_data (G_OBJECT (item), "dialup");
1386
nma_dbus_dialup_deactivate_connection (applet, dialup);
1388
nmi_dbus_signal_user_interface_activated (applet->connection);
1393
* nma_menu_configure_vpn_item_activate
1395
* Signal function called when user clicks "Configure VPN..."
1398
static void nma_menu_configure_vpn_item_activate (GtkMenuItem *item, gpointer user_data)
1400
NMApplet *applet = (NMApplet *)user_data;
1401
const char *argv[] = { BINDIR "/nm-vpn-properties", NULL};
1403
g_return_if_fail (item != NULL);
1404
g_return_if_fail (applet != NULL);
1406
g_spawn_async (NULL, (gchar **) argv, NULL, 0, NULL, NULL, NULL, NULL);
1408
nmi_dbus_signal_user_interface_activated (applet->connection);
1412
* nma_menu_disconnect_vpn_item_activate
1414
* Signal function called when user clicks "Disconnect VPN..."
1417
static void nma_menu_disconnect_vpn_item_activate (GtkMenuItem *item, gpointer user_data)
1419
NMApplet *applet = (NMApplet *)user_data;
1421
g_return_if_fail (item != NULL);
1422
g_return_if_fail (applet != NULL);
1424
nma_dbus_vpn_deactivate_connection (applet->connection);
1426
nmi_dbus_signal_user_interface_activated (applet->connection);
1431
* nma_menu_add_separator_item
1434
static void nma_menu_add_separator_item (GtkWidget *menu)
1436
GtkWidget *menu_item;
1437
menu_item = gtk_separator_menu_item_new ();
1438
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
1439
gtk_widget_show (menu_item);
1444
* nma_menu_add_text_item
1446
* Add a non-clickable text item to a menu
1449
static void nma_menu_add_text_item (GtkWidget *menu, char *text)
1451
GtkWidget *menu_item;
1453
g_return_if_fail (text != NULL);
1454
g_return_if_fail (menu != NULL);
1456
menu_item = gtk_menu_item_new_with_label (text);
1457
gtk_widget_set_sensitive (menu_item, FALSE);
1459
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
1460
gtk_widget_show (menu_item);
1465
* nma_menu_add_device_item
1467
* Add a network device to the menu
1470
static void nma_menu_add_device_item (GtkWidget *menu, NetworkDevice *device, gint n_devices, NMApplet *applet)
1472
g_return_if_fail (menu != NULL);
1473
g_return_if_fail (device != NULL);
1474
g_return_if_fail (applet != NULL);
1476
switch (network_device_get_type (device))
1478
case DEVICE_TYPE_802_3_ETHERNET:
1480
NMWiredMenuItem *item = wired_menu_item_new ();
1481
GtkCheckMenuItem *gtk_item = wired_menu_item_get_check_item (item);
1483
wired_menu_item_update (item, device, n_devices);
1484
if (network_device_get_active (device))
1485
gtk_check_menu_item_set_active (gtk_item, TRUE);
1486
gtk_check_menu_item_set_draw_as_radio (gtk_item, TRUE);
1488
g_object_set_data (G_OBJECT (gtk_item), "device", g_strdup (network_device_get_nm_path (device)));
1489
g_object_set_data (G_OBJECT (gtk_item), "nm-item-data", item);
1490
g_signal_connect(G_OBJECT (gtk_item), "activate", G_CALLBACK (nma_menu_item_activate), applet);
1492
gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (gtk_item));
1493
gtk_widget_show (GTK_WIDGET (gtk_item));
1497
case DEVICE_TYPE_802_11_WIRELESS:
1499
NMWirelessMenuItem *item;
1500
GtkMenuItem *gtk_item;
1502
if (!applet->wireless_enabled)
1505
item = wireless_menu_item_new ();
1506
gtk_item = wireless_menu_item_get_item (item);
1508
wireless_menu_item_update (item, device, n_devices);
1510
g_object_set_data (G_OBJECT (gtk_item), "device", g_strdup (network_device_get_nm_path (device)));
1511
g_object_set_data (G_OBJECT (gtk_item), "nm-item-data", item);
1512
g_signal_connect(G_OBJECT (gtk_item), "activate", G_CALLBACK (nma_menu_item_activate), applet);
1514
gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (gtk_item));
1515
gtk_widget_show (GTK_WIDGET (gtk_item));
1525
static void custom_essid_item_selected (GtkWidget *menu_item, NMApplet *applet)
1527
nma_other_network_dialog_run (applet, FALSE);
1531
static void nma_menu_add_custom_essid_item (GtkWidget *menu, NMApplet *applet)
1533
GtkWidget *menu_item;
1536
menu_item = gtk_menu_item_new ();
1537
label = gtk_label_new_with_mnemonic (_("_Connect to Other Wireless Network..."));
1538
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1539
gtk_container_add (GTK_CONTAINER (menu_item), label);
1540
gtk_widget_show_all (menu_item);
1541
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
1542
g_signal_connect (menu_item, "activate", G_CALLBACK (custom_essid_item_selected), applet);
1546
static void new_network_item_selected (GtkWidget *menu_item, NMApplet *applet)
1548
nma_other_network_dialog_run (applet, TRUE);
1552
static void nma_menu_add_create_network_item (GtkWidget *menu, NMApplet *applet)
1554
GtkWidget *menu_item;
1557
menu_item = gtk_menu_item_new ();
1558
label = gtk_label_new_with_mnemonic (_("Create _New Wireless Network..."));
1559
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1560
gtk_container_add (GTK_CONTAINER (menu_item), label);
1561
gtk_widget_show_all (menu_item);
1562
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
1563
g_signal_connect (menu_item, "activate", G_CALLBACK (new_network_item_selected), applet);
1567
typedef struct AddNetworksCB
1570
gboolean has_encrypted;
1576
* nma_add_networks_helper
1579
static void nma_add_networks_helper (NetworkDevice *dev, WirelessNetwork *net, gpointer user_data)
1581
AddNetworksCB * cb_data = (AddNetworksCB *)user_data;
1582
NMNetworkMenuItem * item;
1583
GtkCheckMenuItem * gtk_item;
1586
g_return_if_fail (dev != NULL);
1587
g_return_if_fail (net != NULL);
1588
g_return_if_fail (cb_data != NULL);
1589
g_return_if_fail (cb_data->menu != NULL);
1590
g_return_if_fail (cb_data->applet != NULL);
1592
applet = cb_data->applet;
1593
item = network_menu_item_new (applet->encryption_size_group);
1594
gtk_item = network_menu_item_get_check_item (item);
1596
gtk_menu_shell_append (GTK_MENU_SHELL (cb_data->menu), GTK_WIDGET (gtk_item));
1597
if ( (applet->nm_state == NM_STATE_CONNECTED)
1598
|| (applet->nm_state == NM_STATE_CONNECTING))
1600
if (network_device_get_active (dev) && wireless_network_get_active (net))
1601
gtk_check_menu_item_set_active (gtk_item, TRUE);
1603
network_menu_item_update (applet, item, net, cb_data->has_encrypted);
1605
g_object_set_data (G_OBJECT (gtk_item), "network", g_strdup (wireless_network_get_essid (net)));
1606
g_object_set_data (G_OBJECT (gtk_item), "device", g_strdup (network_device_get_nm_path (dev)));
1607
g_object_set_data (G_OBJECT (gtk_item), "nm-item-data", item);
1608
g_signal_connect (G_OBJECT (gtk_item), "activate", G_CALLBACK (nma_menu_item_activate), applet);
1610
gtk_widget_show (GTK_WIDGET (gtk_item));
1615
* nma_has_encrypted_networks_helper
1618
static void nma_has_encrypted_networks_helper (NetworkDevice *dev, WirelessNetwork *net, gpointer user_data)
1620
gboolean *has_encrypted = user_data;
1623
g_return_if_fail (dev != NULL);
1624
g_return_if_fail (net != NULL);
1625
g_return_if_fail (has_encrypted != NULL);
1627
capabilities = wireless_network_get_capabilities (net);
1628
if ( (capabilities & NM_802_11_CAP_PROTO_WEP)
1629
|| (capabilities & NM_802_11_CAP_PROTO_WPA)
1630
|| (capabilities & NM_802_11_CAP_PROTO_WPA2))
1631
*has_encrypted = TRUE;
1636
* nma_menu_device_add_networks
1639
static void nma_menu_device_add_networks (GtkWidget *menu, NetworkDevice *dev, NMApplet *applet)
1641
gboolean has_encrypted = FALSE;
1642
AddNetworksCB * add_networks_cb = NULL;
1644
g_return_if_fail (menu != NULL);
1645
g_return_if_fail (applet != NULL);
1646
g_return_if_fail (dev != NULL);
1648
if (!network_device_is_wireless (dev) || !applet->wireless_enabled)
1651
/* Check for any security */
1652
network_device_foreach_wireless_network (dev, nma_has_encrypted_networks_helper, &has_encrypted);
1654
add_networks_cb = g_malloc0 (sizeof (AddNetworksCB));
1655
add_networks_cb->applet = applet;
1656
add_networks_cb->has_encrypted = has_encrypted;
1657
add_networks_cb->menu = menu;
1659
/* Add all networks in our network list to the menu */
1660
network_device_foreach_wireless_network (dev, nma_add_networks_helper, add_networks_cb);
1662
g_free (add_networks_cb);
1667
* nma_menu_add_devices
1670
static void nma_menu_add_vpn_menu (GtkWidget *menu, NMApplet *applet)
1674
GtkMenuItem *other_item;
1676
VPNConnection *active_vpn;
1678
g_return_if_fail (menu != NULL);
1679
g_return_if_fail (applet != NULL);
1681
item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_VPN Connections")));
1683
vpn_menu = GTK_MENU (gtk_menu_new ());
1684
active_vpn = nma_get_first_active_vpn_connection (applet);
1686
for (elt = applet->vpn_connections; elt; elt = g_slist_next (elt))
1688
GtkCheckMenuItem *vpn_item;
1689
VPNConnection *vpn = elt->data;
1690
const char *vpn_name = nma_vpn_connection_get_name (vpn);
1692
vpn_item = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (vpn_name));
1693
/* temporarily do this until we support multiple VPN connections */
1694
gtk_check_menu_item_set_draw_as_radio (vpn_item, TRUE);
1696
nma_vpn_connection_ref (vpn);
1697
g_object_set_data (G_OBJECT (vpn_item), "vpn", vpn);
1699
/* FIXME: all VPN items except the active one are disabled,
1700
* due to a bug in the VPN handling code in NM. See commit to
1701
* src/vpn-manager/nm-vpn-service.c on 2006-02-28 by dcbw for
1706
if (active_vpn == vpn)
1707
gtk_check_menu_item_set_active (vpn_item, TRUE);
1709
gtk_widget_set_sensitive (GTK_WIDGET (vpn_item), FALSE);
1712
if (applet->nm_state != NM_STATE_CONNECTED)
1713
gtk_widget_set_sensitive (GTK_WIDGET (vpn_item), FALSE);
1715
g_signal_connect (G_OBJECT (vpn_item), "activate", G_CALLBACK (nma_menu_vpn_item_activate), applet);
1716
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (vpn_item));
1719
/* Draw a seperator, but only if we have VPN connections above it */
1720
if (applet->vpn_connections)
1722
other_item = GTK_MENU_ITEM (gtk_separator_menu_item_new ());
1723
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
1726
other_item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Configure VPN...")));
1727
g_signal_connect (G_OBJECT (other_item), "activate", G_CALLBACK (nma_menu_configure_vpn_item_activate), applet);
1728
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
1730
other_item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Disconnect VPN...")));
1731
g_signal_connect (G_OBJECT (other_item), "activate", G_CALLBACK (nma_menu_disconnect_vpn_item_activate), applet);
1733
gtk_widget_set_sensitive (GTK_WIDGET (other_item), FALSE);
1734
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
1736
gtk_menu_item_set_submenu (item, GTK_WIDGET (vpn_menu));
1738
gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
1739
gtk_widget_show_all (GTK_WIDGET (item));
1743
static void nma_menu_add_dialup_menu (GtkWidget *menu, NMApplet *applet)
1746
GtkMenu *dialup_menu;
1749
g_return_if_fail (menu != NULL);
1750
g_return_if_fail (applet != NULL);
1752
item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Dial Up Connections")));
1754
dialup_menu = GTK_MENU (gtk_menu_new ());
1755
for (elt = applet->dialup_list; elt; elt = g_slist_next (elt))
1757
GtkMenuItem *connect_item, *disconnect_item;
1758
char *name = elt->data;
1761
/* FIXME: We should save and then check the state of the devices and show Connect _or_ Disconnect for each item */
1763
label = g_strdup_printf (_("Connect to %s..."), name);
1764
connect_item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (label));
1765
g_object_set_data (G_OBJECT (connect_item), "dialup", name);
1766
g_signal_connect (G_OBJECT (connect_item), "activate", G_CALLBACK (nma_menu_dialup_connect_item_activate), applet);
1767
gtk_menu_shell_append (GTK_MENU_SHELL (dialup_menu), GTK_WIDGET (connect_item));
1769
label = g_strdup_printf (_("Disconnect from %s..."), name);
1770
disconnect_item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (label));
1771
g_object_set_data (G_OBJECT (disconnect_item), "dialup", name);
1772
g_signal_connect (G_OBJECT (disconnect_item), "activate", G_CALLBACK (nma_menu_dialup_disconnect_item_activate), applet);
1773
gtk_menu_shell_append (GTK_MENU_SHELL (dialup_menu), GTK_WIDGET (disconnect_item));
1776
gtk_menu_item_set_submenu (item, GTK_WIDGET (dialup_menu));
1777
gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
1778
gtk_widget_show_all (GTK_WIDGET (item));
1782
/** Returns TRUE if, and only if, we have VPN support installed
1784
* Algorithm: just check whether any files exist in the directory
1785
* /etc/NetworkManager/VPN
1787
static gboolean is_vpn_available (void)
1793
if ((dir = g_dir_open (VPN_NAME_FILES_DIR, 0, NULL)) != NULL) {
1794
if (g_dir_read_name (dir) != NULL)
1803
* nma_menu_add_devices
1806
static void nma_menu_add_devices (GtkWidget *menu, NMApplet *applet)
1809
gint n_wireless_interfaces = 0;
1810
gint n_wired_interfaces = 0;
1811
gboolean vpn_available, dialup_available;
1813
g_return_if_fail (menu != NULL);
1814
g_return_if_fail (applet != NULL);
1816
if (!applet->device_list)
1818
nma_menu_add_text_item (menu, _("No network devices have been found"));
1822
if (applet->nm_state == NM_STATE_ASLEEP)
1824
nma_menu_add_text_item (menu, _("Networking disabled"));
1828
for (element = applet->device_list; element; element = element->next)
1830
NetworkDevice *dev = (NetworkDevice *)(element->data);
1834
/* Ignore unsupported devices */
1835
if (!(network_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED))
1838
switch (network_device_get_type (dev))
1840
case DEVICE_TYPE_802_11_WIRELESS:
1841
n_wireless_interfaces++;
1843
case DEVICE_TYPE_802_3_ETHERNET:
1844
n_wired_interfaces++;
1851
/* Add all devices in our device list to the menu */
1852
for (element = applet->device_list; element; element = element->next)
1854
NetworkDevice *dev = (NetworkDevice *)(element->data);
1860
/* Ignore unsupported devices */
1861
if (!(network_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED))
1864
switch (network_device_get_type (dev))
1866
case DEVICE_TYPE_802_3_ETHERNET:
1867
n_devices = n_wired_interfaces;
1870
case DEVICE_TYPE_802_11_WIRELESS:
1871
n_devices = n_wireless_interfaces;
1880
nma_menu_add_device_item (menu, dev, n_devices, applet);
1881
nma_menu_device_add_networks (menu, dev, applet);
1886
/* Add the VPN and Dial Up menus and their associated seperator */
1887
vpn_available = is_vpn_available ();
1888
dialup_available = !! applet->dialup_list;
1889
if (vpn_available || dialup_available)
1891
nma_menu_add_separator_item (menu);
1893
nma_menu_add_vpn_menu (menu, applet);
1894
if (dialup_available)
1895
nma_menu_add_dialup_menu (menu, applet);
1898
if (n_wireless_interfaces > 0 && applet->wireless_enabled)
1900
/* Add the "Other wireless network..." entry */
1901
nma_menu_add_separator_item (menu);
1902
nma_menu_add_custom_essid_item (menu, applet);
1903
nma_menu_add_create_network_item (menu, applet);
1908
static void nma_set_wireless_enabled_cb (GtkWidget *widget, NMApplet *applet)
1912
g_return_if_fail (applet != NULL);
1914
state = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
1915
if (applet->wireless_enabled != state)
1916
nma_dbus_enable_wireless (applet, state);
1920
static void nma_set_networking_enabled_cb (GtkWidget *widget, NMApplet *applet)
1924
g_return_if_fail (applet != NULL);
1926
state = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
1927
if ((applet->nm_state == NM_STATE_ASLEEP && state) || (applet->nm_state != NM_STATE_ASLEEP && !state))
1928
nma_dbus_enable_networking (applet, state);
1933
* nma_menu_item_data_free
1935
* Frees the "network" data tag on a menu item we've created
1938
static void nma_menu_item_data_free (GtkWidget *menu_item, gpointer data)
1943
g_return_if_fail (menu_item != NULL);
1944
g_return_if_fail (data != NULL);
1946
if ((tag = g_object_get_data (G_OBJECT (menu_item), "network")))
1948
g_object_set_data (G_OBJECT (menu_item), "network", NULL);
1952
if ((tag = g_object_get_data (G_OBJECT (menu_item), "nm-item-data")))
1954
g_object_set_data (G_OBJECT (menu_item), "nm-item-data", NULL);
1958
if ((tag = g_object_get_data (G_OBJECT (menu_item), "device")))
1960
g_object_set_data (G_OBJECT (menu_item), "device", NULL);
1964
if ((tag = g_object_get_data (G_OBJECT (menu_item), "vpn")))
1966
g_object_set_data (G_OBJECT (menu_item), "vpn", NULL);
1967
nma_vpn_connection_unref ((VPNConnection *)tag);
1970
if ((tag = g_object_get_data (G_OBJECT (menu_item), "disconnect")))
1972
g_object_set_data (G_OBJECT (menu_item), "disconnect", NULL);
1976
if ((menu = GTK_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item)))))
1977
gtk_container_foreach (GTK_CONTAINER (menu), nma_menu_item_data_free, menu);
1979
gtk_widget_destroy (menu_item);
1984
* nma_dispose_menu_items
1986
* Destroy the menu and each of its items data tags
1989
static void nma_dropdown_menu_clear (GtkWidget *menu)
1991
g_return_if_fail (menu != NULL);
1993
/* Free the "network" data on each menu item, and destroy the item */
1994
gtk_container_foreach (GTK_CONTAINER (menu), nma_menu_item_data_free, menu);
1999
* nma_dropdown_menu_populate
2001
* Set up our networks menu from scratch
2004
static void nma_dropdown_menu_populate (GtkWidget *menu, NMApplet *applet)
2006
g_return_if_fail (menu != NULL);
2007
g_return_if_fail (applet != NULL);
2009
if (!applet->nm_running)
2010
nma_menu_add_text_item (menu, _("NetworkManager is not running..."));
2012
nma_menu_add_devices (menu, applet);
2017
* nma_dropdown_menu_show_cb
2019
* Pop up the wireless networks menu
2022
static void nma_dropdown_menu_show_cb (GtkWidget *menu, NMApplet *applet)
2024
g_return_if_fail (menu != NULL);
2025
g_return_if_fail (applet != NULL);
2027
if (!applet->tooltips)
2028
applet->tooltips = gtk_tooltips_new ();
2029
gtk_tooltips_set_tip (applet->tooltips, applet->event_box, NULL, NULL);
2031
if (applet->dropdown_menu && (menu == applet->dropdown_menu))
2033
nma_dropdown_menu_clear (applet->dropdown_menu);
2034
nma_dropdown_menu_populate (applet->dropdown_menu, applet);
2035
gtk_widget_show_all (applet->dropdown_menu);
2038
nmi_dbus_signal_user_interface_activated (applet->connection);
2042
* nma_dropdown_menu_create
2044
* Create the applet's dropdown menu
2047
static GtkWidget *nma_dropdown_menu_create (GtkMenuItem *parent, NMApplet *applet)
2051
g_return_val_if_fail (parent != NULL, NULL);
2052
g_return_val_if_fail (applet != NULL, NULL);
2054
menu = gtk_menu_new ();
2055
gtk_container_set_border_width (GTK_CONTAINER (menu), 0);
2056
gtk_menu_item_set_submenu (GTK_MENU_ITEM (parent), menu);
2057
g_signal_connect (menu, "show", G_CALLBACK (nma_dropdown_menu_show_cb), applet);
2064
* nma_context_menu_update
2067
static void nma_context_menu_update (NMApplet *applet)
2070
gboolean have_wireless = FALSE;
2072
const char *iface = NULL;
2074
g_return_if_fail (applet != NULL);
2075
g_return_if_fail (applet->stop_wireless_item != NULL);
2076
g_return_if_fail (applet->info_menu_item != NULL);
2078
if ((dev = nma_get_first_active_device (applet->device_list)))
2079
iface = network_device_get_iface (dev);
2082
gtk_widget_set_sensitive (applet->info_menu_item, FALSE);
2084
gtk_widget_set_sensitive (applet->info_menu_item, TRUE);
2086
for (element = applet->device_list; element; element = element->next)
2088
dev = (NetworkDevice *)(element->data);
2092
if (network_device_get_type (dev) == DEVICE_TYPE_802_11_WIRELESS)
2094
have_wireless = TRUE;
2099
if (have_wireless && applet->nm_state != NM_STATE_ASLEEP)
2100
gtk_widget_show_all (applet->stop_wireless_item);
2102
gtk_widget_hide (applet->stop_wireless_item);
2107
* nma_enable_wireless_set_active
2109
* Set the 'Enable Wireless' menu item state to match the daemon's last DBUS
2110
* message. We cannot just do this at menu creation time because the DBUS
2111
* message might not have been sent yet or in case the daemon state changes
2112
* out from under us.
2114
void nma_enable_wireless_set_active (NMApplet *applet)
2116
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (applet->stop_wireless_item), applet->wireless_enabled);
2121
* nma_enable_networking_set_active
2123
* Set the 'Enable Networking' menu item state to match the daemon's last DBUS
2124
* message. We cannot just do this at menu creation time because the DBUS
2125
* message might not have been sent yet or in case the daemon state changes
2126
* out from under us.
2128
static inline void nma_enable_networking_set_active (NMApplet *applet)
2130
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (applet->enable_networking_item), applet->nm_state != NM_STATE_ASLEEP);
2137
* Set the applet's state to one of the NMState enumerations.
2140
void nma_set_state (NMApplet *applet, enum NMState state)
2142
g_return_if_fail (applet != NULL);
2143
g_return_if_fail (state <= NM_STATE_DISCONNECTED);
2144
applet->nm_state = state;
2145
nma_enable_networking_set_active (applet);
2150
* nma_context_menu_create
2152
* Generate the contextual popup menu.
2155
static GtkWidget *nma_context_menu_create (NMApplet *applet)
2158
GtkWidget *menu_item;
2161
g_return_val_if_fail (applet != NULL, NULL);
2163
menu = gtk_menu_new ();
2165
/* 'Enable Networking' item */
2166
applet->enable_networking_item = gtk_check_menu_item_new_with_mnemonic (_("Enable _Networking"));
2167
nma_enable_networking_set_active (applet);
2168
g_signal_connect (G_OBJECT (applet->enable_networking_item), "toggled", G_CALLBACK (nma_set_networking_enabled_cb), applet);
2169
gtk_menu_shell_append (GTK_MENU_SHELL (menu), applet->enable_networking_item);
2171
/* 'Enable Wireless' item */
2172
applet->stop_wireless_item = gtk_check_menu_item_new_with_mnemonic (_("Enable _Wireless"));
2173
nma_enable_wireless_set_active (applet);
2174
g_signal_connect (G_OBJECT (applet->stop_wireless_item), "toggled", G_CALLBACK (nma_set_wireless_enabled_cb), applet);
2175
gtk_menu_shell_append (GTK_MENU_SHELL (menu), applet->stop_wireless_item);
2177
/* 'Connection Information' item */
2178
applet->info_menu_item = gtk_image_menu_item_new_with_mnemonic (_("Connection _Information"));
2179
g_signal_connect (G_OBJECT (applet->info_menu_item), "activate", G_CALLBACK (nma_show_info_cb), applet);
2180
image = gtk_image_new_from_stock (GTK_STOCK_INFO, GTK_ICON_SIZE_MENU);
2181
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (applet->info_menu_item), image);
2182
gtk_menu_shell_append (GTK_MENU_SHELL (menu), applet->info_menu_item);
2185
nma_menu_add_separator_item (menu);
2187
#if 0 /* FIXME: Implement the help callback, nma_help_cb()! */
2189
menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Help"));
2190
g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (nma_help_cb), applet);
2191
image = gtk_image_new_from_stock (GTK_STOCK_HELP, GTK_ICON_SIZE_MENU);
2192
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
2193
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
2194
gtk_widget_set_sensitive (GTK_WIDGET (menu_item), FALSE);
2198
menu_item = gtk_image_menu_item_new_with_mnemonic (_("_About"));
2199
g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (nma_about_cb), applet);
2200
image = gtk_image_new_from_stock (GTK_STOCK_ABOUT, GTK_ICON_SIZE_MENU);
2201
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
2202
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
2204
gtk_widget_show_all (menu);
2211
* nma_theme_change_cb
2213
* Destroy the popdown menu when the theme changes
2216
static void nma_theme_change_cb (NMApplet *applet)
2218
g_return_if_fail (applet != NULL);
2220
if (applet->dropdown_menu)
2221
nma_dropdown_menu_clear (applet->dropdown_menu);
2223
if (applet->top_menu_item)
2225
gtk_menu_item_remove_submenu (GTK_MENU_ITEM (applet->top_menu_item));
2226
applet->dropdown_menu = nma_dropdown_menu_create (GTK_MENU_ITEM (applet->top_menu_item), applet);
2227
g_signal_connect (applet->dropdown_menu, "deactivate", G_CALLBACK (nma_dropdown_menu_deactivate_cb), applet);
2232
* nma_menu_position_func
2234
* Position main dropdown menu, adapted from netapplet
2237
static void nma_menu_position_func (GtkMenu *menu G_GNUC_UNUSED, int *x, int *y, gboolean *push_in, gpointer user_data)
2239
int screen_w, screen_h, button_x, button_y, panel_w, panel_h;
2240
GtkRequisition requisition;
2242
NMApplet *applet = (NMApplet *)user_data;
2244
screen = gtk_widget_get_screen (applet->event_box);
2245
screen_w = gdk_screen_get_width (screen);
2246
screen_h = gdk_screen_get_height (screen);
2248
gdk_window_get_origin (applet->event_box->window, &button_x, &button_y);
2249
gtk_window_get_size (GTK_WINDOW (gtk_widget_get_toplevel (applet->event_box)), &panel_w, &panel_h);
2253
/* Check to see if we would be placing the menu off of the end of the screen. */
2254
gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
2255
if (button_y + panel_h + requisition.height >= screen_h)
2256
*y = button_y - requisition.height;
2258
*y = button_y + panel_h;
2264
* nma_toplevel_menu_button_press_cb
2266
* Handle left/right-clicks for the dropdown and context popup menus
2269
static gboolean nma_toplevel_menu_button_press_cb (GtkWidget *widget, GdkEventButton *event, NMApplet *applet)
2271
g_return_val_if_fail (applet != NULL, FALSE);
2273
switch (event->button)
2276
gtk_widget_set_state (applet->event_box, GTK_STATE_SELECTED);
2277
gtk_menu_popup (GTK_MENU (applet->dropdown_menu), NULL, NULL, nma_menu_position_func, applet, event->button, event->time);
2280
nma_context_menu_update (applet);
2281
gtk_menu_popup (GTK_MENU (applet->context_menu), NULL, NULL, nma_menu_position_func, applet, event->button, event->time);
2284
g_signal_stop_emission_by_name (widget, "button_press_event");
2293
* nma_toplevel_menu_button_press_cb
2295
* Handle left-unclick on the dropdown menu.
2298
static void nma_dropdown_menu_deactivate_cb (GtkWidget *menu, NMApplet *applet)
2301
g_return_if_fail (applet != NULL);
2303
gtk_widget_set_state (applet->event_box, GTK_STATE_NORMAL);
2310
* Intialize the applet's widgets and packing, create the initial
2314
static void nma_setup_widgets (NMApplet *applet)
2316
/* Event box is the main applet widget */
2317
applet->event_box = gtk_event_box_new ();
2318
gtk_container_set_border_width (GTK_CONTAINER (applet->event_box), 0);
2320
applet->top_menu_item = gtk_menu_item_new();
2321
gtk_widget_set_name (applet->top_menu_item, "ToplevelMenu");
2322
gtk_container_set_border_width (GTK_CONTAINER (applet->top_menu_item), 0);
2324
applet->pixmap = gtk_image_new ();
2325
gtk_container_add (GTK_CONTAINER (applet->event_box), applet->pixmap);
2326
gtk_container_add (GTK_CONTAINER (applet), applet->event_box);
2327
gtk_widget_show_all (GTK_WIDGET (applet));
2329
applet->dropdown_menu = nma_dropdown_menu_create (GTK_MENU_ITEM (applet->top_menu_item), applet);
2330
g_signal_connect (applet->event_box, "button_press_event", G_CALLBACK (nma_toplevel_menu_button_press_cb), applet);
2331
g_signal_connect (applet->dropdown_menu, "deactivate", G_CALLBACK (nma_dropdown_menu_deactivate_cb), applet);
2333
applet->context_menu = nma_context_menu_create (applet);
2334
applet->encryption_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
2339
* nma_gconf_info_notify_callback
2341
* Callback from gconf when wireless key/values have changed.
2344
static void nma_gconf_info_notify_callback (GConfClient *client, guint connection_id, GConfEntry *entry, gpointer user_data)
2346
NMApplet * applet = (NMApplet *)user_data;
2347
const char * key = NULL;
2349
g_return_if_fail (client != NULL);
2350
g_return_if_fail (entry != NULL);
2351
g_return_if_fail (applet != NULL);
2353
if ((key = gconf_entry_get_key (entry)))
2355
int net_path_len = strlen (GCONF_PATH_WIRELESS_NETWORKS) + 1;
2357
if (strncmp (GCONF_PATH_WIRELESS_NETWORKS"/", key, net_path_len) == 0)
2359
char *network = g_strdup ((key + net_path_len));
2361
char *unescaped_network;
2363
/* If its a key under the network name, zero out the slash so we
2364
* are left with only the network name.
2366
unescaped_network = gconf_unescape_key (network, strlen (network));
2367
if ((slash_pos = strchr (unescaped_network, '/')))
2370
nmi_dbus_signal_update_network (applet->connection, unescaped_network, NETWORK_TYPE_ALLOWED);
2371
g_free (unescaped_network);
2379
* nma_gconf_vpn_connections_notify_callback
2381
* Callback from gconf when VPN connection values have changed.
2384
static void nma_gconf_vpn_connections_notify_callback (GConfClient *client, guint connection_id, GConfEntry *entry, gpointer user_data)
2386
NMApplet * applet = (NMApplet *)user_data;
2387
const char * key = NULL;
2389
/*g_debug ("Entering nma_gconf_vpn_connections_notify_callback, key='%s'", gconf_entry_get_key (entry));*/
2391
g_return_if_fail (client != NULL);
2392
g_return_if_fail (entry != NULL);
2393
g_return_if_fail (applet != NULL);
2395
if ((key = gconf_entry_get_key (entry)))
2397
int path_len = strlen (GCONF_PATH_VPN_CONNECTIONS) + 1;
2399
if (strncmp (GCONF_PATH_VPN_CONNECTIONS"/", key, path_len) == 0)
2401
char *name = g_strdup ((key + path_len));
2403
char *unescaped_name;
2407
/* If its a key under the the VPN name, zero out the slash so we
2408
* are left with only the VPN name.
2410
if ((slash_pos = strchr (name, '/')))
2412
unescaped_name = gconf_unescape_key (name, strlen (name));
2414
/* Check here if the name entry is gone so we can remove the conn from the UI */
2415
name_path = g_strdup_printf ("%s/%s/name", GCONF_PATH_VPN_CONNECTIONS, name);
2416
gconf_client_clear_cache (client);
2417
value = gconf_client_get (client, name_path, NULL);
2418
if (value == NULL) {
2419
/*g_debug ("removing '%s' from UI", name_path);*/
2420
nma_dbus_vpn_remove_one_vpn_connection (applet, unescaped_name);
2422
gconf_value_free (value);
2426
nmi_dbus_signal_update_vpn_connection (applet->connection, unescaped_name);
2428
g_free (unescaped_name);
2439
* Destroy the applet and clean up its data
2442
static void G_GNUC_NORETURN nma_destroy (NMApplet *applet)
2444
if (applet->dropdown_menu)
2445
nma_dropdown_menu_clear (applet->dropdown_menu);
2446
if (applet->top_menu_item)
2447
gtk_menu_item_remove_submenu (GTK_MENU_ITEM (applet->top_menu_item));
2449
nma_icons_free (applet);
2451
nmi_passphrase_dialog_destroy (applet);
2452
#ifdef ENABLE_NOTIFY
2453
if (applet->notification)
2455
notify_notification_close (applet->notification, NULL);
2456
g_object_unref (applet->notification);
2460
if (applet->redraw_timeout_id > 0)
2462
gtk_timeout_remove (applet->redraw_timeout_id);
2463
applet->redraw_timeout_id = 0;
2466
if (applet->gconf_client)
2467
g_object_unref (G_OBJECT (applet->gconf_client));
2469
nma_free_data_model (applet);
2471
g_free (applet->glade_file);
2473
gconf_client_notify_remove (applet->gconf_client, applet->gconf_prefs_notify_id);
2474
gconf_client_notify_remove (applet->gconf_client, applet->gconf_vpn_notify_id);
2475
g_object_unref (G_OBJECT (applet->gconf_client));
2477
dbus_method_dispatcher_unref (applet->nmi_methods);
2479
exit (EXIT_SUCCESS);
2486
* Create the initial instance of our wireless applet
2489
static GtkWidget * nma_get_instance (NMApplet *applet)
2491
gtk_widget_hide (GTK_WIDGET (applet));
2493
applet->nm_running = FALSE;
2494
applet->device_list = NULL;
2495
applet->vpn_connections = NULL;
2496
applet->dialup_list = NULL;
2497
applet->nm_state = NM_STATE_DISCONNECTED;
2498
applet->tooltips = NULL;
2499
applet->passphrase_dialog = NULL;
2500
#ifdef ENABLE_NOTIFY
2501
applet->notification = NULL;
2504
applet->glade_file = g_build_filename (GLADEDIR, "applet.glade", NULL);
2505
if (!applet->glade_file || !g_file_test (applet->glade_file, G_FILE_TEST_IS_REGULAR))
2507
nma_schedule_warning_dialog (applet, _("The NetworkManager Applet could not find some required resources (the glade file was not found)."));
2508
g_free (applet->glade_file);
2509
applet->glade_file = NULL;
2513
applet->info_dialog_xml = glade_xml_new (applet->glade_file, "info_dialog", NULL);
2515
applet->gconf_client = gconf_client_get_default ();
2516
if (!applet->gconf_client)
2519
gconf_client_add_dir (applet->gconf_client, GCONF_PATH_WIRELESS, GCONF_CLIENT_PRELOAD_NONE, NULL);
2520
applet->gconf_prefs_notify_id = gconf_client_notify_add (applet->gconf_client, GCONF_PATH_WIRELESS,
2521
nma_gconf_info_notify_callback, applet, NULL, NULL);
2523
gconf_client_add_dir (applet->gconf_client, GCONF_PATH_VPN_CONNECTIONS, GCONF_CLIENT_PRELOAD_NONE, NULL);
2524
applet->gconf_vpn_notify_id = gconf_client_notify_add (applet->gconf_client, GCONF_PATH_VPN_CONNECTIONS,
2525
nma_gconf_vpn_connections_notify_callback, applet, NULL, NULL);
2527
/* Convert old-format stored network entries to the new format.
2528
* Must be RUN BEFORE DBUS INITIALIZATION since we have to do
2529
* synchronous calls against gnome-keyring.
2531
nma_compat_convert_oldformat_entries (applet->gconf_client);
2533
nma_dbus_init_helper (applet);
2535
/* Load pixmaps and create applet widgets */
2536
nma_setup_widgets (applet);
2538
g_signal_connect (applet, "destroy", G_CALLBACK (nma_destroy), NULL);
2539
g_signal_connect (applet, "style-set", G_CALLBACK (nma_theme_change_cb), NULL);
2541
/* Start redraw timeout */
2542
applet->redraw_timeout_id = g_timeout_add (1000, (GtkFunction) nma_redraw_timeout, applet);
2544
return GTK_WIDGET (applet);
2548
static void nma_icons_free (NMApplet *applet)
2552
g_object_unref (applet->no_connection_icon);
2553
g_object_unref (applet->wired_icon);
2554
g_object_unref (applet->adhoc_icon);
2555
g_object_unref (applet->vpn_lock_icon);
2557
g_object_unref (applet->wireless_00_icon);
2558
g_object_unref (applet->wireless_25_icon);
2559
g_object_unref (applet->wireless_50_icon);
2560
g_object_unref (applet->wireless_75_icon);
2561
g_object_unref (applet->wireless_100_icon);
2563
for (i = 0; i < NUM_CONNECTING_STAGES; i++)
2567
for (j = 0; j < NUM_CONNECTING_FRAMES; j++)
2568
g_object_unref (applet->network_connecting_icons[i][j]);
2571
for (i = 0; i < NUM_VPN_CONNECTING_FRAMES; i++)
2572
g_object_unref (applet->vpn_connecting_icons[i]);
2575
static void nma_icons_zero (NMApplet *applet)
2579
applet->no_connection_icon = NULL;
2580
applet->wired_icon = NULL;
2581
applet->adhoc_icon = NULL;
2582
applet->vpn_lock_icon = NULL;
2584
applet->wireless_00_icon = NULL;
2585
applet->wireless_25_icon = NULL;
2586
applet->wireless_50_icon = NULL;
2587
applet->wireless_75_icon = NULL;
2588
applet->wireless_100_icon = NULL;
2590
for (i = 0; i < NUM_CONNECTING_STAGES; i++)
2594
for (j = 0; j < NUM_CONNECTING_FRAMES; j++)
2595
applet->network_connecting_icons[i][j] = NULL;
2598
for (i = 0; i < NUM_VPN_CONNECTING_FRAMES; i++)
2599
applet->vpn_connecting_icons[i] = NULL;
2603
#define ICON_LOAD(x, y) \
2605
GError *err = NULL; \
2606
x = gtk_icon_theme_load_icon (icon_theme, y, 22, 0, &err); \
2609
g_warning ("Icon %s missing: %s", y, err->message); \
2610
g_error_free (err); \
2616
nma_icons_load_from_disk (NMApplet *applet, GtkIconTheme *icon_theme)
2622
* NULL out the icons, so if we error and call nma_icons_free(), we don't hit stale
2623
* data on the not-yet-reached icons. This can happen off nma_icon_theme_changed().
2625
nma_icons_zero (applet);
2627
ICON_LOAD(applet->no_connection_icon, "nm-no-connection");
2628
ICON_LOAD(applet->wired_icon, "nm-device-wired");
2629
ICON_LOAD(applet->adhoc_icon, "nm-adhoc");
2630
ICON_LOAD(applet->vpn_lock_icon, "nm-vpn-lock");
2632
ICON_LOAD(applet->wireless_00_icon, "nm-signal-00");
2633
ICON_LOAD(applet->wireless_25_icon, "nm-signal-25");
2634
ICON_LOAD(applet->wireless_50_icon, "nm-signal-50");
2635
ICON_LOAD(applet->wireless_75_icon, "nm-signal-75");
2636
ICON_LOAD(applet->wireless_100_icon, "nm-signal-100");
2638
for (i = 0; i < NUM_CONNECTING_STAGES; i++)
2642
for (j = 0; j < NUM_CONNECTING_FRAMES; j++)
2646
name = g_strdup_printf ("nm-stage%02d-connecting%02d", i+1, j+1);
2647
ICON_LOAD(applet->network_connecting_icons[i][j], name);
2652
for (i = 0; i < NUM_VPN_CONNECTING_FRAMES; i++)
2656
name = g_strdup_printf ("nm-vpn-connecting%02d", i+1);
2657
ICON_LOAD(applet->vpn_connecting_icons[i], name);
2666
char *msg = g_strdup(_("The NetworkManager applet could not find some required resources. It cannot continue.\n"));
2667
show_warning_dialog (msg);
2668
nma_icons_free (applet);
2674
static void nma_icon_theme_changed (GtkIconTheme *icon_theme, NMApplet *applet)
2676
nma_icons_free (applet);
2677
nma_icons_load_from_disk (applet, icon_theme);
2678
/* FIXME: force redraw */
2681
static gboolean nma_icons_init (NMApplet *applet)
2683
GtkIconTheme *icon_theme;
2684
const gchar *style = " \
2687
GtkMenuBar::shadow_type = GTK_SHADOW_NONE \
2688
GtkMenuBar::internal-padding = 0 \
2690
style \"MenuItem\" \
2695
class \"GtkMenuBar\" style \"MenuBar\"\
2696
widget \"*ToplevelMenu*\" style \"MenuItem\"\
2699
/* FIXME: Do we need to worry about other screens? */
2700
gtk_rc_parse_string (style);
2702
icon_theme = gtk_icon_theme_get_default ();
2703
if (!nma_icons_load_from_disk (applet, icon_theme))
2705
g_signal_connect (icon_theme, "changed", G_CALLBACK (nma_icon_theme_changed), applet);
2710
NMApplet *nma_new ()
2712
return g_object_new (NM_TYPE_APPLET, "title", "NetworkManager", NULL);