changeset 22101:0b823f16162c

merge of '15b495a6774e316e3d7962181284bcf13b9ccffa' and 'faa1a78074f2f15f483ea8a41a79c2b0bcfe3279'
author Jeffrey Connelly <jaconnel@calpoly.edu>
date Mon, 14 Jan 2008 02:10:26 +0000
parents 1226083ed7e2 (current diff) 447167972ca3 (diff)
children e6e018d0bf03
files COPYRIGHT libpurple/protocols/myspace/myspace.h
diffstat 20 files changed, 321 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Mon Jan 14 02:06:47 2008 +0000
+++ b/COPYRIGHT	Mon Jan 14 02:10:26 2008 +0000
@@ -371,6 +371,7 @@
 Richard Stellingwerff
 Charlie Stockman
 David Stoddard
+Andreas Stührk
 Oleg Sukhodolsky
 Sun Microsystems
 Mårten Svantesson (fursten)
--- a/ChangeLog	Mon Jan 14 02:06:47 2008 +0000
+++ b/ChangeLog	Mon Jan 14 02:10:26 2008 +0000
@@ -23,14 +23,14 @@
 	Finch:
 	* Color is used in the buddylist to indicate status, and the conversation
 	  window to indicate various message attributes. Look at the sample gntrc
-	  file in the man-page for details.
+	  file in the man page for details.
 	* The default keybinding for dump-screen is now M-D and uses a file
 	  request dialog. M-d will properly delete-forward-word, and M-f has been
 	  fixed to imitate readline's behavior.
 	* New bindings alt+tab and alt+shift+tab to help navigating between the
-	  higlighted windows (details on the man-page).
+	  higlighted windows (details on the man page).
 	* Recently signed on (or off) buddies blink in the buddy list.
-	* New action 'Room List' in the action-list can be used to get the list of
+	* New action 'Room List' in the action list can be used to get the list of
 	  available chat rooms for an online account.
 
 version 2.3.1 (12/7/2007):
--- a/ChangeLog.API	Mon Jan 14 02:06:47 2008 +0000
+++ b/ChangeLog.API	Mon Jan 14 02:10:26 2008 +0000
@@ -18,6 +18,18 @@
 			* purple_roomlist_field_get_type
 			* purple_roomlist_field_get_label
 			* purple_roomlist_field_get_hidden
+		* unlocalized_name field in PurpleAttentionType for UIs that need it.
+		* Some accessor and mutator functions for PurpleAttentionType:
+			* purple_attention_type_set_name
+			* purple_attention_type_set_incoming_desc
+			* purple_attention_type_set_outgoing_desc
+			* purple_attention_type_set_icon_name
+			* purple_attention_type_set_unlocalized_name
+			* purple_attention_type_get_name
+			* purple_attention_type_get_incoming_desc
+			* purple_attention_type_get_outgoing_desc
+			* purple_attention_type_get_icon_name
+			* purple_attention_type_get_unlocalized_name
 
 	Pidgin:
 		Added:
--- a/libpurple/dbus-server.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/dbus-server.c	Mon Jan 14 02:10:26 2008 +0000
@@ -689,6 +689,7 @@
 		switch (purple_values[i]->type)
 		{
 		case PURPLE_TYPE_INT:
+		case PURPLE_TYPE_ENUM:
 			xint = my_arg(gint);
 			dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &xint);
 			break;
@@ -729,7 +730,7 @@
 			if (id == 0 && val != NULL)
 				error = TRUE;      /* Some error happened. */
 			dbus_message_iter_append_basic(iter,
-					(sizeof(void *) == 4) ? DBUS_TYPE_UINT32 : DBUS_TYPE_UINT64, &id);
+					(sizeof(id) == sizeof(dbus_int32_t)) ? DBUS_TYPE_INT32 : DBUS_TYPE_INT64, &id);
 			break;
 		default: /* no conversion implemented */
 			g_return_val_if_reached(TRUE);
--- a/libpurple/protocols/jabber/jabber.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Mon Jan 14 02:10:26 2008 +0000
@@ -2301,14 +2301,10 @@
 GList *jabber_attention_types(PurpleAccount *account)
 {
 	static GList *types = NULL;
-	PurpleAttentionType *attn;
 
 	if (!types) {
-		attn = g_new0(PurpleAttentionType, 1);
-		attn->name = _("Buzz");
-		attn->incoming_description = _("%s has buzzed you!");
-		attn->outgoing_description = _("Buzzing %s...");
-		types = g_list_append(types, attn);
+		types = g_list_append(types, purple_attention_type_new("Buzz", _("Buzz"),
+				_("%s has buzzed you!"), _("Buzzing %s...")));
 	}
 
 	return types;
--- a/libpurple/protocols/msn/msn.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/msn/msn.c	Mon Jan 14 02:10:26 2008 +0000
@@ -126,11 +126,8 @@
 	static GList *list = NULL;
 
 	if (!list) {
-		attn = g_new0(PurpleAttentionType, 1);
-		attn->name = _("Nudge");
-		attn->incoming_description = _("%s has nudged you!");
-		attn->outgoing_description = _("Nudging %s...");
-		list = g_list_append(list, attn);
+		list = g_list_append(list, purple_attention_type_new("Nudge", _("Nudge"),
+				_("%s has nudged you!"), _("Nudging %s...")));
 	}
 
 	return list;
--- a/libpurple/protocols/msnp9/msn.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/msnp9/msn.c	Mon Jan 14 02:10:26 2008 +0000
@@ -122,15 +122,11 @@
 static GList *
 msn_attention_types(PurpleAccount *account)
 {
-	PurpleAttentionType *attn;
 	static GList *list = NULL;
 
 	if (!list) {
-		attn = g_new0(PurpleAttentionType, 1);
-		attn->name = _("Nudge");
-		attn->incoming_description = _("%s has nudged you!");
-		attn->outgoing_description = _("Nudging %s...");
-		list = g_list_append(list, attn);
+		list = g_list_append(list, purple_attention_type_new("Nudge", _("Nudge"),
+				_("%s has nudged you!"), _("Nudging %s...")));
 	}
 
 	return list;
--- a/libpurple/protocols/myspace/myspace.h	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/myspace/myspace.h	Mon Jan 14 02:10:26 2008 +0000
@@ -180,8 +180,6 @@
 #define MSIM_CONTACT_LIST_IMPORT_ALL_FRIENDS	1
 #define MSIM_CONTACT_LIST_IMPORT_TOP_FRIENDS	2
 
-#define MsimAttentionType PurpleAttentionType
-
 /* Functions */
 gboolean msim_load(PurplePlugin *plugin);
 GList *msim_status_types(PurpleAccount *acct);
--- a/libpurple/protocols/myspace/zap.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/myspace/zap.c	Mon Jan 14 02:10:26 2008 +0000
@@ -29,15 +29,12 @@
 msim_attention_types(PurpleAccount *acct)
 {
 	static GList *types = NULL;
-	MsimAttentionType* attn;
+	PurpleAttentionType* attn;
 
 	if (!types) {
-#define _MSIM_ADD_NEW_ATTENTION(icn, nme, incoming, outgoing)              \
-		attn = g_new0(MsimAttentionType, 1);                       \
-		attn->icon_name = icn;                                     \
-		attn->name = nme;                                          \
-		attn->incoming_description = incoming;                     \
-		attn->outgoing_description = outgoing;                     \
+#define _MSIM_ADD_NEW_ATTENTION(icn, ulname, nme, incoming, outgoing) \
+		attn = purple_attention_type_new(ulname, nme, incoming, outgoing); \
+		purple_attention_type_set_icon_name(attn, icn); \
 		types = g_list_append(types, attn);
 
 		/* TODO: icons for each zap */
@@ -48,37 +45,46 @@
 		 * projectile or weapon."  This term often has an electrical
 		 * connotation, for example, "he was zapped by electricity when
 		 * he put a fork in the toaster." */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Zap"), _("%s has zapped you!"), _("Zapping %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Zap", _("Zap"), _("%s has zapped you!"),
+				_("Zapping %s..."));
 
 		/* Whack means "to hit or strike someone with a sharp blow" */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Whack"), _("%s has whacked you!"), _("Whacking %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Whack", _("Whack"),
+				_("%s has whacked you!"), _("Whacking %s..."));
 
 		/* Torch means "to set on fire."  Don't worry, this doesn't
 		 * make a whole lot of sense in English, either.  Feel free
 		 * to translate it literally. */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Torch"), _("%s has torched you!"), _("Torching %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Torch", _("Torch"),
+				_("%s has torched you!"), _("Torching %s..."));
 
 		/* Smooch means "to kiss someone, often enthusiastically" */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Smooch"), _("%s has smooched you!"), _("Smooching %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Smooch", _("Smooch"),
+				_("%s has smooched you!"), _("Smooching %s..."));
 
 		/* A hug is a display of affection; wrapping your arms around someone */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Hug"), _("%s has hugged you!"), _("Hugging %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Hug", _("Hug"), _("%s has hugged you!"),
+				_("Hugging %s..."));
 
 		/* Slap means "to hit someone with an open/flat hand" */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Slap"), _("%s has slapped you!"), _("Slapping %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Slap", _("Slap"),
+				_("%s has slapped you!"), _("Slapping %s..."));
 
 		/* Goose means "to pinch someone on their butt" */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Goose"), _("%s has goosed you!"), _("Goosing %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Goose", _("Goose"),
+				_("%s has goosed you!"), _("Goosing %s..."));
 
 		/* A high-five is when two people's hands slap each other
 		 * in the air above their heads.  It is done to celebrate
 		 * something, often a victory, or to congratulate someone. */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("High-five"), _("%s has high-fived you!"), _("High-fiving %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "High-five", _("High-five"),
+				_("%s has high-fived you!"), _("High-fiving %s..."));
 
 		/* We're not entirely sure what the MySpace people mean by
 		 * this... but we think it's the equivalent of "prank."  Or, for
 		 * someone to perform a mischievous trick or practical joke. */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Punk"), _("%s has punk'd you!"), _("Punking %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Punk", _("Punk"),
+				_("%s has punk'd you!"), _("Punking %s..."));
 
 		/* Raspberry is a slang term for the vibrating sound made
 		 * when you stick your tongue out of your mouth with your
@@ -87,7 +93,8 @@
 		 * gesture, so it does not carry a harsh negative
 		 * connotation.  It is generally used in a playful tone
 		 * with friends. */
-		_MSIM_ADD_NEW_ATTENTION(NULL, _("Raspberry"), _("%s has raspberried you!"), _("Raspberrying %s..."));
+		_MSIM_ADD_NEW_ATTENTION(NULL, "Raspberry", _("Raspberry"),
+				_("%s has raspberried you!"), _("Raspberrying %s..."));
 	}
 
 	return types;
@@ -99,14 +106,14 @@
 {
 	GList *types;
 	MsimSession *session;
-	MsimAttentionType *attn;
+	PurpleAttentionType *attn;
 	PurpleBuddy *buddy;
 
 	session = (MsimSession *)gc->proto_data;
 
 	/* Look for this attention type, by the code index given. */
 	types = msim_attention_types(gc->account);
-	attn = (MsimAttentionType *)g_list_nth_data(types, code);
+	attn = (PurpleAttentionType *)g_list_nth_data(types, code);
 
 	if (!attn) {
 		purple_debug_info("msim_send_attention", "got invalid zap code %d\n", code);
@@ -200,12 +207,12 @@
 	i = 0;
 	do
 	{
-		MsimAttentionType *attn;
+		PurpleAttentionType *attn;
 
-		attn = (MsimAttentionType *)types->data;
+		attn = (PurpleAttentionType *)types->data;
 
-		act = purple_menu_action_new(attn->name, PURPLE_CALLBACK(msim_send_zap_from_menu),
-				GUINT_TO_POINTER(i), NULL);
+		act = purple_menu_action_new(purple_attention_type_get_name(attn),
+				PURPLE_CALLBACK(msim_send_zap_from_menu), GUINT_TO_POINTER(i), NULL);
 		zap_menu = g_list_append(zap_menu, act);
 
 		++i;
--- a/libpurple/protocols/yahoo/yahoo.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Mon Jan 14 02:10:26 2008 +0000
@@ -4165,17 +4165,13 @@
 
 GList *yahoo_attention_types(PurpleAccount *account)
 {
-	PurpleAttentionType *attn;
 	static GList *list = NULL;
 
 	if (!list) {
 		/* Yahoo only supports one attention command: the 'buzz'. */
 		/* This is index number YAHOO_BUZZ. */
-		attn = g_new0(PurpleAttentionType, 1);
-		attn->name = _("Buzz");
-		attn->incoming_description = _("%s has buzzed you!");
-		attn->outgoing_description = _("Buzzing %s...");
-		list = g_list_append(list, attn);
+		list = g_list_append(list, purple_attention_type_new("Buzz", _("Buzz"),
+				_("%s has buzzed you!"), _("Buzzing %s...")));
 	}
 
 	return list;
--- a/libpurple/protocols/yahoo/yahoo.h	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo.h	Mon Jan 14 02:10:26 2008 +0000
@@ -48,6 +48,8 @@
 /*not sure, must test:*/
 #define YAHOOJP_XFER_RELAY_HOST "relay.msg.yahoo.com" 
 #define YAHOOJP_XFER_RELAY_PORT 80
+#define YAHOOJP_ROOMLIST_URL "http://insider.msg.yahoo.co.jp/ycontent/"
+#define YAHOOJP_ROOMLIST_LOCALE "ja"
 
 #define YAHOO_AUDIBLE_URL "http://us.dl1.yimg.com/download.yahoo.com/dl/aud"
 
--- a/libpurple/protocols/yahoo/yahoo_packet.h	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo_packet.h	Mon Jan 14 02:10:26 2008 +0000
@@ -101,7 +101,7 @@
 	YAHOO_SERVICE_AUTH_REQ_15 = 0xd6,
 	YAHOO_SERVICE_CHGRP_15 = 0xe7,
 	YAHOO_SERVICE_STATUS_15 = 0xf0,
-	YAHOO_SERVICE_LIST_15 = 0Xf1,
+	YAHOO_SERVICE_LIST_15 = 0xf1,
 	YAHOO_SERVICE_FILETRANS_15 = 0xdc,
 	YAHOO_SERVICE_FILETRANS_INFO_15 = 0xdd,
 	YAHOO_SERVICE_FILETRANS_ACC_15 = 0xde,
--- a/libpurple/protocols/yahoo/yahoochat.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Mon Jan 14 02:10:26 2008 +0000
@@ -1461,28 +1461,30 @@
 
 PurpleRoomlist *yahoo_roomlist_get_list(PurpleConnection *gc)
 {
-	struct yahoo_roomlist *yrl;
+	PurpleAccount *account;
 	PurpleRoomlist *rl;
-	const char *rll;
+	PurpleRoomlistField *f;
+	GList *fields = NULL;
+	struct yahoo_roomlist *yrl;
+	const char *rll, *rlurl;
 	char *url;
-	GList *fields = NULL;
-	PurpleRoomlistField *f;
 
-	rll = purple_account_get_string(purple_connection_get_account(gc),
-								  "room_list_locale", YAHOO_ROOMLIST_LOCALE);
+	account = purple_connection_get_account(gc);
 
-	if (rll != NULL && *rll != '\0') {
-		url = g_strdup_printf("%s?chatcat=0&intl=%s",
-	        purple_account_get_string(purple_connection_get_account(gc),
-	        "room_list", YAHOO_ROOMLIST_URL), rll);
-	} else {
-		url = g_strdup_printf("%s?chatcat=0",
-	        purple_account_get_string(purple_connection_get_account(gc),
-	        "room_list", YAHOO_ROOMLIST_URL));
+	/* for Yahoo Japan, it appears there is only one valid URL and locale */
+	if(purple_account_get_bool(account, "yahoojp", FALSE)) {
+		rll = YAHOOJP_ROOMLIST_LOCALE;
+		rlurl = YAHOOJP_ROOMLIST_URL;
+	}
+	else { /* but for the rest of the world that isn't the case */
+		rll = purple_account_get_string(account, "room_list_locale", YAHOO_ROOMLIST_LOCALE);
+		rlurl = purple_account_get_string(account, "room_list", YAHOO_ROOMLIST_URL);
 	}
 
+	url = g_strdup_printf("%s?chatcat=0&intl=%s", rlurl, rll);
+
 	yrl = g_new0(struct yahoo_roomlist, 1);
-	rl = purple_roomlist_new(purple_connection_get_account(gc));
+	rl = purple_roomlist_new(account);
 	yrl->list = rl;
 
 	purple_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL);
@@ -1508,7 +1510,7 @@
 
 	purple_roomlist_set_fields(rl, fields);
 
-	if (purple_proxy_connect(NULL, purple_connection_get_account(gc), yrl->host, 80,
+	if (purple_proxy_connect(NULL, account, yrl->host, 80,
 	                       yahoo_roomlist_got_connected, yrl) == NULL)
 	{
 		purple_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list."));
--- a/libpurple/prpl.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/prpl.c	Mon Jan 14 02:10:26 2008 +0000
@@ -29,6 +29,107 @@
 #include "util.h"
 
 /**************************************************************************/
+/** @name Attention Type API                                              */
+/**************************************************************************/
+PurpleAttentionType *
+purple_attention_type_new(const char *ulname, const char *name,
+						const char *inc_desc, const char *out_desc)
+{
+	PurpleAttentionType *attn = g_new0(PurpleAttentionType, 1);
+
+	purple_attention_type_set_name(attn, name);
+	purple_attention_type_set_incoming_desc(attn, inc_desc);
+	purple_attention_type_set_outgoing_desc(attn, out_desc);
+	purple_attention_type_set_unlocalized_name(attn, ulname);
+
+	return attn;
+}
+
+
+void
+purple_attention_type_set_name(PurpleAttentionType *type, const char *name)
+{
+	g_return_if_fail(type != NULL);
+
+	type->name = name;
+}
+
+void
+purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc)
+{
+	g_return_if_fail(type != NULL);
+
+	type->incoming_description = desc;
+}
+
+void
+purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc)
+{
+	g_return_if_fail(type != NULL);
+
+	type->outgoing_description = desc;
+}
+
+void
+purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name)
+{
+	g_return_if_fail(type != NULL);
+	
+	type->icon_name = name;
+}
+
+void
+purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname)
+{
+	g_return_if_fail(type != NULL);
+
+	type->unlocalized_name = ulname;
+}
+
+const char *
+purple_attention_type_get_name(PurpleAttentionType *type)
+{
+	g_return_val_if_fail(type != NULL, NULL);
+
+	return type->name;
+}
+
+const char *
+purple_attention_type_get_incoming_desc(PurpleAttentionType *type)
+{
+	g_return_val_if_fail(type != NULL, NULL);
+
+	return type->incoming_description;
+}
+
+const char *
+purple_attention_type_get_outgoing_desc(PurpleAttentionType *type)
+{
+	g_return_val_if_fail(type != NULL, NULL);
+
+	return type->outgoing_description;
+}
+
+const char *
+purple_attention_type_get_icon_name(PurpleAttentionType *type)
+{
+	g_return_val_if_fail(type != NULL, NULL);
+
+	if(type->icon_name == NULL || *(type->icon_name) == '\0')
+		return NULL;
+
+	return type->icon_name;
+}
+
+const char *
+purple_attention_type_get_unlocalized_name(PurpleAttentionType *type)
+{
+	g_return_val_if_fail(type != NULL, NULL);
+
+	return type->unlocalized_name;
+}
+
+/**************************************************************************/
 /** @name Protocol Plugin API  */
 /**************************************************************************/
 void
--- a/libpurple/prpl.h	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/prpl.h	Mon Jan 14 02:10:26 2008 +0000
@@ -99,9 +99,9 @@
 	const char *incoming_description;  /**< Shown when sent */
 	const char *outgoing_description;  /**< Shown when receied */
 	const char *icon_name;             /**< Icon to display (optional) */
+	const char *unlocalized_name;      /**< Unlocalized name for UIs needing it */
 
 	/* Reserved fields for future purposes */
-	gpointer _reserved1;
 	gpointer _reserved2;
 	gpointer _reserved3;
 	gpointer _reserved4;
@@ -412,6 +412,127 @@
 #endif
 
 /**************************************************************************/
+/** @name Attention Type API                                              */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Creates a new #PurpleAttentionType object and sets its mandatory parameters.
+ *
+ * @param ulname A non-localized string that can be used by UIs in need of such
+ *               non-localized strings.  This should be the same as @a name,
+ *               without localization.
+ * @param name A localized string that the UI may display for the event. This
+ *             should be the same string as @a ulname, with localization.
+ * @param inc_desc A localized description shown when the event is received.
+ * @param out_desc A localized description shown when the event is sent.
+ * @return A pointer to the new object.
+ * @since 2.4.0
+ */
+PurpleAttentionType *purple_attention_type_new(const char *ulname, const char *name,
+								const char *inc_desc, const char *out_desc);
+
+/**
+ * Sets the displayed name of the attention-demanding event.
+ *
+ * @param type The attention type.
+ * @param name The localized name that will be displayed by UIs. This should be
+ *             the same string given as the unlocalized name, but with
+ *             localization.
+ * @since 2.4.0
+ */
+void purple_attention_type_set_name(PurpleAttentionType *type, const char *name);
+
+/**
+ * Sets the description of the attention-demanding event shown in  conversations
+ * when the event is received.
+ *
+ * @param type The attention type.
+ * @param desc The localized description for incoming events.
+ * @since 2.4.0
+ */
+void purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc);
+
+/**
+ * Sets the description of the attention-demanding event shown in conversations
+ * when the event is sent.
+ *
+ * @param type The attention type.
+ * @param desc The localized description for outgoing events.
+ * @since 2.4.0
+ */
+void purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc);
+
+/**
+ * Sets the name of the icon to display for the attention event; this is optional.
+ *
+ * @param type The attention type.
+ * @param name The icon's name.
+ * @note Icons are optional for attention events.
+ * @since 2.4.0
+ */
+void purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name);
+
+/**
+ * Sets the unlocalized name of the attention event; some UIs may need this,
+ * thus it is required.
+ *
+ * @param type The attention type.
+ * @param ulname The unlocalized name.  This should be the same string given as
+ *               the localized name, but without localization.
+ * @since 2.4.0
+ */
+void purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname);
+
+/**
+ * Get the attention type's name as displayed by the UI.
+ *
+ * @param type The attention type.
+ * @return The name.
+ * @since 2.4.0
+ */
+const char *purple_attention_type_get_name(PurpleAttentionType *type);
+
+/**
+ * Get the attention type's description shown when the event is received.
+ *
+ * @param type The attention type.
+ * @return The description.
+ * @since 2.4.0
+ */
+const char *purple_attention_type_get_incoming_desc(PurpleAttentionType *type);
+
+/**
+ * Get the attention type's description shown when the event is sent.
+ *
+ * @param type The attention type.
+ * @return The description.
+ * @since 2.4.0
+ */
+const char *purple_attention_type_get_outgoing_desc(PurpleAttentionType *type);
+
+/**
+ * Get the attention type's icon name.
+ *
+ * @param type The attention type.
+ * @return The icon name or @c NULL if unset/empty.
+ * @note Icons are optional for attention events.
+ * @since 2.4.0
+ */
+const char *purple_attention_type_get_icon_name(PurpleAttentionType *type);
+
+/**
+ * Get the attention type's unlocalized name; this is useful for some UIs.
+ *
+ * @param type The attention type
+ * @return The unlocalized name.
+ * @since 2.4.0
+ */
+const char *purple_attention_type_get_unlocalized_name(PurpleAttentionType *type);
+
+/*@}*/
+
+/**************************************************************************/
 /** @name Protocol Plugin API                                             */
 /**************************************************************************/
 /*@{*/
--- a/libpurple/util.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/libpurple/util.c	Mon Jan 14 02:10:26 2008 +0000
@@ -4629,6 +4629,15 @@
 #endif /* !_WIN32 */
 }
 
+static void
+set_status_with_attrs(PurpleStatus *status, ...)
+{
+	va_list args;
+	va_start(args, status);
+	purple_status_set_active_with_attrs(status, TRUE, args);
+	va_end(args);
+}
+
 void purple_util_set_current_song(const char *title, const char *artist, const char *album)
 {
 	GList *list = purple_accounts_get_all();
@@ -4644,10 +4653,11 @@
 		if (!tune)
 			continue;
 		if (title) {
-			purple_status_set_active(tune, TRUE);
-			purple_status_set_attr_string(tune, PURPLE_TUNE_TITLE, title);
-			purple_status_set_attr_string(tune, PURPLE_TUNE_ARTIST, artist);
-			purple_status_set_attr_string(tune, PURPLE_TUNE_ALBUM, album);
+			set_status_with_attrs(tune,
+					PURPLE_TUNE_TITLE, title,
+					PURPLE_TUNE_ARTIST, artist,
+					PURPLE_TUNE_ALBUM, album,
+					NULL);
 		} else {
 			purple_status_set_active(tune, FALSE);
 		}
--- a/pidgin/gtkimhtmltoolbar.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Mon Jan 14 02:10:26 2008 +0000
@@ -1312,6 +1312,7 @@
 
 	gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0);
 	g_object_set_data(G_OBJECT(hbox), "lean-view", box);
+	gtk_widget_show(box);
 
 	purple_prefs_connect_callback(toolbar, PIDGIN_PREFS_ROOT "/conversations/toolbar/wide",
 			imhtmltoolbar_view_pref_changed, toolbar);
--- a/pidgin/gtkmain.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/pidgin/gtkmain.c	Mon Jan 14 02:10:26 2008 +0000
@@ -508,6 +508,7 @@
 		{"session",  required_argument, NULL, 's'},
 		{"version",  no_argument,       NULL, 'v'},
 		{"display",  required_argument, NULL, 'D'},
+		{"sync",     no_argument,       NULL, 'S'},
 		{0, 0, 0, 0}
 	};
 
@@ -517,7 +518,7 @@
 	debug_enabled = FALSE;
 #endif
 
-	/* This is the first Glib function call. Make sure to initialize GThread bfeore then */
+	/* Initialize GThread before calling any Glib or GTK+ functions. */
 	g_thread_init(NULL);
 
 #ifdef ENABLE_NLS
@@ -654,6 +655,7 @@
 			opt_si = FALSE;
 			break;
 		case 'D':   /* --display */
+		case 'S':   /* --sync */
 			/* handled by gtk_init_check below */
 			break;
 		case '?':	/* show terse help */
--- a/pidgin/gtkstatusbox.c	Mon Jan 14 02:06:47 2008 +0000
+++ b/pidgin/gtkstatusbox.c	Mon Jan 14 02:10:26 2008 +0000
@@ -507,18 +507,10 @@
 	purple_signals_disconnect_by_handle(statusbox);
 	purple_prefs_disconnect_by_handle(statusbox);
 
-	gdk_cursor_unref(statusbox->hand_cursor);
-	gdk_cursor_unref(statusbox->arrow_cursor);
+	destroy_icon_box(statusbox);
 
-	purple_imgstore_unref(statusbox->buddy_icon_img);
-	g_object_unref(G_OBJECT(statusbox->buddy_icon));
-	g_object_unref(G_OBJECT(statusbox->buddy_icon_hover));
 	g_object_unref(G_OBJECT(statusbox->store));
 	g_object_unref(G_OBJECT(statusbox->dropdown_store));
-
-	if (statusbox->buddy_icon_sel)
-		gtk_widget_destroy(statusbox->buddy_icon_sel);
-
 	G_OBJECT_CLASS(parent_class)->finalize(obj);
 }
 
--- a/po/POTFILES.in	Mon Jan 14 02:06:47 2008 +0000
+++ b/po/POTFILES.in	Mon Jan 14 02:10:26 2008 +0000
@@ -72,6 +72,7 @@
 libpurple/protocols/bonjour/bonjour.c
 libpurple/protocols/bonjour/bonjour.h
 libpurple/protocols/bonjour/jabber.c
+libpurple/protocols/bonjour/mdns_win32.c
 libpurple/protocols/gg/gg.c
 libpurple/protocols/irc/cmds.c
 libpurple/protocols/irc/dcc_send.c
@@ -213,6 +214,7 @@
 pidgin/pidgin.h
 pidgin/pidgincombobox.c
 pidgin/pidginstock.c
+pidgin/pidgintooltip.c
 pidgin/pixmaps/emotes/default/24/default.theme.in
 pidgin/pixmaps/emotes/none/none.theme.in
 pidgin/plugins/cap/cap.c