changeset 14722:51685370de57

[gaim-migrate @ 17476] Implement the network manager stuff for wingaim. Also, fix some assertions and fix the freeing of the autorecon data without removing it from the hash. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Fri, 13 Oct 2006 02:31:36 +0000
parents 90882b641dda
children d18b9360ba54
files gtk/gtkconn.c libgaim/dnsquery.c libgaim/network.c libgaim/win32/win32dep.c
diffstat 4 files changed, 119 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/gtk/gtkconn.c	Fri Oct 13 00:37:44 2006 +0000
+++ b/gtk/gtkconn.c	Fri Oct 13 02:31:36 2006 +0000
@@ -79,8 +79,7 @@
 		gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox),
 					   (gaim_connections_get_connecting() != NULL));
 
-	if (hash != NULL)
-		g_hash_table_remove(hash, account);
+	g_hash_table_remove(hash, account);
 
 	gaim_gtk_blist_update_account_error_state(account, NULL);
 }
@@ -204,10 +203,9 @@
 
 	while (list) {
 		GaimAccount *account = (GaimAccount*)list->data;
-		GaimAutoRecon *info = g_hash_table_lookup(hash, account);
-		if (info)
-			free_auto_recon(info);
-		do_signon(account);
+		g_hash_table_remove(hash, account);
+		if (gaim_account_is_disconnected(account))
+			do_signon(account);
 		list = list->next;
 	}
 }
@@ -222,7 +220,8 @@
 
 	while (l) {
 		GaimAccount *a = (GaimAccount*)l->data;
-		gaim_account_disconnect(a);
+		if (!gaim_account_is_disconnected(a))
+			gaim_account_disconnect(a);
 		l = l->next;
 	}
 }
--- a/libgaim/dnsquery.c	Fri Oct 13 00:37:44 2006 +0000
+++ b/libgaim/dnsquery.c	Fri Oct 13 02:31:36 2006 +0000
@@ -893,10 +893,6 @@
 void
 gaim_dnsquery_init(void)
 {
-#ifdef _WIN32
-	if (!g_thread_supported())
-		g_thread_init(NULL);
-#endif
 }
 
 void
--- a/libgaim/network.c	Fri Oct 13 00:37:44 2006 +0000
+++ b/libgaim/network.c	Fri Oct 13 02:31:36 2006 +0000
@@ -28,6 +28,8 @@
 #ifndef _WIN32
 #include <net/if.h>
 #include <sys/ioctl.h>
+#else
+#include <nspapi.h>
 #endif
 
 /* Solaris */
@@ -48,6 +50,8 @@
 libnm_glib_ctx *nm_context = NULL;
 guint nm_callback_idx = 0;
 
+#elif defined _WIN32
+static int current_network_count;
 #endif
 
 struct _GaimNetworkListenData {
@@ -372,6 +376,103 @@
 	return ntohs(addr.sin_port);
 }
 
+#ifdef _WIN32
+static guint
+wgaim_get_connected_network_count(void)
+{
+	guint net_cnt = 0;
+
+	WSAQUERYSET qs;
+	HANDLE h;
+	int retval;
+
+	memset(&qs, 0, sizeof(WSAQUERYSET));
+	qs.dwSize = sizeof(WSAQUERYSET);
+	qs.dwNameSpace = NS_ALL;
+
+	retval = WSALookupServiceBegin(&qs, LUP_RETURN_ALL, &h);
+	if (retval != ERROR_SUCCESS) {
+		gchar *msg = g_win32_error_message(retval);
+		gaim_debug_warning("network", "Couldn't look up connected networks. %s (%lu).\n", msg, retval);
+		g_free(msg);
+	} else {
+		char buf[1024];
+		WSAQUERYSET *res = (LPWSAQUERYSET) buf;
+		DWORD size = sizeof(buf);
+		while (WSALookupServiceNext(h, 0, &size, res) == ERROR_SUCCESS) {
+			net_cnt++;
+			gaim_debug_info("network", "found network '%s'\n",
+					res->lpszServiceInstanceName ? res->lpszServiceInstanceName : "(NULL)");
+			size = sizeof(buf);
+		}
+
+		WSALookupServiceEnd(h);
+	}
+
+	return net_cnt;
+
+}
+
+static gboolean wgaim_network_change_thread_cb(gpointer data)
+{
+	guint new_count;
+	GaimConnectionUiOps *ui_ops = gaim_connections_get_ui_ops();
+
+	new_count = wgaim_get_connected_network_count();
+
+	gaim_debug_info("network", "Received Network Change Notification. Current network count is %d, previous count was %d.\n", new_count, current_network_count);
+
+	if (new_count > 0) {
+		ui_ops->network_connected();
+	} else if (new_count == 0 && current_network_count > 0) {
+		ui_ops->network_disconnected();
+	}
+
+	current_network_count = new_count;
+
+	return FALSE;
+}
+
+static gpointer wgaim_network_change_thread(gpointer data)
+{
+	HANDLE h;
+	WSAQUERYSET qs;
+
+	int WSAAPI (*MyWSANSPIoctl) (
+	HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
+	DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,
+	LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion) = NULL;
+ 
+	MyWSANSPIoctl = (void*) wgaim_find_and_loadproc("ws2_32.dll", "WSANSPIoctl");
+	if (!MyWSANSPIoctl) {
+		gaim_debug_error("network", "Couldn't load WSANSPIoctl from ws2_32.dll.\n");
+		g_thread_exit(NULL);
+		return NULL;
+	}
+
+	while (TRUE) {
+		int retval;
+		DWORD retLen = 0;
+
+		memset(&qs, 0, sizeof(WSAQUERYSET));
+		qs.dwSize = sizeof(WSAQUERYSET);
+		qs.dwNameSpace = NS_ALL;
+
+		retval = WSALookupServiceBegin(&qs, LUP_RETURN_ALL, &h);
+
+		/* This will block until there is a network change */
+		/* This is missing from the MinGW libws2_32.a as of version 3.7.
+		 * When this patch: http://sourceforge.net/tracker/index.php?func=detail&aid=1576083&group_id=2435&atid=302435 gets into a release, we can call this directly
+		 * retval = WSANSPIoctl(h, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &retLen, NULL);*/
+		 retval = MyWSANSPIoctl(h, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &retLen, NULL);
+
+		retval = WSALookupServiceEnd(h);
+
+		g_idle_add(wgaim_network_change_thread_cb, NULL);
+	}
+}
+#endif
+
 gboolean
 gaim_network_is_available(void)
 {
@@ -388,6 +489,8 @@
 		}
 		if (libnm_retval == LIBNM_ACTIVE_NETWORK_CONNECTION)	return TRUE;
 	}
+#elif _WIN32
+	return (current_network_count > 0);
 #endif
 	return TRUE;
 }
@@ -429,6 +532,13 @@
 void
 gaim_network_init(void)
 {
+#ifdef _WIN32
+	GError *err = NULL;
+	current_network_count = wgaim_get_connected_network_count();
+	if (!g_thread_create(wgaim_network_change_thread, NULL, FALSE, &err))
+		gaim_debug_error("network", "Couldn't create Network Monitor thread: %s\n", err ? err->message : "");
+#endif
+
 	gaim_prefs_add_none  ("/core/network");
 	gaim_prefs_add_bool  ("/core/network/auto_ip", TRUE);
 	gaim_prefs_add_string("/core/network/public_ip", "");
--- a/libgaim/win32/win32dep.c	Fri Oct 13 00:37:44 2006 +0000
+++ b/libgaim/win32/win32dep.c	Fri Oct 13 02:31:36 2006 +0000
@@ -444,6 +444,9 @@
 		gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
 	g_free(newenv);
 
+	if (!g_thread_supported())
+		g_thread_init(NULL);
+
 	gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init end\n");
 }