changeset 29239:02bc1e883f05

merged with im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Wed, 06 Jan 2010 22:51:29 +0900
parents 39bc284215ce (current diff) 82bc5679ef95 (diff)
children 520e920df676
files libpurple/protocols/msn/msn.c pidgin/gtkconv.c
diffstat 35 files changed, 300 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri Dec 25 19:25:22 2009 +0900
+++ b/COPYRIGHT	Wed Jan 06 22:51:29 2010 +0900
@@ -154,6 +154,7 @@
 David Fiander
 Rob Flynn <gaim@robflynn.com>
 Rob Foehl (rwf)
+Chris Foote
 Alan Ford
 Nathan Fredrickson
 Chris J. Friesen
--- a/ChangeLog	Fri Dec 25 19:25:22 2009 +0900
+++ b/ChangeLog	Wed Jan 06 22:51:29 2010 +0900
@@ -12,6 +12,10 @@
 	* Messages from some mobile clients are no longer displayed as
 	  Chinese characters (broken in 2.6.4)
 
+	Gadu-Gadu:
+	* Fix display of avatars after a server-side change. (Krzysztof
+	  Klinikowski)
+
 	MSN:
 	* File transfer requests will no longer cause a crash if you delete the
 	  file before the other side accepts.
@@ -19,6 +23,7 @@
 	  meaning they can be moved or deleted without complaints from your OS.
 	* Buddies who sign in from a second location will no longer cause an
 	  unnecessary chat window to open.
+	* Support setting an animated GIF as a buddy icon.
 
 	XMPP:
 	* Added support for the SCRAM-SHA-1 SASL mechanism.  This is only
--- a/ChangeLog.API	Fri Dec 25 19:25:22 2009 +0900
+++ b/ChangeLog.API	Wed Jan 06 22:51:29 2010 +0900
@@ -7,6 +7,13 @@
 		  purple_xfer_request_denied if an error is found when selecting
 		  a file to send. Request denied is still used when a receive
 		  request is not allowed.
+	Perl:
+		Changed:
+		* Corrected the package names for the PurpleProxyType and
+		  PurpleLogReadFlags enums to have the correct number of colons
+		  (from Purple::ProxyType::::<type> to Purple::ProxyType::<type>
+		  and Purple::Log:ReadFlags::::<type> to
+		  Purple::Log::ReadFlags::<type>)  (Chris Foote)
 
 version 2.6.4 (11/29/2009):
 	No changes
--- a/finch/gntidle.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/gntidle.c	Wed Jan 06 22:51:29 2010 +0900
@@ -21,6 +21,8 @@
  *
  */
 
+#include <internal.h>
+
 #include "finch.h"
 #include "gntidle.h"
 #include "gntwm.h"
--- a/finch/gntrequest.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/gntrequest.c	Wed Jan 06 22:51:29 2010 +0900
@@ -23,6 +23,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+#include <internal.h>
+
 #include <gnt.h>
 #include <gntbox.h>
 #include <gntbutton.h>
@@ -35,7 +37,6 @@
 #include <gnttree.h>
 
 #include "finch.h"
-#include <internal.h>
 #include "gntrequest.h"
 #include "debug.h"
 #include "util.h"
--- a/finch/gntstatus.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/gntstatus.c	Wed Jan 06 22:51:29 2010 +0900
@@ -23,6 +23,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+#include <internal.h>
+
 #include <gnt.h>
 #include <gntbox.h>
 #include <gntbutton.h>
@@ -34,7 +36,6 @@
 #include <gntutils.h>
 
 #include "finch.h"
-#include <internal.h>
 
 #include <notify.h>
 #include <request.h>
--- a/finch/libgnt/gntinternal.h	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntinternal.h	Wed Jan 06 22:51:29 2010 +0900
@@ -32,6 +32,14 @@
 # define gnt_warning g_warning
 #endif
 
+#ifndef G_GNUC_NULL_TERMINATED
+#	if defined(__GNUC__) && __GNUC__ >= 4
+#		define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
+#	else
+#		define G_GNUC_NULL_TERMINATED
+#	endif
+#endif
+
 extern int gnt_need_conversation_to_locale;
 extern const char *C_(const char *x);
 
--- a/finch/libgnt/gntline.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntline.c	Wed Jan 06 22:51:29 2010 +0900
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
 #include "gntline.h"
 
 enum
--- a/finch/libgnt/gntmenuitem.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntmenuitem.c	Wed Jan 06 22:51:29 2010 +0900
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
 #include "gntmenu.h"
 #include "gntmenuitem.h"
 
--- a/finch/libgnt/gntmenuitemcheck.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntmenuitemcheck.c	Wed Jan 06 22:51:29 2010 +0900
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
 #include "gntmenuitemcheck.h"
 
 static GntMenuItemClass *parent_class = NULL;
--- a/finch/libgnt/gntprogressbar.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntprogressbar.c	Wed Jan 06 22:51:29 2010 +0900
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  **/
 
+#include "gntinternal.h"
 #include "gntprogressbar.h"
 #include "gntutils.h"
 
--- a/finch/libgnt/gntslider.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntslider.c	Wed Jan 06 22:51:29 2010 +0900
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
 #include "gntcolors.h"
 #include "gntkeys.h"
 #include "gntslider.h"
--- a/finch/libgnt/gntwidget.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntwidget.c	Wed Jan 06 22:51:29 2010 +0900
@@ -22,6 +22,7 @@
 
 /* Stuff brutally ripped from Gflib */
 
+#include "gntinternal.h"
 #include "gntwidget.h"
 #include "gntstyle.h"
 #include "gntmarshal.h"
--- a/finch/libgnt/gntwindow.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/gntwindow.c	Wed Jan 06 22:51:29 2010 +0900
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "gntinternal.h"
 #include "gntstyle.h"
 #include "gntwindow.h"
 
--- a/finch/libgnt/wms/irssi.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/finch/libgnt/wms/irssi.c	Wed Jan 06 22:51:29 2010 +0900
@@ -33,6 +33,8 @@
 #include <string.h>
 #include <sys/types.h>
 
+#include "gntinternal.h"
+
 #include "gnt.h"
 #include "gntbox.h"
 #include "gntmenu.h"
--- a/libpurple/account.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/account.c	Wed Jan 06 22:51:29 2010 +0900
@@ -1341,7 +1341,8 @@
 
 	handles = g_list_remove(handles, info);
 
-	info->auth_cb(info->userdata);
+	if (info->auth_cb != NULL)
+		info->auth_cb(info->userdata);
 
 	purple_signal_emit(purple_accounts_get_handle(),
 			"account-authorization-granted", info->account, info->user);
@@ -1356,7 +1357,8 @@
 
 	handles = g_list_remove(handles, info);
 
-	info->deny_cb(info->userdata);
+	if (info->deny_cb != NULL)
+		info->deny_cb(info->userdata);
 
 	purple_signal_emit(purple_accounts_get_handle(),
 			"account-authorization-denied", info->account, info->user);
@@ -1383,10 +1385,12 @@
 				"account-authorization-requested", account, remote_user));
 
 	if (plugin_return > 0) {
-		auth_cb(user_data);
+		if (auth_cb != NULL)
+			auth_cb(user_data);
 		return NULL;
 	} else if (plugin_return < 0) {
-		deny_cb(user_data);
+		if (deny_cb != NULL)
+			deny_cb(user_data);
 		return NULL;
 	}
 
@@ -2311,7 +2315,7 @@
 
 	gc = purple_account_get_connection(account);
 	if (gc != NULL)
-	        prpl = purple_connection_get_prpl(gc);
+		prpl = purple_connection_get_prpl(gc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
@@ -2328,7 +2332,7 @@
 	PurplePlugin *prpl = NULL;
 
 	if (gc != NULL)
-	        prpl = purple_connection_get_prpl(gc);
+		prpl = purple_connection_get_prpl(gc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
@@ -2367,7 +2371,7 @@
 	PurplePlugin *prpl = NULL;
 
 	if (gc != NULL)
-	        prpl = purple_connection_get_prpl(gc);
+		prpl = purple_connection_get_prpl(gc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
@@ -2384,7 +2388,7 @@
 	PurplePlugin *prpl = NULL;
 
 	if (gc != NULL)
-	        prpl = purple_connection_get_prpl(gc);
+		prpl = purple_connection_get_prpl(gc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
@@ -2412,7 +2416,7 @@
 	PurplePlugin *prpl = NULL;
 
 	if (gc != NULL)
-	        prpl = purple_connection_get_prpl(gc);
+		prpl = purple_connection_get_prpl(gc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
@@ -2432,7 +2436,7 @@
 	purple_account_set_password(account, new_pw);
 
 	if (gc != NULL)
-	        prpl = purple_connection_get_prpl(gc);
+		prpl = purple_connection_get_prpl(gc);
 
 	if (prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
--- a/libpurple/conversation.h	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/conversation.h	Wed Jan 06 22:51:29 2010 +0900
@@ -368,7 +368,8 @@
  * @param type    The type of conversation.
  * @param account The account opening the conversation window on the purple
  *                user's end.
- * @param name    The name of the conversation.
+ * @param name    The name of the conversation.  For PURPLE_CONV_TYPE_IM,
+ *                this is the name of the buddy.
  *
  * @return The new conversation.
  */
--- a/libpurple/dbus-server.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/dbus-server.c	Wed Jan 06 22:51:29 2010 +0900
@@ -601,7 +601,6 @@
 {
 	static DBusObjectPathVTable vtable = {NULL, &purple_dbus_dispatch, NULL, NULL, NULL, NULL};
 	DBusError error;
-	int result;
 
 	dbus_error_init(&error);
 	purple_dbus_connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
@@ -625,16 +624,15 @@
 		return;
 	}
 
-	dbus_request_name_reply =
-	result = dbus_bus_request_name(purple_dbus_connection,
+	dbus_request_name_reply = dbus_bus_request_name(purple_dbus_connection,
 			DBUS_SERVICE_PURPLE, 0, &error);
 
 	if (dbus_error_is_set(&error))
 	{
 		dbus_connection_unref(purple_dbus_connection);
-		dbus_error_free(&error);
 		purple_dbus_connection = NULL;
 		init_error = g_strdup_printf(N_("Failed to get serv name: %s"), error.name);
+		dbus_error_free(&error);
 		return;
 	}
 
--- a/libpurple/ft.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/ft.c	Wed Jan 06 22:51:29 2010 +0900
@@ -69,6 +69,30 @@
 	g_free(priv);
 }
 
+static const gchar *
+purple_xfer_status_type_to_string(PurpleXferStatusType type)
+{
+	static const struct {
+		PurpleXferStatusType type;
+		const char *name;
+	} type_names[] = {
+		{ PURPLE_XFER_STATUS_UNKNOWN, "unknown" },
+		{ PURPLE_XFER_STATUS_NOT_STARTED, "not started" },
+		{ PURPLE_XFER_STATUS_ACCEPTED, "accepted" },
+		{ PURPLE_XFER_STATUS_STARTED, "started" },
+		{ PURPLE_XFER_STATUS_DONE, "done" },
+		{ PURPLE_XFER_STATUS_CANCEL_LOCAL, "cancelled locally" },
+		{ PURPLE_XFER_STATUS_CANCEL_REMOTE, "cancelled remotely" }
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS(type_names); ++i)
+		if (type_names[i].type == type)
+			return type_names[i].name;
+
+	return "invalid state";
+}
+
 GList *
 purple_xfers_get_all()
 {
@@ -180,6 +204,11 @@
 {
 	g_return_if_fail(xfer != NULL);
 
+	if (purple_debug_is_verbose())
+		purple_debug_info("xfer", "Changing status of xfer %p from %s to %s\n",
+				xfer, purple_xfer_status_type_to_string(xfer->status),
+				purple_xfer_status_type_to_string(status));
+
 	if (xfer->status == status)
 		return;
 
@@ -539,6 +568,8 @@
 	type = purple_xfer_get_type(xfer);
 	account = purple_xfer_get_account(xfer);
 
+	purple_debug_misc("xfer", "request accepted for %p\n", xfer); 
+
 	if (!filename && type == PURPLE_XFER_RECEIVE) {
 		xfer->status = PURPLE_XFER_STATUS_ACCEPTED;
 		xfer->ops.init(xfer);
@@ -616,6 +647,8 @@
 {
 	g_return_if_fail(xfer != NULL);
 
+	purple_debug_misc("xfer", "xfer %p denied\n", xfer);
+
 	if (xfer->ops.request_denied != NULL)
 		xfer->ops.request_denied(xfer);
 
@@ -1144,6 +1177,8 @@
 
 			purple_input_remove(xfer->watcher);
 			xfer->watcher = 0;
+
+			purple_debug_misc("xfer", "prpl is ready on ft %p, waiting for UI\n", xfer);
 			return;
 		}
 	}
@@ -1206,8 +1241,12 @@
 	priv = g_hash_table_lookup(xfers_data, xfer);
 	priv->ready |= PURPLE_XFER_READY_UI;
 
-	if (0 == (priv->ready & PURPLE_XFER_READY_PRPL))
+	if (0 == (priv->ready & PURPLE_XFER_READY_PRPL)) {
+		purple_debug_misc("xfer", "UI is ready on ft %p, waiting for prpl\n", xfer);
 		return;
+	}
+
+	purple_debug_misc("xfer", "UI (and prpl) ready on ft %p, so proceeding\n", xfer);
 
 	type = purple_xfer_get_type(xfer);
 	if (type == PURPLE_XFER_SEND)
@@ -1234,8 +1273,12 @@
 	priv->ready |= PURPLE_XFER_READY_PRPL;
 
 	/* I don't think fwrite/fread are ever *not* ready */
-	if (xfer->dest_fp == NULL && 0 == (priv->ready & PURPLE_XFER_READY_UI))
+	if (xfer->dest_fp == NULL && 0 == (priv->ready & PURPLE_XFER_READY_UI)) {
+		purple_debug_misc("xfer", "prpl is ready on ft %p, waiting for UI\n", xfer);
 		return;
+	}
+
+	purple_debug_misc("xfer", "Prpl (and UI) ready on ft %p, so proceeding\n", xfer);
 
 	priv->ready = PURPLE_XFER_READY_NONE;
 
--- a/libpurple/media.h	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/media.h	Wed Jan 06 22:51:29 2010 +0900
@@ -75,7 +75,7 @@
 	PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION = 1 << 3,
 	PURPLE_MEDIA_CAPS_AUDIO_VIDEO = 1 << 4,
 	PURPLE_MEDIA_CAPS_MODIFY_SESSION = 1 << 5,
-	PURPLE_MEDIA_CAPS_CHANGE_DIRECTION = 1 << 6,
+	PURPLE_MEDIA_CAPS_CHANGE_DIRECTION = 1 << 6
 } PurpleMediaCaps;
 
 /** Media session types */
@@ -93,7 +93,7 @@
 typedef enum {
 	PURPLE_MEDIA_STATE_NEW = 0,
 	PURPLE_MEDIA_STATE_CONNECTED,
-	PURPLE_MEDIA_STATE_END,
+	PURPLE_MEDIA_STATE_END
 } PurpleMediaState;
 
 /** Media info types */
@@ -106,7 +106,7 @@
 	PURPLE_MEDIA_INFO_PAUSE,
 	PURPLE_MEDIA_INFO_UNPAUSE,
 	PURPLE_MEDIA_INFO_HOLD,
-	PURPLE_MEDIA_INFO_UNHOLD,
+	PURPLE_MEDIA_INFO_UNHOLD
 } PurpleMediaInfoType;
 
 typedef enum {
@@ -114,18 +114,18 @@
 	PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX,
 	PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX,
 	PURPLE_MEDIA_CANDIDATE_TYPE_RELAY,
-	PURPLE_MEDIA_CANDIDATE_TYPE_MULTICAST,
+	PURPLE_MEDIA_CANDIDATE_TYPE_MULTICAST
 } PurpleMediaCandidateType;
 
 typedef enum {
 	PURPLE_MEDIA_COMPONENT_NONE = 0,
 	PURPLE_MEDIA_COMPONENT_RTP = 1,
-	PURPLE_MEDIA_COMPONENT_RTCP = 2,
+	PURPLE_MEDIA_COMPONENT_RTCP = 2
 } PurpleMediaComponentType;
 
 typedef enum {
 	PURPLE_MEDIA_NETWORK_PROTOCOL_UDP,
-	PURPLE_MEDIA_NETWORK_PROTOCOL_TCP,
+	PURPLE_MEDIA_NETWORK_PROTOCOL_TCP
 } PurpleMediaNetworkProtocol;
 
 #include "signals.h"
--- a/libpurple/plugins/perl/common/Log.xs	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/plugins/perl/common/Log.xs	Wed Jan 06 22:51:29 2010 +0900
@@ -6,7 +6,7 @@
 BOOT:
 {
 	HV *type_stash = gv_stashpv("Purple::Log::Type", 1);
-	HV *flags_stash = gv_stashpv("Purple::Log:ReadFlags::", 1);
+	HV *flags_stash = gv_stashpv("Purple::Log::ReadFlags", 1);
 
 	static const constiv *civ, type_const_iv[] = {
 #define const_iv(name) {#name, (IV)PURPLE_LOG_##name}
--- a/libpurple/plugins/perl/common/Proxy.xs	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/plugins/perl/common/Proxy.xs	Wed Jan 06 22:51:29 2010 +0900
@@ -5,7 +5,7 @@
 
 BOOT:
 {
-	HV *stash = gv_stashpv("Purple::ProxyType::", 1);
+	HV *stash = gv_stashpv("Purple::ProxyType", 1);
 
 	static const constiv *civ, const_iv[] = {
 #define const_iv(name) {#name, (IV)PURPLE_PROXY_##name}
--- a/libpurple/plugins/signals-test.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/plugins/signals-test.c	Wed Jan 06 22:51:29 2010 +0900
@@ -547,6 +547,26 @@
 	purple_debug_misc("signals test", "quitting ()\n");
 }
 
+static void
+printhash(gpointer key, gpointer value, gpointer data)
+{
+	char *a = (char *)key;
+	char *b = (char *)value;
+	GString *str = (GString *)data;
+	g_string_append_printf(str, "   [%s] = [%s]\n", a, b ? b : "(null)");
+}
+
+static gboolean
+uri_handler(const char *proto, const char *cmd, GHashTable *params)
+{
+	GString *str = g_string_new("\n{\n");
+	g_hash_table_foreach(params, printhash, str);
+	g_string_append_c(str, '}');
+	purple_debug_misc("signals test", "uri handler (%s, %s, %s)\n", proto, cmd, str->str);
+	g_string_free(str, TRUE);
+	return FALSE;
+}
+
 /**************************************************************************
  * File transfer signal callbacks
  **************************************************************************/
@@ -820,6 +840,8 @@
 	/* Core signals */
 	purple_signal_connect(core_handle, "quitting",
 						plugin, PURPLE_CALLBACK(quitting_cb), NULL);
+	purple_signal_connect(core_handle, "uri-handler",
+						plugin,	PURPLE_CALLBACK(uri_handler), NULL);
 
 	/* File transfer signals */
 	purple_signal_connect(ft_handle, "file-recv-accept",
--- a/libpurple/protocols/bonjour/bonjour.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/bonjour/bonjour.c	Wed Jan 06 22:51:29 2010 +0900
@@ -392,11 +392,8 @@
 		purple_notify_user_info_add_pair(user_info, _("XMPP Account"), bb->jid);
 }
 
-static void
-bonjour_group_buddy(PurpleConnection *connection, const char *who, const char *old_group, const char *new_group)
-{
+static void bonjour_do_group_change(PurpleBuddy *buddy, const char *new_group) {
 	PurpleBlistNodeFlags oldflags;
-	PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
 
 	if (buddy == NULL)
 		return;
@@ -404,13 +401,38 @@
 	oldflags = purple_blist_node_get_flags((PurpleBlistNode *)buddy);
 
 	/* If we're moving them out of the bonjour group, make them persistent */
-	if (strcmp(new_group, BONJOUR_GROUP_NAME) == 0)
+	if (purple_strequal(new_group, BONJOUR_GROUP_NAME))
 		purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags | PURPLE_BLIST_NODE_FLAG_NO_SAVE);
 	else
 		purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags ^ PURPLE_BLIST_NODE_FLAG_NO_SAVE);
 
 }
 
+static void
+bonjour_group_buddy(PurpleConnection *connection, const char *who, const char *old_group, const char *new_group)
+{
+	PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
+
+	bonjour_do_group_change(buddy, new_group);
+
+}
+
+static void
+bonjour_rename_group(PurpleConnection *connection, const char *old_name, PurpleGroup *group, GList *moved_buddies)
+{
+	GList *cur;
+	const char *new_group;
+	PurpleBuddy *buddy;
+
+	new_group = purple_group_get_name(group);
+
+	for (cur = moved_buddies; cur; cur = cur->next) {
+		buddy = cur->data;
+		bonjour_do_group_change(buddy, new_group);
+	}
+
+}
+
 static gboolean
 bonjour_can_receive_file(PurpleConnection *connection, const char *who)
 {
@@ -478,7 +500,7 @@
 	NULL,                                                    /* get_cb_away */
 	NULL,                                                    /* alias_buddy */
 	bonjour_group_buddy,                                     /* group_buddy */
-	NULL,                                                    /* rename_group */
+	bonjour_rename_group,                                    /* rename_group */
 	NULL,                                                    /* buddy_free */
 	bonjour_convo_closed,                                    /* convo_closed */
 	NULL,                                                    /* normalize */
--- a/libpurple/protocols/gg/gg.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/gg/gg.c	Wed Jan 06 22:51:29 2010 +0900
@@ -947,7 +947,7 @@
 		if (xmlnode_avatar == NULL)
 			goto out;
 
-		xmlnode_bigavatar = xmlnode_get_child(xmlnode_avatar, "bigAvatar");
+		xmlnode_bigavatar = xmlnode_get_child(xmlnode_avatar, "originBigAvatar");
 		if (xmlnode_bigavatar == NULL)
 			goto out;
 
--- a/libpurple/protocols/jabber/buddy.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/jabber/buddy.c	Wed Jan 06 22:51:29 2010 +0900
@@ -823,7 +823,8 @@
 			const gchar *title = NULL;
 			if (is_domain) {
 				title = _("Uptime");
-				message = g_strdup_printf(_("%s"), last);
+				message = last;
+				last = NULL;
 			} else {
 				title = _("Logged Off");
 				message = g_strdup_printf(_("%s ago"), last);
--- a/libpurple/protocols/jabber/roster.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/jabber/roster.c	Wed Jan 06 22:51:29 2010 +0900
@@ -193,7 +193,9 @@
                          JabberIqType type, const char *id, xmlnode *query)
 {
 	xmlnode *item, *group;
+#if 0
 	const char *ver;
+#endif
 
 	if (!jabber_is_own_account(js, from)) {
 		purple_debug_warning("jabber", "Received bogon roster push from %s\n",
@@ -266,11 +268,13 @@
 		}
 	}
 
+#if 0
 	ver = xmlnode_get_attrib(query, "ver");
 	if (ver) {
 		 PurpleAccount *account = purple_connection_get_account(js->gc);
 		 purple_account_set_string(account, "roster_ver", ver);
 	}
+#endif
 
 	js->currently_parsing_roster_push = FALSE;
 }
--- a/libpurple/protocols/msn/msn.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/msn/msn.c	Wed Jan 06 22:51:29 2010 +0900
@@ -1569,6 +1569,8 @@
 {
 	const char *bname;
 	MsnAddReqData *data;
+	MsnSession *session;
+	MsnUser *user;
 
 	bname = purple_buddy_get_name(buddy);
 
@@ -1590,12 +1592,18 @@
 	data->buddy = buddy;
 	data->group = group;
 
-	purple_request_input(gc, NULL, _("Authorization Request Message:"),
-	                     NULL, _("Please authorize me!"), TRUE, FALSE, NULL,
-	                     _("_OK"), G_CALLBACK(finish_auth_request),
-	                     _("_Cancel"), G_CALLBACK(cancel_auth_request),
-	                     purple_connection_get_account(gc), bname, NULL,
-	                     data);
+	session = purple_connection_get_protocol_data(gc);
+	user = msn_userlist_find_user(session->userlist, bname);
+	if (user && user->authorized) {
+		finish_auth_request(data, NULL);
+	} else {
+		purple_request_input(gc, NULL, _("Authorization Request Message:"),
+		                     NULL, _("Please authorize me!"), TRUE, FALSE, NULL,
+		                     _("_OK"), G_CALLBACK(finish_auth_request),
+		                     _("_Cancel"), G_CALLBACK(cancel_auth_request),
+		                     purple_connection_get_account(gc), bname, NULL,
+		                     data);
+	}
 }
 
 static void
@@ -2691,7 +2699,7 @@
 	OPT_PROTO_MAIL_CHECK,
 	NULL,					/* user_splits */
 	NULL,					/* protocol_options */
-	{"png", 0, 0, 96, 96, 0, PURPLE_ICON_SCALE_SEND},	/* icon_spec */
+	{"png,gif", 0, 0, 96, 96, 0, PURPLE_ICON_SCALE_SEND},	/* icon_spec */
 	msn_list_icon,			/* list_icon */
 	msn_list_emblems,		/* list_emblems */
 	msn_status_text,		/* status_text */
--- a/libpurple/protocols/msn/slp.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/msn/slp.c	Wed Jan 06 22:51:29 2010 +0900
@@ -276,6 +276,38 @@
 	msn_slplink_queue_slpmsg(slplink, slpmsg);
 }
 
+/* XXX: this could be improved if we tracked custom smileys
+ * per-protocol, per-account, per-session or (ideally) per-conversation
+ */
+static PurpleStoredImage *
+find_valid_emoticon(PurpleAccount *account, const char *path)
+{
+	GList *smileys;
+
+	if (!purple_account_get_bool(account, "custom_smileys", TRUE))
+		return NULL;
+
+	smileys = purple_smileys_get_all();
+
+	for (; smileys; smileys = g_list_delete_link(smileys, smileys)) {
+		PurpleSmiley *smiley;
+		PurpleStoredImage *img;
+
+		smiley = smileys->data;
+		img = purple_smiley_get_stored_image(smiley);
+
+		if (purple_strequal(path, purple_imgstore_get_filename(img))) {
+			g_list_free(smileys);
+			return img;
+		}
+
+		purple_imgstore_unref(img);
+	}
+
+	purple_debug_error("msn", "Received illegal request for file %s\n", path);
+	return NULL;
+}
+
 #define MAX_FILE_NAME_LEN 0x226
 
 static void
@@ -293,7 +325,7 @@
 		MsnSlpMessage *slpmsg;
 		MsnObject *obj;
 		char *msnobj_data;
-		PurpleStoredImage *img;
+		PurpleStoredImage *img = NULL;
 		int type;
 
 		/* Send Ok */
@@ -312,50 +344,38 @@
 		type = msn_object_get_type(obj);
 		g_free(msnobj_data);
 
-		if ((type != MSN_OBJECT_USERTILE) && (type != MSN_OBJECT_EMOTICON))
-		{
-			purple_debug_error("msn", "Wrong object?\n");
-			msn_object_destroy(obj);
-			g_return_if_reached();
-		}
-
 		if (type == MSN_OBJECT_EMOTICON) {
-			char *path;
-			path = g_build_filename(purple_smileys_get_storing_dir(),
-					obj->location, NULL);
-			img = purple_imgstore_new_from_file(path);
-			g_free(path);
-		} else {
+			img = find_valid_emoticon(slplink->session->account, obj->location);
+		} else if (type == MSN_OBJECT_USERTILE) {
 			img = msn_object_get_image(obj);
 			if (img)
 				purple_imgstore_ref(img);
 		}
 		msn_object_destroy(obj);
 
-		if (img == NULL)
-		{
-			purple_debug_error("msn", "Wrong object.\n");
-			g_return_if_reached();
-		}
+		if (img != NULL) {
+			/* DATA PREP */
+			slpmsg = msn_slpmsg_new(slplink);
+			slpmsg->slpcall = slpcall;
+			slpmsg->session_id = slpcall->session_id;
+			msn_slpmsg_set_body(slpmsg, NULL, 4);
+			slpmsg->info = "SLP DATA PREP";
+			msn_slplink_queue_slpmsg(slplink, slpmsg);
 
-		/* DATA PREP */
-		slpmsg = msn_slpmsg_new(slplink);
-		slpmsg->slpcall = slpcall;
-		slpmsg->session_id = slpcall->session_id;
-		msn_slpmsg_set_body(slpmsg, NULL, 4);
-		slpmsg->info = "SLP DATA PREP";
-		msn_slplink_queue_slpmsg(slplink, slpmsg);
+			/* DATA */
+			slpmsg = msn_slpmsg_new(slplink);
+			slpmsg->slpcall = slpcall;
+			slpmsg->flags = 0x20;
+			slpmsg->info = "SLP DATA";
+			msn_slpmsg_set_image(slpmsg, img);
+			msn_slplink_queue_slpmsg(slplink, slpmsg);
+			purple_imgstore_unref(img);
 
-		/* DATA */
-		slpmsg = msn_slpmsg_new(slplink);
-		slpmsg->slpcall = slpcall;
-		slpmsg->flags = 0x20;
-		slpmsg->info = "SLP DATA";
-		msn_slpmsg_set_image(slpmsg, img);
-		msn_slplink_queue_slpmsg(slplink, slpmsg);
-		purple_imgstore_unref(img);
+			accepted = TRUE;
 
-		accepted = TRUE;
+		} else {
+			purple_debug_error("msn", "Wrong object.\n");
+		}
 	}
 
 	else if (!strcmp(euf_guid, MSN_FT_GUID))
--- a/libpurple/protocols/msn/slplink.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/msn/slplink.c	Wed Jan 06 22:51:29 2010 +0900
@@ -669,9 +669,8 @@
 #define MAX_FILE_NAME_LEN 0x226
 
 static gchar *
-gen_context(const char *file_name, const char *file_path)
+gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path)
 {
-	struct stat st;
 	gsize size = 0;
 	MsnContextHeader header;
 	gchar *u8 = NULL;
@@ -683,8 +682,7 @@
 	glong uni_len = 0;
 	gsize len;
 
-	if (g_stat(file_path, &st) == 0)
-		size = st.st_size;
+	size = purple_xfer_get_size(xfer);
 
 	if(!file_name) {
 		gchar *basename = g_path_get_basename(file_path);
@@ -761,7 +759,7 @@
 
 	xfer->data = slpcall;
 
-	context = gen_context(fn, fp);
+	context = gen_context(xfer, fn, fp);
 
 	msn_slpcall_invite(slpcall, MSN_FT_GUID, 2, context);
 
--- a/libpurple/protocols/msn/userlist.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/msn/userlist.c	Wed Jan 06 22:51:29 2010 +0900
@@ -210,6 +210,7 @@
 
 	if (list_op & MSN_LIST_PL_OP)
 	{
+		user->authorized = TRUE;
 		got_new_entry(gc, passport, store, message);
 	}
 }
--- a/libpurple/protocols/mxit/splashscreen.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/libpurple/protocols/mxit/splashscreen.c	Wed Jan 06 22:51:29 2010 +0900
@@ -24,7 +24,6 @@
  */
 
 #include "internal.h"
-#include <glib/gstdio.h>
 
 #include "purple.h"
 #include "imgstore.h"
--- a/pidgin/gtkconv.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/pidgin/gtkconv.c	Wed Jan 06 22:51:29 2010 +0900
@@ -5582,10 +5582,12 @@
 	}
 
 	/* Somebody wants to keep this conversation around, so don't time it out */
-	timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
-	if (timer) {
-		purple_timeout_remove(timer);
-		purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(0));
+	if (conv) {
+		timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
+		if (timer) {
+			purple_timeout_remove(timer);
+			purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(0));
+		}
 	}
 }
 
@@ -7751,16 +7753,24 @@
 	}
 }
 
+struct _status_timeout_user {
+	gchar *name;
+	PurpleAccount *account;
+};
+
 static gboolean
-update_buddy_status_timeout(PurpleBuddy *buddy)
+update_buddy_status_timeout(struct _status_timeout_user *user)
 {
 	/* To remove the signing-on/off door icon */
 	PurpleConversation *conv;
 
-	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, user->name, user->account);
 	if (conv)
 		pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON);
 
+	g_free(user->name);
+	g_free(user);
+
 	return FALSE;
 }
 
@@ -7769,6 +7779,7 @@
 {
 	PidginConversation *gtkconv;
 	PurpleConversation *conv;
+	struct _status_timeout_user *user;
 
 	gtkconv = get_gtkconv_with_contact(purple_buddy_get_contact(buddy));
 	if (gtkconv)
@@ -7781,8 +7792,12 @@
 			pidgin_conv_update_fields(conv, PIDGIN_CONV_MENU);
 	}
 
+	user = g_malloc(sizeof(struct _status_timeout_user));
+	user->name = g_strdup(buddy->name);
+	user->account = buddy->account;
+
 	/* In case a conversation is started after the buddy has signed-on/off */
-	purple_timeout_add_seconds(11, (GSourceFunc)update_buddy_status_timeout, buddy);
+	purple_timeout_add_seconds(11, (GSourceFunc)update_buddy_status_timeout, user);
 }
 
 static void
--- a/pidgin/gtklog.c	Fri Dec 25 19:25:22 2009 +0900
+++ b/pidgin/gtklog.c	Wed Jan 06 22:51:29 2010 +0900
@@ -423,6 +423,7 @@
 {
 	PidginLogViewer *viewer = data;
 	gtk_imhtml_search_find(GTK_IMHTML(viewer->imhtml), viewer->search);
+	g_object_steal_data(G_OBJECT(viewer->entry), "search-find-cb");
 	return FALSE;
 }
 
@@ -475,8 +476,11 @@
 	g_free(read);
 
 	if (viewer->search != NULL) {
+		guint source;
 		gtk_imhtml_search_clear(GTK_IMHTML(viewer->imhtml));
-		g_idle_add(search_find_cb, viewer);
+		source = g_idle_add(search_find_cb, viewer);
+		g_object_set_data_full(G_OBJECT(viewer->entry), "search-find-cb",
+		                       GINT_TO_POINTER(source), (GDestroyNotify)g_source_remove);
 	}
 
 	pidgin_clear_cursor(viewer->window);
--- a/po/de.po	Fri Dec 25 19:25:22 2009 +0900
+++ b/po/de.po	Wed Jan 06 22:51:29 2010 +0900
@@ -11,9 +11,9 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-12-10 22:38+0100\n"
-"PO-Revision-Date: 2009-12-11 20:55+0100\n"
-"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
+"POT-Creation-Date: 2010-01-06 09:43+0100\n"
+"PO-Revision-Date: 2010-01-06 09:39+0100\n"
+"Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -1960,6 +1960,9 @@
 msgstr ""
 "%s ist keine reguläre Datei. Pidgin wird die Datei nicht überschreiben.\n"
 
+msgid "File is not readable."
+msgstr "Datei ist nicht lesbar."
+
 #, c-format
 msgid "%s wants to send you %s (%s)"
 msgstr "%s möchte Ihnen %s (%s) senden"
@@ -3855,6 +3858,8 @@
 
 msgid "Server thinks authentication is complete, but client does not"
 msgstr ""
+"Der Server ist der Meinung, dass die Authentifizierung vollständig ist, der "
+"Client aber nicht"
 
 msgid "SASL authentication failed"
 msgstr "SASL-Authentifizierung fehlgeschlagen"
@@ -3865,19 +3870,17 @@
 
 #, fuzzy
 msgid "Unable to canonicalize username"
-msgstr "Kann nicht konfigurieren"
+msgstr "Benutzername konnte nicht in Normalform gebracht werden"
 
 #, fuzzy
 msgid "Unable to canonicalize password"
-msgstr "Es konnte kein lauschender Port geöffnet werden."
-
-#, fuzzy
+msgstr "Passwort konnte nicht in Normalform gebracht werden"
+
 msgid "Malicious challenge from server"
-msgstr "Ungültige Challenge vom Server"
-
-#, fuzzy
+msgstr "Bösartige Challenge vom Server"
+
 msgid "Unexpected response from server"
-msgstr "Ungültige HTTP-Antwort vom Server empfangen"
+msgstr "Unerwartete Antwort vom Server"
 
 msgid "The BOSH connection manager terminated your session."
 msgstr "Der BOSH-Verbindungsmanager hat Ihre Sitzung beendet."
@@ -3979,13 +3982,8 @@
 msgid "Resource"
 msgstr "Ressource"
 
-#, fuzzy
 msgid "Uptime"
-msgstr "Aktualisieren"
-
-#, c-format
-msgid "%s"
-msgstr ""
+msgstr "Betriebszeit"
 
 msgid "Logged Off"
 msgstr "Abgemeldet"
@@ -4186,13 +4184,6 @@
 msgid "Ping timed out"
 msgstr "Ping-Zeitüberschreitung"
 
-msgid ""
-"Unable to find alternative XMPP connection methods after failing to connect "
-"directly."
-msgstr ""
-"Nach dem Fehlschlagen einer direkten XMPP-Verbindung können keine "
-"alternativen Verbindungsmethoden gefunden werden."
-
 msgid "Invalid XMPP ID"
 msgstr "Ungültige XMPP-ID"
 
@@ -5168,6 +5159,10 @@
 msgid "Your new MSN friendly name is too long."
 msgstr "Ihr neuer MSN-Benutzername zu lang."
 
+#, c-format
+msgid "Set friendly name for %s."
+msgstr "Setze Spitznamen für %s."
+
 msgid "Set your friendly name."
 msgstr "Setze Ihren Spitznamen."
 
@@ -12103,9 +12098,6 @@
 msgid "Lao"
 msgstr "Laotisch"
 
-msgid "Lithuanian"
-msgstr "Litauisch"
-
 msgid "Macedonian"
 msgstr "Makedonisch"
 
@@ -12208,6 +12200,9 @@
 msgid "Amharic"
 msgstr "Amharisch"
 
+msgid "Lithuanian"
+msgstr "Litauisch"
+
 #, c-format
 msgid "About %s"
 msgstr "Über %s"
@@ -12250,7 +12245,19 @@
 "<br/>We can't help with 3rd party protocols or plugins!<br/>This list's "
 "primary language is <b>English</b>.  You are welcome to post in another "
 "language, but the responses may be less helpful.<br/><br/>"
-msgstr "<font size=\"4\">Hilfe von anderen Pidgin-Benutzern:</font> <a href=\"mailto:support@pidgin.im\">support@pidgin.im</a><br/>Dies ist eine <b>öffentliche</b> Mailing-Liste! (<a href=\"http://pidgin.im/pipermail/support/\">Archiv</a>)<br/>Wir können nicht bei Problemen mit Drittanbieter-Protokollen oder Plugins helfen!<br/>Die Hauptsprache dieser Liste ist <b>Englisch</b>.  Sie können gern in einer anderen Sprache schreiben, aber die Antworten könnten weniger hilfreich sein.<br/>Deutschsprachige Benutzer können auch das Portal <a href=\"http://www.pidgin-im.de/\">Pidgin-IM.de</a> nutzen.  Dort finden Sie aktuelle Informationen zu Pidgin, können mit anderen Benutzern im <a href=\"http://forum.pidgin-im.de/\">Forum</a> diskutieren und Hilfe zu Problemen finden.  Beachten Sie, dass dieses Portal unabhängig vom offiziellen Pidgin-Projekt ist.<br/><br/>"
+msgstr ""
+"<font size=\"4\">Hilfe von anderen Pidgin-Benutzern:</font> <a href=\"mailto:"
+"support@pidgin.im\">support@pidgin.im</a><br/>Dies ist eine <b>öffentliche</"
+"b> Mailing-Liste! (<a href=\"http://pidgin.im/pipermail/support/\">Archiv</"
+"a>)<br/>Wir können nicht bei Problemen mit Drittanbieter-Protokollen oder "
+"Plugins helfen!<br/>Die Hauptsprache dieser Liste ist <b>Englisch</b>.  Sie "
+"können gern in einer anderen Sprache schreiben, aber die Antworten könnten "
+"weniger hilfreich sein.<br/>Deutschsprachige Benutzer können auch das Portal "
+"<a href=\"http://www.pidgin-im.de/\">Pidgin-IM.de</a> nutzen.  Dort finden "
+"Sie aktuelle Informationen zu Pidgin, können mit anderen Benutzern im <a "
+"href=\"http://forum.pidgin-im.de/\">Forum</a> diskutieren und Hilfe zu "
+"Problemen finden.  Beachten Sie, dass dieses Portal unabhängig vom "
+"offiziellen Pidgin-Projekt ist.<br/><br/>"
 
 #, c-format
 msgid ""