changeset 15730:c2f74eb8dbef

merge of '3de02ea0a320455a7d89aa8dc2ff11b30d9db1ae' and 'ee860116b53f187b67c513cca2b6374682585482'
author Mark Doliner <mark@kingant.net>
date Mon, 26 Feb 2007 04:33:46 +0000
parents da4813f14457 (diff) 47ca3cfedb32 (current diff)
children 4ffeecc47fd3
files pidgin/pixmaps/tray/16/Makefile.am pidgin/pixmaps/tray/16/tray-away.ico pidgin/pixmaps/tray/16/tray-away.png pidgin/pixmaps/tray/16/tray-busy.ico pidgin/pixmaps/tray/16/tray-busy.png pidgin/pixmaps/tray/16/tray-connecting.png pidgin/pixmaps/tray/16/tray-extended-away.ico pidgin/pixmaps/tray/16/tray-extended-away.png pidgin/pixmaps/tray/16/tray-message.ico pidgin/pixmaps/tray/16/tray-message.png pidgin/pixmaps/tray/16/tray-offline.ico pidgin/pixmaps/tray/16/tray-offline.png pidgin/pixmaps/tray/16/tray-online.ico pidgin/pixmaps/tray/16/tray-online.png
diffstat 43 files changed, 163 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Mon Feb 26 04:30:10 2007 +0000
+++ b/configure.ac	Mon Feb 26 04:33:46 2007 +0000
@@ -1938,7 +1938,7 @@
 		   pidgin/pixmaps/toolbar/16/Makefile
 		   pidgin/pixmaps/toolbar/16/scalable/Makefile
 		   pidgin/pixmaps/tray/Makefile
-		   pidgin/pixmaps/tray/16/Makefile
+		   pidgin/pixmaps/tray/22/Makefile
 		   pidgin/plugins/Makefile
 		   pidgin/plugins/cap/Makefile
 		   pidgin/plugins/gestures/Makefile
--- a/console/Makefile.am	Mon Feb 26 04:30:10 2007 +0000
+++ b/console/Makefile.am	Mon Feb 26 04:33:46 2007 +0000
@@ -1,5 +1,10 @@
 if ENABLE_GNT
 
+EXTRA_DIST = \
+		getopt.c \
+		getopt.h \
+		getopt1.c
+
 SUBDIRS = libgnt plugins
 
 bin_PROGRAMS = gaim-text
--- a/libpurple/dnsquery.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/libpurple/dnsquery.c	Mon Feb 26 04:33:46 2007 +0000
@@ -119,13 +119,13 @@
 static gboolean
 gaim_dnsquery_ui_resolve(GaimDnsQueryData *query_data)
 {
-    GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops();
+	GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops();
 
-    if (ops && ops->resolve_host)
-    {
-        if (ops->resolve_host(query_data, gaim_dnsquery_resolved, gaim_dnsquery_failed))
-            return TRUE;
-    }
+	if (ops && ops->resolve_host)
+	{
+		if (ops->resolve_host(query_data, gaim_dnsquery_resolved, gaim_dnsquery_failed))
+			return TRUE;
+	}
 
 	return FALSE;
 }
@@ -390,9 +390,9 @@
 
 /**
  * @return TRUE if the request was sent succesfully.  FALSE
- *         if the request could not be sent.  This isn't
- *         necessarily an error.  If the child has expired,
- *         for example, we won't be able to send the message.
+ * 		if the request could not be sent.  This isn't
+ * 		necessarily an error.  If the child has expired,
+ * 		for example, we won't be able to send the message.
  */
 static gboolean
 send_dns_request_to_child(GaimDnsQueryData *query_data,
@@ -471,13 +471,13 @@
 	query_data = queued_requests->data;
 	queued_requests = g_slist_delete_link(queued_requests, queued_requests);
 
-    if (gaim_dnsquery_ui_resolve(query_data))
-    {
-        /* The UI is handling the resolve; we're done */
-    	handle_next_queued_request();
-    	return;
-    }
-	
+	if (gaim_dnsquery_ui_resolve(query_data))
+	{
+		/* The UI is handling the resolve; we're done */
+		handle_next_queued_request();
+		return;
+	}
+
 	/*
 	 * If we have any children, attempt to have them perform the DNS
 	 * query.  If we're able to send the query then resolver will be
@@ -601,7 +601,7 @@
 	GaimDnsQueryData *query_data;
 
 	g_return_val_if_fail(hostname != NULL, NULL);
-	g_return_val_if_fail(port     != 0, NULL);
+	g_return_val_if_fail(port	  != 0, NULL);
 	g_return_val_if_fail(callback != NULL, NULL);
 
 	query_data = g_new(GaimDnsQueryData, 1);
@@ -727,11 +727,11 @@
 	query_data = data;
 	query_data->timeout = 0;
 
-    if (gaim_dnsquery_ui_resolve(query_data))
-    {
-        /* The UI is handling the resolve; we're done */
-    	return FALSE;
-    }
+	if (gaim_dnsquery_ui_resolve(query_data))
+	{
+		/* The UI is handling the resolve; we're done */
+		return FALSE;
+	}
 
 	if (inet_aton(query_data->hostname, &sin.sin_addr))
 	{
@@ -774,7 +774,7 @@
 	GaimDnsQueryData *query_data;
 
 	g_return_val_if_fail(hostname != NULL, NULL);
-	g_return_val_if_fail(port     != 0, NULL);
+	g_return_val_if_fail(port	  != 0, NULL);
 	g_return_val_if_fail(callback != NULL, NULL);
 
 	gaim_debug_info("dnsquery", "Performing DNS lookup for %s\n", hostname);
@@ -817,11 +817,11 @@
 	query_data = data;
 	query_data->timeout = 0;
 
-    if (gaim_dnsquery_ui_resolve(query_data))
-    {
-        /* The UI is handling the resolve; we're done */
-    	return FALSE;
-    }
+	if (gaim_dnsquery_ui_resolve(query_data))
+	{
+		/* The UI is handling the resolve; we're done */
+		return FALSE;
+	}
 
 	if (!inet_aton(query_data->hostname, &sin.sin_addr)) {
 		struct hostent *hp;
@@ -854,7 +854,7 @@
 	GaimDnsQueryData *query_data;
 
 	g_return_val_if_fail(hostname != NULL, NULL);
-	g_return_val_if_fail(port     != 0, NULL);
+	g_return_val_if_fail(port	  != 0, NULL);
 	g_return_val_if_fail(callback != NULL, NULL);
 
 	query_data = g_new(GaimDnsQueryData, 1);
@@ -881,10 +881,10 @@
 void
 gaim_dnsquery_destroy(GaimDnsQueryData *query_data)
 {
-    GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops();
+	GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops();
 
-    if (ops && ops->destroy)
-        ops->destroy(query_data);
+	if (ops && ops->destroy)
+		ops->destroy(query_data);
 
 #if defined(__unix__) || defined(__APPLE__)
 	queued_requests = g_slist_remove(queued_requests, query_data);
@@ -940,7 +940,7 @@
 {
 	g_return_val_if_fail(query_data != NULL, 0);
 
-	return query_data->port;	
+	return query_data->port;
 }
 
 void
--- a/libpurple/dnsquery.h	Mon Feb 26 04:30:10 2007 +0000
+++ b/libpurple/dnsquery.h	Mon Feb 26 04:33:46 2007 +0000
@@ -49,14 +49,14 @@
  */
 typedef struct
 {
-    /* If implemented, the UI is responsible for DNS queries */
-    gboolean (*resolve_host)(GaimDnsQueryData *query_data, GaimDnsQueryResolvedCallback resolved_cb, GaimDnsQueryFailedCallback failed_cb);
-    
-    /* After destroy is called, query_data will be feed, so this must
-     * cancel any further use of it the UI would do. Unneeded if 
-     * resolve_host is not implemented.
-     */
-    void (*destroy)(GaimDnsQueryData *query_data);
+	/* If implemented, the UI is responsible for DNS queries */
+	gboolean (*resolve_host)(GaimDnsQueryData *query_data, GaimDnsQueryResolvedCallback resolved_cb, GaimDnsQueryFailedCallback failed_cb);
+
+	/* After destroy is called, query_data will be feed, so this must
+	 * cancel any further use of it the UI would do. Unneeded if 
+	 * resolve_host is not implemented.
+	 */
+	void (*destroy)(GaimDnsQueryData *query_data);
 } GaimDnsQueryUiOps;
 
 #ifdef __cplusplus
--- a/libpurple/dnssrv.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/libpurple/dnssrv.c	Mon Feb 26 04:33:46 2007 +0000
@@ -67,6 +67,8 @@
 	char *query;
 	char *error_message;
 	GSList *results;
+#else
+	pid_t pid;
 #endif
 };
 
@@ -188,6 +190,7 @@
 	GaimSrvResponse *tmp;
 	int i;
 	GaimSrvCallback cb = query_data->cb;
+	int status;
 
 	read(source, &size, sizeof(int));
 	gaim_debug_info("dnssrv","found %d SRV entries\n", size);
@@ -197,6 +200,7 @@
 	}
 
 	cb(res, size, query_data->extradata);
+	waitpid(query_data->pid, &status, 0);
 
 	gaim_srv_cancel(query_data);
 }
@@ -344,6 +348,7 @@
 	query_data = g_new0(GaimSrvQueryData, 1);
 	query_data->cb = cb;
 	query_data->extradata = extradata;
+	query_data->pid = pid;
 	query_data->handle = gaim_input_add(out[0], GAIM_INPUT_READ, resolved, query_data);
 
 	g_free(query);
--- a/libpurple/protocols/jabber/jabber.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Mon Feb 26 04:33:46 2007 +0000
@@ -283,7 +283,7 @@
 			sasl_encode(js->sasl, &data[pos], towrite, &out, &olen);
 			pos += towrite;
 
-			if (js->writeh > 0)
+			if (js->writeh == 0)
 				ret = jabber_do_send(js, out, olen);
 			else {
 				ret = -1;
--- a/libpurple/win32/win32dep.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/libpurple/win32/win32dep.c	Mon Feb 26 04:33:46 2007 +0000
@@ -588,6 +588,8 @@
 }
 
 /* DLL initializer */
+/* suppress gcc "no previous prototype" warning */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
 	libgaimdll_hInstance = hinstDLL;
 	return TRUE;
--- a/pidgin/gaimstock.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/pidgin/gaimstock.c	Mon Feb 26 04:33:46 2007 +0000
@@ -164,13 +164,13 @@
 	{ PIDGIN_STOCK_TOOLBAR_TYPING, "toolbar", "typing.png", TRUE, FALSE, FALSE, FALSE },
 	{ PIDGIN_STOCK_TOOLBAR_PENDING, "status", "message-pending.png", TRUE, FALSE, FALSE, FALSE },
 	
-	{ PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", TRUE, FALSE, FALSE, FALSE },
-	{ PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", TRUE, FALSE, FALSE, FALSE },
-	{ PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", TRUE, FALSE, FALSE, FALSE },
-	{ PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", TRUE, FALSE, FALSE, FALSE },
-	{ PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", TRUE, FALSE, FALSE, FALSE },
-	{ PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", TRUE, FALSE, FALSE, FALSE },
-	{ PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-message.png", TRUE, FALSE, FALSE, FALSE }
+	{ PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", FALSE, TRUE, FALSE, FALSE },
+	{ PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", FALSE, TRUE, FALSE, FALSE },
+	{ PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", FALSE, TRUE, FALSE, FALSE },
+	{ PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", FALSE, TRUE, FALSE, FALSE },
+	{ PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", FALSE, TRUE, FALSE, FALSE },
+	{ PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", FALSE, TRUE, FALSE, FALSE },
+	{ PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-message.png", FALSE, TRUE, FALSE, FALSE }
 };
 
 static gchar *
--- a/pidgin/gtkaccount.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/pidgin/gtkaccount.c	Mon Feb 26 04:33:46 2007 +0000
@@ -2563,11 +2563,23 @@
 void
 pidgin_account_init(void)
 {
+	char *default_avatar = NULL;
 	gaim_prefs_add_none("/gaim/gtk/accounts");
 	gaim_prefs_add_none("/gaim/gtk/accounts/dialog");
 	gaim_prefs_add_int("/gaim/gtk/accounts/dialog/width",  520);
 	gaim_prefs_add_int("/gaim/gtk/accounts/dialog/height", 321);
-	gaim_prefs_add_path("/gaim/gtk/accounts/buddyicon", NULL);
+	default_avatar = g_build_filename(g_get_home_dir(), ".face.icon", NULL);
+	if (!g_file_test(default_avatar, G_FILE_TEST_EXISTS)) {
+		g_free(default_avatar);
+		default_avatar = g_build_filename(g_get_home_dir(), ".face", NULL);
+		if (!g_file_test(default_avatar, G_FILE_TEST_EXISTS)) {
+			g_free(default_avatar);
+			default_avatar = NULL;
+		}
+	}
+		
+printf("AVATAR: %s\n", default_avatar);
+	gaim_prefs_add_path("/gaim/gtk/accounts/buddyicon", default_avatar);
 
 	gaim_signal_register(pidgin_account_get_handle(), "account-modified",
 						 gaim_marshal_VOID__POINTER, NULL, 1,
--- a/pidgin/gtkblist.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/pidgin/gtkblist.c	Mon Feb 26 04:33:46 2007 +0000
@@ -2301,8 +2301,11 @@
 		td->avatar_is_prpl_icon = TRUE;
 	}
 #endif
-	td->avatar_width = gdk_pixbuf_get_width(td->avatar);
-	td->avatar_height = gdk_pixbuf_get_height(td->avatar);
+
+	if (td->avatar) {
+		td->avatar_width = gdk_pixbuf_get_width(td->avatar);
+		td->avatar_height = gdk_pixbuf_get_height(td->avatar);
+	}
 
 	g_free(node_name);
 	g_free(tooltip_text);
--- a/pidgin/gtkdocklet-x11.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/pidgin/gtkdocklet-x11.c	Mon Feb 26 04:33:46 2007 +0000
@@ -116,7 +116,7 @@
 	}
 
 	if(icon_name)
-		gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
+		gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL));
 
 #if 0
 	GdkPixbuf *p;
--- a/pidgin/pixmaps/tray/16/Makefile.am	Mon Feb 26 04:30:10 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-TRAY_ICONS =	tray-away.png \
-		tray-busy.png \
-		tray-connecting.png \
-		tray-extended-away.png \
-		tray-message.png \
-		tray-offline.png \
-		tray-online.png
-
-EXTRA_DIST = 	tray-away.ico \
-		tray-busy.ico \
-		tray-connecting.ico \
-		tray-extended-away.ico \
-		tray-message.ico \
-		tray-offline.ico \
-		tray-online.ico 
-
-pidgintraypixdir = $(datadir)/pixmaps/pidgin/tray/16
-pidgintraypix_DATA = $(TRAY_ICONS)
Binary file pidgin/pixmaps/tray/16/tray-away.ico has changed
Binary file pidgin/pixmaps/tray/16/tray-away.png has changed
Binary file pidgin/pixmaps/tray/16/tray-busy.ico has changed
Binary file pidgin/pixmaps/tray/16/tray-busy.png has changed
Binary file pidgin/pixmaps/tray/16/tray-connecting.png has changed
Binary file pidgin/pixmaps/tray/16/tray-extended-away.ico has changed
Binary file pidgin/pixmaps/tray/16/tray-extended-away.png has changed
Binary file pidgin/pixmaps/tray/16/tray-message.ico has changed
Binary file pidgin/pixmaps/tray/16/tray-message.png has changed
Binary file pidgin/pixmaps/tray/16/tray-offline.ico has changed
Binary file pidgin/pixmaps/tray/16/tray-offline.png has changed
Binary file pidgin/pixmaps/tray/16/tray-online.ico has changed
Binary file pidgin/pixmaps/tray/16/tray-online.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pixmaps/tray/22/Makefile.am	Mon Feb 26 04:33:46 2007 +0000
@@ -0,0 +1,18 @@
+TRAY_ICONS =	tray-away.png \
+		tray-busy.png \
+		tray-connecting.png \
+		tray-extended-away.png \
+		tray-message.png \
+		tray-offline.png \
+		tray-online.png
+
+EXTRA_DIST = 	tray-away.ico \
+		tray-busy.ico \
+		tray-connecting.ico \
+		tray-extended-away.ico \
+		tray-message.ico \
+		tray-offline.ico \
+		tray-online.ico 
+
+pidgintraypixdir = $(datadir)/pixmaps/pidgin/tray/22
+pidgintraypix_DATA = $(TRAY_ICONS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pixmaps/tray/22/Makefile.mingw	Mon Feb 26 04:33:46 2007 +0000
@@ -0,0 +1,20 @@
+#
+# Makefile.mingw
+#
+# Description: Makefile for win32 (mingw) version of Pidgin pixmaps
+#
+
+GAIM_TOP := ../../../..
+include $(GAIM_TOP)/libpurple/win32/global.mak
+
+datadir = $(GAIM_INSTALL_DIR)
+include ./Makefile.am
+
+.PHONY: install
+
+install:
+	if test '$(pidgintraypix_DATA)'; then \
+	  mkdir -p $(pidgintraypixdir); \
+	  cp $(pidgintraypix_DATA) $(pidgintraypixdir); \
+	fi;
+
Binary file pidgin/pixmaps/tray/22/tray-away.ico has changed
Binary file pidgin/pixmaps/tray/22/tray-away.png has changed
Binary file pidgin/pixmaps/tray/22/tray-busy.ico has changed
Binary file pidgin/pixmaps/tray/22/tray-busy.png has changed
Binary file pidgin/pixmaps/tray/22/tray-connecting.png has changed
Binary file pidgin/pixmaps/tray/22/tray-extended-away.ico has changed
Binary file pidgin/pixmaps/tray/22/tray-extended-away.png has changed
Binary file pidgin/pixmaps/tray/22/tray-message.ico has changed
Binary file pidgin/pixmaps/tray/22/tray-message.png has changed
Binary file pidgin/pixmaps/tray/22/tray-offline.ico has changed
Binary file pidgin/pixmaps/tray/22/tray-offline.png has changed
Binary file pidgin/pixmaps/tray/22/tray-online.ico has changed
Binary file pidgin/pixmaps/tray/22/tray-online.png has changed
--- a/pidgin/pixmaps/tray/Makefile.am	Mon Feb 26 04:30:10 2007 +0000
+++ b/pidgin/pixmaps/tray/Makefile.am	Mon Feb 26 04:33:46 2007 +0000
@@ -1,1 +1,6 @@
-SUBDIRS = 16
+SUBDIRS = 22
+
+EXTRA_DIST = \
+	Makefile.mingw \
+	22/Makefile.mingw
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pixmaps/tray/Makefile.mingw	Mon Feb 26 04:33:46 2007 +0000
@@ -0,0 +1,14 @@
+#
+# Makefile.mingw
+#
+# Description: Makefile for win32 (mingw) version of Gaim pixmaps
+#
+
+include ./Makefile.am
+
+install:
+	if test '$(SUBDIRS)'; then \
+	  list='$(SUBDIRS)'; for subdir in $$list; do \
+	    $(MAKE) -C $$subdir -f Makefile.mingw install || exit 1; \
+	  done; \
+	fi;
--- a/pidgin/win32/gtkdocklet-win32.c	Mon Feb 26 04:30:10 2007 +0000
+++ b/pidgin/win32/gtkdocklet-win32.c	Mon Feb 26 04:33:46 2007 +0000
@@ -45,8 +45,7 @@
  *  LOCALS
  */
 static HWND systray_hwnd = NULL;
-static const char *prev_icon_name = NULL;
-static HICON prev_hicon = NULL;
+static HICON cached_icons[DOCKLET_STATUS_CONNECTING + 1];
 static GtkWidget *image = NULL;
 static NOTIFYICONDATA _nicon_data;
 
@@ -444,7 +443,7 @@
 static HICON load_hicon_from_stock(const char *stock) {
 	HICON hicon = NULL;
 	GdkPixbuf *pixbuf = gtk_widget_render_icon(image, stock,
-		gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), NULL);
+		gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), NULL);
 
 	if (pixbuf) {
 		hicon = pixbuf_to_hicon(pixbuf);
@@ -456,28 +455,11 @@
 }
 
 
-
-static void systray_change_icon(const char *icon_name) {
-	HICON hicon;
-
-	/* Avoid looking up the icon if it hasn't really changed.
-	 * This will happen when re-displaying the icon when blinking.  */
-	if (icon_name == prev_icon_name) {
-		hicon = prev_hicon;
-		prev_hicon = NULL;
-	} else
-		hicon = load_hicon_from_stock(icon_name);
-
+static void systray_change_icon(HICON hicon) {
 	g_return_if_fail(hicon != NULL);
 
 	_nicon_data.hIcon = hicon;
 	Shell_NotifyIcon(NIM_MODIFY, &_nicon_data);
-
-	if (prev_hicon)
-		DestroyIcon(prev_hicon);
-	prev_hicon = hicon;
-	prev_icon_name = icon_name;
-
 }
 
 static void systray_remove_nid(void) {
@@ -485,11 +467,14 @@
 }
 
 static void winpidgin_tray_update_icon(DockletStatus icon) {
-	const gchar *icon_name = NULL;
 
 	g_return_if_fail(image != NULL);
+	g_return_if_fail(icon < (sizeof(cached_icons) / sizeof(HICON)));
 
-	switch (icon) {
+	/* Look up and cache the HICON if we don't already have it */
+	if (cached_icons[icon] == NULL) {
+		const gchar *icon_name = NULL;
+		switch (icon) {
 		case DOCKLET_STATUS_OFFLINE:
 			icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
 			break;
@@ -511,10 +496,14 @@
 		case DOCKLET_STATUS_XA:
 			icon_name = PIDGIN_STOCK_TRAY_XA;
 			break;
+		}
+
+		g_return_if_fail(icon_name != NULL);
+
+		cached_icons[icon] = load_hicon_from_stock(icon_name);
 	}
 
-	if(icon_name)
-		systray_change_icon(icon_name);
+	systray_change_icon(cached_icons[icon]);
 }
 
 static void winpidgin_tray_blank_icon() {
@@ -567,10 +556,17 @@
 }
 
 static void winpidgin_tray_destroy() {
+	int cached_cnt = sizeof(cached_icons) / sizeof(HICON);
 	systray_remove_nid();
 	DestroyWindow(systray_hwnd);
 	pidgin_docklet_remove();
 
+	while (--cached_cnt >= 0) {
+		if (cached_icons[cached_cnt] != NULL)
+			DestroyIcon(cached_icons[cached_cnt]);
+		cached_icons[cached_cnt] = NULL;
+	}
+
 	g_object_unref(image);
 	image = NULL;
 }
@@ -587,5 +583,8 @@
 
 /* Used by docklet's plugin load func */
 void docklet_ui_init() {
+	/* Initialize the cached icons to NULL */
+	ZeroMemory(cached_icons, sizeof(cached_icons));
+
 	pidgin_docklet_set_ui_ops(&winpidgin_tray_ops);
 }