[patch] gui should reflect the actual state of vpn



Currently, if the user selects a VPN connection, the GUI immediately reflects there is a VPN connection active. If the connection then fails, the composited lock icon goes away. This is bad since it is confusing to users (it confused me the other day), and doesn't really reflect the true state of VPN, which also has a (very tiny) risk of DNS spoofing on a rogue AP.

The attached patch sends dbus signals from NM to nm-applet letting it know when the state changes, and removes the pull code from the applet, which is overall much cleaner IMO.

May I commit?

Index: gnome/applet/applet-dbus-vpn.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet-dbus-vpn.c,v
retrieving revision 1.5
diff -d -u -p -8 -r1.5 applet-dbus-vpn.c
--- gnome/applet/applet-dbus-vpn.c	21 Jun 2005 15:07:00 -0000	1.5
+++ gnome/applet/applet-dbus-vpn.c	25 Aug 2005 19:30:57 -0000
@@ -34,96 +34,59 @@
 #include "vpn-connection.h"
 #include "nm-utils.h"
 
 static void nmwa_free_gui_vpn_connections (NMWirelessApplet *applet);
 static void nmwa_free_dbus_vpn_connections (NMWirelessApplet *applet);
 static void nmwa_dbus_vpn_schedule_copy (NMWirelessApplet *applet);
 
 /*
- * nmwa_dbus_vpn_get_active_vpn_connection_cb
+ * nmwa_dbus_vpn_get_active_vpn_connection
  *
- * Callback from nmwa_dbus_vpn_get_active_vpn_connection
+ * Get the active VPN connection from the dbus side of the applet
  *
  */
-static void nmwa_dbus_vpn_get_active_vpn_connection_cb (DBusPendingCall *pcall, void *user_data)
+VPNConnection *nmwa_dbus_vpn_get_active_vpn_connection (NMWirelessApplet *applet)
 {
-	DBusMessage *		reply;
-	NMWirelessApplet *	applet = (NMWirelessApplet *) user_data;
-	const char *		act_vpn;
-
-	g_return_if_fail (pcall != NULL);
-	g_return_if_fail (applet != NULL);
-
-	dbus_pending_call_ref (pcall);
-
-	if (!dbus_pending_call_get_completed (pcall))
-		goto out;
-
-	if (!(reply = dbus_pending_call_steal_reply (pcall)))
-		goto out;
-
-	if (    dbus_message_is_error (reply, NM_DBUS_NO_ACTIVE_VPN_CONNECTION)
-		|| dbus_message_is_error (reply, NM_DBUS_NO_VPN_CONNECTIONS))
-	{
-		/* Remove the active VPN connection if one exists */
-		if (applet->dbus_active_vpn_name)
-		{
-			g_free (applet->dbus_active_vpn_name);
-			applet->dbus_active_vpn_name = NULL;
-		}
+	VPNConnection	*vpn;
+	NMVPNState	vpn_state;
+	GSList		*elt;
 
-		dbus_message_unref (reply);
-		goto out;
-	}
+	elt = applet->dbus_vpn_connections;
 
-	if (dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &act_vpn, DBUS_TYPE_INVALID))
+	for (; elt; elt = g_slist_next (elt))
 	{
-		g_free (applet->dbus_active_vpn_name);
-		if (strlen (act_vpn))
-			applet->dbus_active_vpn_name = g_strdup (act_vpn);
-		else
-			applet->dbus_active_vpn_name = NULL;
+		vpn = (VPNConnection*) elt->data;
+		vpn_state = nmwa_vpn_connection_get_state (vpn);
+		if (vpn_state == NM_VPN_STATE_STARTED)
+			return vpn;
 	}
-	dbus_message_unref (reply);
-
-out:
-	applet->vpn_pending_call_list = g_slist_remove (applet->vpn_pending_call_list, pcall);
-	nmwa_dbus_vpn_schedule_copy (applet);
 
-	dbus_pending_call_unref (pcall);
+	return NULL;
 }
 
-
 /*
- * nmwa_dbus_vpn_get_active_vpn_connection
- *
- * Get the active VPN connection from NetworkManager
+ * nmwa_dbus_vpn_update_vpn_connection_state
  *
+ * Sets the state for a dbus vpn connection and schedules a copy to the applet gui.
  */
-void nmwa_dbus_vpn_get_active_vpn_connection (NMWirelessApplet *applet)
+void nmwa_dbus_vpn_update_vpn_connection_state (NMWirelessApplet *applet, const char *vpn_name, NMVPNState vpn_state)
 {
-	DBusMessage *		message;
-	DBusPendingCall *	pcall = NULL;
+	VPNConnection	*vpn;
 
 	g_return_if_fail (applet != NULL);
 
-	if ((message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "getActiveVPNConnection")))
+	vpn = nmwa_vpn_connection_find_by_name (applet->dbus_vpn_connections, vpn_name);
+	if (vpn != NULL)
 	{
-		dbus_connection_send_with_reply (applet->connection, message, &pcall, -1);
-		dbus_message_unref (message);
-		if (pcall)
-		{
-			dbus_pending_call_set_notify (pcall, nmwa_dbus_vpn_get_active_vpn_connection_cb, applet, NULL);
-			applet->vpn_pending_call_list = g_slist_append (applet->vpn_pending_call_list, pcall);
-		}
+		nmwa_vpn_connection_set_state (vpn, vpn_state);
+		nmwa_dbus_vpn_schedule_copy (applet);
 	}
 }
 
-
 typedef struct VpnPropsCBData
 {
 	NMWirelessApplet *	applet;	
 	char *			name;
 } VpnPropsCBData;
 
 static void free_vpn_props_cb_data (VpnPropsCBData *data)
 {
@@ -144,16 +107,17 @@ static void free_vpn_props_cb_data (VpnP
 static void nmwa_dbus_vpn_properties_cb (DBusPendingCall *pcall, void *user_data)
 {
 	DBusMessage *		reply;
 	VpnPropsCBData *	cb_data = user_data;
 	NMWirelessApplet *	applet;
 	const char *		name;
 	const char *        user_name;
 	const char *        service;
+	NMVPNState		state;
 
 	g_return_if_fail (pcall != NULL);
 	g_return_if_fail (cb_data != NULL);
 	g_return_if_fail (cb_data->applet != NULL);
 	g_return_if_fail (cb_data->name != NULL);
 
 	dbus_pending_call_ref (pcall);
 
@@ -164,42 +128,38 @@ static void nmwa_dbus_vpn_properties_cb 
 
 	if (!(reply = dbus_pending_call_steal_reply (pcall)))
 		goto out;
 
 	if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
 	{
 		if (dbus_message_is_error (reply, NM_DBUS_INVALID_VPN_CONNECTION))
 		{
-			VPNConnection * vpn;
-
-			if (applet->dbus_active_vpn_name && cb_data->name && !strcmp (applet->dbus_active_vpn_name, cb_data->name))
-			{
-				g_free (applet->dbus_active_vpn_name);
-				applet->dbus_active_vpn_name = NULL;
-			}
+			/* Error */
 		}
 
 		dbus_message_unref (reply);
 		goto out;
 	}
 
-	if (dbus_message_get_args (reply, NULL,	DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user_name, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID))
+	if (dbus_message_get_args (reply, NULL,	DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user_name, DBUS_TYPE_STRING, &service, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
 	{
 		VPNConnection *	vpn;
 
 		/* If its already there, update the service, otherwise add it to the list */
 		if ((vpn = nmwa_vpn_connection_find_by_name (applet->dbus_vpn_connections, name)))
 		{
 			nmwa_vpn_connection_set_service (vpn, service);
+			nmwa_vpn_connection_set_state (vpn, state);
 		}
 		else
 		{
 			vpn = nmwa_vpn_connection_new (name);
 			nmwa_vpn_connection_set_service (vpn, service);
+			nmwa_vpn_connection_set_state (vpn, state);
 			applet->dbus_vpn_connections = g_slist_append (applet->dbus_vpn_connections, vpn);
 		}
 	}
 	dbus_message_unref (reply);
 
 out:
 	applet->vpn_pending_call_list = g_slist_remove (applet->vpn_pending_call_list, pcall);
 	nmwa_dbus_vpn_schedule_copy (applet);
@@ -331,22 +291,16 @@ void nmwa_dbus_vpn_remove_one_vpn_connec
 	VPNConnection *	vpn;
 
 	g_return_if_fail (applet != NULL);
 	g_return_if_fail (vpn_name != NULL);
 
 	if ((vpn = nmwa_vpn_connection_find_by_name (applet->dbus_vpn_connections, vpn_name)))
 	{
 		applet->dbus_vpn_connections = g_slist_remove (applet->dbus_vpn_connections, vpn);
-		if (applet->dbus_active_vpn_name != NULL &&
-		    !strcmp (applet->dbus_active_vpn_name, nmwa_vpn_connection_get_name (vpn)))
-		{
-			g_free (applet->dbus_active_vpn_name);
-			applet->dbus_active_vpn_name = NULL;
-		}
 		nmwa_vpn_connection_unref (vpn);
 		nmwa_dbus_vpn_schedule_copy (applet);
 	}
 }
 
 
 static int vpn_copy_idle_id = 0;
 
@@ -360,44 +314,32 @@ static gboolean nmwa_dbus_vpn_connection
 {
 	vpn_copy_idle_id = 0;
 
 	g_return_val_if_fail (applet != NULL, FALSE);
 
 	/* Only copy over if we have a complete data model */
 	if (g_slist_length (applet->vpn_pending_call_list) == 0)
 	{
-		VPNConnection *	act_vpn = NULL;
 		GSList *			elt;
 
-		/* Match up the active vpn with a device in the list */
-		if (applet->dbus_active_vpn_name)
-			act_vpn = nmwa_vpn_connection_find_by_name (applet->dbus_vpn_connections, applet->dbus_active_vpn_name);
-
 		/* Now copy the data over to the GUI side */
 		g_mutex_lock (applet->data_mutex);
 
 		nmwa_free_gui_vpn_connections (applet);
 
 		/* Deep-copy VPN connections to GUI data model */
 		for (elt = applet->dbus_vpn_connections; elt; elt = g_slist_next (elt))
 		{
 			VPNConnection	*src_vpn = elt->data;
 			VPNConnection	*new_vpn;
 
 			new_vpn = nmwa_vpn_connection_copy (src_vpn);
 			if (new_vpn)
-			{
 				applet->gui_vpn_connections = g_slist_append (applet->gui_vpn_connections, new_vpn);
-				if (src_vpn == act_vpn)
-				{
-					nmwa_vpn_connection_ref (new_vpn);
-					applet->gui_active_vpn = new_vpn;
-				}
-			}
 		}
 
 		g_mutex_unlock (applet->data_mutex);
 	}
 
 	return FALSE;
 }
 
@@ -423,37 +365,28 @@ static void nmwa_dbus_vpn_schedule_copy 
 	}
 }
 
 
 static void nmwa_free_gui_vpn_connections (NMWirelessApplet *applet)
 {
 	g_return_if_fail (applet != NULL);
 
-	if (applet->gui_active_vpn)
-		nmwa_vpn_connection_unref (applet->gui_active_vpn);
-	applet->gui_active_vpn = NULL;
-
 	if (applet->gui_vpn_connections)
 	{
 		g_slist_foreach (applet->gui_vpn_connections, (GFunc) nmwa_vpn_connection_unref, NULL);
 		g_slist_free (applet->gui_vpn_connections);
 		applet->gui_vpn_connections = NULL;
 	}
 }
 
 
 static void nmwa_free_dbus_vpn_connections (NMWirelessApplet *applet)
 {
-	GSList	*elt;
-
 	g_return_if_fail (applet != NULL);
-
-	g_free (applet->dbus_active_vpn_name);
-	applet->dbus_active_vpn_name = NULL;
 
 	if (applet->dbus_vpn_connections)
 	{
 		g_slist_foreach (applet->dbus_vpn_connections, (GFunc) nmwa_vpn_connection_unref, NULL);
 		g_slist_free (applet->dbus_vpn_connections);
 		applet->dbus_vpn_connections = NULL;
 	}
 }
Index: gnome/applet/applet-dbus-vpn.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet-dbus-vpn.h,v
retrieving revision 1.2
diff -d -u -p -8 -r1.2 applet-dbus-vpn.h
--- gnome/applet/applet-dbus-vpn.h	12 Jun 2005 14:35:58 -0000	1.2
+++ gnome/applet/applet-dbus-vpn.h	25 Aug 2005 19:30:57 -0000
@@ -25,15 +25,14 @@
 
 #include <glib.h>
 #include <dbus/dbus.h>
 #include "vpn-connection.h"
 
 void		nmwa_dbus_vpn_update_one_vpn_connection			(NMWirelessApplet *applet, const char *vpn_name);
 void		nmwa_dbus_vpn_update_vpn_connections			(NMWirelessApplet *applet);
 void		nmwa_dbus_vpn_remove_one_vpn_connection			(NMWirelessApplet *applet, const char *vpn_name);
-void		nmwa_dbus_vpn_get_active_vpn_connection			(NMWirelessApplet *applet);
 
 void		nmwa_dbus_vpn_activate_connection				(DBusConnection *connection, const char *name, GSList *passwords);
 void		nmwa_dbus_vpn_deactivate_connection			(DBusConnection *connection);
-
+void 		nmwa_dbus_vpn_update_vpn_connection_state		(NMWirelessApplet *applet, const char *vpn_name, NMVPNState vpn_state);
 
 #endif
Index: gnome/applet/applet-dbus.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet-dbus.c,v
retrieving revision 1.9
diff -d -u -p -8 -r1.9 applet-dbus.c
--- gnome/applet/applet-dbus.c	12 Aug 2005 19:11:30 -0000	1.9
+++ gnome/applet/applet-dbus.c	25 Aug 2005 19:30:57 -0000
@@ -515,19 +515,22 @@ static DBusHandlerResult nmwa_dbus_filte
 	else if (    dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionAdded")
 			|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionUpdate"))	/* VPN connection properties changed */
 	{
 		char *name = NULL;
 
 		if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
 			nmwa_dbus_vpn_update_one_vpn_connection (applet, name);
 	}
-	else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionChange"))	/* Active VPN connection changed */
+	else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionStateChange"))	/* Active VPN connection changed */
 	{
-		nmwa_dbus_vpn_get_active_vpn_connection (applet);
+		char *name = NULL;
+		NMVPNState vpn_state;
+		if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &vpn_state, DBUS_TYPE_INVALID))
+			nmwa_dbus_vpn_update_vpn_connection_state (applet, name, vpn_state);
 	}
 	else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionRemoved"))
 	{
 		char *name = NULL;
 
 		if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
 			nmwa_dbus_vpn_remove_one_vpn_connection (applet, name);
 	}
Index: gnome/applet/applet.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet.c,v
retrieving revision 1.38
diff -d -u -p -8 -r1.38 applet.c
--- gnome/applet/applet.c	19 Aug 2005 15:22:46 -0000	1.38
+++ gnome/applet/applet.c	25 Aug 2005 19:30:57 -0000
@@ -592,18 +592,18 @@ void nmwa_schedule_vpn_login_banner_dial
 	char *msg;
 	char *msg2;
 
 	g_return_if_fail (applet != NULL);
 	g_return_if_fail (vpn_name != NULL);
 	g_return_if_fail (banner != NULL);
 
 	msg2 = g_strdup_printf (_("VPN connection '%s' said:"), vpn_name);
-	msg = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">%s</span>\n\n"
-						"%s\n\n\"%s\""), _("VPN Login Message"), msg2, banner);
+	msg = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s\n\n\"%s\"",
+					_("VPN Login Message"), msg2, banner);
 	g_free (msg2);
 
 	g_idle_add ((GSourceFunc) nmwa_show_vpn_login_banner_dialog, msg);
 }
 
 
 /*
  * nmwa_driver_notify_get_ignored_list
@@ -860,26 +860,49 @@ gboolean nmwa_driver_notify (gpointer us
 	gdk_x11_window_set_user_time (dialog->window, timestamp);
 
 out:
 	network_device_unref (cb_data->dev);
 	return (FALSE);
 }
 
 
+VPNConnection* nmwa_get_active_vpn_connection (NMWirelessApplet *applet)
+{
+	VPNConnection	*vpn;
+	NMVPNState	vpn_state;
+	GSList		*elt;
+
+	elt = applet->gui_vpn_connections;
+
+	for (; elt; elt = g_slist_next (elt))
+	{
+		vpn = (VPNConnection*) elt->data;
+		vpn_state = nmwa_vpn_connection_get_state (vpn);
+		if (vpn_state == NM_VPN_STATE_STARTED)
+			return vpn;
+	}
+
+	return NULL;
+}
+
+
 static void nmwa_set_icon (NMWirelessApplet *applet, GdkPixbuf *new_icon)
 {
 	GdkPixbuf	*composite;
+	VPNConnection	*vpn;
 
 	g_return_if_fail (applet != NULL);
 	g_return_if_fail (new_icon != NULL);
 
 	composite = gdk_pixbuf_copy (new_icon);
 
-	if (applet->gui_active_vpn)
+	vpn = nmwa_get_active_vpn_connection (applet);
+
+	if (vpn)
 	{
 		int dest_x = gdk_pixbuf_get_width (new_icon) - gdk_pixbuf_get_width (applet->vpn_lock_icon);
 		int dest_y = gdk_pixbuf_get_height (new_icon) - gdk_pixbuf_get_height (applet->vpn_lock_icon) - 2;
 
 		gdk_pixbuf_composite (applet->vpn_lock_icon, composite, dest_x, dest_y, gdk_pixbuf_get_width (applet->vpn_lock_icon),
 							gdk_pixbuf_get_height (applet->vpn_lock_icon), dest_x, dest_y, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
 	}
 
@@ -1024,23 +1047,23 @@ static GdkPixbuf * nmwa_act_stage_to_pix
  * Figure out what the currently active device is from NetworkManager, its type,
  * and what our icon on the panel should look like for each type.
  *
  */
 static void nmwa_update_state (NMWirelessApplet *applet)
 {
 	gboolean			show_applet = TRUE;
 	gboolean			need_animation = FALSE;
-	gboolean			active_vpn = FALSE;
 	GdkPixbuf *		pixbuf = NULL;
 	GdkPixbuf *		progress = NULL;
 	gint				strength = -1;
 	char *			tip = NULL;
 	WirelessNetwork *	active_network = NULL;
 	NetworkDevice *	act_dev = NULL;
+	VPNConnection		*vpn;
 
 	g_mutex_lock (applet->data_mutex);
 
 	act_dev = nmwa_get_first_active_device (applet->gui_device_list);
 	if (act_dev && network_device_is_wireless (act_dev))
 	{
 		active_network = network_device_get_active_wireless_network (act_dev);
 		strength = CLAMP ((int)network_device_get_strength (act_dev), 0, 100);
@@ -1104,21 +1127,22 @@ static void nmwa_update_state (NMWireles
 	}
 
 done:
 	g_mutex_unlock (applet->data_mutex);
 
 	if (!applet->tooltips)
 		applet->tooltips = gtk_tooltips_new ();
 
-	if (applet->gui_active_vpn != NULL) {
+	vpn = nmwa_get_active_vpn_connection (applet);
+	if (vpn != NULL) {
 		char *newtip;
 		char *vpntip;
 
-		vpntip = g_strdup_printf (_("VPN connection to '%s'"), nmwa_vpn_connection_get_name (applet->gui_active_vpn));
+		vpntip = g_strdup_printf (_("VPN connection to '%s'"), nmwa_vpn_connection_get_name (vpn));
 		newtip = g_strconcat (tip, "\n", vpntip, NULL);
 		g_free (vpntip);
 		g_free (tip);
 		tip = newtip;
 	}
 
 	gtk_tooltips_set_tip (applet->tooltips, applet->event_box, tip, NULL);
 	g_free (tip);
@@ -1287,17 +1311,18 @@ static void nmwa_menu_vpn_item_activate 
 	g_return_if_fail (applet != NULL);
 
 	if ((tag = g_object_get_data (G_OBJECT (item), "vpn")))
 	{
 		VPNConnection	*vpn = (VPNConnection *)tag;
 		const char	*name = nmwa_vpn_connection_get_name (vpn);
 		GSList         *passwords;
 
-		if (vpn != applet->gui_active_vpn)
+		VPNConnection	*active_vpn = nmwa_get_active_vpn_connection (applet);
+		if (vpn != active_vpn)
 		{
 			char *gconf_key;
 			char *escaped_name;
 			gboolean last_attempt_success;
 			gboolean reprompt;
 
 			escaped_name = gconf_escape_key (name, strlen (name));
 			gconf_key = g_strdup_printf ("%s/%s/last_attempt_success", GCONF_PATH_VPN_CONNECTIONS, escaped_name);
@@ -1651,34 +1676,37 @@ static void nmwa_menu_device_add_network
  *
  */
 static void nmwa_menu_add_vpn_menu (GtkWidget *menu, NMWirelessApplet *applet)
 {
 	GtkMenuItem	*item;
 	GtkMenu		*vpn_menu;
 	GtkMenuItem	*other_item;
 	GSList		*elt;
+	VPNConnection	*active_vpn;
 
 	g_return_if_fail (menu != NULL);
 	g_return_if_fail (applet != NULL);
 
 	item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_VPN Connections")));
 
 	vpn_menu = GTK_MENU (gtk_menu_new ());
+	active_vpn = nmwa_get_active_vpn_connection (applet);
+
 	for (elt = applet->gui_vpn_connections; elt; elt = g_slist_next (elt))
 	{
 		GtkCheckMenuItem	*vpn_item;
 		VPNConnection		*vpn = elt->data;
 		const char		*vpn_name = nmwa_vpn_connection_get_name (vpn);
 
 		vpn_item = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (vpn_name));
 		nmwa_vpn_connection_ref (vpn);
 		g_object_set_data (G_OBJECT (vpn_item), "vpn", vpn);
 
-		if (applet->gui_active_vpn && (strcmp (vpn_name, nmwa_vpn_connection_get_name (applet->gui_active_vpn)) == 0))
+		if (active_vpn && (strcmp (vpn_name, nmwa_vpn_connection_get_name (active_vpn)) == 0))
 			gtk_check_menu_item_set_active (vpn_item, TRUE);
 
 		g_signal_connect (G_OBJECT (vpn_item), "activate", G_CALLBACK (nmwa_menu_vpn_item_activate), applet);
 		gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (vpn_item));
 	}
 
 	/* Draw a seperator, but only if we have VPN connections above it */
 	if (applet->gui_vpn_connections)
@@ -1688,17 +1716,17 @@ static void nmwa_menu_add_vpn_menu (GtkW
 	}
 
 	other_item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Configure VPN...")));
 	g_signal_connect (G_OBJECT (other_item), "activate", G_CALLBACK (nmwa_menu_configure_vpn_item_activate), applet);
 	gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
 
 	other_item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Disconnect VPN...")));
 	g_signal_connect (G_OBJECT (other_item), "activate", G_CALLBACK (nmwa_menu_disconnect_vpn_item_activate), applet);
-	if (!applet->gui_active_vpn)
+	if (!active_vpn)
 		gtk_widget_set_sensitive (GTK_WIDGET (other_item), FALSE);
 	gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
 
 	gtk_menu_item_set_submenu (item, GTK_WIDGET (vpn_menu));
 
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
 	gtk_widget_show_all (GTK_WIDGET (item));
 }
@@ -2394,22 +2422,20 @@ static GtkWidget * nmwa_get_instance (NM
 {
 	GError *	error = NULL;
 
 	gtk_widget_hide (GTK_WIDGET (applet));
 
 	applet->nm_running = FALSE;
 	applet->dev_pending_call_list = NULL;
 	applet->dbus_device_list = NULL;
-	applet->dbus_active_vpn_name = NULL;
 	applet->dbus_vpn_connections = NULL;
 	applet->dbus_nm_state = NM_STATE_DISCONNECTED;
 	applet->vpn_pending_call_list = NULL;
 	applet->gui_device_list = NULL;
-	applet->gui_active_vpn = NULL;
 	applet->gui_vpn_connections = NULL;
 	applet->dialup_list = NULL;
 	applet->gui_nm_state = NM_STATE_DISCONNECTED;
 	applet->tooltips = NULL;
 	applet->thread_context = NULL;
 	applet->thread_loop = NULL;
 	applet->thread_done = FALSE;
 	applet->scanning_menu = NULL;
Index: gnome/applet/applet.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet.h,v
retrieving revision 1.12
diff -d -u -p -8 -r1.12 applet.h
--- gnome/applet/applet.h	5 Aug 2005 18:58:16 -0000	1.12
+++ gnome/applet/applet.h	25 Aug 2005 19:30:57 -0000
@@ -98,20 +98,18 @@ typedef struct
 
 	GSList *			dev_pending_call_list;
 	GSList *			dbus_device_list;
 	NMState			dbus_nm_state;
 
 	GSList *			dialup_list;
 
 	GSList *			gui_vpn_connections;
-	VPNConnection *	gui_active_vpn;
 
 	GSList *			vpn_pending_call_list;
-	char *			dbus_active_vpn_name;
 	GSList *			dbus_vpn_connections;
 
 	GdkPixbuf *		no_connection_icon;
 	GdkPixbuf *		wired_icon;
 	GdkPixbuf *		adhoc_icon;
 #define NUM_PROGRESS_FRAMES 11
 	GdkPixbuf *		progress_icons[NUM_PROGRESS_FRAMES];
 #define NUM_WIRED_CONNECTING_FRAMES 11
Index: gnome/applet/vpn-connection.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/vpn-connection.c,v
retrieving revision 1.2
diff -d -u -p -8 -r1.2 vpn-connection.c
--- gnome/applet/vpn-connection.c	12 Jun 2005 14:35:58 -0000	1.2
+++ gnome/applet/vpn-connection.c	25 Aug 2005 19:30:57 -0000
@@ -23,16 +23,17 @@
 #include "vpn-connection.h"
 
 
 struct VPNConnection
 {
 	int   refcount;
 	char	*name;
 	char *service;
+	NMVPNState state;
 };
 
 
 VPNConnection *nmwa_vpn_connection_new (const char *name)
 {
 	VPNConnection *vpn;
 
 	g_return_val_if_fail (name != NULL, NULL);
@@ -50,17 +51,18 @@ VPNConnection *nmwa_vpn_connection_copy 
 	VPNConnection *dst_vpn;
 
 	g_return_val_if_fail (src_vpn != NULL, NULL);
 
 	dst_vpn = g_malloc0 (sizeof (VPNConnection));
 	dst_vpn->refcount = 1;
 	dst_vpn->name = g_strdup (src_vpn->name);
 	dst_vpn->service = src_vpn->service ? g_strdup (src_vpn->service) : NULL;
-	
+	dst_vpn->state = src_vpn->state;
+
 	return dst_vpn;
 }
 
 
 void nmwa_vpn_connection_ref (VPNConnection *vpn)
 {
 	g_return_if_fail (vpn != NULL);
 
@@ -129,9 +131,21 @@ VPNConnection *nmwa_vpn_connection_find_
 		return NULL;
 
 	if ((elt = g_slist_find_custom (list, name, (GCompareFunc) is_same_name)))
 		vpn = elt->data;
 
 	return vpn;	
 }
 
+NMVPNState nmwa_vpn_connection_get_state (VPNConnection *vpn)
+{
+	g_return_val_if_fail (vpn != NULL, NM_VPN_STATE_UNKNOWN);
+
+	return vpn->state;
+}
+
+void nmwa_vpn_connection_set_state (VPNConnection *vpn, NMVPNState state)
+{
+	g_return_if_fail (vpn != NULL);
 
+	vpn->state = state;
+}
Index: gnome/applet/vpn-connection.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/vpn-connection.h,v
retrieving revision 1.2
diff -d -u -p -8 -r1.2 vpn-connection.h
--- gnome/applet/vpn-connection.h	12 Jun 2005 14:35:58 -0000	1.2
+++ gnome/applet/vpn-connection.h	25 Aug 2005 19:30:57 -0000
@@ -29,11 +29,14 @@ VPNConnection *	nmwa_vpn_connection_copy
 void				nmwa_vpn_connection_ref			(VPNConnection *vpn);
 void				nmwa_vpn_connection_unref		(VPNConnection *vpn);
 
 const char *		nmwa_vpn_connection_get_name		(VPNConnection *vpn);
 
 const char *		nmwa_vpn_connection_get_service	(VPNConnection *vpn);
 void				nmwa_vpn_connection_set_service	(VPNConnection *vpn, const char *service);
 
+NMVPNState		nmwa_vpn_connection_get_state (VPNConnection *vpn);
+void			nmwa_vpn_connection_set_state (VPNConnection *vpn, NMVPNState state);
+
 VPNConnection *	nmwa_vpn_connection_find_by_name	(GSList *list, const char *name);
 
 #endif
Index: src/vpn-manager/nm-dbus-vpn.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/vpn-manager/nm-dbus-vpn.c,v
retrieving revision 1.7
diff -d -u -p -8 -r1.7 nm-dbus-vpn.c
--- src/vpn-manager/nm-dbus-vpn.c	17 Aug 2005 16:11:49 -0000	1.7
+++ src/vpn-manager/nm-dbus-vpn.c	25 Aug 2005 19:30:58 -0000
@@ -54,16 +54,48 @@ void nm_dbus_vpn_signal_vpn_connection_u
 	vpn_name = nm_vpn_connection_get_name (vpn);
 	dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_INVALID);
 	if (!dbus_connection_send (con, message, NULL))
 		nm_warning ("Could not raise the %s signal!", signal);
 
 	dbus_message_unref (message);
 }
 
+/*
+ * nm_dbus_vpn_signal_vpn_connection_state_change
+ *
+ * Notifies the bus that a VPN connection's state has changed.
+ */
+void nm_dbus_vpn_signal_vpn_connection_state_change (DBusConnection *con, NMVPNConnection *vpn)
+{
+	DBusMessage	*message;
+	const char	*vpn_name;
+	NMVPNService	*service;
+	NMVPNState	vpn_state;
+
+	g_return_if_fail (con != NULL);
+	g_return_if_fail (vpn != NULL);
+
+	if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "VPNConnectionStateChange")))
+	{
+		nm_warning ("Not enough memory for new dbus message!");
+		return;
+	}
+
+	vpn_name = nm_vpn_connection_get_name (vpn);
+	service = nm_vpn_connection_get_service (vpn);
+	vpn_state = nm_vpn_service_get_state (service);
+
+	dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_UINT32, &vpn_state, DBUS_TYPE_INVALID);
+	if (!dbus_connection_send (con, message, NULL))
+		nm_warning ("Could not raise the VPNConnectionStateChange signal!");
+
+	dbus_message_unref (message);
+}
+
 
 /*
  * nm_dbus_vpn_signal_vpn_connection_change
  *
  * Notifies the bus that the current VPN connection, if any, has changed.
  *
  */
 void nm_dbus_vpn_signal_vpn_connection_change (DBusConnection *con, NMVPNConnection *vpn)
@@ -614,22 +646,26 @@ static DBusMessage *nm_dbus_vpn_get_vpn_
 		return NULL;
 
 	dbus_error_init (&error);
 	if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
 	{
 		if ((vpn_con = nm_vpn_manager_find_connection_by_name (data->data->vpn_manager, name)))
 		{
 			const char *user_name;
-			const char *service;
+			const char *service_name;
+			NMVPNService *service;
+			NMVPNState state;
 
 			user_name = nm_vpn_connection_get_user_name (vpn_con);
-			service = nm_vpn_service_get_service_name (nm_vpn_connection_get_service (vpn_con));
+			service = nm_vpn_connection_get_service (vpn_con);
+			service_name = nm_vpn_service_get_service_name (service);
+			state = nm_vpn_service_get_state (service);
 
-			dbus_message_append_args (reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user_name, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID);
+			dbus_message_append_args (reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user_name, DBUS_TYPE_STRING, &service_name, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
 			good = TRUE;
 		}
 	}
 
 	if (!good)
 		reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "InvalidVPNConnection", "No VPN connection with that name was found.");
 
 	return reply;
@@ -642,16 +678,18 @@ static DBusMessage *nm_dbus_vpn_get_vpn_
  * Return the name of the currently active VPN connection.
  *
  */
 static DBusMessage *nm_dbus_vpn_get_active_vpn_connection (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
 {
 	DBusMessage		*reply = NULL;
 	const char		*name;
 	NMVPNConnection	*vpn = NULL;
+	NMVPNService *service = NULL;
+	NMVPNState vpn_state = NM_VPN_STATE_UNKNOWN;
 
 	g_return_val_if_fail (data != NULL, NULL);
 	g_return_val_if_fail (data->data != NULL, NULL);
 	g_return_val_if_fail (connection != NULL, NULL);
 	g_return_val_if_fail (message != NULL, NULL);
 
 	/* Check for no VPN Manager */
 	if (!data->data->vpn_manager)
@@ -659,17 +697,19 @@ static DBusMessage *nm_dbus_vpn_get_acti
 
 	if (!(vpn = nm_vpn_manager_get_active_vpn_connection (data->data->vpn_manager)))
 		return nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "NoActiveVPNConnection", "There is no active VPN connection.");
 
 	if (!(reply = dbus_message_new_method_return (message)))
 		return NULL;
 
 	name = nm_vpn_connection_get_name (vpn);
-	dbus_message_append_args (reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
+	service = nm_vpn_connection_get_service (vpn);
+	vpn_state = nm_vpn_service_get_state (service);
+	dbus_message_append_args (reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &vpn_state, DBUS_TYPE_INVALID);
 
 	return reply;
 }
 
 
 /*
  * nm_dbus_vpn_activate_connection
  *
Index: src/vpn-manager/nm-dbus-vpn.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/vpn-manager/nm-dbus-vpn.h,v
retrieving revision 1.4
diff -d -u -p -8 -r1.4 nm-dbus-vpn.h
--- src/vpn-manager/nm-dbus-vpn.h	16 May 2005 12:57:08 -0000	1.4
+++ src/vpn-manager/nm-dbus-vpn.h	25 Aug 2005 19:30:58 -0000
@@ -21,22 +21,22 @@
 
 #ifndef NM_DBUS_VPN_H
 #define NM_DBUS_VPN_H
 
 #include "NetworkManagerDbusUtils.h"
 #include "nm-vpn-manager.h"
 #include "nm-vpn-connection.h"
 
-
 void				nm_dbus_vpn_schedule_vpn_connections_update	(NMData *app_data);
 void				nm_dbus_vpn_update_one_vpn_connection		(DBusConnection *connection, const char *vpn, NMData *data);
 
 void				nm_dbus_vpn_signal_vpn_connection_update	(DBusConnection *con, NMVPNConnection *vpn, const char *signal);
 void				nm_dbus_vpn_signal_vpn_connection_change	(DBusConnection *con, NMVPNConnection *vpn);
 void				nm_dbus_vpn_signal_vpn_failed				(DBusConnection *con, const char *signal, NMVPNConnection *vpn, const char *error_msg);
 void				nm_dbus_vpn_signal_vpn_login_banner		(DBusConnection *con, NMVPNConnection *vpn, const char *banner);
+void				nm_dbus_vpn_signal_vpn_connection_state_change	(DBusConnection *con, NMVPNConnection *vpn);
 
 char **			nm_dbus_vpn_get_routes					(DBusConnection *connection, NMVPNConnection *vpn, int *num_items);
 
 NMDbusMethodList *	nm_dbus_vpn_methods_setup				(void);
 
 #endif
Index: src/vpn-manager/nm-vpn-manager.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/vpn-manager/nm-vpn-manager.c,v
retrieving revision 1.10
diff -d -u -p -8 -r1.10 nm-vpn-manager.c
--- src/vpn-manager/nm-vpn-manager.c	13 Jul 2005 16:58:13 -0000	1.10
+++ src/vpn-manager/nm-vpn-manager.c	25 Aug 2005 19:30:58 -0000
@@ -572,16 +572,17 @@ gboolean nm_vpn_manager_process_signal (
 	{
 		NMVPNState	old_state;
 		NMVPNState	new_state;
 
 		if (dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &old_state, DBUS_TYPE_UINT32, &new_state, DBUS_TYPE_INVALID))
 		{
 			nm_info ("VPN service '%s' signaled new state %d, old state %d.", service_name, new_state, old_state);
 			nm_vpn_service_set_state (service, new_state);
+			nm_dbus_vpn_signal_vpn_connection_state_change (manager->app_data->dbus_connection, active);
 
 			/* If the VPN daemon state is now stopped and it was starting, clear the active connection */
 			if (((new_state == NM_VPN_STATE_STOPPED) || (new_state == NM_VPN_STATE_SHUTDOWN) || (new_state == NM_VPN_STATE_STOPPING))
 				&& ((old_state == NM_VPN_STATE_STARTED) || (old_state == NM_VPN_STATE_STARTING)))
 			{
 				nm_vpn_manager_set_active_vpn_connection (manager, NULL);
 			}
 		}
@@ -629,16 +630,17 @@ gboolean nm_vpn_manager_process_name_own
 	if (!old_owner_good && new_owner_good)
 	{
 		/* VPN service got created. */
 	}
 	else if (old_owner_good && !new_owner_good)
 	{
 		/* VPN service went away. */
 		nm_vpn_service_set_state (service, NM_VPN_STATE_SHUTDOWN);
+		nm_dbus_vpn_signal_vpn_connection_state_change (manager->app_data->dbus_connection, active);
 		nm_vpn_manager_set_active_vpn_connection (manager, NULL);
 		nm_dbus_vpn_signal_vpn_connection_change (manager->app_data->dbus_connection, active);
 	}
 
 	nm_vpn_connection_unref (active);
 	return TRUE;
 }
 
@@ -756,17 +758,16 @@ void nm_vpn_manager_deactivate_vpn_conne
 		goto out;
 	}
 
 	/* Call the specific VPN service, let dbus activate it if needed */
 	dbus_connection_send (manager->app_data->dbus_connection, message, NULL);
 	dbus_message_unref (message);
 
 out:
-	nm_vpn_manager_set_active_vpn_connection (manager, NULL);
 	nm_vpn_connection_unref (active);
 
 	if ((dev = nm_get_active_device (manager->app_data)))
 		nm_system_device_set_from_ip4_config (dev);
 }
 
 
 /*********************************************************************/
Index: vpn-daemons/vpnc/src/nm-vpnc-service.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/vpn-daemons/vpnc/src/nm-vpnc-service.c,v
retrieving revision 1.7
diff -d -u -p -8 -r1.7 nm-vpnc-service.c
--- vpn-daemons/vpnc/src/nm-vpnc-service.c	19 Aug 2005 15:39:33 -0000	1.7
+++ vpn-daemons/vpnc/src/nm-vpnc-service.c	25 Aug 2005 19:30:58 -0000
@@ -910,16 +910,17 @@ static void nm_vpnc_dbus_process_helper_
 									DBUS_TYPE_STRING, &cisco_banner, DBUS_TYPE_INVALID);
 		if (!dbus_connection_send (data->con, signal, NULL))
 		{
 			nm_warning ("Could not raise the "NM_DBUS_VPN_SIGNAL_IP4_CONFIG" signal!");
 			goto out;
 		}
 
 		dbus_message_unref (signal);
+		nm_vpnc_set_state (data, NM_VPN_STATE_STARTED);
 		success = TRUE;
 	}
 
 out:
 	if (!success)
 	{
 		nm_warning ("Received invalid IP4 Config information from helper, terminating vpnc.");
 		nm_vpnc_dbus_handle_stop_vpn (data);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]