changeset 22517:63ffeb5c20a0

merge of '72c6d2dad88b0353a473a6e6398fc42ad3972716' and 'd1cb8f8d708a727ac0688ccbb562f411e438c635'
author Ka-Hing Cheung <khc@hxbc.us>
date Fri, 21 Mar 2008 03:17:36 +0000
parents 04edbd747947 (current diff) 8972581c2326 (diff)
children 6aa076a2ea6f
files
diffstat 24 files changed, 192 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Mar 21 03:17:26 2008 +0000
+++ b/ChangeLog	Fri Mar 21 03:17:36 2008 +0000
@@ -16,6 +16,7 @@
 	* Fix a crash when starting if you have a Zephyr account
 	* Increase XMPP ping timeout to 120 seconds, to prevent poor network
 	  connections from timing out unnecessarily.
+	* Don't crash on XMPP forms with empty default values.
 
 	Pidgin:
 	* Remove a workaround for older versions gstreamer that was causing
--- a/configure.ac	Fri Mar 21 03:17:26 2008 +0000
+++ b/configure.ac	Fri Mar 21 03:17:36 2008 +0000
@@ -166,7 +166,7 @@
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h signal.h stdint.h regex.h)
+AC_CHECK_HEADERS_ONCE(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h signal.h stdint.h regex.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -658,14 +658,21 @@
 dnl #######################################################################
 dnl # Check for GStreamer
 dnl #######################################################################
+dnl
+dnl TODO: Depend on gstreamer >= 0.10.10, and remove the conditional use of
+dnl       gst_registry_fork_set_enabled.
 AC_ARG_ENABLE(gstreamer,
 	[AC_HELP_STRING([--disable-gstreamer], [compile without GStreamer audio support])],
 	enable_gst="$enableval", enable_gst="yes")
 if test "x$enable_gst" != "xno"; then
-	PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10 >= 0.10.10], [
+	PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], [
 		AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
 		AC_SUBST(GSTREAMER_CFLAGS)
 		AC_SUBST(GSTREAMER_LIBS)
+		AC_CHECK_LIB(gstreamer-0.10, gst_registry_fork_set_enabled,
+			[ AC_DEFINE(GST_CAN_DISABLE_FORKING, [],
+			  [Define if gst_registry_fork_set_enabled exists])],
+			[], [$GSTREAMER_LIBS])
 	], [
 		AC_MSG_RESULT(no)
 		enable_gst="no"
@@ -1046,7 +1053,7 @@
 AC_ARG_WITH(zephyr, [AC_HELP_STRING([--with-zephyr=PREFIX], [compile Zephyr plugin against external libzephyr])], zephyr="$withval", zephyr="no")
 AM_CONDITIONAL(EXTERNAL_LIBZEPHYR, test "x$zephyr" != "xno")
 
-AC_CHECK_HEADER(sys/utsname.h)
+AC_CHECK_HEADERS_ONCE(sys/utsname.h)
 AC_CHECK_FUNC(uname)
 
 AC_ARG_ENABLE(fortify, [AC_HELP_STRING([--disable-fortify], [compile without FORTIFY_SOURCE support])], , enable_fortify=yes)
@@ -2096,11 +2103,21 @@
 AC_MSG_RESULT(no)
 AC_CHECK_FUNCS(gethostid lrand48)
 AC_CHECK_FUNCS(memcpy memmove random strchr strerror vprintf)
-AC_CHECK_HEADERS(malloc.h paths.h sgtty.h stdarg.h sys/cdefs.h)
-AC_CHECK_HEADERS(sys/file.h sys/filio.h sys/ioctl.h sys/msgbuf.h)
-AC_CHECK_HEADERS(sys/select.h sys/uio.h sys/utsname.h sys/wait.h)
-AC_CHECK_HEADERS(termios.h)
-AC_CHECK_HEADERS(sys/sysctl.h sys/socket.h)
+AC_CHECK_HEADERS_ONCE(malloc.h paths.h sgtty.h stdarg.h sys/cdefs.h)
+AC_CHECK_HEADERS_ONCE(sys/file.h sys/filio.h sys/ioctl.h sys/msgbuf.h)
+AC_CHECK_HEADERS_ONCE(sys/select.h sys/uio.h sys/utsname.h sys/wait.h)
+AC_CHECK_HEADERS_ONCE(termios.h)
+
+# sys/sysctl.h on OpenBSD 4.2 requires sys/param.h
+AC_CHECK_HEADERS_ONCE(sys/param.h)
+AC_CHECK_HEADERS(sys/sysctl.h, [], [],
+	[[
+		#ifdef HAVE_PARAM_H
+		# include <sys/param.h>
+		#endif
+	]])
+
+AC_CHECK_HEADERS_ONCE(sys/socket.h)
 AC_VAR_TIMEZONE_EXTERNALS
 
 AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff,
--- a/finch/libgnt/gntwm.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/finch/libgnt/gntwm.c	Fri Mar 21 03:17:36 2008 +0000
@@ -101,6 +101,7 @@
 static gboolean idle_update;
 static GList *act = NULL; /* list of WS with unseen activitiy */
 static gboolean ignore_keys = FALSE;
+static gboolean started_python = FALSE;
 
 static GList *
 g_list_bring_to_front(GList *list, gpointer data)
@@ -1342,7 +1343,10 @@
 		wm->workspaces = g_list_delete_link(wm->workspaces, wm->workspaces);
 	}
 #ifdef USE_PYTHON
-	Py_Finalize();
+	if (started_python) {
+		Py_Finalize();
+		started_python = FALSE;
+	}
 #endif
 }
 
@@ -1523,8 +1527,11 @@
 #ifdef USE_PYTHON
 	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "run-python", run_python,
 				GNT_KEY_F3, NULL);
-	Py_SetProgramName("gnt");
-	Py_Initialize();
+	if (!Py_IsInitialized()) {
+		Py_SetProgramName("gnt");
+		Py_Initialize();
+		started_python = TRUE;
+	}
 #endif
 
 	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
--- a/libpurple/account.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/account.c	Fri Mar 21 03:17:36 2008 +0000
@@ -751,6 +751,7 @@
 		description = g_strdup("");
 
 	current_error = g_new0(PurpleConnectionErrorInfo, 1);
+	PURPLE_DBUS_REGISTER_POINTER(current_error, PurpleConnectionErrorInfo);
 	current_error->type = type;
 	current_error->description = description;
 
@@ -1009,6 +1010,7 @@
 		purple_log_free(account->system_log);
 
 	priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+	PURPLE_DBUS_UNREGISTER_POINTER(priv->current_error);
 	g_free(priv->current_error);
 	g_free(priv);
 
@@ -2365,8 +2367,7 @@
 }
 
 static void
-set_current_error(PurpleAccount *account,
-                  PurpleConnectionErrorInfo *new_err)
+set_current_error(PurpleAccount *account, PurpleConnectionErrorInfo *new_err)
 {
 	PurpleAccountPrivate *priv;
 	PurpleConnectionErrorInfo *old_err;
@@ -2389,6 +2390,7 @@
 	if(old_err)
 		g_free(old_err->description);
 
+	PURPLE_DBUS_UNREGISTER_POINTER(old_err);
 	g_free(old_err);
 }
 
@@ -2406,6 +2408,7 @@
 	g_return_if_fail(account != NULL);
 
 	err = g_new0(PurpleConnectionErrorInfo, 1);
+	PURPLE_DBUS_REGISTER_POINTER(err, PurpleConnectionErrorInfo);
 
 	err->type = type;
 	err->description = g_strdup(description);
--- a/libpurple/internal.h	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/internal.h	Fri Mar 21 03:17:36 2008 +0000
@@ -182,6 +182,14 @@
 #	endif
 #endif
 
+#ifndef G_GSIZE_MODIFIER
+#	if GLIB_SIZEOF_LONG == 8
+#		define G_GSIZE_MODIFIER "l"
+#	else
+#		define G_GSIZE_MODIFIER ""
+#	endif
+#endif
+
 #ifndef G_GSIZE_FORMAT
 #	if GLIB_SIZEOF_LONG == 8
 #		define G_GSIZE_FORMAT "lu"
@@ -190,6 +198,14 @@
 #	endif
 #endif
 
+#ifndef G_GSSIZE_FORMAT
+#	if GLIB_SIZEOF_LONG == 8
+#		define G_GSSIZE_FORMAT "li"
+#	else
+#		define G_GSSIZE_FORMAT "i"
+#	endif
+#endif
+
 #ifndef G_GNUC_NULL_TERMINATED
 #	if     __GNUC__ >= 4
 #		define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
--- a/libpurple/nat-pmp.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/nat-pmp.c	Fri Mar 21 03:17:36 2008 +0000
@@ -182,7 +182,7 @@
 
     if (!(buf = malloc(needed)))
 	{
-		purple_debug_warning("nat-pmp", "malloc\n");
+		purple_debug_warning("nat-pmp", "Failed to malloc %i\n", needed);
 		return NULL;
     }
 
@@ -232,7 +232,7 @@
 						sin->sin_addr.s_addr = rti_sin->sin_addr.s_addr;
 						memcpy(sin, rti_info[RTAX_GATEWAY], sizeof(struct sockaddr_in));
 
-						purple_debug_info("nat-pmp", "found a default gateway\n");
+						purple_debug_info("nat-pmp", "Found a default gateway\n");
 						found = TRUE;
 						break;
 					}
@@ -455,7 +455,8 @@
 	{
 		success = (resp->opcode == (req.opcode + 128));
 		if (!success)
-			purple_debug_info("nat-pmp", "The opcode for the response from the NAT device does not match the request opcode!\n");
+			purple_debug_info("nat-pmp", "The opcode for the response from the NAT device (%i) does not match the request opcode (%i + 128 = %i)!\n",
+							  resp->opcode, req.opcode, req.opcode + 128);
 	}
 
 #ifdef PMP_DEBUG
@@ -492,7 +493,8 @@
 	success = purple_pmp_create_map(((type == PURPLE_PMP_TYPE_UDP) ? PMP_MAP_OPCODE_UDP : PMP_MAP_OPCODE_TCP),
 							privateport, 0, 0);
 	if (!success)
-		purple_debug_warning("nat-pmp", "Failed to properly destroy mapping for %d!\n", privateport);
+		purple_debug_warning("nat-pmp", "Failed to properly destroy mapping for %s port %d!\n",
+							 ((type == PURPLE_PMP_TYPE_UDP) ? "UDP" : "TCP"), privateport);
 
 	return success;
 }
--- a/libpurple/plugins/test.pl	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/plugins/test.pl	Fri Mar 21 03:17:36 2008 +0000
@@ -1,6 +1,4 @@
-#!/usr/bin/env perl -w
-
-use Gaim;
+use Purple;
 
 %PLUGIN_INFO = (
 	perl_api_version => 2,
@@ -8,51 +6,37 @@
 	version          => '1.0',
 	summary          => 'Provides as a test base for the perl plugin.',
 	description      => 'Provides as a test base for the perl plugin.',
-	author           => 'Christian Hammond <chipx86@gnupdate.org>',
+	author           => 'Etan Reisner <deryni\@pidgin.im>',
 	url              => 'http://pidgin.im',
 
-	load             => "plugin_load",
-	unload           => "plugin_unload"
+	load             => "plugin_load"
 );
 
-sub account_away_cb {
-	Gaim::debug_info("perl test plugin", "In account_away_cb\n");
-
-	my ($account, $state, $message, $data) = @_;
-
-	Gaim::debug_info("perl test plugin", "Account " .
-	                 $account->get_username() . " went away.\n");
-	Gaim::debug_info("perl test plugin", $data . "\n");
-}
-
 sub plugin_init {
 	return %PLUGIN_INFO;
 }
 
+sub account_status_cb {
+	my ($account, $old, $new, $data) = @_;
+
+	Purple::Debug::info("perl test plugin", "In account_status_cb\n");
+
+	Purple::Debug::info("perl test plugin", "Account " .
+	                    $account->get_username() . " changed status.\n");
+	Purple::Debug::info("perl test plugin", $data . "\n");
+}
+
 sub plugin_load {
-	Gaim::debug_info("perl test plugin", "plugin_load\n");
 	my $plugin = shift;
 
-	Gaim::debug_info("perl test plugin", "Listing accounts.\n");
-	foreach $account (Gaim::accounts()) {
-		Gaim::debug_info("perl test plugin", $account->get_username() . "\n");
+	Purple::Debug::info("perl test plugin", "plugin_load\n");
+
+	Purple::Debug::info("perl test plugin", "Listing accounts.\n");
+	foreach $account (Purple::Accounts::get_all()) {
+		Purple::Debug::info("perl test plugin", $account->get_username() . "\n");
 	}
 
-	Gaim::debug_info("perl test plugin", "Listing buddy list.\n");
-	foreach $group (Gaim::BuddyList::groups()) {
-		Gaim::debug_info("perl test plugin",
-		                 $group->get_name() . ":\n");
-
-		foreach $buddy ($group->buddies()) {
-			Gaim::debug_info("perl test plugin",
-			                 "  " . $buddy->get_name() . "\n");
-		}
-	}
-
-	Gaim::signal_connect(Gaim::Accounts::handle, "account-away",
-	                     $plugin, \&account_away_cb, "test");
+	Purple::Signal::connect(Purple::Accounts::get_handle(),
+	                        "account-status-changed", $plugin,
+	                        \&account_status_cb, "test");
 }
-
-sub plugin_unload {
-	my $plugin = shift;
-}
--- a/libpurple/protocols/jabber/Makefile.mingw	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/protocols/jabber/Makefile.mingw	Fri Mar 21 03:17:36 2008 +0000
@@ -83,7 +83,7 @@
 			-lpurple
 
 ifeq ($(CYRUS_SASL), 1)
-CYRUS_SASL_TOP := $(WIN32_DEV_TOP)/cyrus-sasl-2.1.22
+CYRUS_SASL_TOP := $(WIN32_DEV_TOP)/cyrus-sasl-2.1.22-daa1
 INCLUDE_PATHS += -I$(CYRUS_SASL_TOP)/include
 LIB_PATHS += -L$(CYRUS_SASL_TOP)/lib
 LIBS += -llibsasl
--- a/libpurple/protocols/jabber/auth.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/protocols/jabber/auth.c	Fri Mar 21 03:17:36 2008 +0000
@@ -490,6 +490,12 @@
 	{
 		char *mech_name = xmlnode_get_data(mechnode);
 #ifdef HAVE_CYRUS_SASL
+		/* Skip the GSSAPI mechanism unless it's enabled for this account */
+		if (mech_name && !strcmp(mech_name, "GSSAPI") &&
+			!purple_account_get_bool(js->gc->account, "auth_gssapi", TRUE)) {
+			continue;
+		}
+
 		g_string_append(js->sasl_mechs, mech_name);
 		g_string_append_c(js->sasl_mechs, ' ');
 #else
--- a/libpurple/protocols/jabber/libxmpp.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/protocols/jabber/libxmpp.c	Fri Mar 21 03:17:36 2008 +0000
@@ -224,6 +224,14 @@
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 						   option);
 
+#ifdef HAVE_CYRUS_SASL
+	option = purple_account_option_bool_new(
+											_("Use GSSAPI (Kerberos v5) for authentication"),
+											"auth_gssapi", TRUE);
+	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+											   option);	
+#endif
+	
 	option = purple_account_option_int_new(_("Connect port"), "port", 5222);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 						   option);
--- a/libpurple/protocols/jabber/xdata.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/protocols/jabber/xdata.c	Fri Mar 21 03:17:36 2008 +0000
@@ -285,7 +285,10 @@
 
 			for(valuenode = xmlnode_get_child(fn, "value"); valuenode;
 					valuenode = xmlnode_get_next_twin(valuenode)) {
-				selected = g_list_prepend(selected, xmlnode_get_data(valuenode));
+				char *data = xmlnode_get_data(valuenode);
+				if (data != NULL) {
+					selected = g_list_prepend(selected, data);
+				}
 			}
 
 			for(optnode = xmlnode_get_child(fn, "option"); optnode;
--- a/libpurple/protocols/myspace/markup.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/protocols/myspace/markup.c	Fri Mar 21 03:17:36 2008 +0000
@@ -181,7 +181,7 @@
 {
 	guint dpi;
 
-	dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
+	dpi = purple_account_get_int(session->account, "dpi", MSIM_DEFAULT_DPI);
 
 	return (guint)msim_round((POINTS_PER_INCH * 1. / dpi) * height);
 
@@ -195,7 +195,7 @@
 {
 	guint dpi;
 
-	dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
+	dpi = purple_account_get_int(session->account, "dpi", MSIM_DEFAULT_DPI);
 
 	return (guint)msim_round((dpi * 1. / POINTS_PER_INCH) * point);
 }
--- a/libpurple/protocols/qq/send_core.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/protocols/qq/send_core.c	Fri Mar 21 03:17:36 2008 +0000
@@ -87,7 +87,7 @@
 		if (len > MAX_PACKET_SIZE) {
 			purple_debug(PURPLE_DEBUG_ERROR, "QQ",
 				   "xxx [%05d] %s, %d bytes is too large, do not send\n",
-				   qq_get_cmd_desc(cmd), qd->send_seq, len);
+				   qd->send_seq, qq_get_cmd_desc(cmd), len);
 			return -1;
 		} else {	/* I update the len for TCP packet */
 			cursor = buf;
--- a/libpurple/protocols/simple/simple.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/protocols/simple/simple.c	Fri Mar 21 03:17:36 2008 +0000
@@ -1209,7 +1209,7 @@
 			while (ssparts[i])
 			{
 				g_strchug(ssparts[i]);
-				if (g_str_has_prefix(ssparts[i], "terminated"))
+				if (purple_str_has_prefix(ssparts[i], "terminated"))
 				{
 					purple_debug_info("simple", "Subscription expired!");
 					g_free(b->dialog->ourtag);
--- a/libpurple/win32/libc_interface.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/libpurple/win32/libc_interface.c	Fri Mar 21 03:17:36 2008 +0000
@@ -320,12 +320,16 @@
 		switch(errornum) {
 			case WSAECONNABORTED: /* 10053 */
 				snprintf(errbuf, sizeof(errbuf), _("Connection interrupted by other software on your computer."));
+				break;
 			case WSAECONNRESET: /* 10054 */
 				snprintf(errbuf, sizeof(errbuf), _("Remote host closed connection."));
+				break;
 			case WSAETIMEDOUT: /* 10060 */
 				snprintf(errbuf, sizeof(errbuf), _("Connection timed out."));
+				break;
 			case WSAECONNREFUSED: /*10061 */
 				snprintf(errbuf, sizeof(errbuf), _("Connection refused."));
+				break;
 			default:
 				snprintf(errbuf, sizeof(errbuf), "Windows socket error #%d", errornum);
 		}
@@ -452,6 +456,11 @@
 int wpurple_rename (const char *oldname, const char *newname) {
 	struct stat oldstat, newstat;
 
+	/* As of Glib 2.8.5, g_rename() uses MoveFileEx() with MOVEFILE_REPLACE_EXISTING to behave more sanely */
+	if (glib_check_version(2, 8, 5) == NULL) {
+		return g_rename(oldname, newname);
+	}
+
 	if(g_stat(oldname, &oldstat) == 0) {
 		/* newname exists */
 		if(g_stat(newname, &newstat) == 0) {
--- a/pidgin/gtkblist.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/gtkblist.c	Fri Mar 21 03:17:36 2008 +0000
@@ -549,7 +549,7 @@
 		char *msg = g_strdup_printf(ngettext("You have %d contact named %s. Would you like to merge them?", "You currently have %d contacts named %s. Would you like to merge them?", i), i, alias);
 		purple_request_action(NULL, NULL, msg, _("Merging these contacts will cause them to share a single entry on the buddy list and use a single conversation window. "
 							 "You can separate them again by choosing 'Expand' from the contact's context menu"), 0, NULL, NULL, NULL,
-				      merges, 2, _("_Merge"), PURPLE_CALLBACK(gtk_blist_do_personize), _("_Cancel"), PURPLE_CALLBACK(g_list_free));
+				      merges, 2, _("_Yes"), PURPLE_CALLBACK(gtk_blist_do_personize), _("_No"), PURPLE_CALLBACK(g_list_free));
 		g_free(msg);
 	} else
 		g_list_free(merges);
@@ -3354,24 +3354,34 @@
 
 		purple_notify_user_info_destroy(user_info);
 	} else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+		gint count;
 		PurpleGroup *group = (PurpleGroup*)node;
 		PurpleNotifyUserInfo *user_info;
 
 		user_info = purple_notify_user_info_new();
 
-		/* Total buddies (from online accounts) in group */
-		tmp = g_strdup_printf("%d",
-		                      purple_blist_get_group_size(group, FALSE));
-		purple_notify_user_info_add_pair(user_info, _("Total Buddies"),
-		                                 tmp);
-		g_free(tmp);
-
-		/* Online buddies in group */
-		tmp = g_strdup_printf("%d",
-		                      purple_blist_get_group_online_count(group));
-		purple_notify_user_info_add_pair(user_info, _("Online Buddies"),
-		                                 tmp);
-		g_free(tmp);
+		count = purple_blist_get_group_online_count(group);
+
+		if (count != 0) {
+			/* Online buddies in group */
+			tmp = g_strdup_printf("%d", count);
+			purple_notify_user_info_add_pair(user_info,
+			                                 _("Online Buddies"),
+			                                 tmp);
+			g_free(tmp);
+		}
+		count = 0;
+
+		count = purple_blist_get_group_size(group, FALSE);
+		if (count != 0) {
+			/* Total buddies (from online accounts) in group */
+			tmp = g_strdup_printf("%d", count);
+			purple_notify_user_info_add_pair(user_info,
+			                                 _("Total Buddies"),
+			                                 tmp);
+			g_free(tmp);
+		}
+		count = 0;
 
 		tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
 		g_string_append(str, tmp);
@@ -6356,43 +6366,25 @@
 	vbox = gtk_vbox_new(FALSE, 0);
 	gtk_container_add(GTK_CONTAINER(hbox), vbox);
 
-	label = gtk_label_new(
-		_("Please enter the screen name of the person you would like "
-		  "to add to your buddy list. You may optionally enter an alias, "
-		  "or nickname,  for the buddy. The alias will be displayed in "
-		  "place of the screen name whenever possible.\n"));
-
-	gtk_widget_set_size_request(GTK_WIDGET(label), 400, -1);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	g_signal_connect(G_OBJECT(data->window), "destroy",
+	                 G_CALLBACK(destroy_add_buddy_dialog_cb), data);
+
+	label = gtk_label_new(_("Add a buddy.\n"));
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_container_add(GTK_CONTAINER(vbox), hbox);
-
-	g_signal_connect(G_OBJECT(data->window), "destroy",
-					 G_CALLBACK(destroy_add_buddy_dialog_cb), data);
-
 	table = gtk_table_new(4, 2, FALSE);
 	gtk_table_set_row_spacings(GTK_TABLE(table), 5);
 	gtk_table_set_col_spacings(GTK_TABLE(table), 5);
 	gtk_container_set_border_width(GTK_CONTAINER(table), 0);
 	gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
 
-	/* Set up stuff for the account box */
-	label = gtk_label_new_with_mnemonic(_("A_ccount:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
-
 	data->account_box = pidgin_account_option_menu_new(account, FALSE,
 			G_CALLBACK(add_buddy_select_account_cb), NULL, data);
 
-	gtk_table_attach_defaults(GTK_TABLE(table), data->account_box, 1, 2, 0, 1);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), data->account_box);
-	pidgin_set_accessible_label (data->account_box, label);
-	/* End of account box */
-
-	label = gtk_label_new_with_mnemonic(_("_Screen name:"));
+	gtk_table_attach_defaults(GTK_TABLE(table), data->account_box, 0, 2, 0, 1);
+
+	label = gtk_label_new_with_mnemonic(_("Buddy's _screen name:"));
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
 
@@ -6404,23 +6396,23 @@
 		gtk_entry_set_text(GTK_ENTRY(data->entry), username);
 	else
 		gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window),
-										  GTK_RESPONSE_OK, FALSE);
+		                                  GTK_RESPONSE_OK, FALSE);
 
 	gtk_entry_set_activates_default (GTK_ENTRY(data->entry), TRUE);
 	gtk_label_set_mnemonic_widget(GTK_LABEL(label), data->entry);
 	pidgin_set_accessible_label (data->entry, label);
 
 	g_signal_connect(G_OBJECT(data->entry), "changed",
-					 G_CALLBACK(pidgin_set_sensitive_if_input),
-					 data->window);
-
-	label = gtk_label_new_with_mnemonic(_("A_lias:"));
+	                 G_CALLBACK(pidgin_set_sensitive_if_input),
+	                 data->window);
+
+	label = gtk_label_new_with_mnemonic(_("(Optional) A_lias:"));
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
 
 	data->entry_for_alias = gtk_entry_new();
 	gtk_table_attach_defaults(GTK_TABLE(table),
-							  data->entry_for_alias, 1, 2, 2, 3);
+	                          data->entry_for_alias, 1, 2, 2, 3);
 
 	if (alias != NULL)
 		gtk_entry_set_text(GTK_ENTRY(data->entry_for_alias), alias);
@@ -6432,7 +6424,7 @@
 	gtk_label_set_mnemonic_widget(GTK_LABEL(label), data->entry_for_alias);
 	pidgin_set_accessible_label (data->entry_for_alias, label);
 
-	label = gtk_label_new_with_mnemonic(_("_Group:"));
+	label = gtk_label_new_with_mnemonic(_("Add buddy to _group:"));
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4);
 
--- a/pidgin/gtkconv.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/gtkconv.c	Fri Mar 21 03:17:36 2008 +0000
@@ -4366,9 +4366,9 @@
 	int wrapped_lines;
 	int lines;
 	GdkRectangle oneline;
-	GtkRequisition sr;
 	int height, diff;
 	int pad_top, pad_inside, pad_bottom;
+	int max_height = gtkconv->tab_cont->allocation.height / 2;
 
 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
 
@@ -4380,9 +4380,8 @@
 
 	lines = gtk_text_buffer_get_line_count(buffer);
 
-	/* Show a maximum of 4 lines */
-	lines = MIN(lines, 4);
-	wrapped_lines = MIN(MAX(wrapped_lines, 2), 4);
+	/* Show at least two lines */
+	wrapped_lines = MAX(wrapped_lines, 2);
 
 	pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
 	pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
@@ -4392,12 +4391,12 @@
 	if (wrapped_lines > lines)
 		height += (oneline.height + pad_inside) * (wrapped_lines - lines);
 
+	height = MIN(height, max_height);
+
 	diff = height - gtkconv->entry->allocation.height;
 	if (diff == 0 || (diff < 0 && -diff < oneline.height / 2))
 		return FALSE;
 
-	gtk_widget_size_request(gtkconv->lower_hbox, &sr);
-
 	gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
 		diff + gtkconv->lower_hbox->allocation.height);
 
--- a/pidgin/gtkmain.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/gtkmain.c	Fri Mar 21 03:17:36 2008 +0000
@@ -99,6 +99,9 @@
 	SIGTERM,
 	SIGQUIT,
 	SIGCHLD,
+#if defined(USE_GSTREAMER) && !defined(GST_CAN_DISABLE_FORKING)
+	SIGALRM,
+#endif
 	-1
 };
 
@@ -188,9 +191,27 @@
 		fprintf(stderr, "%s", segfault_message);
 		abort();
 		break;
+#if defined(USE_GSTREAMER) && !defined(GST_CAN_DISABLE_FORKING)
+/* By default, gstreamer forks when you initialize it, and waitpids for the
+ * child.  But if libpurple reaps the child rather than leaving it to
+ * gstreamer, gstreamer's initialization fails.  So, we wait a second before
+ * reaping child processes, to give gst a chance to reap it if it wants to.
+ *
+ * This is not needed in later gstreamers, which let us disable the forking.
+ * And, it breaks the world on some Real Unices.
+ */
 	case SIGCHLD:
+		/* Restore signal catching */
+		signal(SIGCHLD, sighandler);
+		alarm(1);
+		break;
+	case SIGALRM:
+#else
+	case SIGCHLD:
+#endif
 		clean_pid();
-		signal(SIGCHLD, sighandler);    /* restore signal catching on this one! */
+		/* Restore signal catching */
+		signal(SIGCHLD, sighandler);
 		break;
 	default:
 		purple_debug_warning("sighandler", "Caught signal %d\n", sig);
--- a/pidgin/gtkscrollbook.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/gtkscrollbook.c	Fri Mar 21 03:17:36 2008 +0000
@@ -268,7 +268,9 @@
 	/* Close */
 	eb = gtk_event_box_new();
 	gtk_box_pack_end(GTK_BOX(scroll_book->hbox), eb, FALSE, FALSE, 0);
+#if GTK_CHECK_VERSION(2,4,0)
 	gtk_event_box_set_visible_window(GTK_EVENT_BOX(eb), FALSE);
+#endif
 	gtk_widget_set_events(eb, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
 	close_button = gtk_label_new("×");
 	g_signal_connect(G_OBJECT(eb), "enter-notify-event", G_CALLBACK(close_button_entered_cb), close_button);
--- a/pidgin/gtksession.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/gtksession.c	Fri Mar 21 03:17:36 2008 +0000
@@ -37,6 +37,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <gdk/gdk.h>
+#include <gtk/gtk.h>
 
 #define ERROR_LENGTH 512
 
@@ -162,8 +163,10 @@
 		ret[j++] = g_strdup(config_dir);
 	}
 
+#if GTK_CHECK_VERSION(2,2,0)
 	ret[j++] = g_strdup("--display");
 	ret[j++] = g_strdup((gchar *)gdk_display_get_name(gdk_display_get_default()));
+#endif
 
 	ret[j++] = NULL;
 
--- a/pidgin/gtksound.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/gtksound.c	Fri Mar 21 03:17:36 2008 +0000
@@ -302,7 +302,9 @@
 
 #ifdef USE_GSTREAMER
 	purple_debug_info("sound", "Initializing sound output drivers.\n");
+#ifdef GST_CAN_DISABLE_FORKING
 	gst_registry_fork_set_enabled (FALSE);
+#endif
 	if ((gst_init_failed = !gst_init_check(NULL, NULL, &error))) {
 		purple_notify_error(NULL, _("GStreamer Failure"),
 					_("GStreamer failed to initialize."),
--- a/pidgin/gtkutils.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/gtkutils.c	Fri Mar 21 03:17:36 2008 +0000
@@ -3413,6 +3413,7 @@
 	return FALSE;
 #endif
 #else
+#if GTK_CHECK_VERSION(2,4,0)
 	/* This finds the currently active window and makes that the parent window. */
 	GList *windows = NULL;
 	GtkWidget *parent = NULL;
@@ -3455,6 +3456,7 @@
 		gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(parent));
 		return TRUE;
 	}
+#endif
 	return FALSE;
 #endif
 }
--- a/pidgin/minidialog.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/minidialog.c	Fri Mar 21 03:17:36 2008 +0000
@@ -51,7 +51,7 @@
 pidgin_mini_dialog_get_type (void)
 {
 	static GType g_define_type_id = 0;
-	if (G_UNLIKELY (g_define_type_id == 0))
+	if (g_define_type_id == 0)
 	{
 		static const GTypeInfo g_define_type_info = {
 			sizeof (PidginMiniDialogClass),
--- a/pidgin/win32/winpidgin.c	Fri Mar 21 03:17:26 2008 +0000
+++ b/pidgin/win32/winpidgin.c	Fri Mar 21 03:17:36 2008 +0000
@@ -498,7 +498,7 @@
 		return;
 	}
 
-	if (!(msg_win = FindWindowEx(HWND_MESSAGE, NULL, TEXT("WinpidginMsgWinCls"), NULL))) {
+	if (!(msg_win = FindWindowEx(NULL, NULL, TEXT("WinpidginMsgWinCls"), NULL))) {
 		printf("Unable to find an instance of Pidgin to handle protocol message.\n");
 		return;
 	}