changeset 30145:bd0ce3844104

merged with im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Thu, 15 Apr 2010 16:48:50 +0900
parents 018801f22934 (current diff) c66e766acb06 (diff)
children 06fa97f637a7
files libpurple/certificate.c libpurple/protocols/jabber/jabber.c libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h libpurple/protocols/yahoo/libymsg.c pidgin/eggtrayicon.c pidgin/eggtrayicon.h pidgin/gtkconv.c pidgin/gtkutils.c
diffstat 40 files changed, 763 insertions(+), 1185 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri Apr 09 14:56:00 2010 +0900
+++ b/COPYRIGHT	Thu Apr 15 16:48:50 2010 +0900
@@ -546,6 +546,7 @@
 Justin Wood
 Ximian
 Ma Xuan
+Yonas Yanfa
 Jared Yanovich
 Timmy Yee
 Li Yuan
--- a/ChangeLog	Fri Apr 09 14:56:00 2010 +0900
+++ b/ChangeLog	Thu Apr 15 16:48:50 2010 +0900
@@ -36,7 +36,6 @@
 	  in the distant past.  (Greg McNew)
 	* Added a menu set mood globally for all mood-supporting accounts
 	  (currently XMPP and ICQ).
-	* Use standard (but small) GTK+ buttons instead of custom "X" symbol.
 	* Default binding of Ctrl+Shift+v to 'Paste as Plain Text' in
 	  conversation windows. This can be changed in .gtkrc-2.0. For example,
 	  Ctrl+v can be bound to 'Paste as Plain Text' by default.
@@ -44,6 +43,8 @@
 	  "drawing-buddy". (Daniele Ricci, Andrea Piccinelli)
 	* Be more accommodating when scaling down large images for use as
 	  buddy icons.
+	* The 'Message Timestamp Formats' plugin allows changing the timestamp
+	  format from the timestamps' context menu in conversation log.
 
 	Bonjour:
 	* Added support for IPv6. (Thanks to T_X for testing)
@@ -53,13 +54,18 @@
 	  Klinikowski for the work and testing put in here!)
 	* Minimum requirement for external libgadu is now also 1.9.0-rc2.
 
-	ICQ:
+	AIM and ICQ:
 	* X-Status (Custom ICQ status icon) support.  Since most of the icons
 	  available reflect moods, this is labeled "Set Mood" on the Accounts->ICQ
 	  Account menu. (Andrew Ivanov, Tomáš Kebert, Yuriy Yevgrafov, and trac
 	  users bob007, salieff, and nops)
-	* Allow setting and displaying icons between 1x1 and 100x100 pixels.
-	  Previously only icons between 48x48 and 52x64 were allowed.
+	* Allow setting and displaying icons between 1x1 and 100x100 pixels for
+	  ICQ.  Previously only icons between 48x48 and 52x64 were allowed.
+	* When using the clientLogin authentication method, prompt for a
+	  password on reconnect when "Remember Password" is not checked and
+	  authentication fails due to an incorrect password.  (This is the same
+	  behavior as the legacy authentication method)
+	* Support sending and receiving HTML-formatted messages for ICQ.
 
 	MSN:
 	* Support for version 9 of the MSN protocol has been removed.  This
--- a/ChangeLog.API	Fri Apr 09 14:56:00 2010 +0900
+++ b/ChangeLog.API	Thu Apr 15 16:48:50 2010 +0900
@@ -3,6 +3,10 @@
 version 2.7.0 (??/??/????):
 	libpurple:
 		Added:
+		* Account signals (see account-signals.dox); useful for D-Bus
+		   * account-signed-on
+		   * account-signed-off
+		   * account-connection-error
 		* purple_account_get_name_for_display
 		* purple_buddy_get_media_caps
 		* purple_buddy_set_media_caps
--- a/doc/PERL-HOWTO.dox	Fri Apr 09 14:56:00 2010 +0900
+++ b/doc/PERL-HOWTO.dox	Thu Apr 15 16:48:50 2010 +0900
@@ -72,8 +72,8 @@
 sub plugin_load {
 	$plugin = shift;
 
-	# Testing was done using Oscar, but this should work regardless of the protocol chosen
-	my $protocol = "prpl-oscar";
+	# Testing was done using AIM, but this should work regardless of the protocol chosen
+	my $protocol = "prpl-aim";
 	my $account_name = "test";
 
 	# Create a new Account
@@ -149,7 +149,7 @@
 sub plugin_load {
 	my $plugin = shift;
 
-	my $protocol = "prpl-oscar";
+	my $protocol = "prpl-aim";
 	my $account_name = "test";
 
 	# This is how we get an account to use in the following tests.  You should replace the username
@@ -232,7 +232,7 @@
 @code
 sub plugin_load {
 	my $plugin = shift;
-	my $protocol = "prpl-oscar";
+	my $protocol = "prpl-aim";
 	my $account_name = "test";
 
 	$account = Purple::Accounts::find($account_name, $protocol);
--- a/doc/account-signals.dox	Fri Apr 09 14:56:00 2010 +0900
+++ b/doc/account-signals.dox	Thu Apr 15 16:48:50 2010 +0900
@@ -17,6 +17,9 @@
   @signal account-authorization-denied
   @signal account-authorization-granted
   @signal account-error-changed
+  @signal account-signed-on
+  @signal account-signed-off
+  @signal account-connection-error
  @endsignals
 
  @see account.h
@@ -196,5 +199,36 @@
   @since 2.3.0
  @endsignaldef
 
+ @signaldef account-signed-on
+  @signalproto
+void (*signed_on)(PurpleAccount *account);
+  @endsignalproto
+  @signaldesc
+   Emitted when an account has signed on.
+  @param account The account that has signed on.
+  @since 2.7.0
+ @endsignaldef
+
+ @signaldef account-signed-off
+  @signalproto
+void (*signed_off)(PurpleAccount *account);
+  @endsignalproto
+  @signaldesc
+   Emitted when an account has signed off.
+  @param account The account that has signed off.
+  @since 2.7.0
+ @endsignaldef
+
+ @signaldef account-connection-error
+  @signalproto
+void (*connection_error)(PurpleAccount *gc, PurpleConnectionError err, const gchar *desc)
+  @endsignalproto
+  @signaldesc
+   Emitted when a connection error occurs, before @ref signed-off.
+   @param account The account on which the error has occurred
+   @param err     The error that occurred
+   @param desc    A description of the error, giving more information.
+  @since 2.7.0
+ @endsignaldef
  */
 // vim: syntax=c.doxygen tw=75 et
--- a/libpurple/account.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/account.c	Thu Apr 15 16:48:50 2010 +0900
@@ -2510,6 +2510,19 @@
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
 	purple_account_clear_current_error(account);
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-signed-on",
+	                   account);
+}
+
+static void
+signed_off_cb(PurpleConnection *gc,
+              gpointer unused)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-signed-off",
+	                   account);
 }
 
 static void
@@ -2560,6 +2573,9 @@
 	err->description = g_strdup(description);
 
 	set_current_error(account, err);
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-connection-error",
+	                   account, type, description);
 }
 
 const PurpleConnectionErrorInfo *
@@ -2901,8 +2917,27 @@
 	                       purple_value_new(PURPLE_TYPE_POINTER),
 	                       purple_value_new(PURPLE_TYPE_POINTER));
 
+	purple_signal_register(handle, "account-signed-on",
+	                       purple_marshal_VOID__POINTER, NULL, 1,
+	                       purple_value_new(PURPLE_TYPE_SUBTYPE,
+	                                        PURPLE_SUBTYPE_ACCOUNT));
+
+	purple_signal_register(handle, "account-signed-off",
+	                       purple_marshal_VOID__POINTER, NULL, 1,
+	                       purple_value_new(PURPLE_TYPE_SUBTYPE,
+	                                        PURPLE_SUBTYPE_ACCOUNT));
+
+	purple_signal_register(handle, "account-connection-error",
+	                       purple_marshal_VOID__POINTER_INT_POINTER, NULL, 3,
+	                       purple_value_new(PURPLE_TYPE_SUBTYPE,
+	                                        PURPLE_SUBTYPE_ACCOUNT),
+	                       purple_value_new(PURPLE_TYPE_ENUM),
+	                       purple_value_new(PURPLE_TYPE_STRING));
+
 	purple_signal_connect(conn_handle, "signed-on", handle,
 	                      PURPLE_CALLBACK(signed_on_cb), NULL);
+	purple_signal_connect(conn_handle, "signed-off", handle,
+	                      PURPLE_CALLBACK(signed_off_cb), NULL);
 	purple_signal_connect(conn_handle, "connection-error", handle,
 	                      PURPLE_CALLBACK(connection_error_cb), NULL);
 
--- a/libpurple/certificate.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/certificate.c	Thu Apr 15 16:48:50 2010 +0900
@@ -714,6 +714,7 @@
 		x509_singleuse_verify_cb );
 
 	/* Cleanup */
+	g_free(cn);
 	g_free(primary);
 	g_free(secondary);
 	g_free(sha_asc);
@@ -859,6 +860,7 @@
 					purple_debug_info("certificate/x509/ca",
 							  "Loaded %s from %s\n",
 							  name ? name : "(unknown)", fullpath);
+					g_free(name);
 				} else {
 					purple_debug_error("certificate/x509/ca",
 							  "Failed to load certificate from %s\n",
@@ -1535,6 +1537,7 @@
 				  "Name mismatch: Certificate given for %s "
 				  "has a name of %s\n",
 				  vrq->subject_name, sn);
+		g_free(sn);
 	}
 
 	x509_tls_cached_complete(vrq, flags);
--- a/libpurple/network.h	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/network.h	Thu Apr 15 16:48:50 2010 +0900
@@ -123,8 +123,8 @@
  * The default value is TRUE
  *
  * @param map_external Should the open port be mapped externally?
- * @deprecated In 3.0.0 a boolean will be added to the above functions to
- *             perform the same function.
+ * @deprecated In 3.0.0 a boolean will be added to the functions mentioned
+ *             above to perform the same function.
  * @since 2.3.0
  */
 void purple_network_listen_map_external(gboolean map_external);
@@ -236,15 +236,15 @@
  */
 void *purple_network_get_handle(void);
 
-/**	
+/**
  * Update the STUN server IP given the host name
  * Will result in a DNS query being executed asynchronous
- * 
+ *
  * @param stun_server The host name of the STUN server to set
  * @since 2.6.0
  */
 void purple_network_set_stun_server(const gchar *stun_server);
-	
+
 /**
  * Get the IP address of the STUN server as a string representation
  *
@@ -252,16 +252,16 @@
  * @since 2.6.0
  */
 const gchar *purple_network_get_stun_ip(void);
-	
-/**	
+
+/**
  * Update the TURN server IP given the host name
  * Will result in a DNS query being executed asynchronous
- * 
+ *
  * @param turn_server The host name of the TURN server to set
  * @since 2.6.0
  */
 void purple_network_set_turn_server(const gchar *turn_server);
-	
+
 /**
  * Get the IP address of the TURN server as a string representation
  *
@@ -269,14 +269,14 @@
  * @since 2.6.0
  */
 const gchar *purple_network_get_turn_ip(void);
-		
+
 /**
  * Remove a port mapping (UPnP or NAT-PMP) associated with listening socket
  *
  * @param fd Socket to remove the port mapping for
  * @since 2.6.0
  */
-void purple_network_remove_port_mapping(gint fd);	
+void purple_network_remove_port_mapping(gint fd);
 
 /**
  * Convert a UTF-8 domain name to ASCII in accordance with the IDNA
--- a/libpurple/protocols/bonjour/jabber.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/bonjour/jabber.c	Thu Apr 15 16:48:50 2010 +0900
@@ -683,7 +683,7 @@
 	g_slist_free(buddies);
 
 	if (mbba->matched_buddies == NULL) {
-		purple_debug_info("bonjour", "We don't like invisible buddies, this is not a superheros comic\n");
+		purple_debug_info("bonjour", "We don't like invisible buddies, this is not a superheroes comic\n");
 		g_free(mbba);
 		close(client_socket);
 		return;
--- a/libpurple/protocols/gg/gg.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/gg/gg.c	Thu Apr 15 16:48:50 2010 +0900
@@ -1000,7 +1000,6 @@
 				       int status, const char *descr)
 {
 	gchar *from;
-	gchar *msg;
 	const char *st;
 	gchar *avatarurl;
 	PurpleUtilFetchUrlData *url_data;
@@ -1048,11 +1047,14 @@
 
 	purple_debug_info("gg", "st = %s\n", st);
 	//msg = charset_convert(descr, "CP1250", "UTF-8");
-	msg = g_strdup_printf("%s", descr);
-	purple_prpl_got_user_status(purple_connection_get_account(gc),
-				  from, st, "message", msg, NULL);
+	if (descr == NULL) {
+		purple_prpl_got_user_status(purple_connection_get_account(gc),
+		      from, st, NULL);
+	} else {
+		purple_prpl_got_user_status(purple_connection_get_account(gc),
+		    from, st, "message", descr, NULL);
+	}
 	g_free(from);
-	g_free(msg);
 }
 
 static void ggp_sr_close_cb(gpointer user_data)
@@ -1608,12 +1610,12 @@
 				purple_debug_info("gg",
 					"notify60: (%d) status=%d; version=%d; descr=%s\n",
 					ev->event.notify60[i].uin,
-					ev->event.notify60[i].status,
+					GG_S(ev->event.notify60[i].status),
 					ev->event.notify60[i].version,
 					ev->event.notify60[i].descr ? ev->event.notify60[i].descr : "(null)");
 
 				ggp_generic_status_handler(gc, ev->event.notify60[i].uin,
-					ev->event.notify60[i].status,
+					GG_S(ev->event.notify60[i].status),
 					ev->event.notify60[i].descr);
 			}
 			break;
@@ -1623,7 +1625,7 @@
 					ev->event.status.descr ? ev->event.status.descr : "(null)");
 
 			ggp_generic_status_handler(gc, ev->event.status.uin,
-				ev->event.status.status, ev->event.status.descr);
+				GG_S(ev->event.status.status), ev->event.status.descr);
 			break;
 		case GG_EVENT_STATUS60:
 			purple_debug_info("gg",
--- a/libpurple/protocols/gg/lib/events.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/gg/lib/events.c	Thu Apr 15 16:48:50 2010 +0900
@@ -1143,7 +1143,7 @@
 		case GG_NOTIFY_REPLY80:
 		{
 			struct gg_notify_reply80 *n = (void*) p;
-			int length = h->length, i = 0;
+			unsigned int length = h->length, i = 0;
 
 			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
 
--- a/libpurple/protocols/gg/lib/libgadu.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/gg/lib/libgadu.c	Thu Apr 15 16:48:50 2010 +0900
@@ -412,7 +412,8 @@
 {
 	struct gg_header h;
 	char *buf = NULL;
-	int ret = 0, offset, size = 0;
+	int ret = 0;
+	unsigned int offset, size = 0;
 
 	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_recv_packet(%p);\n", sess);
 
@@ -609,7 +610,7 @@
 	h->length = gg_fix32(tmp_length - sizeof(struct gg_header));
 
 	if ((gg_debug_level & GG_DEBUG_DUMP)) {
-		int i;
+		unsigned int i;
 
 		gg_debug_session(sess, GG_DEBUG_DUMP, "// gg_send_packet(0x%.2x)", gg_fix32(h->type));
 		for (i = 0; i < tmp_length; ++i)
--- a/libpurple/protocols/jabber/jabber.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/jabber/jabber.c	Thu Apr 15 16:48:50 2010 +0900
@@ -846,6 +846,14 @@
 		return NULL;
 	}
 
+	if (!js->user->node || *(js->user->node) == '\0') {
+		purple_connection_error_reason(gc,
+			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
+			_("Invalid XMPP ID. Username portion must be set."));
+		/* Destroying the connection will free the JabberStream */
+		return NULL;
+	}
+
 	if (!js->user->domain || *(js->user->domain) == '\0') {
 		purple_connection_error_reason(gc,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
--- a/libpurple/protocols/null/nullprpl.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/null/nullprpl.c	Thu Apr 15 16:48:50 2010 +0900
@@ -997,7 +997,7 @@
 
     /* This cast is OK because this list is only staying around for the life
      * of this function and none of the conversations are being deleted
-	 * in that timespan. */
+     * in that timespan. */
     seen_ids = g_list_prepend(seen_ids, (char *)name); /* no, it's new. */
     purple_debug_info("nullprpl", "%s (%d), ", name, id);
 
@@ -1117,10 +1117,10 @@
   NULL,                                /* send_attention */
   NULL,                                /* get_attention_types */
   sizeof(PurplePluginProtocolInfo),    /* struct_size */
-  NULL,				       /* get_account_text_table */
+  NULL,                                /* get_account_text_table */
   NULL,                                /* initiate_media */
   NULL,                                /* get_media_caps */
-  NULL				       /* get_moods */
+  NULL                                 /* get_moods */
 };
 
 static void nullprpl_init(PurplePlugin *plugin)
--- a/libpurple/protocols/oscar/clientlogin.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/oscar/clientlogin.c	Thu Apr 15 16:48:50 2010 +0900
@@ -428,6 +428,9 @@
 				"was %d (%d): %s\n", status_code, status_detail_code, response);
 
 		if (status_code == 330 && status_detail_code == 3011) {
+			PurpleAccount *account = purple_connection_get_account(gc);
+			if (!purple_account_get_remember_password(account))
+				purple_account_set_password(account, NULL);
 			purple_connection_error_reason(gc,
 					PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
 					_("Incorrect password"));
@@ -515,8 +518,12 @@
 
 	if (error_message != NULL || len == 0) {
 		gchar *tmp;
-		tmp = g_strdup_printf(_("Error requesting %s: %s"),
-				URL_CLIENT_LOGIN, error_message);
+		if (error_message != NULL)
+			tmp = g_strdup_printf(_("Error requesting %s: %s"),
+					URL_CLIENT_LOGIN, error_message);
+		else
+			tmp = g_strdup_printf(_("Error requesting %s"),
+					URL_CLIENT_LOGIN);
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
--- a/libpurple/protocols/oscar/family_icbm.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/oscar/family_icbm.c	Thu Apr 15 16:48:50 2010 +0900
@@ -274,6 +274,7 @@
 			| AIM_IMPARAM_FLAG_MISSED_CALLS_ENABLED
 			| AIM_IMPARAM_FLAG_EVENTS_ALLOWED
 			| AIM_IMPARAM_FLAG_SMS_SUPPORTED
+			| AIM_IMPARAM_FLAG_SEND_ME_HTML_FOR_ICQ
 			| AIM_IMPARAM_FLAG_OFFLINE_MSGS_ALLOWED;
 	params.maxmsglen = 8000;
 	params.minmsginterval = 0;
--- a/libpurple/protocols/oscar/family_oservice.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/oscar/family_oservice.c	Thu Apr 15 16:48:50 2010 +0900
@@ -1094,8 +1094,6 @@
 static int
 aim_parse_extstatus(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
 {
-	int ret = 0;
-	aim_rxcallback_t userfunc;
 	guint16 type;
 	guint8 flags, length;
 
@@ -1108,25 +1106,54 @@
 	 * A flag of 0x40 could mean "I don't have your icon, upload it"
 	 */
 
-	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) {
-		switch (type) {
+	switch (type) {
 		case 0x0000:
 		case 0x0001: { /* buddy icon checksum */
 			/* not sure what the difference between 1 and 0 is */
 			guint8 *md5 = byte_stream_getraw(bs, length);
-			ret = userfunc(od, conn, frame, type, flags, length, md5);
+
+			if ((flags == 0x00) || (flags == 0x41)) {
+				if (!flap_connection_getbytype(od, SNAC_FAMILY_BART) && !od->iconconnecting) {
+					od->iconconnecting = TRUE;
+					od->set_icon = TRUE;
+					aim_srv_requestnew(od, SNAC_FAMILY_BART);
+				} else {
+					PurpleAccount *account = purple_connection_get_account(od->gc);
+					PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account);
+					if (img == NULL) {
+						aim_ssi_delicon(od);
+					} else {
+
+						purple_debug_info("oscar",
+										"Uploading icon to icon server\n");
+						aim_bart_upload(od, purple_imgstore_get_data(img),
+						                purple_imgstore_get_size(img));
+						purple_imgstore_unref(img);
+					}
+				}
+			} else if (flags == 0x81) {
+				PurpleAccount *account = purple_connection_get_account(od->gc);
+				PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account);
+				if (img == NULL)
+					aim_ssi_delicon(od);
+				else {
+					aim_ssi_seticon(od, md5, length);
+					purple_imgstore_unref(img);
+				}
+			}
+
 			g_free(md5);
-			} break;
-		case 0x0002: { /* available message */
+		} break;
+
+		case 0x0002: {
+			/* We just set an available message? */
 			/* there is a second length that is just for the message */
 			char *msg = byte_stream_getstr(bs, byte_stream_get16(bs));
-			ret = userfunc(od, conn, frame, msg);
 			g_free(msg);
-			} break;
-		}
+		} break;
 	}
 
-	return ret;
+	return 0;
 }
 
 static int
--- a/libpurple/protocols/oscar/oscar.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/oscar/oscar.c	Thu Apr 15 16:48:50 2010 +0900
@@ -85,8 +85,7 @@
 		| OSCAR_CAPABILITY_XTRAZ;
 
 static guint8 features_aim[] = {0x01, 0x01, 0x01, 0x02};
-static guint8 features_icq[] = {0x01, 0x06};
-static guint8 features_icq_offline[] = {0x01};
+static guint8 features_icq[] = {0x01};
 static guint8 ck[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
 struct create_room {
@@ -202,7 +201,6 @@
 static int purple_conv_chat_incoming_msg(OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_email_parseupdate(OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_icon_parseicon   (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int oscar_icon_req        (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_parse_msgack     (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_parse_evilnotify (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_parse_searcherror(OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -1590,7 +1588,6 @@
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x0001, purple_parse_genericerr, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x000f, purple_selfinfo, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x001f, purple_memrequest, 0);
-	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x0021, oscar_icon_req,0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_REDIRECT, purple_handle_redirect, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_MOTD, purple_parse_motd, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_EVIL, purple_parse_evilnotify, 0);
@@ -1608,11 +1605,11 @@
 		return;
 	}
 
+	gc->flags |= PURPLE_CONNECTION_HTML;
 	if (oscar_util_valid_name_icq((purple_account_get_username(account)))) {
 		od->icq = TRUE;
 		gc->flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
 	} else {
-		gc->flags |= PURPLE_CONNECTION_HTML;
 		gc->flags |= PURPLE_CONNECTION_AUTO_RESP;
 	}
 
@@ -2526,8 +2523,15 @@
 	 *
 	 * Note: There *may* be some clients which send messages as HTML formatted -
 	 *       they need to be special-cased somehow.
+	 *
+	 * Update: Newer ICQ clients have started sending IMs as HTML.  We can
+	 * distinguish HTML IMs from non-HTML IMs by looking at the features.  If
+	 * the features are "0x 01 06" then the message is plain text.  If the
+	 * features are "0x 01" then the message is HTML.
 	 */
-	if (od->icq && oscar_util_valid_name_icq(userinfo->bn)) {
+	if (od->icq && oscar_util_valid_name_icq(userinfo->bn)
+			&& (args->featureslen != 1 || args->features[0] != 0x01))
+	{
 		/* being recevied by ICQ from ICQ - escape HTML so it is displayed as sent */
 		gchar *tmp2 = g_markup_escape_text(tmp, -1);
 		g_free(tmp);
@@ -4754,20 +4758,8 @@
 			args.flags |= AIM_IMFLAGS_OFFLINE;
 
 		if (od->icq) {
-			/* We have to present different "features" (whose meaning
-			   is unclear and are merely a result of protocol inspection)
-			   to offline ICQ buddies. Otherwise, the official
-			   ICQ client doesn't treat those messages as being "ANSI-
-			   encoded" (and instead, assumes them to be UTF-8).
-			   For more details, see SF issue 1179452.
-			*/
-			if (buddy && PURPLE_BUDDY_IS_ONLINE(buddy)) {
-				args.features = features_icq;
-				args.featureslen = sizeof(features_icq);
-			} else {
-				args.features = features_icq_offline;
-				args.featureslen = sizeof(features_icq_offline);
-			}
+			args.features = features_icq;
+			args.featureslen = sizeof(features_icq);
 		} else {
 			args.features = features_aim;
 			args.featureslen = sizeof(features_aim);
@@ -4817,25 +4809,11 @@
 
 		args.destbn = name;
 
-		/*
-		 * If we're IMing an SMS user or an ICQ user from an ICQ account, then strip HTML.
-		 */
 		if (oscar_util_valid_name_sms(name)) {
-			/* Messaging an SMS (mobile) user */
+			/* Messaging an SMS (mobile) user--strip HTML */
 			tmp2 = purple_markup_strip_html(tmp1);
 			is_html = FALSE;
-		} else if (od->icq) {
-			if (oscar_util_valid_name_icq(name)) {
-				/* From ICQ to ICQ */
-				tmp2 = purple_markup_strip_html(tmp1);
-				is_html = FALSE;
-			} else {
-				/* From ICQ to AIM */
-				tmp2 = g_strdup(tmp1);
-				is_html = TRUE;
-			}
 		} else {
-			/* From AIM to AIM and AIM to ICQ */
 			tmp2 = g_strdup(tmp1);
 			is_html = TRUE;
 		}
@@ -6272,64 +6250,6 @@
 	return ret;
 }
 
-
-static int oscar_icon_req(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
-	PurpleConnection *gc = od->gc;
-	va_list ap;
-	guint16 type;
-	guint8 flags = 0, length = 0;
-	guchar *md5 = NULL;
-
-	va_start(ap, fr);
-	type = va_arg(ap, int);
-
-	switch(type) {
-		case 0x0000:
-		case 0x0001: {
-			flags = va_arg(ap, int);
-			length = va_arg(ap, int);
-			md5 = va_arg(ap, guchar *);
-
-			if ((flags == 0x00) || (flags == 0x41)) {
-				if (!flap_connection_getbytype(od, SNAC_FAMILY_BART) && !od->iconconnecting) {
-					od->iconconnecting = TRUE;
-					od->set_icon = TRUE;
-					aim_srv_requestnew(od, SNAC_FAMILY_BART);
-				} else {
-					PurpleAccount *account = purple_connection_get_account(gc);
-					PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account);
-					if (img == NULL) {
-						aim_ssi_delicon(od);
-					} else {
-
-						purple_debug_info("oscar",
-										"Uploading icon to icon server\n");
-						aim_bart_upload(od, purple_imgstore_get_data(img),
-						                purple_imgstore_get_size(img));
-						purple_imgstore_unref(img);
-					}
-				}
-			} else if (flags == 0x81) {
-				PurpleAccount *account = purple_connection_get_account(gc);
-				PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account);
-				if (img == NULL)
-					aim_ssi_delicon(od);
-				else {
-					aim_ssi_seticon(od, md5, length);
-					purple_imgstore_unref(img);
-				}
-			}
-		} break;
-
-		case 0x0002: { /* We just set an "available" message? */
-		} break;
-	}
-
-	va_end(ap);
-
-	return 0;
-}
-
 void oscar_set_permit_deny(PurpleConnection *gc) {
 	PurpleAccount *account = purple_connection_get_account(gc);
 	OscarData *od = purple_connection_get_protocol_data(gc);
--- a/libpurple/protocols/oscar/oscar.h	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/oscar/oscar.h	Thu Apr 15 16:48:50 2010 +0900
@@ -746,6 +746,7 @@
 #define AIM_IMPARAM_FLAG_EVENTS_ALLOWED         0x00000008
 #define AIM_IMPARAM_FLAG_SMS_SUPPORTED          0x00000010
 #define AIM_IMPARAM_FLAG_OFFLINE_MSGS_ALLOWED   0x00000100
+#define AIM_IMPARAM_FLAG_SEND_ME_HTML_FOR_ICQ   0x00000400
 
 /* This is what the server will give you if you don't set them yourself. */
 /* This is probably out of date. */
--- a/libpurple/protocols/simple/simple.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/simple/simple.c	Thu Apr 15 16:48:50 2010 +0900
@@ -1653,6 +1653,7 @@
 		}
 		purple_debug(PURPLE_DEBUG_MISC, "simple", "in process response response: %d\n", msg->response);
 		process_input_message(sip, msg);
+		sipmsg_free(msg);
 	} else {
 		purple_debug(PURPLE_DEBUG_MISC, "simple", "received a incomplete sip msg: %s\n", conn->inbuf);
 	}
@@ -1663,14 +1664,17 @@
 	struct simple_account_data *sip = gc->proto_data;
 	struct sipmsg *msg;
 	int len;
-	time_t currtime;
+	time_t currtime = time(NULL);
 
 	static char buffer[65536];
 	if((len = recv(source, buffer, sizeof(buffer) - 1, 0)) > 0) {
 		buffer[len] = '\0';
 		purple_debug_info("simple", "\n\nreceived - %s\n######\n%s\n#######\n\n", ctime(&currtime), buffer);
 		msg = sipmsg_parse_msg(buffer);
-		if(msg) process_input_message(sip, msg);
+		if (msg) {
+			process_input_message(sip, msg);
+			sipmsg_free(msg);
+		}
 	}
 }
 
@@ -1777,10 +1781,14 @@
 		return;
 	}
 
+	/*
+	 * TODO: Is it correct to set sip->fd to the listenfd?  For the TCP
+	 *       listener we set sip->listenfd, but maybe UDP is different?
+	 *       Maybe we use the same fd for outgoing data or something?
+	 */
 	sip->fd = listenfd;
 
 	sip->listenport = purple_network_get_port_from_fd(sip->fd);
-	sip->listenfd = sip->fd;
 
 	sip->listenpa = purple_input_add(sip->fd, PURPLE_INPUT_READ, simple_udp_process, sip->gc);
 
@@ -1965,54 +1973,69 @@
 {
 	struct simple_account_data *sip = gc->proto_data;
 
-	if(sip) {
-		/* unregister */
-		if (sip->registerstatus == SIMPLE_REGISTER_COMPLETE)
-		{
-			g_hash_table_foreach(sip->buddies,
-				(GHFunc)simple_unsubscribe,
-				(gpointer)sip);
+	if (!sip)
+		return;
+
+	/* unregister */
+	if (sip->registerstatus == SIMPLE_REGISTER_COMPLETE)
+	{
+		g_hash_table_foreach(sip->buddies,
+			(GHFunc)simple_unsubscribe,
+			(gpointer)sip);
+
+		if (purple_account_get_bool(sip->account, "dopublish", TRUE))
+			send_closed_publish(sip);
 
-			if(purple_account_get_bool(sip->account,
-						   "dopublish", TRUE))
-				send_closed_publish(sip);
+		do_register_exp(sip, 0);
+	}
+	connection_free_all(sip);
 
-			do_register_exp(sip, 0);
-		}
-		connection_free_all(sip);
+	if (sip->listenpa)
+		purple_input_remove(sip->listenpa);
+	if (sip->tx_handler)
+		purple_input_remove(sip->tx_handler);
+	if (sip->resendtimeout)
+		purple_timeout_remove(sip->resendtimeout);
+	if (sip->registertimeout)
+		purple_timeout_remove(sip->registertimeout);
+	if (sip->query_data != NULL)
+		purple_dnsquery_destroy(sip->query_data);
 
-		if (sip->query_data != NULL)
-			purple_dnsquery_destroy(sip->query_data);
-
-		if (sip->srv_query_data != NULL)
-			purple_srv_cancel(sip->srv_query_data);
+	if (sip->srv_query_data != NULL)
+		purple_srv_cancel(sip->srv_query_data);
 
-		if (sip->listen_data != NULL)
-			purple_network_listen_cancel(sip->listen_data);
+	if (sip->listen_data != NULL)
+		purple_network_listen_cancel(sip->listen_data);
+
+	if (sip->fd >= 0)
+		close(sip->fd);
+	if (sip->listenfd >= 0)
+		close(sip->listenfd);
 
-		g_free(sip->servername);
-		g_free(sip->username);
-		g_free(sip->password);
-		g_free(sip->registrar.nonce);
-		g_free(sip->registrar.opaque);
-		g_free(sip->registrar.target);
-		g_free(sip->registrar.realm);
-		g_free(sip->registrar.digest_session_key);
-		g_free(sip->proxy.nonce);
-		g_free(sip->proxy.opaque);
-		g_free(sip->proxy.target);
-		g_free(sip->proxy.realm);
-		g_free(sip->proxy.digest_session_key);
-		g_free(sip->publish_etag);
-		if(sip->txbuf)
-			purple_circ_buffer_destroy(sip->txbuf);
-		g_free(sip->realhostname);
-		if(sip->listenpa) purple_input_remove(sip->listenpa);
-		if(sip->tx_handler) purple_input_remove(sip->tx_handler);
-		if(sip->resendtimeout) purple_timeout_remove(sip->resendtimeout);
-		if(sip->registertimeout) purple_timeout_remove(sip->registertimeout);
-	}
-	g_free(gc->proto_data);
+	g_free(sip->servername);
+	g_free(sip->username);
+	g_free(sip->password);
+	g_free(sip->registrar.nonce);
+	g_free(sip->registrar.opaque);
+	g_free(sip->registrar.target);
+	g_free(sip->registrar.realm);
+	g_free(sip->registrar.digest_session_key);
+	g_free(sip->proxy.nonce);
+	g_free(sip->proxy.opaque);
+	g_free(sip->proxy.target);
+	g_free(sip->proxy.realm);
+	g_free(sip->proxy.digest_session_key);
+	g_free(sip->status);
+	g_hash_table_destroy(sip->buddies);
+	g_free(sip->regcallid);
+	while (sip->transactions)
+		transactions_remove(sip, sip->transactions->data);
+	g_free(sip->publish_etag);
+	if (sip->txbuf)
+		purple_circ_buffer_destroy(sip->txbuf);
+	g_free(sip->realhostname);
+
+	g_free(sip);
 	gc->proto_data = NULL;
 }
 
--- a/libpurple/protocols/simple/sipmsg.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/simple/sipmsg.c	Thu Apr 15 16:48:50 2010 +0900
@@ -55,15 +55,15 @@
 }
 
 struct sipmsg *sipmsg_parse_header(const gchar *header) {
-	struct sipmsg *msg = g_new0(struct sipmsg,1);
-	gchar **parts, **lines = g_strsplit(header,"\r\n",0);
+	struct sipmsg *msg;
+	gchar **parts, **lines;
 	gchar *dummy, *dummy2, *tmp;
 	const gchar *tmp2;
 	int i = 1;
 
+	lines = g_strsplit(header,"\r\n",0);
 	if(!lines[0]) {
 		g_strfreev(lines);
-		g_free(msg);
 		return NULL;
 	}
 
@@ -71,10 +71,10 @@
 	if(!parts[0] || !parts[1] || !parts[2]) {
 		g_strfreev(parts);
 		g_strfreev(lines);
-		g_free(msg);
 		return NULL;
 	}
 
+	msg = g_new0(struct sipmsg,1);
 	if(strstr(parts[0],"SIP")) { /* numeric response */
 		msg->method = g_strdup(parts[2]);
 		msg->response = strtol(parts[1],NULL,10);
@@ -90,7 +90,7 @@
 		if(!parts[0] || !parts[1]) {
 			g_strfreev(parts);
 			g_strfreev(lines);
-			g_free(msg);
+			sipmsg_free(msg);
 			return NULL;
 		}
 		dummy = parts[1];
@@ -106,6 +106,7 @@
 			dummy2 = tmp;
 		}
 		sipmsg_add_header(msg, parts[0], dummy2);
+		g_free(dummy2);
 		g_strfreev(parts);
 	}
 	g_strfreev(lines);
@@ -116,9 +117,10 @@
 
 	if(msg->response) {
 		tmp2 = sipmsg_find_header(msg, "CSeq");
+		g_free(msg->method);
 		if(!tmp2) {
 			/* SHOULD NOT HAPPEN */
-			msg->method = 0;
+			msg->method = NULL;
 		} else {
 			parts = g_strsplit(tmp2, " ", 2);
 			msg->method = g_strdup(parts[1]);
@@ -168,7 +170,7 @@
 	return g_string_free(outstr, FALSE);
 }
 void sipmsg_add_header(struct sipmsg *msg, const gchar *name, const gchar *value) {
-	struct siphdrelement *element = g_new0(struct siphdrelement,1);
+	struct siphdrelement *element = g_new(struct siphdrelement,1);
 	element->name = g_strdup(name);
 	element->value = g_strdup(value);
 	msg->headers = g_slist_append(msg->headers, element);
--- a/libpurple/protocols/yahoo/libymsg.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/libpurple/protocols/yahoo/libymsg.c	Thu Apr 15 16:48:50 2010 +0900
@@ -1779,7 +1779,7 @@
 				tmp = &splits[i][14];
 				sem = strchr(tmp, ';');
 
-				if(tmp != NULL) {
+				if (sem != NULL) {
 					tmp2 = g_strndup(tmp, sem - tmp);
 					purple_debug_info("yahoo", "Got needed part of B cookie: %s\n",
 							tmp2 ? tmp2 : "(null)");
@@ -1789,6 +1789,7 @@
 		}
 	}
 
+	g_strfreev(splits);
 	return tmp2;
 }
 
@@ -2768,6 +2769,7 @@
 	p2p_data->connection_type = YAHOO_P2P_WE_ARE_SERVER;
 	p2p_data->source = -1;
 
+	/* FIXME: Shouldn't this deal with the PurpleNetworkListenData* */
 	purple_network_listen(YAHOO_PAGER_PORT_P2P, SOCK_STREAM, yahoo_p2p_server_listen_cb, p2p_data);
 
 	g_free(base64_ip);
@@ -3748,6 +3750,7 @@
 
 	g_free(yd->cookie_y);
 	g_free(yd->cookie_t);
+	g_free(yd->cookie_b);
 
 	if (yd->txhandler)
 		purple_input_remove(yd->txhandler);
--- a/pidgin/Makefile.am	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/Makefile.am	Thu Apr 15 16:48:50 2010 +0900
@@ -75,7 +75,6 @@
 bin_PROGRAMS = pidgin
 
 pidgin_SOURCES = \
-	eggtrayicon.c \
 	pidginstock.c \
 	gtkaccount.c \
 	gtkblist.c \
@@ -126,7 +125,6 @@
 	pidgintooltip.c
 
 pidgin_headers = \
-	eggtrayicon.h \
 	gtkaccount.h \
 	gtkblist.h \
 	gtkblist-theme.h \
--- a/pidgin/eggtrayicon.c	Fri Apr 09 14:56:00 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,617 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* eggtrayicon.c
- * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02111-1301, USA.
- */
-
-#include <config.h>
-#include <string.h>
-
-#include "eggtrayicon.h"
-
-#include <X11/Xatom.h>
-
-#define _(x) x
-#define N_(x) x
-
-#define SYSTEM_TRAY_REQUEST_DOCK    0
-#define SYSTEM_TRAY_BEGIN_MESSAGE   1
-#define SYSTEM_TRAY_CANCEL_MESSAGE  2
-
-#define SYSTEM_TRAY_ORIENTATION_HORZ 0
-#define SYSTEM_TRAY_ORIENTATION_VERT 1
-
-enum {
-  PROP_0,
-  PROP_ORIENTATION
-};
-
-static GtkPlugClass *parent_class = NULL;
-
-static void egg_tray_icon_init (EggTrayIcon *icon);
-static void egg_tray_icon_class_init (EggTrayIconClass *klass);
-
-static void egg_tray_icon_get_property (GObject    *object,
-					guint       prop_id,
-					GValue     *value,
-					GParamSpec *pspec);
-
-static void egg_tray_icon_realize   (GtkWidget *widget);
-static void egg_tray_icon_unrealize (GtkWidget *widget);
-
-static void egg_tray_icon_add (GtkContainer *container,
-                               GtkWidget *widget);
-
-static void egg_tray_icon_update_manager_window    (EggTrayIcon *icon,
-						    gboolean     dock_if_realized);
-static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon);
-
-GType
-egg_tray_icon_get_type (void)
-{
-  static GType our_type = 0;
-
-  if (our_type == 0)
-    {
-      our_type = g_type_from_name("EggTrayIcon");
-
-      if (our_type == 0)
-        {
-      static const GTypeInfo our_info =
-      {
-	sizeof (EggTrayIconClass),
-	(GBaseInitFunc) NULL,
-	(GBaseFinalizeFunc) NULL,
-	(GClassInitFunc) egg_tray_icon_class_init,
-	NULL, /* class_finalize */
-	NULL, /* class_data */
-	sizeof (EggTrayIcon),
-	0,    /* n_preallocs */
-	(GInstanceInitFunc) egg_tray_icon_init,
-	NULL /* value_table */
-      };
-
-      our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0);
-        }
-      else if (parent_class == NULL)
-        {
-          /* we're reheating the old class from a previous instance -  engage ugly hack =( */
-          egg_tray_icon_class_init((EggTrayIconClass *)g_type_class_peek(our_type));
-        }
-    }
-
-  return our_type;
-}
-
-static void
-egg_tray_icon_init (EggTrayIcon *icon)
-{
-  icon->stamp = 1;
-  icon->orientation = GTK_ORIENTATION_HORIZONTAL;
-
-  gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
-}
-
-static void
-egg_tray_icon_class_init (EggTrayIconClass *klass)
-{
-  GObjectClass *gobject_class = (GObjectClass *)klass;
-  GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
-  GtkContainerClass *container_class = (GtkContainerClass *)klass;
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  gobject_class->get_property = egg_tray_icon_get_property;
-
-  widget_class->realize   = egg_tray_icon_realize;
-  widget_class->unrealize = egg_tray_icon_unrealize;
-
-  container_class->add = egg_tray_icon_add;
-
-  g_object_class_install_property (gobject_class,
-				   PROP_ORIENTATION,
-				   g_param_spec_enum ("orientation",
-						      _("Orientation"),
-						      _("The orientation of the tray."),
-						      GTK_TYPE_ORIENTATION,
-						      GTK_ORIENTATION_HORIZONTAL,
-						      G_PARAM_READABLE));
-}
-
-static void
-egg_tray_icon_get_property (GObject    *object,
-			    guint       prop_id,
-			    GValue     *value,
-			    GParamSpec *pspec)
-{
-  EggTrayIcon *icon = EGG_TRAY_ICON (object);
-
-  switch (prop_id)
-    {
-    case PROP_ORIENTATION:
-      g_value_set_enum (value, icon->orientation);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
-
-static Display *
-egg_tray_icon_get_x_display(EggTrayIcon *icon)
-{
-  Display *xdisplay = NULL;
-
-#if GTK_CHECK_VERSION(2,1,0)
-  {
-    GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (icon));
-    if (!GDK_IS_DISPLAY (display))
-      display = gdk_display_get_default ();
-
-    xdisplay = GDK_DISPLAY_XDISPLAY (display);
-  }
-#else
-  xdisplay = gdk_display;
-#endif
-
-  return xdisplay;
-}
-
-static void
-egg_tray_icon_get_orientation_property (EggTrayIcon *icon)
-{
-  Display *xdisplay;
-  Atom type;
-  int format;
-  union {
-	gulong *prop;
-	guchar *prop_ch;
-  } prop = { NULL };
-  gulong nitems;
-  gulong bytes_after;
-  int error, result;
-
-  g_return_if_fail(icon->manager_window != None);
-
-  xdisplay = egg_tray_icon_get_x_display(icon);
-
-  if (xdisplay == NULL)
-    return;
-
-  gdk_error_trap_push ();
-  type = None;
-  result = XGetWindowProperty (xdisplay,
-			       icon->manager_window,
-			       icon->orientation_atom,
-			       0, G_MAXLONG, FALSE,
-			       XA_CARDINAL,
-			       &type, &format, &nitems,
-			       &bytes_after, &(prop.prop_ch));
-  error = gdk_error_trap_pop ();
-
-  if (error || result != Success)
-    return;
-
-  if (type == XA_CARDINAL)
-    {
-      GtkOrientation orientation;
-
-      orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ?
-					GTK_ORIENTATION_HORIZONTAL :
-					GTK_ORIENTATION_VERTICAL;
-
-      if (icon->orientation != orientation)
-	{
-	  icon->orientation = orientation;
-
-	  g_object_notify (G_OBJECT (icon), "orientation");
-	}
-    }
-
-  if (prop.prop)
-    XFree (prop.prop);
-}
-
-static GdkFilterReturn
-egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data)
-{
-  EggTrayIcon *icon = user_data;
-  XEvent *xev = (XEvent *)xevent;
-
-  if (xev->xany.type == ClientMessage &&
-      xev->xclient.message_type == icon->manager_atom &&
-      xev->xclient.data.l[1] == icon->selection_atom)
-    {
-      egg_tray_icon_update_manager_window (icon, TRUE);
-    }
-  else if (xev->xany.window == icon->manager_window)
-    {
-      if (xev->xany.type == PropertyNotify &&
-	  xev->xproperty.atom == icon->orientation_atom)
-	{
-	  egg_tray_icon_get_orientation_property (icon);
-	}
-      if (xev->xany.type == DestroyNotify)
-	{
-	  egg_tray_icon_manager_window_destroyed (icon);
-	}
-    }
-
-  return GDK_FILTER_CONTINUE;
-}
-
-static void
-egg_tray_icon_unrealize (GtkWidget *widget)
-{
-  EggTrayIcon *icon = EGG_TRAY_ICON (widget);
-  GdkWindow *root_window;
-
-  if (icon->manager_window != None)
-    {
-      GdkWindow *gdkwin;
-
-#if GTK_CHECK_VERSION(2,1,0)
-      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget),
-                                              icon->manager_window);
-#else
-      gdkwin = gdk_window_lookup (icon->manager_window);
-#endif
-
-      gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
-    }
-
-#if GTK_CHECK_VERSION(2,1,0)
-  root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
-#else
-  root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ());
-#endif
-
-  gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon);
-
-  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
-    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
-}
-
-static void
-egg_tray_icon_send_manager_message (EggTrayIcon *icon,
-				    long         message,
-				    Window       window,
-				    long         data1,
-				    long         data2,
-				    long         data3)
-{
-  XClientMessageEvent ev;
-  Display *display;
-
-  ev.type = ClientMessage;
-  ev.window = window;
-  ev.message_type = icon->system_tray_opcode_atom;
-  ev.format = 32;
-  ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window);
-  ev.data.l[1] = message;
-  ev.data.l[2] = data1;
-  ev.data.l[3] = data2;
-  ev.data.l[4] = data3;
-
-#if GTK_CHECK_VERSION(2,1,0)
-  display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
-#else
-  display = gdk_display;
-#endif
-
-  gdk_error_trap_push ();
-  XSendEvent (display,
-	      icon->manager_window, False, NoEventMask, (XEvent *)&ev);
-  XSync (display, False);
-  gdk_error_trap_pop ();
-}
-
-static void
-egg_tray_icon_send_dock_request (EggTrayIcon *icon)
-{
-  egg_tray_icon_send_manager_message (icon,
-				      SYSTEM_TRAY_REQUEST_DOCK,
-				      icon->manager_window,
-				      gtk_plug_get_id (GTK_PLUG (icon)),
-				      0, 0);
-}
-
-static void
-egg_tray_icon_update_manager_window (EggTrayIcon *icon,
-				     gboolean     dock_if_realized)
-{
-  Display *xdisplay;
-
-  if (icon->manager_window != None)
-    return;
-
-  xdisplay = egg_tray_icon_get_x_display(icon);
-
-  if (xdisplay == NULL)
-    return;
-
-  XGrabServer (xdisplay);
-
-  icon->manager_window = XGetSelectionOwner (xdisplay,
-					     icon->selection_atom);
-
-  if (icon->manager_window != None)
-    XSelectInput (xdisplay,
-		  icon->manager_window, StructureNotifyMask|PropertyChangeMask);
-
-  XUngrabServer (xdisplay);
-  XFlush (xdisplay);
-
-  if (icon->manager_window != None)
-    {
-      GdkWindow *gdkwin;
-
-#if GTK_CHECK_VERSION(2,1,0)
-      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
-					      icon->manager_window);
-#else
-      gdkwin = gdk_window_lookup (icon->manager_window);
-#endif
-
-      gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);
-
-      if (dock_if_realized && GTK_WIDGET_REALIZED (icon))
-	egg_tray_icon_send_dock_request (icon);
-
-      egg_tray_icon_get_orientation_property (icon);
-    }
-}
-
-static void
-egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon)
-{
-  GdkWindow *gdkwin;
-
-  g_return_if_fail (icon->manager_window != None);
-
-#if GTK_CHECK_VERSION(2,1,0)
-  gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
-					  icon->manager_window);
-#else
-  gdkwin = gdk_window_lookup (icon->manager_window);
-#endif
-
-  gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
-
-  icon->manager_window = None;
-
-  egg_tray_icon_update_manager_window (icon, TRUE);
-}
-
-static gboolean
-transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
-{
-  GtkWidget *focus_child = NULL;
-  gint border_width, x, y, width, height;
-  gboolean retval = FALSE;
-
-  gdk_window_clear_area (widget->window, event->area.x, event->area.y,
-                         event->area.width, event->area.height);
-
-  if (GTK_WIDGET_CLASS (parent_class)->expose_event)
-    retval = GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
-
-  if (GTK_CONTAINER (widget)->focus_child)
-    focus_child = GTK_CONTAINER (GTK_CONTAINER (widget)->focus_child)->focus_child;
-  if (focus_child && GTK_WIDGET_HAS_FOCUS (focus_child))
-    {
-      border_width = GTK_CONTAINER (widget)->border_width;
-
-      x = widget->allocation.x + border_width;
-      y = widget->allocation.y + border_width;
-
-      width  = widget->allocation.width  - 2 * border_width;
-      height = widget->allocation.height - 2 * border_width;
-
-      gtk_paint_focus (widget->style, widget->window,
-                       GTK_WIDGET_STATE (widget),
-                       &event->area, widget, "tray_icon",
-                       x, y, width, height);
-    }
-
-  return retval;
-}
-
-static void
-make_transparent_again (GtkWidget *widget, GtkStyle *previous_style,
-                       gpointer user_data)
-{
-	gdk_window_set_back_pixmap(widget->window, NULL, TRUE);
-}
-
-static void
-make_transparent (GtkWidget *widget, gpointer user_data)
-{
-	if (GTK_WIDGET_NO_WINDOW (widget) || GTK_WIDGET_APP_PAINTABLE (widget))
-		return;
-
-	gtk_widget_set_app_paintable (widget, TRUE);
-	gtk_widget_set_double_buffered (widget, FALSE);
-	gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
-	g_signal_connect (widget, "expose_event",
-	                 G_CALLBACK (transparent_expose_event), NULL);
-	g_signal_connect_after (widget, "style_set",
-	                       G_CALLBACK (make_transparent_again), NULL);
-}
-
-static void
-egg_tray_icon_realize (GtkWidget *widget)
-{
-  EggTrayIcon *icon = EGG_TRAY_ICON (widget);
-  gint screen;
-  Display *xdisplay;
-  char buffer[256];
-  GdkWindow *root_window;
-
-  if (GTK_WIDGET_CLASS (parent_class)->realize)
-    GTK_WIDGET_CLASS (parent_class)->realize (widget);
-
-  make_transparent (widget, NULL);
-
-  xdisplay = egg_tray_icon_get_x_display(icon);
-
-  if (xdisplay == NULL)
-    return;
-
-#if GTK_CHECK_VERSION(2,1,0)
-  screen = gdk_screen_get_number (gtk_widget_get_screen (widget));
-#else
-  screen = XScreenNumberOfScreen (DefaultScreenOfDisplay (gdk_display));
-#endif
-
-  /* Now see if there's a manager window around */
-  g_snprintf (buffer, sizeof (buffer),
-	      "_NET_SYSTEM_TRAY_S%d",
-	      screen);
-
-  icon->selection_atom = XInternAtom (xdisplay, buffer, False);
-
-  icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False);
-
-  icon->system_tray_opcode_atom = XInternAtom (xdisplay,
-						   "_NET_SYSTEM_TRAY_OPCODE",
-						   False);
-
-  icon->orientation_atom = XInternAtom (xdisplay,
-					"_NET_SYSTEM_TRAY_ORIENTATION",
-					False);
-
-  egg_tray_icon_update_manager_window (icon, FALSE);
-  egg_tray_icon_send_dock_request (icon);
-
-#if GTK_CHECK_VERSION(2,1,0)
-  root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
-#else
-  root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ());
-#endif
-
-  /* Add a root window filter so that we get changes on MANAGER */
-  gdk_window_add_filter (root_window,
-			 egg_tray_icon_manager_filter, icon);
-}
-
-static void
-egg_tray_icon_add (GtkContainer *container, GtkWidget *widget)
-{
-	g_signal_connect (widget, "realize",
-	                 G_CALLBACK (make_transparent), NULL);
-	GTK_CONTAINER_CLASS (parent_class)->add (container, widget);
-}
-
-#if GTK_CHECK_VERSION(2,1,0)
-EggTrayIcon *
-egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name)
-{
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
-  return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL);
-}
-#endif
-
-EggTrayIcon*
-egg_tray_icon_new (const gchar *name)
-{
-  return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL);
-}
-
-guint
-egg_tray_icon_send_message (EggTrayIcon *icon,
-			    gint         timeout,
-			    const gchar *message,
-			    gint         len)
-{
-  guint stamp;
-
-  g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0);
-  g_return_val_if_fail (timeout >= 0, 0);
-  g_return_val_if_fail (message != NULL, 0);
-
-  if (icon->manager_window == None)
-    return 0;
-
-  if (len < 0)
-    len = strlen (message);
-
-  stamp = icon->stamp++;
-
-  /* Get ready to send the message */
-  egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,
-				      (Window)gtk_plug_get_id (GTK_PLUG (icon)),
-				      timeout, len, stamp);
-
-  /* Now to send the actual message */
-  gdk_error_trap_push ();
-  while (len > 0)
-    {
-      XClientMessageEvent ev;
-      Display *xdisplay;
-
-      xdisplay = egg_tray_icon_get_x_display(icon);
-
-      if (xdisplay == NULL)
-        return 0;
-
-      ev.type = ClientMessage;
-      ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon));
-      ev.format = 8;
-      ev.message_type = XInternAtom (xdisplay,
-				     "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
-      if (len > 20)
-	{
-	  memcpy (&ev.data, message, 20);
-	  len -= 20;
-	  message += 20;
-	}
-      else
-	{
-	  memcpy (&ev.data, message, len);
-	  len = 0;
-	}
-
-      XSendEvent (xdisplay,
-		  icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev);
-      XSync (xdisplay, False);
-    }
-  gdk_error_trap_pop ();
-
-  return stamp;
-}
-
-void
-egg_tray_icon_cancel_message (EggTrayIcon *icon,
-			      guint        id)
-{
-  g_return_if_fail (EGG_IS_TRAY_ICON (icon));
-  g_return_if_fail (id > 0);
-
-  egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
-				      (Window)gtk_plug_get_id (GTK_PLUG (icon)),
-				      id, 0, 0);
-}
-
-GtkOrientation
-egg_tray_icon_get_orientation (EggTrayIcon *icon)
-{
-  g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL);
-
-  return icon->orientation;
-}
--- a/pidgin/eggtrayicon.h	Fri Apr 09 14:56:00 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* eggtrayicon.h
- * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02111-1301, USA.
- */
-
-#ifndef __EGG_TRAY_ICON_H__
-#define __EGG_TRAY_ICON_H__
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-G_BEGIN_DECLS
-
-#define EGG_TYPE_TRAY_ICON		(egg_tray_icon_get_type ())
-#define EGG_TRAY_ICON(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon))
-#define EGG_TRAY_ICON_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
-#define EGG_IS_TRAY_ICON(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON))
-#define EGG_IS_TRAY_ICON_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON))
-#define EGG_TRAY_ICON_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
-
-typedef struct _EggTrayIcon	  EggTrayIcon;
-typedef struct _EggTrayIconClass  EggTrayIconClass;
-
-struct _EggTrayIcon
-{
-  GtkPlug parent_instance;
-
-  guint stamp;
-
-  Atom selection_atom;
-  Atom manager_atom;
-  Atom system_tray_opcode_atom;
-  Atom orientation_atom;
-  Window manager_window;
-
-  GtkOrientation orientation;
-};
-
-struct _EggTrayIconClass
-{
-  GtkPlugClass parent_class;
-};
-
-GType        egg_tray_icon_get_type       (void);
-
-#if GTK_CHECK_VERSION(2,1,0)
-EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen   *screen,
-					   const gchar *name);
-#endif
-
-EggTrayIcon *egg_tray_icon_new            (const gchar *name);
-
-guint        egg_tray_icon_send_message   (EggTrayIcon *icon,
-					   gint         timeout,
-					   const char  *message,
-					   gint         len);
-void         egg_tray_icon_cancel_message (EggTrayIcon *icon,
-					   guint        id);
-
-GtkOrientation egg_tray_icon_get_orientation (EggTrayIcon *icon);
-
-G_END_DECLS
-
-#endif /* __EGG_TRAY_ICON_H__ */
--- a/pidgin/gtkconv.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/gtkconv.c	Thu Apr 15 16:48:50 2010 +0900
@@ -4941,12 +4941,11 @@
 pidgin_conv_setup_quickfind(PidginConversation *gtkconv, GtkWidget *container)
 {
 	GtkWidget *widget = gtk_hbox_new(FALSE, 0);
-	GtkWidget *label, *entry, *close, *image;
+	GtkWidget *label, *entry, *close;
 
 	gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
 
-	image = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
-	close = pidgin_create_small_button(image);
+	close = pidgin_create_small_button(gtk_label_new("×"));
 	gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0);
 	gtk_tooltips_set_tip(gtkconv->tooltips, close,
 	                     _("Close Find bar"), NULL);
@@ -9586,7 +9585,6 @@
 	GtkWidget *tab_cont = gtkconv->tab_cont;
 	PurpleConversationType conv_type;
 	const gchar *tmp_lab;
-	GtkWidget *close_image;
 
 	conv_type = purple_conversation_get_type(conv);
 
@@ -9598,8 +9596,7 @@
 
 
 	/* Close button. */
-	close_image = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
-	gtkconv->close = pidgin_create_small_button(close_image);
+	gtkconv->close = pidgin_create_small_button(gtk_label_new("×"));
 	gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
 	                     _("Close conversation"), NULL);
 
--- a/pidgin/gtkeventloop.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/gtkeventloop.c	Thu Apr 15 16:48:50 2010 +0900
@@ -41,11 +41,6 @@
 
 } PidginIOClosure;
 
-static void pidgin_io_destroy(gpointer data)
-{
-	g_free(data);
-}
-
 static gboolean pidgin_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
 {
 	PidginIOClosure *closure = data;
@@ -57,7 +52,7 @@
 		purple_cond |= PURPLE_INPUT_WRITE;
 
 #if 0
-	purple_debug(PURPLE_DEBUG_MISC, "gtk_eventloop",
+	purple_debug_misc("gtk_eventloop",
 			   "CLOSURE: callback for %d, fd is %d\n",
 			   closure->result, g_io_channel_unix_get_fd(source));
 #endif
@@ -65,7 +60,7 @@
 #ifdef _WIN32
 	if(! purple_cond) {
 #ifdef DEBUG
-		purple_debug(PURPLE_DEBUG_MISC, "gtk_eventloop",
+		purple_debug_misc("gtk_eventloop",
 			   "CLOSURE received GIOCondition of 0x%x, which does not"
 			   " match 0x%x (READ) or 0x%x (WRITE)\n",
 			   condition, PIDGIN_READ_COND, PIDGIN_WRITE_COND);
@@ -110,10 +105,10 @@
 	channel = g_io_channel_unix_new(fd);
 
 	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
-					      pidgin_io_invoke, closure, pidgin_io_destroy);
+					      pidgin_io_invoke, closure, g_free);
 
 #if 0
-	purple_debug(PURPLE_DEBUG_MISC, "gtk_eventloop",
+	purple_debug_misc("gtk_eventloop",
 			   "CLOSURE: adding input watcher %d for fd %d\n",
 			   closure->result, fd);
 #endif
--- a/pidgin/gtkmain.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/gtkmain.c	Thu Apr 15 16:48:50 2010 +0900
@@ -167,7 +167,7 @@
 
 	if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
 		char errmsg[BUFSIZ];
-		snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
+		snprintf(errmsg, sizeof(errmsg), "Warning: waitpid() returned %d", pid);
 		perror(errmsg);
 	}
 }
@@ -539,10 +539,11 @@
 	char errmsg[BUFSIZ];
 	GIOChannel *signal_channel;
 	GIOStatus signal_status;
+	guint signal_channel_watcher;
 #ifndef DEBUG
 	char *segfault_message_tmp;
 #endif
-	GError *error = NULL;
+	GError *error;
 #endif
 	int opt;
 	gboolean gui_check;
@@ -608,6 +609,7 @@
 		/* we have to convert the message (UTF-8 to console
 		   charset) early because after a segmentation fault
 		   it's not a good practice to allocate memory */
+		error = NULL;
 		segfault_message = g_locale_from_utf8(segfault_message_tmp,
 						      -1, NULL, NULL, &error);
 		if (segfault_message != NULL) {
@@ -652,7 +654,8 @@
 				"binary: %s", error->message);
 		exit(1);
 	}
-	g_io_add_watch(signal_channel, G_IO_IN, mainloop_sighandler, NULL);
+	signal_channel_watcher = g_io_add_watch(signal_channel, G_IO_IN, mainloop_sighandler, NULL);
+	g_io_channel_unref(signal_channel);
 
 	/* Let's not violate any PLA's!!!! */
 	/* jseymour: whatever the fsck that means */
@@ -660,31 +663,31 @@
 	 * useful signals like SIGCHLD, so we unblock all the ones we  *
 	 * declare a handler for. thanks JSeymour and Vann.            */
 	if (sigemptyset(&sigset)) {
-		snprintf(errmsg, BUFSIZ, "Warning: couldn't initialise empty signal set");
+		snprintf(errmsg, sizeof(errmsg), "Warning: couldn't initialise empty signal set");
 		perror(errmsg);
 	}
 	for(sig_indx = 0; catch_sig_list[sig_indx] != -1; ++sig_indx) {
 		if((prev_sig_disp = signal(catch_sig_list[sig_indx], sighandler)) == SIG_ERR) {
-			snprintf(errmsg, BUFSIZ, "Warning: couldn't set signal %d for catching",
+			snprintf(errmsg, sizeof(errmsg), "Warning: couldn't set signal %d for catching",
 				catch_sig_list[sig_indx]);
 			perror(errmsg);
 		}
 		if(sigaddset(&sigset, catch_sig_list[sig_indx])) {
-			snprintf(errmsg, BUFSIZ, "Warning: couldn't include signal %d for unblocking",
+			snprintf(errmsg, sizeof(errmsg), "Warning: couldn't include signal %d for unblocking",
 				catch_sig_list[sig_indx]);
 			perror(errmsg);
 		}
 	}
 	for(sig_indx = 0; ignore_sig_list[sig_indx] != -1; ++sig_indx) {
 		if((prev_sig_disp = signal(ignore_sig_list[sig_indx], SIG_IGN)) == SIG_ERR) {
-			snprintf(errmsg, BUFSIZ, "Warning: couldn't set signal %d to ignore",
+			snprintf(errmsg, sizeof(errmsg), "Warning: couldn't set signal %d to ignore",
 				ignore_sig_list[sig_indx]);
 			perror(errmsg);
 		}
 	}
 
 	if (sigprocmask(SIG_UNBLOCK, &sigset, NULL)) {
-		snprintf(errmsg, BUFSIZ, "Warning: couldn't unblock signals");
+		snprintf(errmsg, sizeof(errmsg), "Warning: couldn't unblock signals");
 		perror(errmsg);
 	}
 #endif
@@ -977,6 +980,9 @@
 
 #ifdef HAVE_SIGNAL_H
 	g_free(segfault_message);
+	g_source_remove(signal_channel_watcher);
+	close(signal_sockets[0]);
+	close(signal_sockets[1]);
 #endif
 
 #ifdef _WIN32
--- a/pidgin/gtkutils.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/gtkutils.c	Thu Apr 15 16:48:50 2010 +0900
@@ -3484,6 +3484,9 @@
 	                    "GtkWidget::focus-line-width = 0\n"
 	                    "xthickness = 0\n"
 	                    "ythickness = 0\n"
+	                    "GtkContainer::border-width = 0\n"
+	                    "GtkButton::inner-border = {0, 0, 0, 0}\n"
+	                    "GtkButton::default-border = {0, 0, 0, 0}\n"
 	                    "}\n"
 	                    "widget \"*.pidgin-small-close-button\" style \"pidgin-small-close-button\"");
 
--- a/pidgin/plugins/convcolors.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/convcolors.c	Thu Apr 15 16:48:50 2010 +0900
@@ -198,7 +198,12 @@
 {
 	if (response == GTK_RESPONSE_OK)
 	{
+#if GTK_CHECK_VERSION(2,14,0)
+		GtkWidget *colorsel =
+			gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog));
+#else
 		GtkWidget *colorsel = GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel;
+#endif
 		GdkColor color;
 		char colorstr[8];
 		char tmp[128];
@@ -232,8 +237,15 @@
 	g_snprintf(tmp, sizeof(tmp), "%s/color", data);
 	if (gdk_color_parse(purple_prefs_get_string(tmp), &color))
 	{
+#if GTK_CHECK_VERSION(2,14,0)
+		gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(
+			gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog))),
+			&color);
+#else
 		gtk_color_selection_set_current_color(
-				GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), &color);
+			GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel),
+			&color);
+#endif
 	}
 
 	gtk_window_present(GTK_WINDOW(color_dialog));
--- a/pidgin/plugins/disco/gtkdisco.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/disco/gtkdisco.c	Thu Apr 15 16:48:50 2010 +0900
@@ -430,7 +430,13 @@
 disco_paint_tooltip(GtkWidget *tipwindow, gpointer data)
 {
 	PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
+#if GTK_CHECK_VERSION(2,14,0)
+	gtk_paint_layout(gtk_widget_get_style(tipwindow),
+			gtk_widget_get_window(tipwindow),
+			GTK_STATE_NORMAL, FALSE,
+#else
 	gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
+#endif
 			NULL, tipwindow, "tooltip",
 			6, 6, layout);
 	return TRUE;
--- a/pidgin/plugins/gestures/stroke-draw.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/gestures/stroke-draw.c	Thu Apr 15 16:48:50 2010 +0900
@@ -19,6 +19,9 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
+#if !GTK_CHECK_VERSION(2,14,0)
+#define gtk_widget_get_window(x) x->window
+#endif
 
 static void gstroke_invisible_window_init (GtkWidget *widget);
 /*FIXME: Maybe these should be put in a structure, and not static...*/
@@ -75,7 +78,8 @@
       /* FIXME: this does not work. It will only work if we create a
          corresponding GDK window for stroke_window and draw on
          that... */
-      gdk_draw_line (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
+      gdk_draw_line (gtk_widget_get_window(widget),
+                     widget->style->fg_gc[GTK_STATE_NORMAL],
                      last_mouse_position.last_point.x,
                      last_mouse_position.last_point.y,
                      x,
@@ -156,7 +160,7 @@
 	  if (cursor == NULL)
 		  cursor = gdk_cursor_new(GDK_PENCIL);
 
-      gdk_pointer_grab (widget->window, FALSE,
+      gdk_pointer_grab (gtk_widget_get_window(widget), FALSE,
 			GDK_BUTTON_RELEASE_MASK, NULL, cursor,
 			event->button.time);
       timer_id = g_timeout_add (GSTROKE_TIMEOUT_DURATION,
@@ -334,8 +338,8 @@
   unsigned long mask, col_border, col_background;
   unsigned int border_width;
   XSizeHints hints;
-  Display *disp = GDK_WINDOW_XDISPLAY(widget->window);
-  Window wind = GDK_WINDOW_XWINDOW (widget->window);
+  Display *disp = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(widget));
+  Window wind = GDK_WINDOW_XWINDOW (gtk_widget_get_window(widget));
   int screen = DefaultScreen (disp);
 
 	if (!gstroke_draw_strokes())
--- a/pidgin/plugins/notify.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/notify.c	Thu Apr 15 16:48:50 2010 +0900
@@ -547,7 +547,11 @@
 	}
 
 	count = count_messages(purplewin);
+#if GTK_CHECK_VERSION(2,14,0)
+	gdkwin = gtk_widget_get_window(window);
+#else
 	gdkwin = window->window;
+#endif
 
 	gdk_property_change(gdkwin, _PurpleUnseenCount, _Cardinal, 32,
 	                    GDK_PROP_MODE_REPLACE, (guchar *) &count, 1);
--- a/pidgin/plugins/pidginrc.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/pidginrc.c	Thu Apr 15 16:48:50 2010 +0900
@@ -242,7 +242,12 @@
 	if (response == GTK_RESPONSE_OK) {
 		GdkColor color;
 		gchar colorstr[8];
+#if GTK_CHECK_VERSION(2,14,0)
+		GtkWidget *colorsel =
+			gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog));
+#else
 		GtkWidget *colorsel = GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel;
+#endif
 
 		gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(colorsel), &color);
 
@@ -273,7 +278,13 @@
 
 	if (pref != NULL && strcmp(pref, "")) {
 		if (gdk_color_parse(pref, &color)) {
+#if GTK_CHECK_VERSION(2,14,0)
+			gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(
+				gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog))),
+				&color);
+#else
 			gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), &color);
+#endif
 		}
 	}
 
@@ -327,7 +338,7 @@
 	pref = purple_prefs_get_string(prefpath);
 
 	if (pref != NULL && strcmp(pref, "")) {
-		gtk_font_selection_set_font_name(GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(font_dialog)->fontsel), pref);
+		gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(font_dialog), pref);
 	}
 
 	gtk_window_present(GTK_WINDOW(font_dialog));
--- a/pidgin/plugins/themeedit.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/themeedit.c	Thu Apr 15 16:48:50 2010 +0900
@@ -61,10 +61,17 @@
 theme_color_selected(GtkDialog *dialog, gint response, const char *prop)
 {
 	if (response == GTK_RESPONSE_OK) {
+		GtkWidget *colorsel;
 		GdkColor color;
 		PidginBlistTheme *theme;
 
-		gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dialog)->colorsel), &color);
+#if GTK_CHECK_VERSION(2,14,0)
+		colorsel =
+			gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog));
+#else
+		colorsel = GTK_COLOR_SELECTION_DIALOG(dialog)->colorsel;
+#endif
+		gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(colorsel), &color);
 
 		theme = pidgin_blist_get_theme();
 
@@ -119,7 +126,7 @@
 	face = pidgin_theme_font_get_font_face(font);
 	dialog = gtk_font_selection_dialog_new(_("Select Font"));
 	if (face && *face)
-		gtk_font_selection_set_font_name(GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(dialog)->fontsel),
+		gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dialog),
 				face);
 	g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(theme_font_face_selected),
 			font);
@@ -145,9 +152,16 @@
 	}
 
 	dialog = gtk_color_selection_dialog_new(_("Select Color"));
+#if GTK_CHECK_VERSION(2,14,0)
+	if (color)
+		gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(
+			gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog))),
+			color);
+#else
 	if (color)
 		gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dialog)->colorsel),
 				color);
+#endif
 	g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(theme_color_selected),
 			prop);
 
--- a/pidgin/plugins/ticker/gtkticker.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/ticker/gtkticker.c	Thu Apr 15 16:48:50 2010 +0900
@@ -21,9 +21,37 @@
  * GtkTicker Copyright 2000 Syd Logan
  */
 
+/* FIXME: GTK+ deprecated GTK_WIDGET_MAPPED/REALIZED, but don't provide
+          accessor functions yet. */
+#undef GSEAL_ENABLE
+
 #include "gtkticker.h"
 #include <gtk/gtk.h>
 
+/* These don't seem to be in a release yet. See BZ #69872 */
+#define gtk_widget_is_mapped(x) GTK_WIDGET_MAPPED(x)
+#define gtk_widget_is_realized(x) GTK_WIDGET_REALIZED(x)
+#define gtk_widget_set_realized(x,y) do {\
+	if (y) \
+		GTK_WIDGET_SET_FLAGS(x, GTK_REALIZED); \
+	else \
+		GTK_WIDGET_UNSET_FLAGS(x, GTK_REALIZED); \
+} while(0)
+#define gtk_widget_set_mapped(x,y) do {\
+	if (y) \
+		GTK_WIDGET_SET_FLAGS(x, GTK_MAPPED); \
+	else \
+		GTK_WIDGET_UNSET_FLAGS(x, GTK_MAPPED); \
+} while(0)
+
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
+
+#if !GTK_CHECK_VERSION(2,14,0)
+#define gtk_widget_get_window(x) x->window
+#endif
+#endif
+
 static void gtk_ticker_compute_offsets (GtkTicker    *ticker);
 static void gtk_ticker_class_init    (GtkTickerClass    *klass);
 static void gtk_ticker_init          (GtkTicker         *ticker);
@@ -119,7 +147,11 @@
 
 static void gtk_ticker_init (GtkTicker *ticker)
 {
+#if GTK_CHECK_VERSION(2,18,0)
+	gtk_widget_set_has_window (GTK_WIDGET (ticker), TRUE);
+#else
 	GTK_WIDGET_UNSET_FLAGS (ticker, GTK_NO_WINDOW);
+#endif
 
 	ticker->interval = (guint) 200;
 	ticker->scootch = (guint) 2;
@@ -149,12 +181,13 @@
 
 	ticker->children = g_list_append (ticker->children, child_info);
 
-	if (GTK_WIDGET_REALIZED (ticker))
+	if (gtk_widget_is_realized (ticker))
 		gtk_widget_realize (widget);
 
-	if (GTK_WIDGET_VISIBLE (ticker) && GTK_WIDGET_VISIBLE (widget))
+	if (gtk_widget_get_visible (GTK_WIDGET (ticker)) &&
+		gtk_widget_get_visible (widget))
 	{
-		if (GTK_WIDGET_MAPPED (ticker))
+		if (gtk_widget_is_mapped (GTK_WIDGET (ticker)))
 			gtk_widget_map (widget);
 
 		gtk_widget_queue_resize (GTK_WIDGET (ticker));
@@ -213,7 +246,7 @@
 {
 	GtkTicker *ticker = (GtkTicker *) data;
 
-	if (GTK_WIDGET_VISIBLE (ticker))
+	if (gtk_widget_get_visible (GTK_WIDGET (ticker)))
 		gtk_widget_queue_resize (GTK_WIDGET (ticker));
 
 	return( TRUE );
@@ -255,7 +288,7 @@
 	g_return_if_fail (widget != NULL);
 	g_return_if_fail (GTK_IS_TICKER (widget));
 
-	GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+	gtk_widget_set_mapped (widget, TRUE);
 	ticker = GTK_TICKER (widget);
 
 	children = ticker->children;
@@ -264,29 +297,42 @@
 		child = children->data;
 		children = children->next;
 
-		if (GTK_WIDGET_VISIBLE (child->widget) &&
-				!GTK_WIDGET_MAPPED (child->widget))
+		if (gtk_widget_get_visible (child->widget) &&
+				!gtk_widget_is_mapped (child->widget))
 			gtk_widget_map (child->widget);
 	}
 
-	gdk_window_show (widget->window);
+	gdk_window_show (gtk_widget_get_window (widget));
 }
 
 static void gtk_ticker_realize (GtkWidget *widget)
 {
 	GdkWindowAttr attributes;
 	gint attributes_mask;
+	GdkWindow *window;
+	GtkStyle *style;
+#if GTK_CHECK_VERSION(2,18,0)
+	GtkAllocation allocation;
+#endif
 
 	g_return_if_fail (widget != NULL);
 	g_return_if_fail (GTK_IS_TICKER (widget));
 
-	GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+	gtk_widget_set_realized (widget, TRUE);
 
 	attributes.window_type = GDK_WINDOW_CHILD;
+#if GTK_CHECK_VERSION(2,18,0)
+	gtk_widget_get_allocation (widget, &allocation);
+	attributes.x = allocation.x;
+	attributes.y = allocation.y;
+	attributes.width = allocation.width;
+	attributes.height = allocation.height;
+#else
 	attributes.x = widget->allocation.x;
 	attributes.y = widget->allocation.y;
 	attributes.width = widget->allocation.width;
 	attributes.height = widget->allocation.height;
+#endif
 	attributes.wclass = GDK_INPUT_OUTPUT;
 	attributes.visual = gtk_widget_get_visual (widget);
 	attributes.colormap = gtk_widget_get_colormap (widget);
@@ -295,12 +341,23 @@
 
 	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
-	widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+	window = gdk_window_new (gtk_widget_get_parent_window (widget),
 			&attributes, attributes_mask);
-	gdk_window_set_user_data (widget->window, widget);
+#if GTK_CHECK_VERSION(2,14,0)
+	gtk_widget_set_window (widget, window);
+#else
+	widget->window = window;
+#endif
+	gdk_window_set_user_data (window, widget);
 
-	widget->style = gtk_style_attach (widget->style, widget->window);
-	gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+#if GTK_CHECK_VERSION(2,14,0)
+	style = gtk_widget_get_style (widget);
+	style = gtk_style_attach (style, window);
+	gtk_widget_set_style (widget, style);
+#else
+	style = widget->style = gtk_style_attach (widget->style, window);
+#endif
+	gtk_style_set_background (style, window, GTK_STATE_NORMAL);
 }
 
 static void gtk_ticker_size_request (GtkWidget *widget, GtkRequisition *requisition)
@@ -309,6 +366,7 @@
 	GtkTickerChild *child;
 	GList *children;
 	GtkRequisition child_requisition;
+	guint border_width;
 
 	g_return_if_fail (widget != NULL);
 	g_return_if_fail (GTK_IS_TICKER (widget));
@@ -324,7 +382,7 @@
 		child = children->data;
 		children = children->next;
 
-		if (GTK_WIDGET_VISIBLE (child->widget))
+		if (gtk_widget_get_visible (child->widget))
 		{
 			gtk_widget_size_request (child->widget, &child_requisition);
 
@@ -336,8 +394,9 @@
 	if ( requisition->width > ticker->spacing )
 		requisition->width -= ticker->spacing;
 
-	requisition->height += GTK_CONTAINER (ticker)->border_width * 2;
-	requisition->width += GTK_CONTAINER (ticker)->border_width * 2;
+	border_width = gtk_container_get_border_width (GTK_CONTAINER (ticker));
+	requisition->height += border_width * 2;
+	requisition->width += border_width * 2;
 }
 
 static void gtk_ticker_compute_offsets (GtkTicker *ticker)
@@ -350,16 +409,24 @@
 	g_return_if_fail (ticker != NULL);
 	g_return_if_fail (GTK_IS_TICKER(ticker));
 
-	border_width = GTK_CONTAINER (ticker)->border_width;
+	border_width = gtk_container_get_border_width (GTK_CONTAINER (ticker));
 
+#if GTK_CHECK_VERSION(2,18,0)
+	{
+		GtkAllocation allocation;
+		gtk_widget_get_allocation (GTK_WIDGET (ticker), &allocation);
+		ticker->width = allocation.width;
+	}
+#else
 	ticker->width = GTK_WIDGET(ticker)->allocation.width;
+#endif
 	ticker->total = 0;
 	children = ticker->children;
 	while (children) {
 		child = children->data;
 
 		child->x = 0;
-		if (GTK_WIDGET_VISIBLE (child->widget)) {
+		if (gtk_widget_get_visible (child->widget)) {
 			gtk_widget_get_child_requisition (child->widget, &child_requisition);
 			child->offset = ticker->total;
 			ticker->total +=
@@ -386,22 +453,35 @@
 
 	ticker = GTK_TICKER (widget);
 
+#if GTK_CHECK_VERSION(2,18,0)
+	{
+		GtkAllocation a;
+		gtk_widget_get_allocation (GTK_WIDGET (ticker), &a);
+		if ( a.width != ticker->width )
+			ticker->dirty = TRUE;
+	}
+#else
 	if ( GTK_WIDGET(ticker)->allocation.width != ticker->width )
 		ticker->dirty = TRUE;
+#endif
 
 	if ( ticker->dirty == TRUE ) {
 		gtk_ticker_compute_offsets( ticker );
 	}
 
+#if GTK_CHECK_VERSION(2,18,0)
+	gtk_widget_set_allocation (widget, allocation);
+#else
 	widget->allocation = *allocation;
-	if (GTK_WIDGET_REALIZED (widget))
-		gdk_window_move_resize (widget->window,
+#endif
+	if (gtk_widget_is_realized (widget))
+		gdk_window_move_resize (gtk_widget_get_window (widget),
 				allocation->x,
 				allocation->y,
 				allocation->width,
 				allocation->height);
 
-	border_width = GTK_CONTAINER (ticker)->border_width;
+	border_width = gtk_container_get_border_width (GTK_CONTAINER (ticker));
 
 	children = ticker->children;
 	while (children)
@@ -409,16 +489,16 @@
 		child = children->data;
 		child->x -= ticker->scootch;
 
-		if (GTK_WIDGET_VISIBLE (child->widget)) {
+		if (gtk_widget_get_visible (child->widget)) {
 			gtk_widget_get_child_requisition (child->widget, &child_requisition);
 			child_allocation.width = child_requisition.width;
 			child_allocation.x = child->offset + border_width + child->x;
-			if ( ( child_allocation.x + child_allocation.width ) < GTK_WIDGET(ticker)->allocation.x  ) {
-				if ( ticker->total >=  GTK_WIDGET(ticker)->allocation.width ) {
-					child->x += GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width + ( ticker->total - ( GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width ) );
+			if ( ( child_allocation.x + child_allocation.width ) < allocation->x  ) {
+				if ( ticker->total >=  allocation->width ) {
+					child->x += allocation->x + allocation->width + ( ticker->total - ( allocation->x + allocation->width ) );
 				}
 				else {
-					child->x += GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width;
+					child->x += allocation->x + allocation->width;
 				}
 			}
 			child_allocation.y = border_width;
@@ -469,7 +549,7 @@
 
 		if (child->widget == widget)
 		{
-			gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
+			gboolean was_visible = gtk_widget_get_visible (widget);
 
 			gtk_widget_unparent (widget);
 
@@ -477,7 +557,7 @@
 			g_list_free (children);
 			g_free (child);
 
-			if (was_visible && GTK_WIDGET_VISIBLE (container))
+			if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
 				gtk_widget_queue_resize (GTK_WIDGET (container));
 
 			break;
--- a/pidgin/plugins/timestamp_format.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/timestamp_format.c	Thu Apr 15 16:48:50 2010 +0900
@@ -8,6 +8,7 @@
 
 #include "gtkconv.h"
 #include "gtkplugin.h"
+#include "gtkimhtml.h"
 
 #include <time.h>
 
@@ -108,19 +109,101 @@
 	return timestamp_cb_common(log->conv, t, show_date, force, dates, FALSE);
 }
 
+static void
+menu_cb(GtkWidget *item, gpointer data)
+{
+	PurplePlugin *plugin = data;
+	GtkWidget *frame = pidgin_plugin_get_config_frame(plugin), *dialog;
+	if (!frame)
+		return;
+
+	dialog = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, NULL,
+			GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
+			GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+			NULL);
+	g_signal_connect_after(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), dialog);
+#if GTK_CHECK_VERSION(2,14,0)
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), frame);
+#else
+	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), frame);
+#endif
+	gtk_window_set_role(GTK_WINDOW(dialog), "plugin_config");
+	gtk_window_set_title(GTK_WINDOW(dialog), _(purple_plugin_get_name(plugin)));
+	gtk_widget_show_all(dialog);
+}
+
+static gboolean
+textview_emission_hook(GSignalInvocationHint *hint, guint n_params,
+		const GValue *pvalues, gpointer data)
+{
+	GtkTextView *view = GTK_TEXT_VIEW(g_value_get_object(pvalues));
+	GtkWidget *menu, *item;
+	GtkTextBuffer *buffer;
+	GtkTextIter cursor;
+	int cx, cy, bx, by;
+
+	if (!GTK_IS_IMHTML(view))
+		return TRUE;
+
+#if GTK_CHECK_VERSION(2,14,0)
+	if (!gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(view)), &cx, &cy, NULL))
+		return TRUE;
+#else
+	if (!gdk_window_get_pointer(GTK_WIDGET(view)->window, &cx, &cy, NULL))
+		return TRUE;
+#endif
+
+	buffer = gtk_text_view_get_buffer(view);
+
+	gtk_text_view_window_to_buffer_coords(view, GTK_TEXT_WINDOW_TEXT, cx, cy, &bx, &by);
+	gtk_text_view_get_iter_at_location(view, &cursor, bx, by);
+	if (!gtk_text_iter_has_tag(&cursor,
+				gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), "comment")))
+		return TRUE;
+
+	menu = g_value_get_object(&pvalues[1]);
+
+	item = gtk_menu_item_new_with_label(_("Timestamp Format Options"));
+	gtk_widget_show_all(item);
+	g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(menu_cb), data);
+	gtk_menu_shell_insert(GTK_MENU_SHELL(menu), item, 0);
+
+	item = gtk_separator_menu_item_new();
+	gtk_widget_show(item);
+	gtk_menu_shell_insert(GTK_MENU_SHELL(menu), item, 1);
+
+	return TRUE;
+}
+
+static guint signal_id;
+static gulong hook_id;
+
 static gboolean
 plugin_load(PurplePlugin *plugin)
 {
+	gpointer klass = NULL;
+
 	purple_signal_connect(pidgin_conversations_get_handle(), "conversation-timestamp",
 	                    plugin, PURPLE_CALLBACK(conversation_timestamp_cb), NULL);
 	purple_signal_connect(purple_log_get_handle(), "log-timestamp",
 	                    plugin, PURPLE_CALLBACK(log_timestamp_cb), NULL);
+
+	klass = g_type_class_ref(GTK_TYPE_TEXT_VIEW);
+
+	/* In 3.0.0, use purple_g_signal_connect_flags */
+	g_signal_parse_name("populate_popup", GTK_TYPE_TEXT_VIEW, &signal_id, NULL, FALSE);
+	hook_id = g_signal_add_emission_hook(signal_id, 0, textview_emission_hook,
+			plugin, NULL);
+
+	g_type_class_unref(klass);
+
 	return TRUE;
 }
 
 static gboolean
 plugin_unload(PurplePlugin *plugin)
 {
+	g_signal_remove_emission_hook(signal_id, hook_id);
 	return TRUE;
 }
 
--- a/pidgin/plugins/xmppconsole.c	Fri Apr 09 14:56:00 2010 +0900
+++ b/pidgin/plugins/xmppconsole.c	Thu Apr 15 16:48:50 2010 +0900
@@ -258,7 +258,7 @@
 
 static void iq_clicked_cb(GtkWidget *w, gpointer nul)
 {
-	GtkWidget *hbox, *to_entry, *label, *type_combo;
+	GtkWidget *vbox, *hbox, *to_entry, *label, *type_combo;
 	GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 	GtkTextIter iter;
 	GtkTextBuffer *buffer;
@@ -277,9 +277,14 @@
 	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
 	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
+#if GTK_CHECK_VERSION(2,14,0)
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+#else
+	vbox = GTK_DIALOG(dialog)->vbox;
+#endif
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("To:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -291,7 +296,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), to_entry, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 	label = gtk_label_new("Type:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
@@ -305,7 +310,7 @@
 	gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);
 	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
 
-	gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+	gtk_widget_show_all(vbox);
 
 	result = gtk_dialog_run(GTK_DIALOG(dialog));
 	if (result != GTK_RESPONSE_ACCEPT) {
@@ -334,6 +339,7 @@
 
 static void presence_clicked_cb(GtkWidget *w, gpointer nul)
 {
+	GtkWidget *vbox;
 	GtkWidget *hbox;
 	GtkWidget *to_entry;
 	GtkWidget *status_entry;
@@ -359,9 +365,14 @@
 	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
 	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
+#if GTK_CHECK_VERSION(2,14,0)
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+#else
+	vbox = GTK_DIALOG(dialog)->vbox;
+#endif
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("To:");
 	gtk_size_group_add_widget(sg, label);
@@ -373,7 +384,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), to_entry, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 	label = gtk_label_new("Type:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_size_group_add_widget(sg, label);
@@ -391,7 +402,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 	label = gtk_label_new("Show:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_size_group_add_widget(sg, label);
@@ -407,7 +418,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), show_combo, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("Status:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -419,7 +430,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), status_entry, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("Priority:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -430,7 +441,7 @@
 	gtk_spin_button_set_value(GTK_SPIN_BUTTON(priority_entry), 0);
 	gtk_box_pack_start(GTK_BOX(hbox), priority_entry, FALSE, FALSE, 0);
 
-	gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+	gtk_widget_show_all(vbox);
 
 	result = gtk_dialog_run(GTK_DIALOG(dialog));
 	if (result != GTK_RESPONSE_ACCEPT) {
@@ -486,6 +497,7 @@
 
 static void message_clicked_cb(GtkWidget *w, gpointer nul)
 {
+	GtkWidget *vbox;
 	GtkWidget *hbox;
 	GtkWidget *to_entry;
 	GtkWidget *body_entry;
@@ -511,9 +523,14 @@
 	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
 	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
+#if GTK_CHECK_VERSION(2,14,0)
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+#else
+	vbox = GTK_DIALOG(dialog)->vbox;
+#endif
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("To:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -525,7 +542,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), to_entry, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 	label = gtk_label_new("Type:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_size_group_add_widget(sg, label);
@@ -540,7 +557,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("Body:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -552,7 +569,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), body_entry, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("Subject:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -564,7 +581,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), subject_entry, FALSE, FALSE, 0);
 
 	hbox = gtk_hbox_new(FALSE, 3);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
 	label = gtk_label_new("Thread:");
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -575,7 +592,7 @@
 	gtk_entry_set_activates_default (GTK_ENTRY (thread_entry), TRUE);
 	gtk_box_pack_start(GTK_BOX(hbox), thread_entry, FALSE, FALSE, 0);
 
-	gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+	gtk_widget_show_all(vbox);
 
 	result = gtk_dialog_run(GTK_DIALOG(dialog));
 	if (result != GTK_RESPONSE_ACCEPT) {
--- a/po/POTFILES.in	Fri Apr 09 14:56:00 2010 +0900
+++ b/po/POTFILES.in	Thu Apr 15 16:48:50 2010 +0900
@@ -201,7 +201,6 @@
 libpurple/win32/libc_interface.c
 libpurple/xmlnode.c
 pidgin.desktop.in
-pidgin/eggtrayicon.c
 pidgin/gtkaccount.c
 pidgin/gtkblist-theme.c
 pidgin/gtkblist.c
--- a/po/ca.po	Fri Apr 09 14:56:00 2010 +0900
+++ b/po/ca.po	Thu Apr 15 16:48:50 2010 +0900
@@ -3,7 +3,7 @@
 # Copyright (C) unknown, Robert Millan <zeratul2@wanadoo.es>
 # Copyright (C) December 2003 (from 2003-12-12 until 2003-12-18),
 #               January (2004-01-07,12), Xan <dxpublica@telefonica.net>
-# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009
+# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010
 #               Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>
 #
 # This file is distributed under the same license as the Pidgin package.
@@ -33,8 +33,8 @@
 msgstr ""
 "Project-Id-Version: Pidgin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-03-29 00:12-0700\n"
-"PO-Revision-Date: 2010-02-16 23:08+0100\n"
+"POT-Creation-Date: 2010-04-07 21:58+0200\n"
+"PO-Revision-Date: 2010-04-09 09:06+0200\n"
 "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
 "Language-Team: Catalan <tradgnome@softcatala.net>\n"
 "MIME-Version: 1.0\n"
@@ -1387,8 +1387,6 @@
 msgid "Saved Statuses"
 msgstr "Estats desats"
 
-#. title
-#. optional information
 msgid "Title"
 msgstr "Títol"
 
@@ -3953,6 +3951,11 @@
 msgid "Organization Unit"
 msgstr "Secció de l'organització"
 
+#. title
+#. optional information
+msgid "Job Title"
+msgstr "Títol de la feina"
+
 msgid "Role"
 msgstr "Rol"
 
@@ -4315,15 +4318,18 @@
 msgid "Allow Buzz"
 msgstr "Permet les botzines"
 
-# Segons la viquipèdia
-#, fuzzy
 msgid "Mood Name"
-msgstr "Nom del mig"
-
-#, fuzzy
+msgstr ""
+
 msgid "Mood Comment"
-msgstr "Comentari de l'amic"
-
+msgstr ""
+
+#. primitive
+#. ID
+#. name - use default
+#. saveable
+#. should be user_settable some day
+#. independent
 msgid "Tune Artist"
 msgstr "Artista de la melodia"
 
@@ -4616,9 +4622,8 @@
 msgid "Initiate Media"
 msgstr "Inicia el medi"
 
-#, fuzzy
 msgid "Account does not support PEP, can't set mood"
-msgstr "Aquest protocol no implementa sales de xat."
+msgstr "Aquest protocol no implementa PEP, no es pot establir l'estat d'ànim."
 
 msgid "config:  Configure a chat room."
 msgstr "config:  configura la sala de xat."
@@ -4673,9 +4678,8 @@
 msgid "buzz: Buzz a user to get their attention"
 msgstr "buzz: fa sonar una botzina a un usuari per tal de que us pari atenció"
 
-#, fuzzy
 msgid "mood: Set current user mood"
-msgstr "Seleccioneu l'usuari correcte"
+msgstr "modd: estableix l'estat d'ànim de l'usuari"
 
 msgid "Extended Away"
 msgstr "Absent des de fa una bona estona"
@@ -4759,13 +4763,13 @@
 "és massa llarga."
 
 msgid "XMPP stream header missing"
-msgstr ""
+msgstr "Falta la capçalera del flux XMPP"
 
 msgid "XMPP Version Mismatch"
-msgstr ""
+msgstr "Les versions del XMPP no coincideixen"
 
 msgid "XMPP stream missing ID"
-msgstr ""
+msgstr "Manca l'ID del fluxe XMPP"
 
 msgid "XML Parse error"
 msgstr "Error en l'anàlisi de l'XML"
@@ -4845,25 +4849,21 @@
 msgid "Please select the resource of %s to which you would like to send a file"
 msgstr "Escolliu a quin recurs de %s voleu enviar un fitxer"
 
-#, fuzzy
 msgid "Afraid"
-msgstr "Àrab"
-
-#, fuzzy
+msgstr "Espantat"
+
 msgid "Amazed"
-msgstr "Avergonyit"
-
-#, fuzzy
+msgstr "Al·lucinant"
+
 msgid "Amorous"
-msgstr "Gloriós"
+msgstr "Amorós"
 
 #. 1
 msgid "Angry"
 msgstr "Enfadat"
 
-#, fuzzy
 msgid "Annoyed"
-msgstr "Bandejat"
+msgstr "Emprenyat"
 
 msgid "Anxious"
 msgstr "Ansiós"
@@ -4878,21 +4878,18 @@
 msgid "Bored"
 msgstr "Avorrit"
 
-#, fuzzy
 msgid "Brave"
-msgstr "Desa"
-
-#, fuzzy
+msgstr "Brau"
+
 msgid "Calm"
-msgstr "Regne"
+msgstr "Calmat"
 
 #, fuzzy
 msgid "Cautious"
 msgstr "Xats"
 
-#, fuzzy
 msgid "Cold"
-msgstr "Negreta"
+msgstr "Fred"
 
 #, fuzzy
 msgid "Confident"
@@ -4914,29 +4911,24 @@
 msgid "Cranky"
 msgstr "Empresa"
 
-#, fuzzy
 msgid "Crazy"
-msgstr "Crazychat"
-
-#, fuzzy
+msgstr "Boig"
+
 msgid "Creative"
-msgstr "Crea"
-
-#, fuzzy
+msgstr "Creatiu"
+
 msgid "Curious"
-msgstr "Gloriós"
+msgstr "Curiós"
 
 #, fuzzy
 msgid "Dejected"
 msgstr "Rebutjat"
 
-#, fuzzy
 msgid "Depressed"
-msgstr "Suprimit"
-
-#, fuzzy
+msgstr "Deprimit"
+
 msgid "Disappointed"
-msgstr "Desconnectat."
+msgstr "Decebut"
 
 msgid "Disgusted"
 msgstr ""
@@ -4945,12 +4937,11 @@
 msgid "Dismayed"
 msgstr "Inhabilitat"
 
-#, fuzzy
 msgid "Distracted"
-msgstr "Separat"
+msgstr "Distret"
 
 msgid "Embarrassed"
-msgstr ""
+msgstr "Avergonyit"
 
 #, fuzzy
 msgid "Envious"
@@ -4964,12 +4955,11 @@
 msgid "Flirtatious"
 msgstr "Gloriós"
 
-#, fuzzy
 msgid "Frustrated"
-msgstr "Nom"
+msgstr "Frustrat"
 
 msgid "Grateful"
-msgstr ""
+msgstr "Agraït"
 
 #, fuzzy
 msgid "Grieving"
@@ -4979,16 +4969,15 @@
 msgid "Grumpy"
 msgstr "Rondinaire"
 
-#, fuzzy
 msgid "Guilty"
-msgstr "Ciutat"
+msgstr "Culpable"
 
 #. 4
 msgid "Happy"
 msgstr "Content"
 
 msgid "Hopeful"
-msgstr ""
+msgstr "Esperançat"
 
 #. 8
 msgid "Hot"
@@ -4998,18 +4987,16 @@
 msgstr ""
 
 msgid "Humiliated"
-msgstr ""
-
-#, fuzzy
+msgstr "Humiliat"
+
 msgid "Hungry"
-msgstr "Enfadat"
-
-#, fuzzy
+msgstr "Afamat"
+
 msgid "Hurt"
-msgstr "Humor"
+msgstr "Ferit"
 
 msgid "Impressed"
-msgstr ""
+msgstr "Impressionat"
 
 #, fuzzy
 msgid "In awe"
@@ -5018,17 +5005,14 @@
 msgid "In love"
 msgstr "Enamorat"
 
-#, fuzzy
 msgid "Indignant"
-msgstr "Indonesi"
-
-#, fuzzy
+msgstr "Indignant"
+
 msgid "Interested"
-msgstr "Interessos"
-
-#, fuzzy
+msgstr "Interessat"
+
 msgid "Intoxicated"
-msgstr "Convidat"
+msgstr "Intoxicat"
 
 #. 6
 msgid "Invincible"
@@ -5037,84 +5021,70 @@
 msgid "Jealous"
 msgstr "Gelós"
 
-#, fuzzy
 msgid "Lonely"
-msgstr "Mico"
-
-#, fuzzy
+msgstr "Sol"
+
 msgid "Lost"
-msgstr "El més alt"
+msgstr "Perdut"
 
 msgid "Lucky"
-msgstr ""
-
-#, fuzzy
+msgstr "Sortós"
+
 msgid "Mean"
-msgstr "Alemany"
-
-#, fuzzy
+msgstr "Malèvol"
+
 msgid "Moody"
-msgstr "Estat d'ànim"
+msgstr "Animat"
 
 msgid "Nervous"
-msgstr ""
-
-#, fuzzy
+msgstr "Nerviós"
+
 msgid "Neutral"
-msgstr "Detalls"
-
-#, fuzzy
+msgstr "Neutral"
+
 msgid "Offended"
-msgstr "Fora de línia"
+msgstr "Ofès"
 
 msgid "Outraged"
-msgstr ""
-
-#, fuzzy
+msgstr "Enrabiat"
+
 msgid "Playful"
-msgstr "Reprodueix"
-
-#, fuzzy
+msgstr "Juganer"
+
 msgid "Proud"
-msgstr "Alt"
-
-#, fuzzy
+msgstr "Orgullós"
+
 msgid "Relaxed"
-msgstr "Nom real"
-
-#, fuzzy
+msgstr "Relaxat"
+
 msgid "Relieved"
-msgstr "Rebuts"
-
-#, fuzzy
+msgstr "Alleujat"
+
 msgid "Remorseful"
-msgstr "Suprimeix"
-
-#, fuzzy
+msgstr "Amb remordiments"
+
 msgid "Restless"
-msgstr "Registra"
+msgstr "Neguitós"
 
 #. 7
 msgid "Sad"
 msgstr "Trist"
 
-#, fuzzy
 msgid "Sarcastic"
-msgstr "Marathi"
+msgstr "Sarcàstic"
 
 msgid "Satisfied"
-msgstr ""
-
-#, fuzzy
+msgstr "Satisfet"
+
 msgid "Serious"
-msgstr "Gloriós"
+msgstr "Seriós"
 
 #, fuzzy
 msgid "Shocked"
 msgstr "Blocat"
 
 msgid "Shy"
-msgstr ""
+msgstr "Vergonyós"
 
 #. 9
 msgid "Sick"
@@ -5126,41 +5096,34 @@
 msgstr "Endormiscat"
 
 msgid "Spontaneous"
-msgstr ""
-
-#, fuzzy
+msgstr "Espontani"
+
 msgid "Stressed"
-msgstr "Velocitat"
-
-#, fuzzy
+msgstr "Estressat"
+
 msgid "Strong"
-msgstr "Cançó"
-
-#, fuzzy
+msgstr "Fort"
+
 msgid "Surprised"
-msgstr "morrejat"
+msgstr "Sorprès"
 
 msgid "Thankful"
-msgstr ""
+msgstr "Agraït"
 
 msgid "Thirsty"
-msgstr ""
-
-#, fuzzy
+msgstr "Assedegat"
+
 msgid "Tired"
-msgstr "Fire"
-
-#, fuzzy
+msgstr "Cansat"
+
 msgid "Undefined"
-msgstr "Subratllat"
-
-#, fuzzy
+msgstr "Indefinit"
+
 msgid "Weak"
-msgstr "Bufetejar"
-
-#, fuzzy
+msgstr "Decandit"
+
 msgid "Worried"
-msgstr "Avorrit"
+msgstr "Preocupat"
 
 msgid "Set User Nickname"
 msgstr "Estableix el sobrenom de l'usuari"
@@ -5525,18 +5488,6 @@
 msgid "Out to Lunch"
 msgstr "A fora dinant"
 
-#. primitive
-#. ID
-#. name - use default
-#. saveable
-#. should be user_settable some day
-#. independent
-msgid "Artist"
-msgstr "Artista"
-
-msgid "Album"
-msgstr "Àlbum"
-
 msgid "Game Title"
 msgstr "Títol del joc"
 
@@ -5684,9 +5635,6 @@
 msgid "Work"
 msgstr "Feina"
 
-msgid "Job Title"
-msgstr "Títol de la feina"
-
 msgid "Company"
 msgstr "Empresa"
 
@@ -6992,103 +6940,86 @@
 msgstr "El nom de sala de xat no és vàlid"
 
 msgid "Thinking"
-msgstr ""
-
-#, fuzzy
+msgstr "Pensant"
+
 msgid "Shopping"
-msgstr "Pari d'escriure"
-
-#, fuzzy
+msgstr "Comprant"
+
 msgid "Questioning"
-msgstr "Diàleg de pregunta"
-
-#, fuzzy
+msgstr "Preguntant"
+
 msgid "Eating"
-msgstr "Radiomissatgeria"
-
-#, fuzzy
+msgstr "Menjant"
+
 msgid "Watching a movie"
-msgstr "Jugant a un joc"
+msgstr "Mirant una pel·lícula"
 
 msgid "Typing"
 msgstr "Teclejant"
 
-#, fuzzy
 msgid "At the office"
-msgstr "Fora de l'oficina"
+msgstr "A l'oficina"
 
 msgid "Taking a bath"
 msgstr ""
 
 msgid "Watching TV"
-msgstr ""
-
-#, fuzzy
+msgstr "Mirant la tele"
+
 msgid "Having fun"
-msgstr "Penja"
-
-#, fuzzy
+msgstr "Passant-ho bé"
+
 msgid "Sleeping"
-msgstr "Endormiscat"
+msgstr "Dormint"
 
 msgid "Using a PDA"
-msgstr ""
-
-#, fuzzy
+msgstr "Emprant el PDA"
+
 msgid "Meeting friends"
-msgstr "Amics de MI"
-
-#, fuzzy
+msgstr "Amb amics"
+
 msgid "On the phone"
 msgstr "Al telèfon"
 
-#, fuzzy
 msgid "Surfing"
-msgstr "Recurrent"
+msgstr "Navegant"
 
 #. "I am mobile." / "John is mobile."
 msgid "Mobile"
 msgstr "Mòbil"
 
-#, fuzzy
 msgid "Searching the web"
-msgstr "Avisa l'usuari"
-
-#, fuzzy
+msgstr "Cercant a la web"
+
 msgid "At a party"
-msgstr "Port d'autorització"
+msgstr "En una festa"
 
 msgid "Having Coffee"
-msgstr ""
+msgstr "Prenent un cafè"
 
 #. Playing video games
-#, fuzzy
 msgid "Gaming"
-msgstr "Jocs d'usuari"
+msgstr "Jugant"
 
 msgid "Browsing the web"
-msgstr ""
-
-#, fuzzy
+msgstr "Navegant la web"
+
 msgid "Smoking"
-msgstr "Cançó"
-
-#, fuzzy
+msgstr "Fumant"
+
 msgid "Writing"
-msgstr "Treballant"
+msgstr "Escrivint"
 
 #. Drinking [Alcohol]
-#, fuzzy
 msgid "Drinking"
-msgstr "Treballant"
+msgstr "Bevent"
 
 # És un estat, com "fora de línia", etc. (josep)
 msgid "Listening to music"
 msgstr "Escoltant música"
 
-#, fuzzy
 msgid "Studying"
-msgstr "S'està enviant"
+msgstr "Estudiant"
 
 #, fuzzy
 msgid "In the restroom"
@@ -7309,7 +7240,7 @@
 msgstr "Jocs"
 
 msgid "ICQ Xtraz"
-msgstr ""
+msgstr "ICQ Xtraz"
 
 msgid "Add-Ins"
 msgstr "Afegits"
@@ -8362,6 +8293,11 @@
 msgid "Admin"
 msgstr "Administrador"
 
+#. XXX: Should this be "Topic"?
+#, fuzzy
+msgid "Room Title"
+msgstr "Llista de sales"
+
 msgid "Notice"
 msgstr "Avís"
 
@@ -10274,9 +10210,6 @@
 msgid "Yahoo! Protocol Plugin"
 msgstr "Connector per al protocol Yahoo!"
 
-msgid "Pager server"
-msgstr "Servidor de cercapersones"
-
 msgid "Pager port"
 msgstr "Port per al cercapersones"
 
@@ -10300,12 +10233,6 @@
 msgid "Chat room list URL"
 msgstr "URL de la llista de sales de xat"
 
-msgid "Yahoo Chat server"
-msgstr "Servidor de xat de Yahoo"
-
-msgid "Yahoo Chat port"
-msgstr "Port del xat de Yahoo"
-
 msgid "Yahoo JAPAN ID..."
 msgstr "ID de Yahoo del Japó..."
 
@@ -10375,6 +10302,15 @@
 "El compte està blocat, però no se'n coneix el motiu. Això es pot solucionar "
 "entrant al web de Yahoo!"
 
+#. indicates a lock due to logging in too frequently
+#, fuzzy
+msgid ""
+"Account locked: You have been logging in too frequently.  Wait a few minutes "
+"before trying to connect again.  Logging into the Yahoo! website may help."
+msgstr ""
+"El compte està blocat perquè s'ha intentat entrar massa cops. Això es pot "
+"solucionar entrant al web de Yahoo!"
+
 #. username or password missing
 msgid "Username or password missing"
 msgstr "Manquen el nom d'uruari o la contrasenya"
@@ -10454,6 +10390,16 @@
 msgid "Unable to establish a connection with %s: %s"
 msgstr "No s'ha pogut establir una connexió amb %s: %s"
 
+msgid "Unable to connect: The server returned an empty response."
+msgstr "No s'ha pogut connectar: el servidor ha retornat una resposta buida."
+
+msgid ""
+"Unable to connect: The server's response did not contain the necessary "
+"information"
+msgstr ""
+"No s'ha pogut connectar: el servidor ha retornat una resposta que no conté "
+"la informació necessària"
+
 msgid "Not at Home"
 msgstr "Fora de casa"
 
@@ -12274,6 +12220,9 @@
 msgid "Bengali"
 msgstr "Bengalí"
 
+msgid "Bengali-India"
+msgstr "Bengalí (Ìndia)"
+
 msgid "Bosnian"
 msgstr "Bosnià"
 
@@ -12527,6 +12476,9 @@
 "Channel: #pidgin on irc.freenode.net<BR>\tXMPP MUC: devel@conference.pidgin."
 "im<BR><BR>"
 msgstr ""
+"<FONT SIZE=\"4\"><B>Recursos útils</B></FONT><BR>\t<A HREF=\"%s\">Lloc web</"
+"A><BR>\t<A HREF=\"%s\">Preguntes més freqüents</A><BR>\tCanal d'IRC: #pidgin "
+"a irc.freenode.net<BR>\tXMPP MUC: devel@conference.pidgin.im<BR><BR>"
 
 #, fuzzy, c-format
 msgid ""
@@ -15370,6 +15322,21 @@
 msgid "This plugin is useful for debugging XMPP servers or clients."
 msgstr "Aquest connector és útil per a depurar servidors i clients XMPP."
 
+#~ msgid "Artist"
+#~ msgstr "Artista"
+
+#~ msgid "Album"
+#~ msgstr "Àlbum"
+
+#~ msgid "Pager server"
+#~ msgstr "Servidor de cercapersones"
+
+#~ msgid "Yahoo Chat server"
+#~ msgstr "Servidor de xat de Yahoo"
+
+#~ msgid "Yahoo Chat port"
+#~ msgstr "Port del xat de Yahoo"
+
 #~ msgid "Error creating conference."
 #~ msgstr "S'ha produït un error en crear la conferència."