changeset 31722:db330f8c1a8c

merge of '6118d1117f31a7fc8db4bd5431af400a7b46ff17' and 'b28bde636d271fd90efcba54f25ecf7af2e5331b'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Tue, 01 Mar 2011 06:24:50 +0000
parents 169ebed69ef0 (current diff) 69094d578a45 (diff)
children 4f414608eaad
files ChangeLog libpurple/protocols/msn/msn.c
diffstat 11 files changed, 470 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Feb 28 09:19:34 2011 +0000
+++ b/ChangeLog	Tue Mar 01 06:24:50 2011 +0000
@@ -4,6 +4,12 @@
 	General:
 	* Our bundled libgadu should now build on HP-UX.
 
+	Pidgin:
+	* Sort by Status no longer causes buddies to move around when you
+	  click them.
+	* Fix embedding in the system tray on older GTK+ releases (such as on
+	  CentOS 5.5 and older Fedora).
+
 	AIM:
 	* Fix a bug where some buddies from your buddy list might not show up.
 	  Affected non-English ICQ users the most. (#13386)
--- a/libpurple/protocols/msn/contact.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/contact.c	Tue Mar 01 06:24:50 2011 +0000
@@ -363,10 +363,9 @@
 	char *type;
 	char *member_id;
 	MsnUser *user;
-	xmlnode *annotation, *display;
+	xmlnode *annotation;
 	guint nid = MSN_NETWORK_UNKNOWN;
 	char *invite = NULL;
-	char *display_text;
 
 	passport = xmlnode_get_data(xmlnode_get_child(member, node));
 	if (!msn_email_is_valid(passport)) {
@@ -376,13 +375,8 @@
 
 	type = xmlnode_get_data(xmlnode_get_child(member, "Type"));
 	member_id = xmlnode_get_data(xmlnode_get_child(member, "MembershipId"));
-	if ((display = xmlnode_get_child(member, "DisplayName"))) {
-		display_text = xmlnode_get_data(display);
-	} else {
-		display_text = NULL;
-	}
 
-	user = msn_userlist_find_add_user(session->userlist, passport, display_text);
+	user = msn_userlist_find_add_user(session->userlist, passport, NULL);
 
 	for (annotation = xmlnode_get_child(member, "Annotations/Annotation");
 	     annotation;
@@ -423,7 +417,6 @@
 	g_free(type);
 	g_free(member_id);
 	g_free(invite);
-	g_free(display_text);
 }
 
 static void
--- a/libpurple/protocols/msn/msn.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/msn.c	Tue Mar 01 06:24:50 2011 +0000
@@ -110,11 +110,9 @@
 
 	g_return_val_if_fail(str != NULL, NULL);
 
-	g_snprintf(buf, sizeof(buf), "%s%s", str,
-			   (strchr(str, '@') ? "" : "@hotmail.com"));
-
-	tmp = g_utf8_strdown(buf, -1);
-	strncpy(buf, tmp, sizeof(buf));
+	tmp = g_strchomp(g_utf8_strdown(str, -1));
+	g_snprintf(buf, sizeof(buf), "%s%s", tmp,
+			   (strchr(tmp, '@') ? "" : "@hotmail.com"));
 	g_free(tmp);
 
 	return buf;
--- a/libpurple/protocols/msn/p2p.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/p2p.c	Tue Mar 01 06:24:50 2011 +0000
@@ -23,72 +23,139 @@
  */
 
 #include "internal.h"
+#include "debug.h"
 
 #include "p2p.h"
 #include "msnutils.h"
 
 MsnP2PInfo *
-msn_p2p_info_new(void)
+msn_p2p_info_new(MsnP2PVersion version)
 {
-	return g_new0(MsnP2PInfo, 1);
+	MsnP2PInfo *info = g_new0(MsnP2PInfo, 1);
+	info->version = version;
+
+	switch (version) {
+		case MSN_P2P_VERSION_ONE:
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", version);
+			g_free(info);
+			info = NULL;
+	}
+
+	return info;
 }
 
 MsnP2PInfo *
 msn_p2p_info_dup(MsnP2PInfo *info)
 {
 	MsnP2PInfo *new_info = g_new0(MsnP2PInfo, 1);
-	*new_info = *info;
+
+	new_info->version = info->version;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+		case MSN_P2P_VERSION_TWO:
+			*new_info = *info;
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+			g_free(new_info);
+			new_info = NULL;
+	}
+
 	return new_info;
 }
 
 void
 msn_p2p_info_free(MsnP2PInfo *info)
 {
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
 	g_free(info);
 }
 
 size_t
 msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire)
 {
-	MsnP2PHeader *header;
+	size_t len;
 
-	header = &info->header;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE: {
+			MsnP2PHeader *header = &info->header.v1;
 
-	header->session_id = msn_pop32le(wire);
-	header->id         = msn_pop32le(wire);
-	header->offset     = msn_pop64le(wire);
-	header->total_size = msn_pop64le(wire);
-	header->length     = msn_pop32le(wire);
-	header->flags      = msn_pop32le(wire);
-	header->ack_id     = msn_pop32le(wire);
-	header->ack_sub_id = msn_pop32le(wire);
-	header->ack_size   = msn_pop64le(wire);
+			header->session_id = msn_pop32le(wire);
+			header->id         = msn_pop32le(wire);
+			header->offset     = msn_pop64le(wire);
+			header->total_size = msn_pop64le(wire);
+			header->length     = msn_pop32le(wire);
+			header->flags      = msn_pop32le(wire);
+			header->ack_id     = msn_pop32le(wire);
+			header->ack_sub_id = msn_pop32le(wire);
+			header->ack_size   = msn_pop64le(wire);
 
-	return P2P_PACKET_HEADER_SIZE;
+			len = P2P_PACKET_HEADER_SIZE;
+			break;
+		}
+
+		case MSN_P2P_VERSION_TWO:
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return len;
 }
 
 char *
 msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len)
 {
-	MsnP2PHeader *header;
-	char *wire;
+	char *wire = NULL;
 	char *tmp;
 
-	header = &info->header;
-	tmp = wire = g_new(char, P2P_PACKET_HEADER_SIZE);
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE: {
+			MsnP2PHeader *header = &info->header.v1;
+			tmp = wire = g_new(char, P2P_PACKET_HEADER_SIZE);
+
+			msn_push32le(tmp, header->session_id);
+			msn_push32le(tmp, header->id);
+			msn_push64le(tmp, header->offset);
+			msn_push64le(tmp, header->total_size);
+			msn_push32le(tmp, header->length);
+			msn_push32le(tmp, header->flags);
+			msn_push32le(tmp, header->ack_id);
+			msn_push32le(tmp, header->ack_sub_id);
+			msn_push64le(tmp, header->ack_size);
 
-	msn_push32le(tmp, header->session_id);
-	msn_push32le(tmp, header->id);
-	msn_push64le(tmp, header->offset);
-	msn_push64le(tmp, header->total_size);
-	msn_push32le(tmp, header->length);
-	msn_push32le(tmp, header->flags);
-	msn_push32le(tmp, header->ack_id);
-	msn_push32le(tmp, header->ack_sub_id);
-	msn_push64le(tmp, header->ack_size);
+			if (len)
+				*len = P2P_PACKET_HEADER_SIZE;
+
+			break;
+		}
 
-	if (len)
-		*len = P2P_PACKET_HEADER_SIZE;
+		case MSN_P2P_VERSION_TWO:
+			if (len)
+				*len = 0;
+
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 
 	return wire;
 
@@ -127,15 +194,30 @@
 void
 msn_p2p_info_to_string(MsnP2PInfo *info, GString *str)
 {
-	g_string_append_printf(str, "Session ID: %u\r\n", info->header.session_id);
-	g_string_append_printf(str, "ID:         %u\r\n", info->header.id);
-	g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", info->header.offset);
-	g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", info->header.total_size);
-	g_string_append_printf(str, "Length:     %u\r\n", info->header.length);
-	g_string_append_printf(str, "Flags:      0x%x\r\n", info->header.flags);
-	g_string_append_printf(str, "ACK ID:     %u\r\n", info->header.ack_id);
-	g_string_append_printf(str, "SUB ID:     %u\r\n", info->header.ack_sub_id);
-	g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", info->header.ack_size);
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE: {
+			MsnP2PHeader *header = &info->header.v1;
+			g_string_append_printf(str, "Session ID: %u\r\n", header->session_id);
+			g_string_append_printf(str, "ID:         %u\r\n", header->id);
+			g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", header->offset);
+			g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", header->total_size);
+			g_string_append_printf(str, "Length:     %u\r\n", header->length);
+			g_string_append_printf(str, "Flags:      0x%x\r\n", header->flags);
+			g_string_append_printf(str, "ACK ID:     %u\r\n", header->ack_id);
+			g_string_append_printf(str, "SUB ID:     %u\r\n", header->ack_sub_id);
+			g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", header->ack_size);
+
+			break;
+		}
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
 	g_string_append_printf(str, "Footer:     0x%08X\r\n", info->footer.value);
 }
 
@@ -150,67 +232,232 @@
 gboolean
 msn_p2p_info_is_valid(MsnP2PInfo *info)
 {
-	return info->header.total_size >= info->header.length;
+	gboolean valid = FALSE;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			valid = info->header.v1.total_size >= info->header.v1.length;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return valid;
 }
 
 gboolean
 msn_p2p_info_is_final(MsnP2PInfo *info)
 {
-	return info->header.offset + info->header.length >= info->header.total_size;
+	gboolean final = FALSE;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			final = info->header.v1.offset + info->header.v1.length >= info->header.v1.total_size;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return final;
 }
 
 guint32
 msn_p2p_info_get_session_id(MsnP2PInfo *info)
 {
-	return info->header.session_id;
+	guint32 session_id = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			session_id = info->header.v1.session_id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return session_id;
 }
 
 guint32
 msn_p2p_info_get_id(MsnP2PInfo *info)
 {
-	return info->header.id;
+	guint32 id = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			id = info->header.v1.id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return id;
 }
 
 guint64
 msn_p2p_info_get_offset(MsnP2PInfo *info)
 {
-	return info->header.offset;
+	guint64 offset = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			offset = info->header.v1.offset;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return offset;
 }
 
 guint64
 msn_p2p_info_get_total_size(MsnP2PInfo *info)
 {
-	return info->header.total_size;
+	guint64 total_size = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			total_size = info->header.v1.total_size;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return total_size;
 }
 
 guint32
 msn_p2p_info_get_length(MsnP2PInfo *info)
 {
-	return info->header.length;
+	guint32 length = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			length = info->header.v1.length;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return length;
 }
 
 guint32
 msn_p2p_info_get_flags(MsnP2PInfo *info)
 {
-	return info->header.flags;
+	guint32 flags = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			flags = info->header.v1.flags;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return flags;
 }
 
 guint32
 msn_p2p_info_get_ack_id(MsnP2PInfo *info)
 {
-	return info->header.ack_id;
+	guint32 ack_id = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			ack_id = info->header.v1.ack_id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return ack_id;
 }
 
 guint32
 msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info)
 {
-	return info->header.ack_sub_id;
+	guint32 ack_sub_id = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			ack_sub_id = info->header.v1.ack_sub_id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return ack_sub_id;
 }
 
 guint64
 msn_p2p_info_get_ack_size(MsnP2PInfo *info)
 {
-	return info->header.ack_size;
+	guint64 ack_size = 0;
+
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			ack_size = info->header.v1.ack_size;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
+	return ack_size;
 }
 
 guint32
@@ -222,55 +469,156 @@
 void
 msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id)
 {
-	info->header.session_id = session_id;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.session_id = session_id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
 }
 
 void
 msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id)
 {
-	info->header.id = id;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.id = id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
+
 }
 
 void
 msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset)
 {
-	info->header.offset = offset;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.offset = offset;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 }
 
 void
 msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size)
 {
-	info->header.total_size = total_size;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.total_size = total_size;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 }
 
 void
 msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length)
 {
-	info->header.length = length;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.length = length;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 }
 
 void
 msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags)
 {
-	info->header.flags = flags;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.flags = flags;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 }
 
 void
 msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id)
 {
-	info->header.ack_id = ack_id;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.ack_id = ack_id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 }
 
 void
 msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id)
 {
-	info->header.ack_sub_id = ack_sub_id;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.ack_sub_id = ack_sub_id;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 }
 
 void
 msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size)
 {
-	info->header.ack_size = ack_size;
+	switch (info->version) {
+		case MSN_P2P_VERSION_ONE:
+			info->header.v1.ack_size = ack_size;
+			break;
+
+		case MSN_P2P_VERSION_TWO:
+			/* Nothing to do! */
+			break;
+
+		default:
+			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
+	}
 }
 
 void
--- a/libpurple/protocols/msn/p2p.h	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/p2p.h	Tue Mar 01 06:24:50 2011 +0000
@@ -58,8 +58,18 @@
 } MsnP2PFooter;
 #define P2P_PACKET_FOOTER_SIZE (1 * 4)
 
+typedef enum
+{
+	MSN_P2P_VERSION_ONE = 0,
+	MSN_P2P_VERSION_TWO = 1,
+} MsnP2PVersion;
+
 typedef struct {
-	MsnP2PHeader header;
+	MsnP2PVersion version;
+	union {
+		MsnP2PHeader v1;
+		MsnP2Pv2Header v2;
+	} header;
 	MsnP2PFooter footer;
 } MsnP2PInfo;
 
@@ -94,7 +104,7 @@
 } MsnP2PAppId;
 
 MsnP2PInfo *
-msn_p2p_info_new(void);
+msn_p2p_info_new(MsnP2PVersion version);
 
 MsnP2PInfo *
 msn_p2p_info_dup(MsnP2PInfo *info);
--- a/libpurple/protocols/msn/slpmsg.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg.c	Tue Mar 01 06:24:50 2011 +0000
@@ -48,7 +48,7 @@
 	else
 		slpmsg->slplink = NULL;
 
-	slpmsg->p2p_info = msn_p2p_info_new();
+	slpmsg->p2p_info = msn_p2p_info_new(MSN_P2P_VERSION_ONE);
 
 	return slpmsg;
 }
--- a/libpurple/protocols/msn/slpmsg_part.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg_part.c	Tue Mar 01 06:24:50 2011 +0000
@@ -54,7 +54,7 @@
 	}
 
 	part = msn_slpmsgpart_new(NULL);
-	part->info = msn_p2p_info_new();
+	part->info = msn_p2p_info_new(MSN_P2P_VERSION_ONE);
 
 	/* Extract the binary SLP header */
 	len = msn_p2p_header_from_wire(part->info, data);
--- a/libpurple/protocols/msn/switchboard.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/switchboard.c	Tue Mar 01 06:24:50 2011 +0000
@@ -265,12 +265,6 @@
 		return;
 	}
 
-	/* Don't add ourselves either... */
-	if (g_str_equal(passport, purple_account_get_username(account))) {
-		g_free(passport);
-		return;
-	}
-
 	if (!msnuser) {
 		purple_debug_info("msn","User %s is not on our list.\n", passport);
 		msnuser = msn_user_new(userlist, passport, NULL);
--- a/libpurple/protocols/msn/user.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/libpurple/protocols/msn/user.c	Tue Mar 01 06:24:50 2011 +0000
@@ -223,7 +223,10 @@
 {
 	g_return_val_if_fail(user != NULL, FALSE);
 
-	if (user->friendly_name && name && (!strcmp(user->friendly_name, name) ||
+	if (!name)
+		return FALSE;
+
+	if (user->friendly_name && (!strcmp(user->friendly_name, name) ||
 				!strcmp(user->passport, name)))
 		return FALSE;
 
--- a/pidgin/gtkblist.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/pidgin/gtkblist.c	Tue Mar 01 06:24:50 2011 +0000
@@ -7743,7 +7743,7 @@
 		gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
 		return;
 	} else {
-		sort_method_none(node, blist, groupiter, cur, iter);
+		sort_method_alphabetical(node, blist, groupiter, cur, iter);
 		return;
 	}
 
--- a/pidgin/gtkdocklet-gtk.c	Mon Feb 28 09:19:34 2011 +0000
+++ b/pidgin/gtkdocklet-gtk.c	Tue Mar 01 06:24:50 2011 +0000
@@ -47,19 +47,37 @@
 static gboolean
 docklet_gtk_embed_timeout_cb(gpointer data)
 {
-	/* The docklet was not embedded within the timeout.
-	 * Remove it as a visibility manager, but leave the plugin
-	 * loaded so that it can embed automatically if/when a notification
-	 * area becomes available.
-	 */
-	purple_debug_info("docklet", "failed to embed within timeout\n");
-	pidgin_docklet_remove();
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+#if !GTK_CHECK_VERSION(2,12,0)
+	if (gtk_status_icon_is_embedded(docklet)) {
+		/* Older GTK+ (<2.12) don't implement the embedded signal, but the
+		   information is still accessable through the above function. */
+		purple_debug_info("docklet", "embedded\n");
 
+		pidgin_docklet_embedded();
+		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+	}
+	else
+#endif
+	{
+		/* The docklet was not embedded within the timeout.
+		 * Remove it as a visibility manager, but leave the plugin
+		 * loaded so that it can embed automatically if/when a notification
+		 * area becomes available.
+		 */
+		purple_debug_info("docklet", "failed to embed within timeout\n");
+		pidgin_docklet_remove();
+		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+	}
+
+#if GTK_CHECK_VERSION(2,12,0)
 	embed_timeout = 0;
 	return FALSE;
+#else
+	return TRUE;
+#endif
 }
 
+#if GTK_CHECK_VERSION(2,12,0)
 static gboolean
 docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data)
 {
@@ -82,6 +100,7 @@
 
 	return TRUE;
 }
+#endif
 
 static void
 docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data)
@@ -206,7 +225,9 @@
 
 	g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL);
 	g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL);
+#if GTK_CHECK_VERSION(2,12,0)
 	g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL);
+#endif
 	g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
 
 	gtk_status_icon_set_visible(docklet, TRUE);
@@ -226,11 +247,15 @@
 	 */
 	if (!recreate) {
 		pidgin_docklet_embedded();
+#if GTK_CHECK_VERSION(2,12,0)
 		if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) {
 			embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
 		} else {
 			embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
 		}
+#else
+		embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+#endif
 	}
 
 	purple_debug_info("docklet", "GTK+ created\n");