changeset 21360:e747ac0c42d6

propagate from branch 'im.pidgin.pidgin.next.minor' (head bd8f1d754a1b94e5ade30c3b135178b236f7b49a) to branch 'im.pidgin.cpw.resiak.disconnectreason' (head 5d84bcfaddc07cab4419ab9f04b31626421b97ff)
author Will Thompson <will.thompson@collabora.co.uk>
date Mon, 15 Oct 2007 10:45:46 +0000
parents fe57b8062249 (current diff) 5915ad785ee7 (diff)
children 6bbd023f0387
files COPYRIGHT ChangeLog.API libpurple/connection.h libpurple/protocols/gg/gg.c libpurple/protocols/jabber/auth.c libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/chat.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/presence.c libpurple/protocols/msn/msn.c libpurple/protocols/novell/novell.c libpurple/protocols/oscar/oscar.c libpurple/protocols/qq/qq.c libpurple/protocols/sametime/sametime.c libpurple/protocols/silc/silc.c libpurple/protocols/silc/util.c libpurple/protocols/simple/simple.c libpurple/protocols/yahoo/yahoo.c
diffstat 108 files changed, 2063 insertions(+), 532 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Sun Oct 14 21:20:50 2007 +0000
+++ b/COPYRIGHT	Mon Oct 15 10:45:46 2007 +0000
@@ -197,6 +197,7 @@
 Akuke Kok
 Konstantin Korikov
 Cole Kowalski
+Matt Kramer
 Gary Kramlich
 Jan Kratochvil
 Andrej Krivulčík
--- a/ChangeLog	Sun Oct 14 21:20:50 2007 +0000
+++ b/ChangeLog	Mon Oct 15 10:45:46 2007 +0000
@@ -12,6 +12,8 @@
 	  remove the plugin from the list of saved plugins so it won't load
 	  at the next startup.  Previously, we were ignoring this case, which
 	  could lead to crashes.
+	* Mark dialog windows as transient for appropriate parent windows to
+	  help window managers do the right thing  (Gabriel Schulhof)
 
 	Finch:
 	* If a plugin says it can't be unloaded, we now display an error and
@@ -50,6 +52,8 @@
 	* Pidgin's display is now saved with the command line for session
 	  restoration.  (David Mohr)
 	* ICQ Birthday notifications are shown as buddy list emblems.
+	* Plugin actions are now available from the docklet context menu
+	  in addition to the Tool menu of the buddy list.
 
 version 2.2.1 (09/29/2007):
 	http://developer.pidgin.im/query?status=closed&milestone=2.2.1
--- a/ChangeLog.API	Sun Oct 14 21:20:50 2007 +0000
+++ b/ChangeLog.API	Mon Oct 15 10:45:46 2007 +0000
@@ -14,6 +14,7 @@
 		  to unload a plugin--fails.  This then prevents the plugin
 		  from being saved in the saved plugins list, so it'll won't
 		  be loaded at the next startup.
+
 		* PurpleDisconnectReason enumeration of machine-readable
 		  types of connection error.
 		* purple_connection_error_reason(), to be used by prpls
@@ -29,6 +30,45 @@
 		  after a connection error (rather than checking
 		  gc->wants_to_die).
 
+		* purple_util_init()
+		* purple_util_uninit()
+
+		* pidgin_dialogs_about_with_parent()
+		* pidgin_log_show_contact_with_parent()
+		* pidgin_log_show_with_parent()
+		* pidgin_plugin_dialog_show_with_parent()
+		* pidgin_pounce_editor_show_with_parent()
+		* pidgin_pounces_manager_show_with_parent()
+		* pidgin_syslog_show_with_parent()
+
+		* purple_request_accept_cancel_with_hint()
+		* purple_request_action_varg_with_hint()
+		* purple_request_action_with_hint()
+		* purple_request_choice_varg_with_hint()
+		* purple_request_choice_with_hint()
+		* purple_request_fields_with_hint()
+		* purple_request_file_with_hint()
+		* purple_request_folder_with_hint()
+		* purple_request_input_with_hint()
+		* purple_request_ok_cancel_with_hint()
+		* purple_request_yes_no_with_hint()
+
+		  UI hints set by libpurple:
+		* PURPLE_REQUEST_UI_HINT_ACCOUNT
+		* PURPLE_REQUEST_UI_HINT_BLIST
+		* PURPLE_REQUEST_UI_HINT_BUDDY
+		* PURPLE_REQUEST_UI_HINT_CONV
+		* PURPLE_REQUEST_UI_HINT_REGISTER
+		* PURPLE_REQUEST_UI_HINT_XFER
+
+		  Common UI hints set by UIs:
+		* PURPLE_REQUEST_UI_HINT_ACCOUNTMGR
+		* PURPLE_REQUEST_UI_HINT_CERTMGR
+		* PURPLE_REQUEST_UI_HINT_PLUGINMGR
+		* PURPLE_REQUEST_UI_HINT_POUNCEMGR
+		* PURPLE_REQUEST_UI_HINT_PREFSMGR
+		* PURPLE_REQUEST_UI_HINT_STATUSMGR
+
 		Changed:
 		* purple_plugin_unload() now honors the return value of a
 		  plugin's unload function and can actually return FALSE now.
@@ -36,6 +76,27 @@
 		  when a dependent plugin fails to unload.  The UI should do
 		  something appropriate.
 
+		Deprecated:
+		* pidgin_dialogs_about()
+		* pidgin_log_show_contact()
+		* pidgin_log_show()
+		* pidgin_plugin_dialog_show()
+		* pidgin_pounce_editor_show()
+		* pidgin_pounces_manager_show()
+		* pidgin_syslog_show()
+
+		* purple_request_accept_cancel()
+		* purple_request_action_varg()
+		* purple_request_action()
+		* purple_request_choice_varg()
+		* purple_request_choice()
+		* purple_request_fields()
+		* purple_request_file()
+		* purple_request_folder()
+		* purple_request_input()
+		* purple_request_ok_cancel()
+		* purple_request_yes_no()
+
 version 2.2.2 (??/??/????):
 	libpurple:
 		Changed:
@@ -100,7 +161,7 @@
 		* gnt_util_parse_xhtml_to_textview to parse XHTML strings in a
 		  GntTextView (this works only if libxml2 is available)
 
-Version 2.1.1 (08/20/2007):
+version 2.1.1 (08/20/2007):
 	libpurple:
 		Changed:
 		* PurpleAccountUiOps.request_authorize's authorize_cb and
--- a/Doxyfile.in	Sun Oct 14 21:20:50 2007 +0000
+++ b/Doxyfile.in	Mon Oct 15 10:45:46 2007 +0000
@@ -169,7 +169,8 @@
                          "endsignalproto=@endcode" \
                          "signaldesc=@par Description:" \
                          "signals=@b Signals:" \
-                         "endsignals="
+                         "endsignals=" \
+                         "constreturn=@note The return value of this function must not be modified or freed. @return"
 
 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
 # only. Doxygen will then generate output that is more tailored for C. 
@@ -457,7 +458,8 @@
 # excluded from the INPUT source files. This way you can easily exclude a 
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
 
-EXCLUDE                = 
+EXCLUDE                = libpurple/purple-client.h \
+                         libpurple/purple-client-bindings.h
 
 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
 # that are symbolic links (a Unix filesystem feature) are excluded from the input.
@@ -857,7 +859,7 @@
 # feature is still experimental and incomplete at the 
 # moment.
 
-GENERATE_XML           = NO
+GENERATE_XML           = YES
 
 # The XML_OUTPUT tag is used to specify where the XML pages will be put. 
 # If a relative path is entered the value of OUTPUT_DIRECTORY will be 
@@ -1160,7 +1162,7 @@
 # not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
 # If 0 is used for the depth value (the default), the graph is not depth-constrained.
 
-MAX_DOT_GRAPH_DEPTH    = 0
+MAX_DOT_GRAPH_DEPTH    = 2
 
 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
 # background. This is disabled by default, which results in a white background. 
--- a/Makefile.am	Sun Oct 14 21:20:50 2007 +0000
+++ b/Makefile.am	Mon Oct 15 10:45:46 2007 +0000
@@ -48,6 +48,13 @@
 if HAVE_DOXYGEN
 	@echo "Running doxygen..."
 	@doxygen
+if HAVE_XSLTPROC
+	@echo "Generating devhelp index..."
+	@xsltproc doxy2devhelp.xsl doc/xml/index.xml > doc/html/pidgin.devhelp
+	@echo "(Symlink doc/html to ~/.local/share/gtk-doc/html/pidgin to make devhelp see the documentation)"
+else
+	@echo "Not generating devhelp index: xsltproc was not found by configure"
+endif
 else
 	@echo "doxygen was not found during configure.  Aborting."
 	@echo;
--- a/configure.ac	Sun Oct 14 21:20:50 2007 +0000
+++ b/configure.ac	Mon Oct 15 10:45:46 2007 +0000
@@ -2101,6 +2101,10 @@
 	[AC_HELP_STRING([--enable-dot],
 		[enable graphs in doxygen via 'dot'])],
 	enable_dot="$enableval", enable_dot="yes")
+AC_ARG_ENABLE(devhelp,
+	[AC_HELP_STRING([--enable-devhelp],
+		[enable building index for devhelp documentation browser])],
+	enable_devhelp="$enableval", enable_devhelp="yes")
 
 if test "x$enable_doxygen" = xyes; then
 	AC_CHECK_PROG(DOXYGEN, doxygen, true, false)
@@ -2120,14 +2124,28 @@
 				AC_DEFINE_UNQUOTED(HAVE_DOT, 1, [whether or not we have dot])
 			fi
 		fi
+
+		if test "x$enable_devhelp" = "xyes"; then
+			AC_CHECK_PROG(XSLTPROC, xsltproc, true, false)
+
+			if test $XSLTPROC = false; then
+				enable_devhelp="no";
+				AC_MSG_WARN([*** xsltproc not found; devhelp index will not be created])
+			else
+				AC_DEFINE_UNQUOTED(HAVE_XSLTPROC, 1, [whether or not we have xsltproc for devhelp index])
+			fi
+		fi
 	fi
 else
 	enable_dot="no"
+	enable_devhelp="no"
 fi
 
 AC_SUBST(enable_doxygen)
 AC_SUBST(enable_dot)
+AC_SUBST(enable_devhelp)
 AM_CONDITIONAL(HAVE_DOXYGEN, test "x$enable_doxygen" = "xyes")
+AM_CONDITIONAL(HAVE_XSLTPROC, test "x$enable_devhelp" = "xyes")
 
 AC_ARG_ENABLE(debug, [AC_HELP_STRING([--enable-debug],
 	[compile with debugging support])], , enable_debug=no)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doxy2devhelp.xsl	Mon Oct 15 10:45:46 2007 +0000
@@ -0,0 +1,98 @@
+<xsl:stylesheet
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:fo="http://www.w3.org/1999/XSL/Format"
+    version="1.0">
+
+<!-- Based on http://bur.st/~eleusis/devhelp/doxy2devhelp.xsl
+             (http://bur.st/~eleusis/devhelp/README)
+     which is based on http://bugzilla.gnome.org/show_bug.cgi?id=122450
+-->
+
+<xsl:output method="xml" version="1.0" indent="yes"/>
+
+<xsl:param name="reference_prefix"></xsl:param>
+
+<xsl:template match="/">
+  <book title="Pidgin Documentation"
+        name="pidgin"
+        link="{$reference_prefix}main.html">
+  <chapters>
+    <sub name="Modules" link="{$reference_prefix}modules.html">
+      <xsl:apply-templates select="doxygenindex/compound[@kind='group']">
+        <xsl:sort select="."/>
+      </xsl:apply-templates>
+    </sub>
+    <!-- annotated.html has the short descriptions beside each struct.  is
+         that more useful than being grouped alphabetically?
+      -->
+    <sub name="Structs" link="{$reference_prefix}classes.html">
+      <xsl:apply-templates select="doxygenindex/compound[@kind='struct']">
+        <xsl:sort select="."/>
+      </xsl:apply-templates>
+    </sub>
+    <!-- This is redundant given Modules -->
+    <!--
+    <sub name="Directories" link="{$reference_prefix}dirs.html">
+      <xsl:apply-templates select="doxygenindex/compound[@kind='dir']">
+        <xsl:sort select="."/>
+      </xsl:apply-templates>
+    </sub>
+    -->
+    <!-- FIXME: Some files show up here but are broken links; mostly
+                files that are under pages...
+      -->
+    <sub name="Files" link="{$reference_prefix}files.html">
+      <xsl:apply-templates select="doxygenindex/compound[@kind='file']">
+        <xsl:sort select="."/>
+      </xsl:apply-templates>
+    </sub>
+    <sub name="Signals, HOWTOs, Other" link="{$reference_prefix}pages.html">
+      <xsl:apply-templates select="doxygenindex/compound[@kind='page']">
+        <xsl:sort select="."/>
+      </xsl:apply-templates>
+    </sub>
+  </chapters>
+
+  <functions>
+    <!-- @todo: maybe select only the real functions, ie those with kind=="function"? -->
+    <xsl:apply-templates select="doxygenindex/compound/member" mode="as-function"/>
+  </functions>
+  </book>
+</xsl:template>
+
+<xsl:template match="compound">
+  <xsl:param name="name"><xsl:value-of select="name"/></xsl:param>
+  <xsl:param name="link"><xsl:value-of select="@refid"/>.html</xsl:param>
+  <sub name="{$name}" link="{$reference_prefix}{$link}">
+  <xsl:apply-templates select="member" mode="as-sub">
+    <xsl:sort select="."/>
+  </xsl:apply-templates>
+  </sub>
+</xsl:template>
+
+<xsl:template match="member" mode="as-function">
+  <!--
+  <function name="atk_set_value" link="atk-atkvalue.html#ATK-SET-VALUE"/>
+  -->
+  <xsl:param name="name"><xsl:value-of select="name"/></xsl:param>
+  <!-- Link is refid attribute of parent element + "#" + diff between refid of parent and own refid -->
+  <xsl:param name="refid_parent"><xsl:value-of select="parent::node()/@refid"/></xsl:param>
+  <xsl:param name="own_refid"><xsl:value-of select="@refid"/></xsl:param>
+  <xsl:param name="offset"><xsl:value-of select="string-length($refid_parent) + 3"/></xsl:param>
+  <xsl:param name="ref_diff"><xsl:value-of select="substring($own_refid, $offset, 33)"/></xsl:param>
+  <xsl:param name="link"><xsl:value-of select="$refid_parent"/>.html#<xsl:value-of select="$ref_diff"/></xsl:param>
+  <function name="{$name}" link="{$reference_prefix}{$link}"/>
+</xsl:template>
+
+<xsl:template match="member" mode="as-sub">
+  <xsl:param name="name"><xsl:value-of select="name"/></xsl:param>
+  <!-- Link is refid attribute of parent element + "#" + diff between refid of parent and own refid -->
+  <xsl:param name="refid_parent"><xsl:value-of select="parent::node()/@refid"/></xsl:param>
+  <xsl:param name="own_refid"><xsl:value-of select="@refid"/></xsl:param>
+  <xsl:param name="offset"><xsl:value-of select="string-length($refid_parent) + 3"/></xsl:param>
+  <xsl:param name="ref_diff"><xsl:value-of select="substring($own_refid, $offset, 33)"/></xsl:param>
+  <xsl:param name="link"><xsl:value-of select="$refid_parent"/>.html#<xsl:value-of select="$ref_diff"/></xsl:param>
+  <sub name="{$name}" link="{$reference_prefix}{$link}"/>
+</xsl:template>
+
+</xsl:stylesheet>
--- a/finch/gntaccount.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntaccount.c	Mon Oct 15 10:45:46 2007 +0000
@@ -632,8 +632,8 @@
 	prompt = g_strdup_printf(_("Are you sure you want to delete %s?"),
 			purple_account_get_username(account));
 
-	purple_request_action(account, _("Delete Account"), prompt, NULL, 0,
-						  account, NULL, NULL, account, 2,
+	purple_request_action_with_hint(account, _("Delete Account"), prompt, NULL, 0,
+						  account, NULL, NULL, PURPLE_REQUEST_UI_HINT_ACCOUNTMGR, account, 2,
 						  _("Delete"), really_delete_account,
 						  _("Cancel"), NULL);
 	g_free(prompt);
@@ -881,10 +881,10 @@
 	data->alias    = (alias != NULL ? g_strdup(alias) : NULL);
 
 	buffer = make_info(account, gc, remote_user, id, alias, msg);
-	purple_request_action(NULL, NULL, _("Add buddy to your list?"),
+	purple_request_action_with_hint(NULL, NULL, _("Add buddy to your list?"),
 	                    buffer, PURPLE_DEFAULT_ACTION_NONE,
 						account, remote_user, NULL,
-						data, 2,
+						PURPLE_REQUEST_UI_HINT_BLIST, data, 2,
 	                    _("Add"),    G_CALLBACK(add_user_cb),
 	                    _("Cancel"), G_CALLBACK(free_add_user_data));
 	g_free(buffer);
@@ -969,10 +969,10 @@
 		gnt_box_set_title(GNT_BOX(uihandle), _("Authorize buddy?"));
 		gnt_box_set_pad(GNT_BOX(uihandle), 0);
 
-		widget = purple_request_action(NULL, _("Authorize buddy?"), buffer, NULL,
+		widget = purple_request_action_with_hint(NULL, _("Authorize buddy?"), buffer, NULL,
 			PURPLE_DEFAULT_ACTION_NONE,
 			account, remote_user, NULL,
-			aa, 2,
+			PURPLE_REQUEST_UI_HINT_BLIST, aa, 2,
 			_("Authorize"), authorize_and_add_cb,
 			_("Deny"), deny_no_add_cb);
 		gnt_screen_release(widget);
@@ -996,10 +996,10 @@
 
 		g_signal_connect_swapped(G_OBJECT(uihandle), "destroy", G_CALLBACK(free_auth_and_add), aa);
 	} else {
-		uihandle = purple_request_action(NULL, _("Authorize buddy?"), buffer, NULL,
+		uihandle = purple_request_action_with_hint(NULL, _("Authorize buddy?"), buffer, NULL,
 			PURPLE_DEFAULT_ACTION_NONE,
 			account, remote_user, NULL,
-			user_data, 2,
+			PURPLE_REQUEST_UI_HINT_BLIST, user_data, 2,
 			_("Authorize"), auth_cb,
 			_("Deny"), deny_cb);
 	}
--- a/finch/gntblist.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntblist.c	Mon Oct 15 10:45:46 2007 +0000
@@ -338,12 +338,12 @@
 		purple_request_field_account_set_value(field, account);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(NULL, _("Add Buddy"), NULL, _("Please enter buddy information."),
+	purple_request_fields_with_hint(NULL, _("Add Buddy"), NULL, _("Please enter buddy information."),
 			fields,
 			_("Add"), G_CALLBACK(add_buddy_cb),
 			_("Cancel"), NULL,
 			account, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 static void
@@ -416,11 +416,11 @@
 	field = purple_request_field_bool_new("autojoin", _("Auto-join"), FALSE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(NULL, _("Add Chat"), NULL,
+	purple_request_fields_with_hint(NULL, _("Add Chat"), NULL,
 			_("You can edit more information from the context menu later."),
 			fields, _("Add"), G_CALLBACK(add_chat_cb), _("Cancel"), NULL,
 			NULL, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 static void
@@ -451,11 +451,11 @@
 static void
 finch_request_add_group()
 {
-	purple_request_input(NULL, _("Add Group"), NULL, _("Enter the name of the group"),
+	purple_request_input_with_hint(NULL, _("Add Group"), NULL, _("Enter the name of the group"),
 			NULL, FALSE, FALSE, NULL,
 			_("Add"), G_CALLBACK(add_group_cb), _("Cancel"), NULL,
 			NULL, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 static PurpleBlistUiOps blist_ui_ops =
@@ -799,10 +799,10 @@
 
 	g_list_free(parts);
 
-	purple_request_fields(NULL, _("Edit Chat"), NULL, _("Please Update the necessary fields."),
+	purple_request_fields_with_hint(NULL, _("Edit Chat"), NULL, _("Please Update the necessary fields."),
 			fields, _("Edit"), G_CALLBACK(chat_components_edit_ok), _("Cancel"), NULL,
 			NULL, NULL, NULL,
-			chat);
+			PURPLE_REQUEST_UI_HINT_BLIST, chat);
 }
 
 static void
@@ -1000,11 +1000,11 @@
 	prompt = g_strdup_printf(_("Please enter the new name for %s"), name);
 
 	text = PURPLE_BLIST_NODE_IS_GROUP(node) ? _("Rename") : _("Set Alias");
-	purple_request_input(node, text, prompt, _("Enter empty string to reset the name."),
+	purple_request_input_with_hint(node, text, prompt, _("Enter empty string to reset the name."),
 			name, FALSE, FALSE, NULL, text, G_CALLBACK(rename_blist_node),
 			_("Cancel"), NULL,
 			NULL, NULL, NULL,
-			node);
+			PURPLE_REQUEST_UI_HINT_BLIST, node);
 
 	g_free(prompt);
 }
@@ -1092,11 +1092,11 @@
 	primary = g_strdup_printf(_("Are you sure you want to remove %s?"), name);
 
 	/* XXX: anything to do with the returned ui-handle? */
-	purple_request_action(node, _("Confirm Remove"),
+	purple_request_action_with_hint(node, _("Confirm Remove"),
 			primary, sec,
 			1,
 			account, name, NULL,
-			node, 2,
+			PURPLE_REQUEST_UI_HINT_BLIST, node, 2,
 			_("Remove"), finch_blist_remove_node,
 			_("Cancel"), NULL);
 	g_free(primary);
@@ -2215,7 +2215,7 @@
 	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(purple_get_blist(), _("New Instant Message"),
+	purple_request_fields_with_hint(purple_get_blist(), _("New Instant Message"),
 						NULL,
 						_("Please enter the screen name or alias of the person "
 						  "you would like to IM."),
@@ -2223,7 +2223,7 @@
 						_("OK"), G_CALLBACK(send_im_select_cb),
 						_("Cancel"), NULL,
 						NULL, NULL, NULL,
-						NULL);
+						PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 static void
@@ -2279,14 +2279,14 @@
 	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(purple_get_blist(), _("Join a Chat"),
+	purple_request_fields_with_hint(purple_get_blist(), _("Join a Chat"),
 						NULL,
 						_("Please enter the name of the chat you want to join."),
 						fields,
 						_("Join"), G_CALLBACK(join_chat_select_cb),
 						_("Cancel"), NULL,
 						NULL, NULL, NULL,
-						NULL);
+						PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 static void
--- a/finch/gntcertmgr.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntcertmgr.c	Mon Oct 15 10:45:46 2007 +0000
@@ -82,7 +82,7 @@
 	if (crt != NULL) {
 		gchar *default_hostname;
 		default_hostname = purple_certificate_get_subject_name(crt);
-		purple_request_input(NULL,
+		purple_request_input_with_hint(NULL,
 				_("Certificate Import"),
 				_("Specify a hostname"),
 				_("Type the host name this certificate is for."),
@@ -90,7 +90,7 @@
 				_("OK"), G_CALLBACK(tls_peers_mgmt_import_ok2_cb),
 				_("Cancel"), G_CALLBACK(tls_peers_mgmt_import_cancel2_cb),
 				NULL, NULL, NULL,
-				crt);
+				PURPLE_REQUEST_UI_HINT_CERTMGR, crt);
 		g_free(default_hostname);
 	} else {
 		gchar * secondary;
@@ -106,13 +106,13 @@
 static void
 add_cert_cb(GntWidget *button, gpointer null)
 {
-	purple_request_file(NULL,
+	purple_request_file_with_hint(NULL,
 			_("Select a PEM certificate"),
 			"certificate.pem",
 			FALSE,
 			G_CALLBACK(tls_peers_mgmt_import_ok_cb),
 			NULL,
-			NULL, NULL, NULL, NULL );
+			NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_CERTMGR, NULL );
 }
 
 /* Save certs in some file */
@@ -155,13 +155,13 @@
 		return;
 	}
 
-	purple_request_file((void*)key,
+	purple_request_file_with_hint((void*)key,
 			_("PEM X.509 Certificate Export"),
 			"certificate.pem", TRUE,
 			G_CALLBACK(tls_peers_mgmt_export_ok_cb),
 			G_CALLBACK(purple_certificate_destroy),
 			NULL, NULL, NULL,
-			crt);
+			PURPLE_REQUEST_UI_HINT_CERTMGR, crt);
 }
 
 /* Show information about a cert */
@@ -233,10 +233,10 @@
 	primary = g_strdup_printf(_("Really delete certificate for %s?"), key);
 
 	purple_request_close_with_handle((void *)key);
-	purple_request_yes_no((void *)key, _("Confirm certificate delete"),
+	purple_request_yes_no_with_hint((void *)key, _("Confirm certificate delete"),
 			primary, NULL,
 			2,
-			NULL, NULL, NULL,
+			NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_CERTMGR,
 			g_strdup(key),
 			tls_peers_mgmt_delete_confirm_cb,
 			g_free);
--- a/finch/gntconn.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntconn.c	Mon Oct 15 10:45:46 2007 +0000
@@ -130,9 +130,9 @@
 				"Finch will not attempt to reconnect the account until you "
 				"correct the error and re-enable the account."), text);
 
-		purple_request_action(account, NULL, primary, secondary, 2,
+		purple_request_action_with_hint(account, NULL, primary, secondary, 2,
 							account, NULL, NULL,
-							account, 3,
+							PURPLE_REQUEST_UI_HINT_BLIST, account, 3,
 							_("OK"), NULL,
 							_("Modify Account"), PURPLE_CALLBACK(ce_modify_account_cb),
 							_("Re-enable Account"), PURPLE_CALLBACK(ce_enable_account_cb));
--- a/finch/gntnotify.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntnotify.c	Mon Oct 15 10:45:46 2007 +0000
@@ -194,6 +194,7 @@
 	PurpleAccount *account = purple_connection_get_account(gc);
 	GString *message = g_string_new(NULL);
 	void *ret;
+	static int key = 0;
 
 	if (!detailed)
 	{
@@ -212,7 +213,7 @@
 
 		to = g_strdup_printf("%s (%s)", tos ? *tos : purple_account_get_username(account),
 					purple_account_get_protocol_name(account));
-		gnt_tree_add_row_after(GNT_TREE(emaildialog.tree), GINT_TO_POINTER(time(NULL)),
+		gnt_tree_add_row_after(GNT_TREE(emaildialog.tree), GINT_TO_POINTER(++key),
 				gnt_tree_create_row(GNT_TREE(emaildialog.tree), to,
 					froms ? *froms : "[Unknown sender]",
 					*subjects),
@@ -360,7 +361,8 @@
 	i = 0;
 	for (iter = results->columns; iter; iter = iter->next)
 	{
-		gnt_tree_set_column_title(GNT_TREE(tree), i, iter->data);
+		PurpleNotifySearchColumn *column = iter->data;
+		gnt_tree_set_column_title(GNT_TREE(tree), i, column->title);
 		i++;
 	}
 
--- a/finch/gntplugin.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntplugin.c	Mon Oct 15 10:45:46 2007 +0000
@@ -469,9 +469,9 @@
 		}
 	}
 
-	return purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
+	return purple_request_fields_with_hint(NULL, _("Preferences"), NULL, NULL, fields,
 			_("Save"), G_CALLBACK(finch_request_save_in_prefs), _("Cancel"), NULL,
 			NULL, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_PLUGINMGR, NULL);
 }
 
--- a/finch/gntpounce.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntpounce.c	Mon Oct 15 10:45:46 2007 +0000
@@ -660,9 +660,9 @@
 	pouncer = purple_account_get_username(account);
 	pouncee = purple_pounce_get_pouncee(pounce);
 	buf = g_strdup_printf(_("Are you sure you want to delete the pounce on %s for %s?"), pouncee, pouncer);
-	purple_request_action(pounce, NULL, buf, NULL, 0,
+	purple_request_action_with_hint(pounce, NULL, buf, NULL, 0,
 						account, pouncee, NULL,
-						pounce, 2,
+						PURPLE_REQUEST_UI_HINT_POUNCEMGR, pounce, 2,
 						_("Delete"), pounces_manager_delete_confirm_cb,
 						_("Cancel"), NULL);
 	g_free(buf);
--- a/finch/gntprefs.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntprefs.c	Mon Oct 15 10:45:46 2007 +0000
@@ -261,9 +261,9 @@
 	add_pref_group(fields, _("Idle"), idle);
 
 	pref_request.showing = TRUE;
-	pref_request.window = purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
+	pref_request.window = purple_request_fields_with_hint(NULL, _("Preferences"), NULL, NULL, fields,
 			_("Save"), G_CALLBACK(save_cb), _("Cancel"), free_strings,
 			NULL, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_PREFSMGR, NULL);
 }
 
--- a/finch/gntrequest.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntrequest.c	Mon Oct 15 10:45:46 2007 +0000
@@ -148,7 +148,7 @@
 		const char *ok_text, GCallback ok_cb,
 		const char *cancel_text, GCallback cancel_cb,
 		PurpleAccount *account, const char *who, PurpleConversation *conv,
-		void *user_data)
+		const char *ui_hint, void *user_data)
 {
 	GntWidget *window, *box, *entry;
 
@@ -205,7 +205,7 @@
 		const char *ok_text, GCallback ok_cb,
 		const char *cancel_text, GCallback cancel_cb,
 		PurpleAccount *account, const char *who, PurpleConversation *conv,
-		void *user_data, va_list choices)
+		const char *ui_hint, void *user_data, va_list choices)
 {
 	GntWidget *window, *combo, *box;
 	const char *text;
@@ -249,7 +249,7 @@
 finch_request_action(const char *title, const char *primary,
 		const char *secondary, int default_value,
 		PurpleAccount *account, const char *who, PurpleConversation *conv,
-		void *user_data, size_t actioncount,
+		const char *ui_hint, void *user_data, size_t actioncount,
 		va_list actions)
 {
 	GntWidget *window, *box, *button;
@@ -393,7 +393,7 @@
 		const char *ok, GCallback ok_cb,
 		const char *cancel, GCallback cancel_cb,
 		PurpleAccount *account, const char *who, PurpleConversation *conv,
-		void *userdata)
+		const char *ui_hint, void *userdata)
 {
 	GntWidget *window, *box;
 	GList *grlist;
@@ -645,7 +645,7 @@
 				gboolean savedialog,
 				GCallback ok_cb, GCallback cancel_cb,
 				PurpleAccount *account, const char *who, PurpleConversation *conv,
-				void *user_data)
+				const char *ui_hint, void *user_data)
 {
 	GntWidget *window = gnt_file_sel_new();
 	GntFileSel *sel = GNT_FILE_SEL(window);
--- a/finch/gntstatus.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/finch/gntstatus.c	Mon Oct 15 10:45:46 2007 +0000
@@ -138,9 +138,9 @@
 	ask = g_strdup_printf(_("Are you sure you want to delete \"%s\""),
 			purple_savedstatus_get_title(saved));
 
-	purple_request_action(saved, _("Delete Status"), ask, NULL, 0,
+	purple_request_action_with_hint(saved, _("Delete Status"), ask, NULL, 0,
 			NULL, NULL, NULL,
-			saved, 2,
+			PURPLE_REQUEST_UI_HINT_STATUSMGR, saved, 2,
 			_("Delete"), really_delete_status,
 			_("Cancel"), NULL);
 	g_free(ask);
--- a/libpurple/account.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/account.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1007,7 +1007,7 @@
 	field = purple_request_field_bool_new("remember", _("Save password"), FALSE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(account,
+	purple_request_fields_with_hint(account,
                         NULL,
                         primary,
                         NULL,
@@ -1015,7 +1015,7 @@
                         _("OK"), ok_cb,
                         _("Cancel"), cancel_cb,
 						account, NULL, NULL,
-                        user_data);
+                        PURPLE_REQUEST_UI_HINT_ACCOUNT, user_data);
 	g_free(primary);
 }
 
@@ -1295,7 +1295,7 @@
 
 	/* I'm sticking this somewhere in the code: bologna */
 
-	purple_request_fields(purple_account_get_connection(account),
+	purple_request_fields_with_hint(purple_account_get_connection(account),
 						NULL,
 						primary,
 						_("Please enter your current password and your "
@@ -1304,7 +1304,7 @@
 						_("OK"), G_CALLBACK(change_password_cb),
 						_("Cancel"), NULL,
 						account, NULL, NULL,
-						account);
+						PURPLE_REQUEST_UI_HINT_ACCOUNT, account);
 }
 
 static void
@@ -1332,14 +1332,14 @@
 			   _("Change user information for %s"),
 			   purple_account_get_username(account));
 
-	purple_request_input(gc, _("Set User Info"), primary, NULL,
+	purple_request_input_with_hint(gc, _("Set User Info"), primary, NULL,
 					   purple_account_get_user_info(account),
 					   TRUE, FALSE, ((gc != NULL) &&
 					   (gc->flags & PURPLE_CONNECTION_HTML) ? "html" : NULL),
 					   _("Save"), G_CALLBACK(set_user_info_cb),
 					   _("Cancel"), NULL,
 					   account, NULL, NULL,
-					   account);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, account);
 }
 
 void
--- a/libpurple/certificate.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/certificate.c	Mon Oct 15 10:45:46 2007 +0000
@@ -563,7 +563,7 @@
 	secondary = g_strdup_printf(_("Common name: %s %s\nFingerprint (SHA1): %s"), cn, cn_match, sha_asc);
 	
 	/* Make a semi-pretty display */
-	purple_request_accept_cancel(
+	purple_request_accept_cancel_with_hint(
 		vrq->cb_data, /* TODO: Find what the handle ought to be */
 		_("Single-use Certificate Verification"),
 		primary,
@@ -572,6 +572,7 @@
 		NULL,         /* No account */
 		NULL,         /* No other user */
 		NULL,         /* No associated conversation */
+		PURPLE_REQUEST_UI_HINT_BLIST,
 		vrq,
 		x509_singleuse_verify_cb,
 		x509_singleuse_verify_cb );
@@ -1185,7 +1186,7 @@
 				  vrq->subject_name);
 		
 	/* Make a semi-pretty display */
-	purple_request_action(
+	purple_request_action_with_hint(
 		vrq->cb_data, /* TODO: Find what the handle ought to be */
 		_("SSL Certificate Verification"),
 		primary,
@@ -1194,6 +1195,7 @@
 		NULL,         /* No account */
 		NULL,         /* No other user */
 		NULL,         /* No associated conversation */
+		PURPLE_REQUEST_UI_HINT_BLIST,
 		x509_tls_cached_ua_ctx_new(vrq, reason),
 		3,            /* Number of actions */
 		_("Accept"), x509_tls_cached_user_auth_accept_cb,
--- a/libpurple/certificate.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/certificate.h	Mon Oct 15 10:45:46 2007 +0000
@@ -435,7 +435,7 @@
  *
  * @return TRUE if 'crt' has a valid signature made by 'issuer',
  *         otherwise FALSE
- * @TODO Find a way to give the reason (bad signature, not the issuer, etc.) 
+ * @todo Find a way to give the reason (bad signature, not the issuer, etc.) 
  */
 gboolean
 purple_certificate_signed_by(PurpleCertificate *crt, PurpleCertificate *issuer);
@@ -450,7 +450,7 @@
  * @param chain      List of PurpleCertificate instances comprising the chain,
  *                   in the order certificate, issuer, issuer's issuer, etc.
  * @return TRUE if the chain is valid. See description.
- * @TODO Specify which certificate in the chain caused a failure
+ * @todo Specify which certificate in the chain caused a failure
  */
 gboolean
 purple_certificate_check_signature_chain(GList *chain);
@@ -781,7 +781,7 @@
  * Displays a window showing X.509 certificate information
  *
  * @param crt    Certificate under an "x509" Scheme
- * @TODO Will break on CA certs, as they have no Common Name
+ * @todo Will break on CA certs, as they have no Common Name
  */
 void
 purple_certificate_display_x509(PurpleCertificate *crt);
--- a/libpurple/connection.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/connection.h	Mon Oct 15 10:45:46 2007 +0000
@@ -249,6 +249,7 @@
 /**************************************************************************/
 /*@{*/
 
+#ifndef PURPLE_DISABLE_DEPRECATED
 /**
  * This function should only be called by purple_account_connect()
  * in account.c.  If you're trying to sign on an account, use that
@@ -265,10 +266,14 @@
  * @param regist   Whether we are registering a new account or just
  *                 trying to do a normal signon.
  * @param password The password to use.
+ *
+ * @deprecated As this is internal, we should make it private in 3.0.0.
  */
 void purple_connection_new(PurpleAccount *account, gboolean regist,
 									const char *password);
+#endif
 
+#ifndef PURPLE_DISABLE_DEPRECATED
 /**
  * This function should only be called by purple_account_unregister()
  * in account.c.
@@ -278,9 +283,15 @@
  *
  * @param account  The account to unregister
  * @param password The password to use.
+ * @param cb Optional callback to be called when unregistration is complete
+ * @param user_data user data to pass to the callback
+ *
+ * @deprecated As this is internal, we should make it private in 3.0.0.
  */
 void purple_connection_new_unregister(PurpleAccount *account, const char *password, PurpleAccountUnregistrationCb cb, void *user_data);
+#endif
 
+#ifndef PURPLE_DISABLE_DEPRECATED
 /**
  * Disconnects and destroys a PurpleConnection.
  *
@@ -289,8 +300,11 @@
  * function instead.
  *
  * @param gc The purple connection to destroy.
+ *
+ * @deprecated As this is internal, we should make it private in 3.0.0.
  */
 void purple_connection_destroy(PurpleConnection *gc);
+#endif
 
 /**
  * Sets the connection state.  PRPLs should call this and pass in
--- a/libpurple/conversation.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/conversation.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1209,9 +1209,9 @@
 	data[0] = conv;
 	data[1] = (gpointer)message;
 
-	purple_request_action(conv, NULL, _("Send Message"), text, 0,
+	purple_request_action_with_hint(conv, NULL, _("Send Message"), text, 0,
 						  purple_conversation_get_account(conv), NULL, conv,
-						  data, 2,
+						  PURPLE_REQUEST_UI_HINT_CONV, data, 2,
 						  _("_Send Message"), G_CALLBACK(purple_conv_send_confirm_cb),
 						  _("Cancel"), NULL);
 }
--- a/libpurple/core.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/core.c	Mon Oct 15 10:45:46 2007 +0000
@@ -94,6 +94,8 @@
 	/* The signals subsystem is important and should be first. */
 	purple_signals_init();
 
+	purple_util_init();
+
 	purple_signal_register(core, "uri-handler",
 		purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
 		purple_value_new(PURPLE_TYPE_BOOLEAN), 3,
@@ -229,6 +231,9 @@
 #ifdef HAVE_DBUS
 	purple_dbus_uninit();
 #endif
+
+	purple_util_uninit();
+
 	purple_signals_uninit();
 
 	g_free(core->ui);
--- a/libpurple/dnsquery.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/dnsquery.h	Mon Oct 15 10:45:46 2007 +0000
@@ -59,7 +59,7 @@
 	                         PurpleDnsQueryFailedCallback failed_cb);
 
 	/** Called just before @a query_data is freed; this should cancel any
-	 *  further use of @q query_data the UI would make. Unneeded if
+	 *  further use of @a query_data the UI would make. Unneeded if
 	 *  #resolve_host is not implemented.
 	 */
 	void (*destroy)(PurpleDnsQueryData *query_data);
--- a/libpurple/ft.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/ft.c	Mon Oct 15 10:45:46 2007 +0000
@@ -309,12 +309,12 @@
 static int
 purple_xfer_choose_file(PurpleXfer *xfer)
 {
-	purple_request_file(xfer, NULL, purple_xfer_get_filename(xfer),
+	purple_request_file_with_hint(xfer, NULL, purple_xfer_get_filename(xfer),
 					  (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE),
 					  G_CALLBACK(purple_xfer_choose_file_ok_cb),
 					  G_CALLBACK(purple_xfer_choose_file_cancel_cb),
 					  purple_xfer_get_account(xfer), xfer->who, NULL,
-					  xfer);
+					  PURPLE_REQUEST_UI_HINT_XFER, xfer);
 
 	return 0;
 }
@@ -359,10 +359,10 @@
 			serv_got_im(purple_account_get_connection(xfer->account),
 								 xfer->who, xfer->message, 0, time(NULL));
 
-		purple_request_accept_cancel(xfer, NULL, buf, NULL,
+		purple_request_accept_cancel_with_hint(xfer, NULL, buf, NULL,
 								  PURPLE_DEFAULT_ACTION_NONE,
 								  xfer->account, xfer->who, NULL,
-								  xfer,
+								  PURPLE_REQUEST_UI_HINT_XFER, xfer,
 								  G_CALLBACK(purple_xfer_choose_file),
 								  G_CALLBACK(cancel_recv_cb));
 
@@ -402,10 +402,10 @@
 					 "Remote host: %s\nRemote port: %d"),
 					   purple_xfer_get_remote_ip(xfer),
 					   purple_xfer_get_remote_port(xfer));
-	purple_request_accept_cancel(xfer, NULL, buf, buf2,
+	purple_request_accept_cancel_with_hint(xfer, NULL, buf, buf2,
 							   PURPLE_DEFAULT_ACTION_NONE,
 							   xfer->account, xfer->who, NULL,
-							   xfer,
+							   PURPLE_REQUEST_UI_HINT_XFER, xfer,
 							   G_CALLBACK(ask_accept_ok),
 							   G_CALLBACK(ask_accept_cancel));
 	g_free(buf);
--- a/libpurple/plugins/autoaccept.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/plugins/autoaccept.c	Mon Oct 15 10:45:46 2007 +0000
@@ -159,12 +159,12 @@
 
 	message = g_strdup_printf(_("When a file-transfer request arrives from %s"), 
 					purple_contact_get_alias((PurpleContact *)node));
-	purple_request_choice(plugin, _("Set Autoaccept Setting"), message,
+	purple_request_choice_with_hint(plugin, _("Set Autoaccept Setting"), message,
 						NULL, purple_blist_node_get_int(node, "autoaccept"),
 						_("_Save"), G_CALLBACK(save_cb),
 						_("_Cancel"), NULL,
 						NULL, NULL, NULL,
-						node,
+						PURPLE_REQUEST_UI_HINT_XFER, node,
 						_("Ask"), FT_ASK,
 						_("Auto Accept"), FT_ACCEPT,
 						_("Auto Reject"), FT_REJECT,
--- a/libpurple/plugins/buddynote.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/plugins/buddynote.c	Mon Oct 15 10:45:46 2007 +0000
@@ -43,14 +43,14 @@
 
 	note = purple_blist_node_get_string(node, "notes");
 
-	purple_request_input(node, _("Notes"),
+	purple_request_input_with_hint(node, _("Notes"),
 					   _("Enter your notes below..."),
 					   NULL,
 					   note, TRUE, FALSE, "html",
 					   _("Save"), G_CALLBACK(do_it_cb),
 					   _("Cancel"), G_CALLBACK(dont_do_it_cb),
 					   NULL, NULL, NULL,
-					   node);
+					   PURPLE_REQUEST_UI_HINT_BUDDY, node);
 }
 
 static void
--- a/libpurple/plugins/idle.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/plugins/idle.c	Mon Oct 15 10:45:46 2007 +0000
@@ -161,7 +161,7 @@
 	request = purple_request_fields_new();
 	purple_request_fields_add_group(request, group);
 
-	purple_request_fields(action->plugin,
+	purple_request_fields_with_hint(action->plugin,
 			N_("I'dle Mak'er"),
 			_("Set Account Idle Time"),
 			NULL,
@@ -169,7 +169,7 @@
 			_("_Set"), G_CALLBACK(idle_action_ok),
 			_("_Cancel"), NULL,
 			NULL, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_ACCOUNT, NULL);
 }
 
 static void
@@ -195,7 +195,7 @@
 	request = purple_request_fields_new();
 	purple_request_fields_add_group(request, group);
 
-	purple_request_fields(action->plugin,
+	purple_request_fields_with_hint(action->plugin,
 			N_("I'dle Mak'er"),
 			_("Unset Account Idle Time"),
 			NULL,
@@ -203,7 +203,7 @@
 			_("_Unset"), G_CALLBACK(unidle_action_ok),
 			_("_Cancel"), NULL,
 			NULL, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_ACCOUNT, NULL);
 }
 
 static void
@@ -221,7 +221,7 @@
 	request = purple_request_fields_new();
 	purple_request_fields_add_group(request, group);
 
-	purple_request_fields(action->plugin,
+	purple_request_fields_with_hint(action->plugin,
 			N_("I'dle Mak'er"),
 			_("Set Idle Time for All Accounts"),
 			NULL,
@@ -229,7 +229,7 @@
 			_("_Set"), G_CALLBACK(idle_all_action_ok),
 			_("_Cancel"), NULL,
 			NULL, NULL, NULL,
-			NULL);
+			PURPLE_REQUEST_UI_HINT_ACCOUNT, NULL);
 }
 
 static void
--- a/libpurple/plugins/log_reader.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/plugins/log_reader.c	Mon Oct 15 10:45:46 2007 +0000
@@ -28,6 +28,19 @@
 	NAME_GUESS_THEM
 };
 
+/* Some common functions. */
+static int get_month(const char *month)
+{
+	int iter;
+	const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
+	for (iter = 0; months[iter]; iter++) {
+		if (strcmp(month, months[iter]) == 0)
+			break;
+	}
+	return iter;
+}
+
 
 /*****************************************************************************
  * Adium Logger                                                              *
@@ -103,9 +116,10 @@
 				} else {
 					char *filename = g_build_filename(path, file, NULL);
 					FILE *handle = g_fopen(filename, "rb");
-					char *contents;
+					char contents[57];   /* XXX: This is really inflexible. */
 					char *contents2;
 					struct adium_logger_data *data;
+					size_t rd;
 					PurpleLog *log;
 
 					if (!handle) {
@@ -113,11 +127,9 @@
 						continue;
 					}
 
-					/* XXX: This is really inflexible. */
-					contents = g_malloc(57);
-					fread(contents, 56, 1, handle);
+					rd = fread(contents, 1, 56, handle) == 0;
 					fclose(handle);
-					contents[56] = '\0';
+					contents[rd] = '\0';
 
 					/* XXX: This is fairly inflexible. */
 					contents2 = contents;
@@ -135,11 +147,9 @@
 
 						purple_debug_error("Adium log parse",
 						                   "Contents timestamp parsing error\n");
-						g_free(contents);
 						g_free(filename);
 						continue;
 					}
-					g_free(contents);
 
 					data = g_new0(struct adium_logger_data, 1);
 					data->path = filename;
@@ -168,21 +178,20 @@
 				} else {
 					char *filename = g_build_filename(path, file, NULL);
 					FILE *handle = g_fopen(filename, "rb");
-					char *contents;
+					char contents[14];   /* XXX: This is really inflexible. */
 					char *contents2;
 					struct adium_logger_data *data;
 					PurpleLog *log;
+					size_t rd;
 
 					if (!handle) {
 						g_free(filename);
 						continue;
 					}
 
-					/* XXX: This is really inflexible. */
-					contents = g_malloc(14);
-					fread(contents, 13, 1, handle);
+					rd = fread(contents, 1, 13, handle);
 					fclose(handle);
-					contents[13] = '\0';
+					contents[rd] = '\0';
 
 					contents2 = contents;
 					while (*contents2 && *contents2 != '(')
@@ -195,13 +204,10 @@
 
 						purple_debug_error("Adium log parse",
 						                   "Contents timestamp parsing error\n");
-						g_free(contents);
 						g_free(filename);
 						continue;
 					}
 
-					g_free(contents);
-
 					tm.tm_year -= 1900;
 					tm.tm_mon  -= 1;
 
@@ -1355,36 +1361,7 @@
 						 * daylight savings time.
 						 */
 						tm.tm_isdst = -1;
-
-						/* Ugly hack, in case current locale
-						 * is not English. This code is taken
-						 * from log.c.
-						 */
-						if (strcmp(month, "Jan") == 0) {
-							tm.tm_mon= 0;
-						} else if (strcmp(month, "Feb") == 0) {
-							tm.tm_mon = 1;
-						} else if (strcmp(month, "Mar") == 0) {
-							tm.tm_mon = 2;
-						} else if (strcmp(month, "Apr") == 0) {
-							tm.tm_mon = 3;
-						} else if (strcmp(month, "May") == 0) {
-							tm.tm_mon = 4;
-						} else if (strcmp(month, "Jun") == 0) {
-							tm.tm_mon = 5;
-						} else if (strcmp(month, "Jul") == 0) {
-							tm.tm_mon = 6;
-						} else if (strcmp(month, "Aug") == 0) {
-							tm.tm_mon = 7;
-						} else if (strcmp(month, "Sep") == 0) {
-							tm.tm_mon = 8;
-						} else if (strcmp(month, "Oct") == 0) {
-							tm.tm_mon = 9;
-						} else if (strcmp(month, "Nov") == 0) {
-							tm.tm_mon = 10;
-						} else if (strcmp(month, "Dec") == 0) {
-							tm.tm_mon = 11;
-						}
+						tm.tm_mon = get_month(month);
 
 						data = g_new0(
 							struct trillian_logger_data, 1);
@@ -1446,7 +1423,7 @@
 
 	file = g_fopen(data->path, "rb");
 	fseek(file, data->offset, SEEK_SET);
-	fread(read, data->length, 1, file);
+	data->length = fread(read, 1, data->length, file);
 	fclose(file);
 
 	if (read[data->length-1] == '\n') {
@@ -1945,7 +1922,7 @@
 	contents = g_malloc(data->length + 2);
 
 	fseek(file, data->offset, SEEK_SET);
-	fread(contents, data->length, 1, file);
+	data->length = fread(contents, 1, data->length, file);
 	fclose(file);
 
 	contents[data->length] = '\n';
@@ -2098,6 +2075,347 @@
 	g_free(data);
 }
 
+/*************************************************************************
+ * aMSN Logger                                                           *
+ *************************************************************************/
+
+/* The aMSN logger doesn't write logs, only reads them.  This is to include
+ * aMSN logs in the log viewer transparently.
+ */
+
+static PurpleLogLogger *amsn_logger;
+
+struct amsn_logger_data {
+	char *path;
+	int offset;
+	int length;
+};
+
+#define AMSN_LOG_CONV_START "|\"LRED[Conversation started on "
+#define AMSN_LOG_CONV_END "|\"LRED[You have closed the window on "
+#define AMSN_LOG_CONV_EXTRA "01 Aug 2001 00:00:00]"
+
+static GList *amsn_logger_parse_file(char *filename, const char *sn, PurpleAccount *account)
+{
+	GList *list = NULL;
+	GError *error;
+	char *contents;
+	struct amsn_logger_data *data;
+	PurpleLog *log;
+
+	purple_debug_info("aMSN logger", "Reading %s\n", filename);
+	error = NULL;
+	if (!g_file_get_contents(filename, &contents, NULL, &error)) {
+		purple_debug_error("aMSN logger",
+		                   "Couldn't read file %s: %s \n", filename,
+		                   (error && error->message) ?
+		                    error->message : "Unknown error");
+		if (error)
+			g_error_free(error);
+	} else {
+		char *c = contents;
+		gboolean found_start = FALSE;
+		char *start_log = c;
+		int offset = 0;
+		struct tm tm;
+		while (c && *c) {
+			if (purple_str_has_prefix(c, AMSN_LOG_CONV_START)) {
+				char month[4];
+				if (sscanf(c + strlen(AMSN_LOG_CONV_START),
+				           "%u %3s %u %u:%u:%u",
+				           &tm.tm_mday, (char*)&month, &tm.tm_year,
+				           &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
+					found_start = FALSE;
+					purple_debug_error("aMSN logger",
+					                   "Error parsing start date for %s\n",
+					                   filename);
+				} else {
+					tm.tm_year -= 1900;
+
+					/* Let the C library deal with
+					 * daylight savings time.
+					 */
+					tm.tm_isdst = -1;
+					tm.tm_mon = get_month(month);
+
+					found_start = TRUE;
+					offset = c - contents;
+					start_log = c;
+				}
+			} else if (purple_str_has_prefix(c, AMSN_LOG_CONV_END) && found_start) {
+				data = g_new0(struct amsn_logger_data, 1);
+				data->path = g_strdup(filename);
+				data->offset = offset;
+				data->length = c - start_log
+					             + strlen(AMSN_LOG_CONV_END)
+					             + strlen(AMSN_LOG_CONV_EXTRA);
+				log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL);
+				log->logger = amsn_logger;
+				log->logger_data = data;
+				list = g_list_prepend(list, log);
+				found_start = FALSE;
+
+				purple_debug_info("aMSN logger",
+				                  "Found log for %s:"
+				                  " path = (%s),"
+				                  " offset = (%d),"
+				                  " length = (%d)\n",
+				                  sn, data->path, data->offset, data->length);
+			}
+			c = strstr(c, "\n");
+			c++;
+		}
+
+		/* I've seen the file end without the AMSN_LOG_CONV_END bit */
+		if (found_start) {
+			data = g_new0(struct amsn_logger_data, 1);
+			data->path = g_strdup(filename);
+			data->offset = offset;
+			data->length = c - start_log
+				             + strlen(AMSN_LOG_CONV_END)
+				             + strlen(AMSN_LOG_CONV_EXTRA);
+			log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL);
+			log->logger = amsn_logger;
+			log->logger_data = data;
+			list = g_list_prepend(list, log);
+			found_start = FALSE;
+
+			purple_debug_info("aMSN logger",
+			                  "Found log for %s:"
+			                  " path = (%s),"
+			                  " offset = (%d),"
+			                  " length = (%d)\n",
+			                  sn, data->path, data->offset, data->length);
+		}
+		g_free(contents);
+	}
+
+	return list;
+}
+
+/* `log_dir`/username@hotmail.com/logs/buddyname@hotmail.com.log */
+/* `log_dir`/username@hotmail.com/logs/Month Year/buddyname@hotmail.com.log */
+static GList *amsn_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account)
+{
+	GList *list = NULL;
+	const char *logdir;
+	char *username;
+	char *log_path;
+	char *buddy_log;
+	char *filename;
+	GDir *dir;
+	const char *name;
+
+	logdir = purple_prefs_get_string("/plugins/core/log_reader/amsn/log_directory");
+
+	/* By clearing the log directory path, this logger can be (effectively) disabled. */
+	if (!logdir || !*logdir)
+		return NULL;
+
+	/* aMSN only works with MSN/WLM */
+	if (strcmp(account->protocol_id, "prpl-msn"))
+		return NULL;
+
+	username = g_strdup(purple_normalize(account, account->username));
+	buddy_log = g_strdup_printf("%s.log", purple_normalize(account, sn));
+	log_path = g_build_filename(logdir, username, "logs", NULL);
+
+	/* First check in the top-level */
+	filename = g_build_filename(log_path, buddy_log, NULL);
+	if (g_file_test(filename, G_FILE_TEST_EXISTS))
+		list = amsn_logger_parse_file(filename, sn, account);
+	else
+		g_free(filename);
+
+	/* Check in previous months */
+	dir = g_dir_open(log_path, 0, NULL);
+	if (dir) {
+		while ((name = g_dir_read_name(dir)) != NULL) {
+			filename = g_build_filename(log_path, name, buddy_log, NULL);
+			if (g_file_test(filename, G_FILE_TEST_EXISTS))
+				list = g_list_concat(list, amsn_logger_parse_file(filename, sn, account));
+			g_free(filename);
+		}
+		g_dir_close(dir);
+	}
+
+	g_free(log_path);
+
+	/* New versions use 'friendlier' directory names */
+	purple_util_chrreplace(username, '@', '_');
+	purple_util_chrreplace(username, '.', '_');
+
+	log_path = g_build_filename(logdir, username, "logs", NULL);
+
+	/* First check in the top-level */
+	filename = g_build_filename(log_path, buddy_log, NULL);
+	if (g_file_test(filename, G_FILE_TEST_EXISTS))
+		list = g_list_concat(list, amsn_logger_parse_file(filename, sn, account));
+	g_free(filename);
+
+	/* Check in previous months */
+	dir = g_dir_open(log_path, 0, NULL);
+	if (dir) {
+		while ((name = g_dir_read_name(dir)) != NULL) {
+			filename = g_build_filename(log_path, name, buddy_log, NULL);
+			if (g_file_test(filename, G_FILE_TEST_EXISTS))
+				list = g_list_concat(list, amsn_logger_parse_file(filename, sn, account));
+			g_free(filename);
+		}
+		g_dir_close(dir);
+	}
+
+	g_free(log_path);
+	g_free(username);
+	g_free(buddy_log);
+
+	return list;
+}
+
+/* Really it's |"L, but the string's been escaped */
+#define AMSN_LOG_FORMAT_TAG "|&quot;L"
+
+static char *amsn_logger_read(PurpleLog *log, PurpleLogReadFlags *flags)
+{
+	struct amsn_logger_data *data;
+	FILE *file;
+	char *contents;
+	char *escaped;
+	GString *formatted;
+	char *start;
+	gboolean in_span = FALSE;
+
+	if (flags != NULL)
+		*flags = PURPLE_LOG_READ_NO_NEWLINE;
+
+	g_return_val_if_fail(log != NULL, g_strdup(""));
+
+	data = log->logger_data;
+
+	g_return_val_if_fail(data->path != NULL, g_strdup(""));
+	g_return_val_if_fail(data->length > 0, g_strdup(""));
+
+	contents = g_malloc(data->length + 2);
+
+	file = g_fopen(data->path, "rb");
+	g_return_val_if_fail(file != NULL, g_strdup(""));
+	
+	fseek(file, data->offset, SEEK_SET);
+	data->length = fread(contents, 1, data->length, file);
+	fclose(file);
+
+	contents[data->length] = '\n';
+	contents[data->length + 1] = '\0';
+
+	escaped = g_markup_escape_text(contents, -1);
+	g_free(contents);
+	contents = escaped;
+
+	formatted = g_string_sized_new(data->length + 2);
+
+	start = contents;
+	while (start && *start) {
+		char *end;
+		char *old_tag;
+		char *tag;
+		end = strstr(start, "\n");
+		if (!end)
+			break;
+		*end = '\0';
+		if (purple_str_has_prefix(start, AMSN_LOG_FORMAT_TAG) && in_span) {
+			/* New format for this line */
+			g_string_append(formatted, "</span><br>");
+			in_span = FALSE;
+		} else if (start != contents) {
+			/* Continue format from previous line */
+			g_string_append(formatted, "<br>");
+		}
+		old_tag = start;
+		tag = strstr(start, AMSN_LOG_FORMAT_TAG);
+		while (tag) {
+			g_string_append_len(formatted, old_tag, tag - old_tag);
+			tag += strlen(AMSN_LOG_FORMAT_TAG);
+			if (in_span) {
+				g_string_append(formatted, "</span>");
+				in_span = FALSE;
+			}
+			if (*tag == 'C') {
+				/* |"LCxxxxxx is a hex colour */
+				char colour[7];
+				strncpy(colour, tag + 1, 6);
+				colour[6] = '\0';
+				g_string_append_printf(formatted, "<span style=\"color: #%s;\">", colour);
+				/* This doesn't appear to work? */
+				/* g_string_append_printf(formatted, "<span style=\"color: #%6s;\">", tag + 1); */
+				in_span = TRUE;
+				old_tag = tag + 7; /* C + xxxxxx */
+			} else {
+				/* |"Lxxx is a 3-digit colour code */
+				if (purple_str_has_prefix(tag, "RED")) {
+					g_string_append(formatted, "<span style=\"color: red;\">");
+					in_span = TRUE;
+				} else if (purple_str_has_prefix(tag, "GRA")) {
+					g_string_append(formatted, "<span style=\"color: gray;\">");
+					in_span = TRUE;
+				} else if (purple_str_has_prefix(tag, "NOR")) {
+					g_string_append(formatted, "<span style=\"color: black;\">");
+					in_span = TRUE;
+				} else if (purple_str_has_prefix(tag, "ITA")) {
+					g_string_append(formatted, "<span style=\"color: blue;\">");
+					in_span = TRUE;
+				} else if (purple_str_has_prefix(tag, "GRE")) {
+					g_string_append(formatted, "<span style=\"color: darkgreen;\">");
+					in_span = TRUE;
+				} else {
+					purple_debug_info("aMSN logger", "Unknown colour format: %3s\n", tag);
+				}
+				old_tag = tag + 3;
+			}
+			tag = strstr(tag, AMSN_LOG_FORMAT_TAG);
+		}
+		g_string_append(formatted, old_tag);
+		start = end + 1;
+	}
+	if (in_span)
+		g_string_append(formatted, "</span>");
+
+	g_free(contents);
+
+	return g_string_free(formatted, FALSE);
+}
+
+static int amsn_logger_size(PurpleLog *log)
+{
+	struct amsn_logger_data *data;
+	char *text;
+	int size;
+
+	g_return_val_if_fail(log != NULL, 0);
+
+	data = log->logger_data;
+	
+	if (purple_prefs_get_bool("/plugins/core/log_reader/fast_sizes")) {
+		return data ? data->length : 0;
+	}
+
+	text = amsn_logger_read(log, NULL);
+	size = strlen(text);
+	g_free(text);
+
+	return size;
+}
+
+static void amsn_logger_finalize(PurpleLog *log)
+{
+	struct amsn_logger_data *data;
+
+	g_return_if_fail(log != NULL);
+
+	data = log->logger_data;
+	g_free(data->path);
+	g_free(data);
+}
+
 /*****************************************************************************
  * Plugin Code                                                               *
  *****************************************************************************/
@@ -2347,6 +2665,19 @@
 #endif
 	purple_prefs_add_string("/plugins/core/log_reader/qip/log_directory", path ? path : "");
 	g_free(path);
+
+	/* Add aMSN Messenger log directory preference. */
+	purple_prefs_add_none("/plugins/core/log_reader/amsn");
+
+	/* Calculate default aMSN log directory. */
+#ifdef _WIN32
+	folder = wpurple_get_special_folder(CSIDL_PROFILE); /* Silly aMSN, not using CSIDL_APPDATA */
+	path = g_build_filename(folder, "amsn", NULL);
+#else
+	path = g_build_filename(purple_home_dir(), ".amsn", NULL);
+#endif
+	purple_prefs_add_string("/plugins/core/log_reader/amsn/log_directory", path);
+	g_free(path);
 }
 
 static gboolean
@@ -2429,6 +2760,18 @@
 										  trillian_logger_size);
 	purple_log_logger_add(trillian_logger);
 
+	/* The names of IM clients are marked for translation at the request of
+	   translators who wanted to transliterate them.  Many translators
+	   choose to leave them alone.  Choose what's best for your language. */
+	amsn_logger = purple_log_logger_new("amsn", _("aMSN"), 6,
+									   NULL,
+									   NULL,
+									   amsn_logger_finalize,
+									   amsn_logger_list,
+									   amsn_logger_read,
+									   amsn_logger_size);
+	purple_log_logger_add(amsn_logger);
+
 	return TRUE;
 }
 
@@ -2445,6 +2788,7 @@
 	purple_log_logger_remove(msn_logger);
 	purple_log_logger_remove(trillian_logger);
 	purple_log_logger_remove(qip_logger);
+	purple_log_logger_remove(amsn_logger);
 
 	return TRUE;
 }
@@ -2505,6 +2849,10 @@
 		"/plugins/core/log_reader/trillian/log_directory", _("Trillian"));
 	purple_plugin_pref_frame_add(frame, ppref);
 
+	ppref = purple_plugin_pref_new_with_name_and_label(
+		"/plugins/core/log_reader/amsn/log_directory", _("aMSN"));
+	purple_plugin_pref_frame_add(frame, ppref);
+
 	return frame;
 }
 
--- a/libpurple/plugins/offlinemsg.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/plugins/offlinemsg.c	Mon Oct 15 10:45:46 2007 +0000
@@ -157,11 +157,11 @@
 						"rest of the messages in a pounce and automatically send them "
 						"when \"%s\" logs back in?"), who, who);
 	
-		purple_request_action(handle, _("Offline Message"), ask,
+		purple_request_action_with_hint(handle, _("Offline Message"), ask,
 					_("You can edit/delete the pounce from the `Buddy Pounces' dialog"),
 					1,
 					offline->account, offline->who, offline->conv,
-					offline, 2,
+					PURPLE_REQUEST_UI_HINT_BUDDY, offline, 2,
 					_("Yes"), record_pounce,
 					_("No"), cancel_poune);
 		g_free(ask);
--- a/libpurple/plugins/perl/common/Request.xs	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/plugins/perl/common/Request.xs	Mon Oct 15 10:45:46 2007 +0000
@@ -141,7 +141,38 @@
 	gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len));
 	g_free(basename);
 
-	RETVAL = purple_request_input(handle, title, primary, secondary, default_value, multiline, masked, hint, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, gpr);
+	RETVAL = purple_request_input_with_hint(handle, title, primary, secondary, default_value, multiline, masked, hint, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, gpr);
+OUTPUT:
+	RETVAL
+
+void *
+purple_request_input_with_hint(handle, title, primary, secondary, default_value, multiline, masked, hint, ok_text, ok_cb, cancel_text, cancel_cb, ui_hint)
+	Purple::Plugin handle
+	const char * title
+	const char * primary
+	const char * secondary
+	const char * default_value
+	gboolean multiline
+	gboolean masked
+	gchar * hint
+	const char * ok_text
+	SV * ok_cb
+	const char * cancel_text
+	SV * cancel_cb
+	const char * ui_hint
+CODE:
+	PurplePerlRequestData *gpr;
+	STRLEN len;
+	char *basename;
+
+	basename = g_path_get_basename(handle->path);
+	purple_perl_normalize_script_name(basename);
+	gpr = g_new(PurplePerlRequestData, 1);
+	gpr->ok_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(ok_cb, len));
+	gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len));
+	g_free(basename);
+
+	RETVAL = purple_request_input_with_hint(handle, title, primary, secondary, default_value, multiline, masked, hint, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, ui_hint, gpr);
 OUTPUT:
 	RETVAL
 
@@ -165,7 +196,32 @@
 	gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len));
 	g_free(basename);
 
-	RETVAL = purple_request_file(handle, title, filename, savedialog, G_CALLBACK(purple_perl_request_ok_cb), G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, gpr);
+	RETVAL = purple_request_file_with_hint(handle, title, filename, savedialog, G_CALLBACK(purple_perl_request_ok_cb), G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, gpr);
+OUTPUT:
+	RETVAL
+
+void *
+purple_request_file_with_hint(handle, title, filename, savedialog, ok_cb, cancel_cb, ui_hint)
+	Purple::Plugin handle
+	const char * title
+	const char * filename
+	gboolean savedialog
+	SV * ok_cb
+	SV * cancel_cb
+	const char * ui_hint
+CODE:
+	PurplePerlRequestData *gpr;
+	STRLEN len;
+	char *basename;
+
+	basename = g_path_get_basename(handle->path);
+	purple_perl_normalize_script_name(basename);
+	gpr = g_new(PurplePerlRequestData, 1);
+	gpr->ok_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(ok_cb, len));
+	gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len));
+	g_free(basename);
+
+	RETVAL = purple_request_file_with_hint(handle, title, filename, savedialog, G_CALLBACK(purple_perl_request_ok_cb), G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, ui_hint, gpr);
 OUTPUT:
 	RETVAL
 
@@ -192,7 +248,35 @@
 	gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len));
 	g_free(basename);
 
-	RETVAL = purple_request_fields(handle, title, primary, secondary, fields, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, gpr);
+	RETVAL = purple_request_fields_with_hint(handle, title, primary, secondary, fields, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, gpr);
+OUTPUT:
+	RETVAL
+
+void *
+purple_request_fields_with_hint(handle, title, primary, secondary, fields, ok_text, ok_cb, cancel_text, cancel_cb, ui_hint)
+	Purple::Plugin handle
+	const char * title
+	const char * primary
+	const char * secondary
+	Purple::Request::Fields fields
+	const char * ok_text
+	SV * ok_cb
+	const char * cancel_text
+	SV * cancel_cb
+	const char *ui_hint
+CODE:
+	PurplePerlRequestData *gpr;
+	STRLEN len;
+	char *basename;
+
+	basename = g_path_get_basename(handle->path);
+	purple_perl_normalize_script_name(basename);
+	gpr = g_new(PurplePerlRequestData, 1);
+	gpr->ok_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(ok_cb, len));
+	gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len));
+	g_free(basename);
+
+	RETVAL = purple_request_fields_with_hint(handle, title, primary, secondary, fields, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, ui_hint, gpr);
 OUTPUT:
 	RETVAL
 
--- a/libpurple/protocols/bonjour/buddy.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/bonjour/buddy.c	Mon Oct 15 10:45:46 2007 +0000
@@ -62,9 +62,11 @@
 }
 
 void
-set_bonjour_buddy_value(BonjourBuddy* buddy, const char *record_key, const char *value, uint32_t len){
+set_bonjour_buddy_value(BonjourBuddy* buddy, const char *record_key, const char *value, guint32 len){
 	gchar **fld = NULL;
 
+	g_return_if_fail(record_key != NULL);
+
 	if (!strcmp(record_key, "1st"))
 		fld = &buddy->first;
 	else if(!strcmp(record_key, "email"))
--- a/libpurple/protocols/bonjour/buddy.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/bonjour/buddy.h	Mon Oct 15 10:45:46 2007 +0000
@@ -83,7 +83,7 @@
 /**
  * Sets a value in the BonjourBuddy struct, destroying the old value
  */
-void set_bonjour_buddy_value(BonjourBuddy *buddy, const char *record_key, const char *value, uint32_t len);
+void set_bonjour_buddy_value(BonjourBuddy *buddy, const char *record_key, const char *value, guint32 len);
 
 /**
  * Check if all the compulsory buddy data is present.
--- a/libpurple/protocols/gg/gg.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/gg/gg.c	Mon Oct 15 10:45:46 2007 +0000
@@ -333,10 +333,10 @@
 {
 	PurpleConnection *gc = (PurpleConnection *)action->context;
 
-	purple_request_file(action, _("Save buddylist..."), NULL, TRUE,
+	purple_request_file_with_hint(action, _("Save buddylist..."), NULL, TRUE,
 			G_CALLBACK(ggp_callback_buddylist_save_ok), NULL,
 			purple_connection_get_account(gc), NULL, NULL,
-			gc);
+			PURPLE_REQUEST_UI_HINT_BLIST, gc);
 }
 /* }}} */
 
@@ -347,10 +347,10 @@
 {
 	PurpleConnection *gc = (PurpleConnection *)action->context;
 
-	purple_request_file(action, "Load buddylist from file...", NULL, FALSE,
+	purple_request_file_with_hint(action, "Load buddylist from file...", NULL, FALSE,
 			G_CALLBACK(ggp_callback_buddylist_load_ok), NULL,
 			purple_connection_get_account(gc), NULL, NULL,
-			gc);
+			PURPLE_REQUEST_UI_HINT_BLIST, gc);
 }
 /* }}} */
 
@@ -503,7 +503,7 @@
 			_("Current token"), token->data, token->size);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(account,
+	purple_request_fields_with_hint(account,
 		_("Register New Gadu-Gadu Account"),
 		_("Register New Gadu-Gadu Account"),
 		_("Please, fill in the following fields"),
@@ -511,7 +511,7 @@
 		_("OK"), G_CALLBACK(ggp_callback_register_account_ok),
 		_("Cancel"), G_CALLBACK(ggp_callback_register_account_cancel),
 		purple_connection_get_account(gc), NULL, NULL,
-		gc);
+		PURPLE_REQUEST_UI_HINT_REGISTER, gc);
 }
 /* }}} */
 
@@ -662,7 +662,7 @@
 			_("Only online"), FALSE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(gc,
+	purple_request_fields_with_hint(gc,
 		_("Find buddies"),
 		_("Find buddies"),
 		_("Please, enter your search criteria below"),
@@ -670,7 +670,7 @@
 		_("OK"), G_CALLBACK(ggp_callback_find_buddies),
 		_("Cancel"), NULL,
 		purple_connection_get_account(gc), NULL, NULL,
-		gc);
+		PURPLE_REQUEST_UI_HINT_BLIST, gc);
 }
 /* }}} */
 
@@ -800,14 +800,14 @@
 		_("Please, enter your current password and your new password for UIN: "),
 		ggp_get_uin(purple_connection_get_account(gc)));
 
-	purple_request_fields(gc,
+	purple_request_fields_with_hint(gc,
 		_("Change Gadu-Gadu Password"),
 		_("Change Gadu-Gadu Password"),
 		msg,
 		fields, _("OK"), G_CALLBACK(ggp_callback_change_passwd_ok),
 		_("Cancel"), NULL,
 		purple_connection_get_account(gc), NULL, NULL,
-		gc);
+		PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 
 	g_free(msg);
 }
@@ -880,7 +880,7 @@
 
 	msg = g_strdup_printf(_("Select a chat for buddy: %s"),
 			      purple_buddy_get_alias(buddy));
-	purple_request_fields(gc,
+	purple_request_fields_with_hint(gc,
 			_("Add to chat..."),
 			_("Add to chat..."),
 			msg,
@@ -888,7 +888,7 @@
 			_("Add"), G_CALLBACK(ggp_callback_add_to_chat_ok),
 			_("Cancel"), NULL,
 			purple_connection_get_account(gc), NULL, NULL,			  
-			gc);
+			PURPLE_REQUEST_UI_HINT_BUDDY, gc);
 	g_free(msg);
 }
 /* }}} */
--- a/libpurple/protocols/jabber/auth.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/auth.c	Mon Oct 15 10:45:46 2007 +0000
@@ -322,10 +322,10 @@
 				} else if (!plaintext) {
 					char *msg = g_strdup_printf(_("%s requires plaintext authentication over an unencrypted connection.  Allow this and continue authentication?"),
 							js->gc->account->username);
-					purple_request_yes_no(js->gc, _("Plaintext Authentication"),
+					purple_request_yes_no_with_hint(js->gc, _("Plaintext Authentication"),
 							_("Plaintext Authentication"),
 							msg,
-							2, js->gc->account, NULL, NULL, js->gc->account,
+							2, js->gc->account, NULL, NULL, PURPLE_REQUEST_UI_HINT_ACCOUNT, js->gc->account,
 							allow_cyrus_plaintext_auth,
 							disallow_plaintext_auth);
 					g_free(msg);
@@ -517,13 +517,13 @@
 		if(js->gsc == NULL && !purple_account_get_bool(js->gc->account, "auth_plain_in_clear", FALSE)) {
 			char *msg = g_strdup_printf(_("%s requires plaintext authentication over an unencrypted connection.  Allow this and continue authentication?"),
 					js->gc->account->username);
-			purple_request_yes_no(js->gc, _("Plaintext Authentication"),
+			purple_request_yes_no_with_hint(js->gc, _("Plaintext Authentication"),
 					_("Plaintext Authentication"),
 					msg,
 					2,
 					purple_connection_get_account(js->gc), NULL, NULL,
-					purple_connection_get_account(js->gc), allow_plaintext_auth,
-					disallow_plaintext_auth);
+					PURPLE_REQUEST_UI_HINT_ACCOUNT, purple_connection_get_account(js->gc),
+					allow_plaintext_auth, disallow_plaintext_auth);
 			g_free(msg);
 			return;
 		}
@@ -611,13 +611,13 @@
 		} else if(xmlnode_get_child(query, "password")) {
 			if(js->gsc == NULL && !purple_account_get_bool(js->gc->account,
 						"auth_plain_in_clear", FALSE)) {
-				purple_request_yes_no(js->gc, _("Plaintext Authentication"),
+				purple_request_yes_no_with_hint(js->gc, _("Plaintext Authentication"),
 						_("Plaintext Authentication"),
 						_("This server requires plaintext authentication over an unencrypted connection.  Allow this and continue authentication?"),
 						2,
 						purple_connection_get_account(js->gc), NULL, NULL,
-						purple_connection_get_account(js->gc), allow_plaintext_auth,
-						disallow_plaintext_auth);
+						PURPLE_REQUEST_UI_HINT_ACCOUNT, purple_connection_get_account(js->gc),
+						allow_plaintext_auth, disallow_plaintext_auth);
 				return;
 			}
 			finish_plaintext_authentication(js);
--- a/libpurple/protocols/jabber/buddy.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Mon Oct 15 10:45:46 2007 +0000
@@ -719,7 +719,7 @@
 	if(x_vc_data != NULL)
 		xmlnode_free(x_vc_data);
 
-	purple_request_fields(gc, _("Edit XMPP vCard"),
+	purple_request_fields_with_hint(gc, _("Edit XMPP vCard"),
 						_("Edit XMPP vCard"),
 						_("All items below are optional. Enter only the "
 						  "information with which you feel comfortable."),
@@ -727,7 +727,7 @@
 						_("Save"), G_CALLBACK(jabber_format_info),
 						_("Cancel"), NULL,
 						purple_connection_get_account(gc), NULL, NULL,
-						gc);
+						PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 /*---------------------------------------*/
@@ -2410,12 +2410,12 @@
 		usi->js = js;
 		usi->directory_server = g_strdup(from);
 
-		purple_request_fields(js->gc, _("Search for XMPP users"),
+		purple_request_fields_with_hint(js->gc, _("Search for XMPP users"),
 				_("Search for XMPP users"), instructions, fields,
 				_("Search"), G_CALLBACK(user_search_cb),
 				_("Cancel"), G_CALLBACK(user_search_cancel_cb),
 				purple_connection_get_account(js->gc), NULL, NULL,
-				usi);
+				PURPLE_REQUEST_UI_HINT_ACCOUNT, usi);
 
 		g_free(instructions);
 	}
@@ -2444,14 +2444,14 @@
 	PurpleConnection *gc = (PurpleConnection *) action->context;
 	JabberStream *js = gc->proto_data;
 
-	purple_request_input(gc, _("Enter a User Directory"), _("Enter a User Directory"),
+	purple_request_input_with_hint(gc, _("Enter a User Directory"), _("Enter a User Directory"),
 			_("Select a user directory to search"),
 			js->user_directories ? js->user_directories->data : NULL,
 			FALSE, FALSE, NULL,
 			_("Search Directory"), PURPLE_CALLBACK(jabber_user_search),
 			_("Cancel"), NULL,
 			NULL, NULL, NULL,
-			js);
+			PURPLE_REQUEST_UI_HINT_ACCOUNT, js);
 }
 
 
--- a/libpurple/protocols/jabber/chat.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/chat.c	Mon Oct 15 10:45:46 2007 +0000
@@ -778,14 +778,14 @@
 	purple_roomlist_set_fields(js->roomlist, fields);
 
 
-	purple_request_input(gc, _("Enter a Conference Server"), _("Enter a Conference Server"),
+	purple_request_input_with_hint(gc, _("Enter a Conference Server"), _("Enter a Conference Server"),
 			_("Select a conference server to query"),
 			js->chat_servers ? js->chat_servers->data : NULL,
 			FALSE, FALSE, NULL,
 			_("Find Rooms"), PURPLE_CALLBACK(roomlist_ok_cb),
 			_("Cancel"), PURPLE_CALLBACK(roomlist_cancel_cb),
 			purple_connection_get_account(gc), NULL, NULL,			 
-			js);
+			PURPLE_REQUEST_UI_HINT_CONV, js);
 
 	return js->roomlist;
 }
--- a/libpurple/protocols/jabber/jabber.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1029,21 +1029,21 @@
 	cbdata->who = g_strdup(from);
 
 	if(js->registration)
-		purple_request_fields(js->gc, _("Register New XMPP Account"),
+		purple_request_fields_with_hint(js->gc, _("Register New XMPP Account"),
 				_("Register New XMPP Account"), instructions, fields,
 				_("Register"), G_CALLBACK(jabber_register_cb),
 				_("Cancel"), G_CALLBACK(jabber_register_cancel_cb),
 				purple_connection_get_account(js->gc), NULL, NULL,
-				cbdata);
+				PURPLE_REQUEST_UI_HINT_REGISTER, cbdata);
 	else {
 		char *title = registered?g_strdup_printf(_("Change Account Registration at %s"), from)
 								:g_strdup_printf(_("Register New Account at %s"), from);
-		purple_request_fields(js->gc, title,
+		purple_request_fields_with_hint(js->gc, title,
 			  title, instructions, fields,
 			  registered?_("Change Registration"):_("Register"), G_CALLBACK(jabber_register_cb),
 			  _("Cancel"), G_CALLBACK(jabber_register_cancel_cb),
 			  purple_connection_get_account(js->gc), NULL, NULL,
-			  cbdata);
+			  PURPLE_REQUEST_UI_HINT_REGISTER, cbdata);
 		g_free(title);
 	}
 
@@ -1738,12 +1738,12 @@
 	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(js->gc, _("Change XMPP Password"),
+	purple_request_fields_with_hint(js->gc, _("Change XMPP Password"),
 			_("Change XMPP Password"), _("Please enter your new password"),
 			fields, _("OK"), G_CALLBACK(jabber_password_change_cb),
 			_("Cancel"), NULL,
 			purple_connection_get_account(gc), NULL, NULL,
-			js);
+			PURPLE_REQUEST_UI_HINT_ACCOUNT, js);
 }
 
 GList *jabber_actions(PurplePlugin *plugin, gpointer context)
--- a/libpurple/protocols/jabber/presence.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/presence.c	Mon Oct 15 10:45:46 2007 +0000
@@ -512,7 +512,7 @@
 						if((chat = jabber_chat_find(js, jid->node, jid->domain))) {
 							chat->config_dialog_type = PURPLE_REQUEST_ACTION;
 							chat->config_dialog_handle =
-								purple_request_action(js->gc,
+								purple_request_action_with_hint(js->gc,
 										_("Create New Room"),
 										_("Create New Room"),
 										_("You are creating a new room.  Would"
@@ -520,7 +520,7 @@
 											" accept the default settings?"),
 										/* Default Action */ 1,
 										purple_connection_get_account(js->gc), NULL, chat->conv,
-										chat, 2,
+										PURPLE_REQUEST_UI_HINT_CONV, chat, 2,
 										_("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure),
 										_("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room));
 						}
--- a/libpurple/protocols/jabber/si.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/si.c	Mon Oct 15 10:45:46 2007 +0000
@@ -870,9 +870,9 @@
 
 			purple_request_fields_add_group(fields, group);
 
-			purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields,
+			purple_request_fields_with_hint(jsx->js->gc, _("Select a Resource"), msg, NULL, fields,
 					_("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb),
-					jsx->js->gc->account, xfer->who, NULL, xfer);
+					jsx->js->gc->account, xfer->who, NULL, PURPLE_REQUEST_UI_HINT_XFER, xfer);
 
 			g_free(msg);
 		}
--- a/libpurple/protocols/jabber/usermood.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/usermood.c	Mon Oct 15 10:45:46 2007 +0000
@@ -194,14 +194,14 @@
 											FALSE);
 	purple_request_field_group_add_field(group, field);
 	
-	purple_request_fields(gc, _("Edit User Mood"),
+	purple_request_fields_with_hint(gc, _("Edit User Mood"),
 						  _("Edit User Mood"),
 						  _("Please select your mood from the list."),
 						  fields,
 						  _("Set"), G_CALLBACK(do_mood_set_from_fields),
 						  _("Cancel"), NULL,
 						  purple_connection_get_account(gc), NULL, NULL,
-						  gc);
+						  PURPLE_REQUEST_UI_HINT_BLIST, gc);
 	
 }
 
--- a/libpurple/protocols/jabber/usernick.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/usernick.c	Mon Oct 15 10:45:46 2007 +0000
@@ -73,10 +73,10 @@
 			oldnickname = xmlnode_get_data(nick);
 	}
 	
-	purple_request_input(js->gc, _("Set User Nickname"), _("Please specify a new nickname for you."),
+	purple_request_input_with_hint(js->gc, _("Set User Nickname"), _("Please specify a new nickname for you."),
 		_("This information is visible to all contacts on your contact list, so choose something appropriate."),
 		oldnickname, FALSE, FALSE, NULL, _("Set"), PURPLE_CALLBACK(do_nick_set), _("Cancel"), NULL,
-		purple_connection_get_account(js->gc), NULL, NULL, js);
+		purple_connection_get_account(js->gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, js);
 	g_free(oldnickname);
 }
 
--- a/libpurple/protocols/jabber/xdata.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/jabber/xdata.c	Mon Oct 15 10:45:46 2007 +0000
@@ -395,11 +395,11 @@
 	if((x = xmlnode_get_child(packet, "instructions")))
 		instructions = xmlnode_get_data(x);
 
-	handle = purple_request_fields(js->gc, title, title, instructions, fields,
+	handle = purple_request_fields_with_hint(js->gc, title, title, instructions, fields,
 			_("OK"), G_CALLBACK(jabber_x_data_ok_cb),
 			_("Cancel"), G_CALLBACK(jabber_x_data_cancel_cb),
 			purple_connection_get_account(js->gc), /* XXX Do we have a who here? */ NULL, NULL,
-			data);
+			PURPLE_REQUEST_UI_HINT_ACCOUNT, data);
 
 	g_free(title);
 	g_free(instructions);
--- a/libpurple/protocols/msn/dialog.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/msn/dialog.c	Mon Oct 15 10:45:46 2007 +0000
@@ -135,9 +135,9 @@
 								 passport);
 	}
 
-	purple_request_action(gc, NULL, msg, reason, PURPLE_DEFAULT_ACTION_NONE, 
+	purple_request_action_with_hint(gc, NULL, msg, reason, PURPLE_DEFAULT_ACTION_NONE, 
 						purple_connection_get_account(gc), data->who, NULL,
-						data, 2,
+						PURPLE_REQUEST_UI_HINT_BLIST, data, 2,
 						_("Yes"), G_CALLBACK(msn_add_cb),
 						_("No"), G_CALLBACK(msn_rem_cb));
 
--- a/libpurple/protocols/msn/msn.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/msn/msn.c	Mon Oct 15 10:45:46 2007 +0000
@@ -282,14 +282,14 @@
 
 	gc = (PurpleConnection *) action->context;
 
-	purple_request_input(gc, NULL, _("Set your friendly name."),
+	purple_request_input_with_hint(gc, NULL, _("Set your friendly name."),
 					   _("This is the name that other MSN buddies will "
 						 "see you as."),
 					   purple_connection_get_display_name(gc), FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(msn_act_id),
 					   _("Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void
@@ -301,12 +301,12 @@
 	gc = (PurpleConnection *) action->context;
 	session = gc->proto_data;
 
-	purple_request_input(gc, NULL, _("Set your home phone number."), NULL,
+	purple_request_input_with_hint(gc, NULL, _("Set your home phone number."), NULL,
 					   msn_user_get_home_phone(session->user), FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(msn_set_home_phone_cb),
 					   _("Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void
@@ -318,12 +318,12 @@
 	gc = (PurpleConnection *) action->context;
 	session = gc->proto_data;
 
-	purple_request_input(gc, NULL, _("Set your work phone number."), NULL,
+	purple_request_input_with_hint(gc, NULL, _("Set your work phone number."), NULL,
 					   msn_user_get_work_phone(session->user), FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(msn_set_work_phone_cb),
 					   _("Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void
@@ -335,12 +335,12 @@
 	gc = (PurpleConnection *) action->context;
 	session = gc->proto_data;
 
-	purple_request_input(gc, NULL, _("Set your mobile phone number."), NULL,
+	purple_request_input_with_hint(gc, NULL, _("Set your mobile phone number."), NULL,
 					   msn_user_get_mobile_phone(session->user), FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(msn_set_mobile_phone_cb),
 					   _("Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void
@@ -350,13 +350,13 @@
 
 	gc = (PurpleConnection *) action->context;
 
-	purple_request_action(gc, NULL, _("Allow MSN Mobile pages?"),
+	purple_request_action_with_hint(gc, NULL, _("Allow MSN Mobile pages?"),
 						_("Do you want to allow or disallow people on "
 						  "your buddy list to send you MSN Mobile pages "
 						  "to your cell phone or other mobile device?"),
 						-1,
 						purple_connection_get_account(gc), NULL, NULL,
-						gc, 3,
+						PURPLE_REQUEST_UI_HINT_ACCOUNT, gc, 3,
 						_("Allow"), G_CALLBACK(enable_msn_pages_cb),
 						_("Disallow"), G_CALLBACK(disable_msn_pages_cb),
 						_("Cancel"), NULL);
@@ -400,12 +400,12 @@
 	data->gc = gc;
 	data->passport = buddy->name;
 
-	purple_request_input(gc, NULL, _("Send a mobile message."), NULL,
+	purple_request_input_with_hint(gc, NULL, _("Send a mobile message."), NULL,
 					   NULL, TRUE, FALSE, NULL,
 					   _("Page"), G_CALLBACK(send_to_mobile_cb),
 					   _("Close"), G_CALLBACK(close_mobile_page_cb),
 					   purple_connection_get_account(gc), purple_buddy_get_name(buddy), NULL,
-					   data);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, data);
 }
 
 static gboolean
--- a/libpurple/protocols/novell/novell.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/novell/novell.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1921,10 +1921,10 @@
 
 	/* Prompt the user */
 	gc = purple_account_get_connection(user->client_data);
-	purple_request_action(gc, title, primary, secondary,
+	purple_request_action_with_hint(gc, title, primary, secondary,
 						PURPLE_DEFAULT_ACTION_NONE,
 						purple_connection_get_account(gc), name, NULL,
-						parms, 2,
+						PURPLE_REQUEST_UI_HINT_CONV, parms, 2,
 						_("Yes"), G_CALLBACK(_join_conference_cb),
 						_("No"), G_CALLBACK(_reject_conference_cb));
 
@@ -2175,7 +2175,7 @@
 	if (server == NULL || *server == '\0') {
 
 		/* TODO: Would be nice to prompt if not set!
-		 *  purple_request_fields(gc, _("Server Address"),...);
+		 *  purple_request_fields_with_hint(gc, _("Server Address"),...);
 		 */
 
 		/* ...but for now just error out with a nice message. */
--- a/libpurple/protocols/oscar/oscar.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1443,13 +1443,13 @@
 	purple_debug_info("oscar", "Got SecurID request\n");
 
 	primary = g_strdup_printf("Enter the SecurID key for %s.", purple_account_get_username(account));
-	purple_request_input(gc, NULL, _("Enter SecurID"), primary,
+	purple_request_input_with_hint(gc, NULL, _("Enter SecurID"), primary,
 					   _("Enter the 6 digit number from the digital display."),
 					   FALSE, FALSE, NULL,
 					   _("_OK"), G_CALLBACK(purple_parse_auth_securid_request_yes_cb),
 					   _("_Cancel"), G_CALLBACK(purple_parse_auth_securid_request_no_cb),
 					   account, NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 	g_free(primary);
 
 	return 1;
@@ -2236,12 +2236,12 @@
 	data->gc = gc;
 	data->name = g_strdup(name);
 
-	purple_request_input(data->gc, NULL, _("Authorization Request Message:"),
+	purple_request_input_with_hint(data->gc, NULL, _("Authorization Request Message:"),
 					   NULL, _("Please authorize me!"), TRUE, FALSE, NULL,
 					   _("_OK"), G_CALLBACK(purple_auth_request),
 					   _("_Cancel"), G_CALLBACK(purple_auth_dontrequest),
 					   purple_connection_get_account(gc), name, NULL,
-					   data);
+					   PURPLE_REQUEST_UI_HINT_BLIST, data);
 }
 
 
@@ -2285,12 +2285,12 @@
 purple_auth_dontgrant_msgprompt(gpointer cbdata)
 {
 	struct name_data *data = cbdata;
-	purple_request_input(data->gc, NULL, _("Authorization Denied Message:"),
+	purple_request_input_with_hint(data->gc, NULL, _("Authorization Denied Message:"),
 					   NULL, _("No reason given."), TRUE, FALSE, NULL,
 					   _("_OK"), G_CALLBACK(purple_auth_dontgrant),
 					   _("_Cancel"), G_CALLBACK(oscar_free_name_data),
 					   purple_connection_get_account(data->gc), data->name, NULL,
-					   data);
+					   PURPLE_REQUEST_UI_HINT_BLIST, data);
 }
 
 /* When someone sends you buddies */
@@ -2471,12 +2471,12 @@
 					data->name = g_strdup(text[i*2+1]);
 					data->nick = g_strdup(text[i*2+2]);
 
-					purple_request_action(gc, NULL, message,
+					purple_request_action_with_hint(gc, NULL, message,
 										_("Do you want to add this buddy "
 										  "to your buddy list?"),
 										PURPLE_DEFAULT_ACTION_NONE,
 										purple_connection_get_account(gc), data->name, NULL,
-										data, 2,
+										PURPLE_REQUEST_UI_HINT_BLIST, data, 2,
 										_("_Add"), G_CALLBACK(purple_icq_buddyadd),
 										_("_Decline"), G_CALLBACK(oscar_free_name_data));
 					g_free(message);
@@ -5228,10 +5228,10 @@
 	data->name = g_strdup(sn);
 	data->nick = (buddy ? g_strdup(purple_buddy_get_alias_only(buddy)) : NULL);
 
-	purple_request_yes_no(gc, NULL, _("Authorization Given"), dialog_msg,
+	purple_request_yes_no_with_hint(gc, NULL, _("Authorization Given"), dialog_msg,
 						PURPLE_DEFAULT_ACTION_NONE,
 						purple_connection_get_account(gc), sn, NULL,
-						data,
+						PURPLE_REQUEST_UI_HINT_BLIST, data,
 						G_CALLBACK(purple_icq_buddyadd),
 						G_CALLBACK(oscar_free_name_data));
 	g_free(dialog_msg);
@@ -5927,12 +5927,12 @@
 	data->nick = g_strdup(purple_buddy_get_alias_only(buddy));
 
 	title = g_strdup_printf(_("Buddy Comment for %s"), data->name);
-	purple_request_input(gc, title, _("Buddy Comment:"), NULL,
+	purple_request_input_with_hint(gc, title, _("Buddy Comment:"), NULL,
 					   comment_utf8, TRUE, FALSE, NULL,
 					   _("_OK"), G_CALLBACK(oscar_ssi_editcomment),
 					   _("_Cancel"), G_CALLBACK(oscar_free_name_data),
 					   purple_connection_get_account(gc), data->name, NULL,
-					   data);
+					   PURPLE_REQUEST_UI_HINT_BUDDY, data);
 	g_free(title);
 
 	g_free(comment);
@@ -5977,13 +5977,13 @@
 	buf = g_strdup_printf(_("You have selected to open a Direct IM connection with %s."),
 			buddy->name);
 
-	purple_request_action(gc, NULL, buf,
+	purple_request_action_with_hint(gc, NULL, buf,
 			_("Because this reveals your IP address, it "
 			  "may be considered a security risk.  Do you "
 			  "wish to continue?"),
 			0,
 			purple_connection_get_account(gc), data->who, NULL,
-			data, 2,
+			PURPLE_REQUEST_UI_HINT_BUDDY, data, 2,
 			_("C_onnect"), G_CALLBACK(oscar_ask_directim_yes_cb),
 			_("_Cancel"), G_CALLBACK(oscar_ask_directim_no_cb));
 	g_free(buf);
@@ -6135,12 +6135,12 @@
 
 	purple_request_fields_add_group(fields, g);
 
-	purple_request_fields(gc, _("ICQ Privacy Options"), _("ICQ Privacy Options"),
+	purple_request_fields_with_hint(gc, _("ICQ Privacy Options"), _("ICQ Privacy Options"),
 						NULL, fields,
 						_("OK"), G_CALLBACK(oscar_icq_privacy_opts),
 						_("Cancel"), NULL,
 						purple_connection_get_account(gc), NULL, NULL,
-						gc);
+						PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void oscar_format_screenname(PurpleConnection *gc, const char *nick) {
@@ -6208,12 +6208,12 @@
 static void oscar_show_change_email(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_request_input(gc, NULL, _("Change Address To:"), NULL, NULL,
+	purple_request_input_with_hint(gc, NULL, _("Change Address To:"), NULL, NULL,
 					   FALSE, FALSE, NULL,
 					   _("_OK"), G_CALLBACK(oscar_change_email),
 					   _("_Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void oscar_show_awaitingauth(PurplePluginAction *action)
@@ -6275,7 +6275,7 @@
 static void oscar_show_find_email(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_request_input(gc, _("Find Buddy by E-Mail"),
+	purple_request_input_with_hint(gc, _("Find Buddy by E-Mail"),
 					   _("Search for a buddy by e-mail address"),
 					   _("Type the e-mail address of the buddy you are "
 						 "searching for."),
@@ -6283,7 +6283,7 @@
 					   _("_Search"), G_CALLBACK(search_by_email_cb),
 					   _("_Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void oscar_show_set_info(PurplePluginAction *action)
--- a/libpurple/protocols/oscar/peer.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/oscar/peer.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1033,7 +1033,7 @@
 		buf = g_strdup_printf(_("%s has just asked to directly connect to %s"),
 				sn, purple_account_get_username(account));
 
-		purple_request_action(conn, NULL, buf,
+		purple_request_action_with_hint(conn, NULL, buf,
 						_("This requires a direct connection between "
 						  "the two computers and is necessary for IM "
 						  "Images.  Because your IP address will be "
@@ -1041,7 +1041,7 @@
 						  "risk."),
 						PURPLE_DEFAULT_ACTION_NONE,
 						account, sn, NULL,
-						conn, 2,
+						PURPLE_REQUEST_UI_HINT_BUDDY, conn, 2,
 						_("C_onnect"), G_CALLBACK(peer_connection_got_proposition_yes_cb),
 						_("Cancel"), G_CALLBACK(peer_connection_got_proposition_no_cb));
 	}
--- a/libpurple/protocols/qq/buddy_info.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Mon Oct 15 10:45:46 2007 +0000
@@ -519,12 +519,12 @@
 		mid->info->qq_show = g_strdup(info->qq_show);
 		mid->info->unknown6 = g_strdup(info->unknown6);
 
-		purple_request_fields(gc, _("Modify my information"),
+		purple_request_fields_with_hint(gc, _("Modify my information"),
 			_("Modify my information"), NULL, fields,
 			_("Update my information"), G_CALLBACK(modify_info_ok_cb),
 			_("Cancel"), G_CALLBACK(modify_info_cancel_cb),
 			purple_connection_get_account(gc), NULL, NULL,
-			mid);
+			"account", mid);
 	}
 }
 
--- a/libpurple/protocols/qq/buddy_opt.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/buddy_opt.c	Mon Oct 15 10:45:46 2007 +0000
@@ -209,11 +209,11 @@
 	msg2 = g_strdup(_("Input your reason:"));
 
 	nombre = uid_to_purple_name(uid);
-	purple_request_input(gc, _("Reject request"), msg1, msg2,
+	purple_request_input_with_hint(gc, _("Reject request"), msg1, msg2,
 			   _("Sorry, you are not my type..."), TRUE, FALSE,
 			   NULL, _("Reject"), G_CALLBACK(_qq_reject_add_request_real), _("Cancel"), NULL,
 			   purple_connection_get_account(gc), nombre, NULL,
-			   g2);
+			   PURPLE_REQUEST_UI_HINT_BUDDY, g2);
 	g_free(nombre);
 }
 
@@ -402,7 +402,7 @@
 			g->gc = gc;
 			g->uid = for_uid;
 			msg = g_strdup_printf(_("User %d needs authentication"), for_uid);
-			purple_request_input(gc, NULL, msg,
+			purple_request_input_with_hint(gc, NULL, msg,
 					   _("Input request here"), /* TODO: Awkward string to fix post string freeze - standardize auth dialogues? -evands */
 					   _("Would you be my friend?"),
 					   TRUE, FALSE, NULL, _("Send"),
@@ -410,7 +410,7 @@
 					   (_qq_send_packet_add_buddy_auth_with_gc_and_uid),
 					   _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid),
 					   purple_connection_get_account(gc), nombre, NULL,
-					   g);
+					   PURPLE_REQUEST_UI_HINT_BUDDY, g);
 			g_free(msg);
 			g_free(nombre);
 		} else {	/* add OK */
--- a/libpurple/protocols/qq/group.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/group.c	Mon Oct 15 10:45:46 2007 +0000
@@ -116,14 +116,14 @@
 	purple_roomlist_set_fields(rl, fields);
 	purple_roomlist_set_in_progress(qd->roomlist, TRUE);
 
-	purple_request_input(gc, _("QQ Qun"),
+	purple_request_input_with_hint(gc, _("QQ Qun"),
 			   _("Please enter external group ID"),
 			   _("You can only search for permanent QQ groups\n"),
 			   NULL, FALSE, FALSE, NULL, 
 			   _("Search"), G_CALLBACK(_qq_group_search_callback), 
 			   _("Cancel"), G_CALLBACK(_qq_group_search_cancel_callback), 
 			   purple_connection_get_account(gc), NULL, NULL,
-			   gc);
+			   PURPLE_REQUEST_UI_HINT_CONV, gc);
 
 	return qd->roomlist;
 }
--- a/libpurple/protocols/qq/group_im.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/group_im.c	Mon Oct 15 10:45:46 2007 +0000
@@ -133,11 +133,11 @@
 
 	nombre = uid_to_purple_name(user_uid);
 
-	purple_request_action(gc, _("QQ Qun Operation"),
+	purple_request_action_with_hint(gc, _("QQ Qun Operation"),
 			    msg, reason,
 			    2,
 				purple_connection_get_account(gc), nombre, NULL,
-				g, 3,
+				PURPLE_REQUEST_UI_HINT_CONV, g, 3,
 			    _("Approve"),
 			    G_CALLBACK
 			    (qq_group_approve_application_with_struct),
--- a/libpurple/protocols/qq/group_join.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/group_join.c	Mon Oct 15 10:45:46 2007 +0000
@@ -132,14 +132,14 @@
 	g = g_new0(gc_and_uid, 1);
 	g->gc = gc;
 	g->uid = group->internal_group_id;
-	purple_request_input(gc, NULL, msg,
+	purple_request_input_with_hint(gc, NULL, msg,
 			   _("Input request here"),
 			   _("Would you be my friend?"), TRUE, FALSE, NULL,
 			   _("Send"),
 			   G_CALLBACK(_qq_group_join_auth_with_gc_and_id),
 			   _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid),
 			   purple_connection_get_account(gc), group->group_name_utf8, NULL,
-			   g);
+			   PURPLE_REQUEST_UI_HINT_CONV, g);
 	g_free(msg);
 }
 
@@ -356,13 +356,13 @@
 	g->gc = gc;
 	g->uid = internal_group_id;
 
-	purple_request_action(gc, _("QQ Qun Operation"),
+	purple_request_action_with_hint(gc, _("QQ Qun Operation"),
 			    _("Are you sure you want to leave this Qun?"),
 			    _
 			    ("Note, if you are the creator, \nthis operation will eventually remove this Qun."),
 			    1,
 				purple_connection_get_account(gc), NULL, NULL,
-			    g, 2, _("Cancel"),
+			    PURPLE_REQUEST_UI_HINT_CONV, g, 2, _("Cancel"),
 			    G_CALLBACK(qq_do_nothing_with_gc_and_uid),
 			    _("Continue"), G_CALLBACK(_qq_group_exit_with_gc_and_id));
 }
--- a/libpurple/protocols/qq/group_opt.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/group_opt.c	Mon Oct 15 10:45:46 2007 +0000
@@ -121,9 +121,9 @@
 	g_return_if_fail(g != NULL && g->gc != NULL && g->member > 0);
 
 	qq_send_packet_get_info(g->gc, g->member, TRUE);	/* we want to see window */
-	purple_request_action(g->gc, NULL, _("Do you want to approve the request?"), "", 2,
+	purple_request_action_with_hint(g->gc, NULL, _("Do you want to approve the request?"), "", 2,
 					purple_connection_get_account(g->gc), NULL, NULL,
-					g, 2,
+					PURPLE_REQUEST_UI_HINT_CONV, g, 2,
 					_("Reject"), G_CALLBACK(qq_group_reject_application_with_struct),
 					_("Approve"), G_CALLBACK(qq_group_approve_application_with_struct));
 }
@@ -137,13 +137,13 @@
 	msg2 = g_strdup(_("Enter your reason:"));
 
 	nombre = uid_to_purple_name(g->member);
-	purple_request_input(g->gc, /* title */ NULL, msg1, msg2,
+	purple_request_input_with_hint(g->gc, /* title */ NULL, msg1, msg2,
 			   _("Sorry, you are not my type..."), /* multiline */ TRUE, /* masked */ FALSE,
 			   /* hint */ NULL,
 			   _("Send"), G_CALLBACK(_qq_group_reject_application_real),
 			   _("Cancel"), G_CALLBACK(_qq_group_do_nothing_with_struct),
 			   purple_connection_get_account(g->gc), nombre, NULL,
-			   g);
+			   PURPLE_REQUEST_UI_HINT_CONV, g);
 
 	g_free(msg1);
 	g_free(msg2);
@@ -388,13 +388,13 @@
 	g->gc = gc;
 	g->uid = internal_group_id;
 
-	purple_request_action(gc, _("QQ Qun Operation"),
+	purple_request_action_with_hint(gc, _("QQ Qun Operation"),
 			    _("You have successfully created a Qun"),
 			    _
 			    ("Would you like to set up the Qun details now?"),
 			    1,
 				purple_connection_get_account(gc), NULL, NULL,
-				g, 2,
+				PURPLE_REQUEST_UI_HINT_CONV, g, 2,
 				_("Setup"), G_CALLBACK(qq_group_setup_with_gc_and_uid),
 			    _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid));
 }
--- a/libpurple/protocols/qq/qq.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/qq.c	Mon Oct 15 10:45:46 2007 +0000
@@ -418,9 +418,9 @@
 	g->gc = gc;
 	g->uid = uid;
 
-	purple_request_action(gc, _("Block Buddy"),
+	purple_request_action_with_hint(gc, _("Block Buddy"),
 			    _("Are you sure you want to block this buddy?"), NULL,
-			    1, g, 2,
+			    1, g, "blist", 2,
 			    _("Cancel"),
 			    G_CALLBACK(qq_do_nothing_with_gc_and_uid),
 			    _("Block"), G_CALLBACK(qq_block_buddy_with_gc_and_uid));
@@ -471,11 +471,11 @@
 static void _qq_menu_create_permanent_group(PurplePluginAction * action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_request_input(gc, _("Create QQ Qun"),
+	purple_request_input_with_hint(gc, _("Create QQ Qun"),
 			   _("Input Qun name here"),
 			   _("Only QQ members can create permanent Qun"),
 			   "OpenQ", FALSE, FALSE, NULL,
-			   _("Create"), G_CALLBACK(qq_group_create_with_name), _("Cancel"), NULL, gc);
+			   _("Create"), G_CALLBACK(qq_group_create_with_name), _("Cancel"), NULL, "blist", gc);
 }
 */
 
--- a/libpurple/protocols/qq/sys_msg.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/qq/sys_msg.c	Mon Oct 15 10:45:46 2007 +0000
@@ -83,10 +83,10 @@
 	qq_send_packet_get_info(gc, uid, TRUE);	/* we want to see window */
 
 	nombre = uid_to_purple_name(uid);
-	purple_request_action
+	purple_request_action_with_hint
 	    (gc, NULL, _("Do you want to approve the request?"), "", 2,
 		 purple_connection_get_account(gc), nombre, NULL,
-		 g, 2,
+		 PURPLE_REQUEST_UI_HINT_CONV, g, 2,
 	     _("Reject"), G_CALLBACK(qq_reject_add_request_with_gc_and_uid),
 	     _("Approve"), G_CALLBACK(qq_approve_add_request_with_gc_and_uid));
 	g_free(nombre);
@@ -106,11 +106,11 @@
 
 	qq_send_packet_get_info(gc, uid, TRUE);	/* we want to see window */
 	nombre = uid_to_purple_name(uid);
-	purple_request_action
+	purple_request_action_with_hint
 	    (gc, NULL, _("Do you want to add this buddy?"), "", 2,
 		 purple_connection_get_account(gc), nombre, NULL,
-		 g, 2,
-	     _("Cancel"), NULL,
+		 PURPLE_REQUEST_UI_HINT_BUDDY, g, 2,
+		 _("Cancel"), NULL,
 		 _("Add"), G_CALLBACK(qq_add_buddy_with_gc_and_uid));
 	g_free(nombre);
 }
@@ -165,10 +165,10 @@
 		g->uid = uid;	/* only need to get value */
 		message = g_strdup_printf(_("You have been added by %s"), from);
 		_qq_sys_msg_log_write(gc, message, from);
-		purple_request_action(gc, NULL, message,
+		purple_request_action_with_hint(gc, NULL, message,
 				    _("Would you like to add him?"), 2,
 					purple_connection_get_account(gc), name, NULL,
-					g, 3,
+					PURPLE_REQUEST_UI_HINT_BUDDY, g, 3,
 				    _("Cancel"), NULL,
 					_("Add"), G_CALLBACK(qq_add_buddy_with_gc_and_uid),
 				    _("Search"), G_CALLBACK(_qq_search_before_add_with_gc_and_uid));
@@ -239,10 +239,10 @@
 	reason = g_strdup_printf(_("Message: %s"), msg_utf8);
 	_qq_sys_msg_log_write(gc, message, from);
 
-	purple_request_action
+	purple_request_action_with_hint
 	    (gc, NULL, message, reason, 2,
 		purple_connection_get_account(gc), name, NULL,
-		 g, 3,
+		 PURPLE_REQUEST_UI_HINT_BUDDY, g, 3,
 	     _("Reject"),
 	     G_CALLBACK(qq_reject_add_request_with_gc_and_uid),
 	     _("Approve"),
@@ -259,10 +259,10 @@
 		g2->gc = gc;
 		g2->uid = strtol(from, NULL, 10);
 		message = g_strdup_printf(_("%s is not in your buddy list"), from);
-		purple_request_action(gc, NULL, message,
+		purple_request_action_with_hint(gc, NULL, message,
 				    _("Would you like to add him?"), 2,
 					purple_connection_get_account(gc), name, NULL,
-					g2, 3,
+					PURPLE_REQUEST_UI_HINT_BLIST, g2, 3,
 					_("Cancel"), NULL,
 					_("Add"), G_CALLBACK(qq_add_buddy_with_gc_and_uid),
 				    _("Search"), G_CALLBACK(_qq_search_before_add_with_gc_and_uid));
--- a/libpurple/protocols/sametime/sametime.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Mon Oct 15 10:45:46 2007 +0000
@@ -3423,12 +3423,12 @@
 	   " message to be sent to %s");
   msg1 = g_strdup_printf(msgB, buddy->name);
 
-  purple_request_fields(gc, _("New Conference"),
+  purple_request_fields_with_hint(gc, _("New Conference"),
 		      msgA, msg1, fields,
 		      _("Create"), G_CALLBACK(conf_create_prompt_join),
 		      _("Cancel"), G_CALLBACK(conf_create_prompt_cancel),
 			  acct, purple_buddy_get_name(buddy), NULL,
-		      buddy);
+		      PURPLE_REQUEST_UI_HINT_CONV, buddy);
   g_free(msg1);
 }
 
@@ -3509,12 +3509,12 @@
 	   " create a new conference to invite this user to.");
   msg = g_strdup_printf(msgB, buddy->name);
 
-  purple_request_fields(gc, _("Invite to Conference"),
+  purple_request_fields_with_hint(gc, _("Invite to Conference"),
 		      msgA, msg, fields,
 		      _("Invite"), G_CALLBACK(conf_select_prompt_invite),
 		      _("Cancel"), G_CALLBACK(conf_select_prompt_cancel),
 			  acct, purple_buddy_get_name(buddy), NULL,
-		      buddy);
+		      PURPLE_REQUEST_UI_HINT_CONV, buddy);
   g_free(msg);
 }
 
@@ -3682,13 +3682,13 @@
 	  " continue logging in.");
   msg = g_strdup_printf(msgA, NSTR(purple_account_get_username(acct)));
   
-  purple_request_input(gc, _("Meanwhile Connection Setup"),
+  purple_request_input_with_hint(gc, _("Meanwhile Connection Setup"),
 		     _("No Sametime Community Server Specified"), msg,
 		     MW_PLUGIN_DEFAULT_HOST, FALSE, FALSE, NULL,
 		     _("Connect"), G_CALLBACK(prompt_host_ok_cb),
 		     _("Cancel"), G_CALLBACK(prompt_host_cancel_cb),
 			 acct, NULL, NULL,
-		     gc);
+		     PURPLE_REQUEST_UI_HINT_CONV, gc);
 
   g_free(msg);
 }
@@ -5260,10 +5260,10 @@
   title = g_strdup_printf(_("Import Sametime List for Account %s"),
 			  purple_account_get_username(account));
 
-  purple_request_file(gc, title, NULL, FALSE,
+  purple_request_file_with_hint(gc, title, NULL, FALSE,
 		    G_CALLBACK(st_import_action_cb), NULL,
 		    account, NULL, NULL,
-		    gc);
+		    PURPLE_REQUEST_UI_HINT_CONV, gc);
 
   g_free(title);
 }
@@ -5300,10 +5300,10 @@
   title = g_strdup_printf(_("Export Sametime List for Account %s"),
 			  purple_account_get_username(account));
 
-  purple_request_file(gc, title, NULL, TRUE,
+  purple_request_file_with_hint(gc, title, NULL, TRUE,
 		    G_CALLBACK(st_export_action_cb), NULL,
 			account, NULL, NULL,
-		    gc);
+		    PURPLE_REQUEST_UI_HINT_CONV, gc);
 
   g_free(title);
 }
@@ -5436,12 +5436,12 @@
 	  " the list below to add it to your buddy list.");
   msg = g_strdup_printf(msgB, result->name);
 
-  purple_request_fields(gc, _("Select Notes Address Book"),
+  purple_request_fields_with_hint(gc, _("Select Notes Address Book"),
 		      msgA, msg, fields,
 		      _("Add Group"), G_CALLBACK(remote_group_multi_cb),
 		      _("Cancel"), G_CALLBACK(remote_group_multi_cleanup),
 			  purple_connection_get_account(gc), result->name, NULL,
-		      pd);
+		      PURPLE_REQUEST_UI_HINT_BLIST, pd);
 
   g_free(msg);
 }
@@ -5526,12 +5526,12 @@
   msgB = _("Enter the name of a Notes Address Book group in the field below"
 	  " to add the group and its members to your buddy list.");
 
-  purple_request_input(gc, _("Add Group"), msgA, msgB, NULL,
+  purple_request_input_with_hint(gc, _("Add Group"), msgA, msgB, NULL,
 		     FALSE, FALSE, NULL,
 		     _("Add"), G_CALLBACK(remote_group_action_cb),
 		     _("Cancel"), NULL,
 			 purple_connection_get_account(gc), NULL, NULL,
-		     gc);
+		     PURPLE_REQUEST_UI_HINT_BLIST, gc);
 }
 
 
@@ -5651,12 +5651,12 @@
   msgB = _("Enter a name or partial ID in the field below to search"
 	   " for matching users in your Sametime community.");
 
-  purple_request_input(gc, _("User Search"), msgA, msgB, NULL,
+  purple_request_input_with_hint(gc, _("User Search"), msgA, msgB, NULL,
 		     FALSE, FALSE, NULL,
 		     _("Search"), G_CALLBACK(search_action_cb),
 		     _("Cancel"), NULL,
 			 purple_connection_get_account(gc), NULL, NULL,
-			 gc);
+			 PURPLE_REQUEST_UI_HINT_BLIST, gc);
 }
 
 
--- a/libpurple/protocols/silc/buddy.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc/buddy.c	Mon Oct 15 10:45:46 2007 +0000
@@ -312,9 +312,9 @@
 		a->hostname = strdup(hostname);
 	a->port = port;
 
-	purple_request_action(client->application, _("Key Agreement Request"), tmp,
+	purple_request_action_with_hint(client->application, _("Key Agreement Request"), tmp,
 			      hostname ? tmp2 : NULL, 1, gc->account, client_entry->nickname,
-			      NULL, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
+			      NULL, PURPLE_REQUEST_UI_HINT_BLIST, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
 			      _("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb));
 }
 
@@ -449,11 +449,11 @@
 	p->client = sg->client;
 	p->conn = sg->conn;
 	p->client_id = client_entry->id;
-	purple_request_input(gc, _("IM With Password"), NULL,
+	purple_request_input_with_hint(gc, _("IM With Password"), NULL,
 	                     _("Set IM Password"), NULL, FALSE, TRUE, NULL,
 	                     _("OK"), G_CALLBACK(silcpurple_buddy_privkey_cb),
 	                     _("Cancel"), G_CALLBACK(silcpurple_buddy_privkey_cb),
-	                     gc->account, NULL, NULL, p);
+	                     gc->account, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, p);
 
 	silc_client_list_free(sg->client, sg->conn, clients);
 }
@@ -1056,10 +1056,10 @@
 	}
 
 	/* Open file selector to select the public key. */
-	purple_request_file(r->client->application, _("Open..."), NULL, FALSE,
+	purple_request_file_with_hint(r->client->application, _("Open..."), NULL, FALSE,
 			    G_CALLBACK(silcpurple_add_buddy_ask_import),
 			    G_CALLBACK(silcpurple_add_buddy_ask_pk_cancel),
-			    purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
+			    purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, PURPLE_REQUEST_UI_HINT_BLIST, r);
 
 }
 
@@ -1069,10 +1069,10 @@
 	char tmp[512];
 	g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"),
 		   r->b->name);
-	purple_request_action(r->client->application, _("Add Buddy"), tmp,
+	purple_request_action_with_hint(r->client->application, _("Add Buddy"), tmp,
 			      _("To add the buddy you must import his/her public key. "
 				"Press Import to import a public key."), 0,
-			      purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r, 2,
+			      purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, PURPLE_REQUEST_UI_HINT_BLIST, r, 2,
 			      _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb),
 			      _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb));
 }
@@ -1179,7 +1179,7 @@
 		silc_free(fingerprint);
 	}
 
-	purple_request_fields(r->client->application, _("Add Buddy"),
+	purple_request_fields_with_hint(r->client->application, _("Add Buddy"),
 			      _("Select correct user"),
 			      r->pubkey_search
 			      ? _("More than one user was found with the same public key. Select "
@@ -1189,7 +1189,7 @@
 			      fields,
 			      _("OK"), G_CALLBACK(silcpurple_add_buddy_select_cb),
 			      _("Cancel"), G_CALLBACK(silcpurple_add_buddy_select_cancel),
-			      purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
+			      purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, PURPLE_REQUEST_UI_HINT_BLIST, r);
 }
 
 static void
--- a/libpurple/protocols/silc/chat.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc/chat.c	Mon Oct 15 10:45:46 2007 +0000
@@ -301,10 +301,10 @@
 	f = purple_request_fields_get_field(fields, "list");
 	if (!purple_request_field_list_get_selected(f)) {
 		/* Add new public key */
-		purple_request_file(sg->gc, _("Open Public Key..."), NULL, FALSE,
+		purple_request_file_with_hint(sg->gc, _("Open Public Key..."), NULL, FALSE,
 				    G_CALLBACK(silcpurple_chat_chpk_add),
 				    G_CALLBACK(silcpurple_chat_chpk_cancel),
-				    purple_connection_get_account(sg->gc), NULL, NULL, sgc);
+				    purple_connection_get_account(sg->gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, sgc);
 		return;
 	}
 
@@ -441,11 +441,11 @@
 	if (!channel_pubkeys || !silc_dlist_count(channel_pubkeys)) {
 		f = purple_request_field_list_new("list", NULL);
 		purple_request_field_group_add_field(g, f);
-		purple_request_fields(sg->gc, _("Channel Authentication"),
+		purple_request_fields_with_hint(sg->gc, _("Channel Authentication"),
 				      _("Channel Authentication"), t, fields,
 				      _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
 				      _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
-				      purple_connection_get_account(sg->gc), NULL, NULL, sgc);
+				      purple_connection_get_account(sg->gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, sgc);
 		if (channel_pubkeys)
 		  silc_dlist_uninit(channel_pubkeys);
 		return;
@@ -476,11 +476,11 @@
 	}
 
 	purple_request_field_list_set_multi_select(f, FALSE);
-	purple_request_fields(sg->gc, _("Channel Authentication"),
+	purple_request_fields_with_hint(sg->gc, _("Channel Authentication"),
 			      _("Channel Authentication"), t, fields,
 			      _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
 			      _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
-			      purple_connection_get_account(sg->gc), NULL, NULL, sgc);
+			      purple_connection_get_account(sg->gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, sgc);
 }
 
 static void
@@ -611,10 +611,10 @@
 	g_snprintf(tmp, sizeof(tmp),
 		   _("Please enter the %s channel private group name and passphrase."),
 		   p->channel);
-	purple_request_fields(gc, _("Add Channel Private Group"), NULL, tmp, fields,
+	purple_request_fields_with_hint(gc, _("Add Channel Private Group"), NULL, tmp, fields,
 			      _("Add"), G_CALLBACK(silcpurple_chat_prv_add),
 			      _("Cancel"), G_CALLBACK(silcpurple_chat_prv_cancel),
-			      purple_connection_get_account(gc), NULL, NULL, p);
+			      purple_connection_get_account(gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, p);
 }
 
 
@@ -739,12 +739,12 @@
 	s->channel = ch;
 	s->sg = sg;
 	g_snprintf(tmp, sizeof(tmp), "%d", (int)channel->user_limit);
-	purple_request_input(gc, _("User Limit"), NULL,
+	purple_request_input_with_hint(gc, _("User Limit"), NULL,
 			   _("Set user limit on channel. Set to zero to reset user limit."),
 			   tmp, FALSE, FALSE, NULL,
 			   _("OK"), G_CALLBACK(silcpurple_chat_ulimit_cb),
 			   _("Cancel"), G_CALLBACK(silcpurple_chat_ulimit_cb),
-			   purple_connection_get_account(gc), NULL, NULL, s);
+			   purple_connection_get_account(gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, s);
 }
 
 static void
--- a/libpurple/protocols/silc/ops.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc/ops.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1810,11 +1810,11 @@
 		return;
 	internal->u.ask_pass = completion;
 	internal->context = context;
-	purple_request_input(gc, _("Passphrase"), NULL,
+	purple_request_input_with_hint(gc, _("Passphrase"), NULL,
 			     _("Passphrase required"), NULL, FALSE, TRUE, NULL,
 			     _("OK"), G_CALLBACK(silc_ask_passphrase_cb),
 			     _("Cancel"), G_CALLBACK(silc_ask_passphrase_cb),
-			     purple_connection_get_account(gc), NULL, NULL, internal);
+			     purple_connection_get_account(gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, internal);
 }
 
 
--- a/libpurple/protocols/silc/pk.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc/pk.c	Mon Oct 15 10:45:46 2007 +0000
@@ -107,9 +107,9 @@
 		   _("Fingerprint and babbleprint for the %s key are:\n\n"
 		     "%s\n%s\n"), entity, fingerprint, babbleprint);
 
-	purple_request_action(gc, _("Verify Public Key"), tmp, tmp2,
+	purple_request_action_with_hint(gc, _("Verify Public Key"), tmp, tmp2,
 			      PURPLE_DEFAULT_ACTION_NONE,
-			      purple_connection_get_account(gc), entity, NULL, verify, 3,
+			      purple_connection_get_account(gc), entity, NULL, PURPLE_REQUEST_UI_HINT_BLIST, verify, 3,
 			      _("Yes"), G_CALLBACK(silcpurple_verify_cb),
 			      _("No"), G_CALLBACK(silcpurple_verify_cb),
 			      _("_View..."), G_CALLBACK(silcpurple_verify_details));
--- a/libpurple/protocols/silc/silc.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc/silc.c	Mon Oct 15 10:45:46 2007 +0000
@@ -823,7 +823,7 @@
 	purple_request_field_group_add_field(g, f);
 	purple_request_fields_add_group(fields, g);
 
-	purple_request_fields(gc, _("User Online Status Attributes"),
+	purple_request_fields_with_hint(gc, _("User Online Status Attributes"),
 			    _("User Online Status Attributes"),
 			    _("You can let other users see your online status information "
 			      "and your personal information. Please fill the information "
@@ -831,7 +831,7 @@
 			    fields,
 			    _("OK"), G_CALLBACK(silcpurple_attrs_cb),
 			    _("Cancel"), G_CALLBACK(silcpurple_attrs_cancel),
-				gc->account, NULL, NULL, gc);
+				gc->account, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, gc);
 }
 
 static void
@@ -1035,11 +1035,11 @@
 	purple_request_field_group_add_field(g, f);
 	purple_request_fields_add_group(fields, g);
 
-	purple_request_fields(gc, _("Create New SILC Key Pair"),
+	purple_request_fields_with_hint(gc, _("Create New SILC Key Pair"),
 			      _("Create New SILC Key Pair"), NULL, fields,
 			      _("Generate Key Pair"), G_CALLBACK(silcpurple_create_keypair_cb),
 			      _("Cancel"), G_CALLBACK(silcpurple_create_keypair_cancel),
-			      gc->account, NULL, NULL, gc);
+			      gc->account, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, gc);
 
 	g_strfreev(u);
 	silc_free(hostname);
--- a/libpurple/protocols/silc/util.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc/util.c	Mon Oct 15 10:45:46 2007 +0000
@@ -378,10 +378,10 @@
 
 	buf = g_string_free(s, FALSE);
 
-	purple_request_action(sg->gc, _("Public Key Information"),
+	purple_request_action_with_hint(sg->gc, _("Public Key Information"),
 			      _("Public Key Information"),
 			      buf, 0, purple_connection_get_account(sg->gc),
-			      NULL, NULL, context, 1, _("Close"), callback);
+			      NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, context, 1, _("Close"), callback);
 
 	g_free(buf);
 	silc_free(fingerprint);
--- a/libpurple/protocols/silc/wb.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc/wb.c	Mon Oct 15 10:45:46 2007 +0000
@@ -299,8 +299,8 @@
 	req->channel = channel;
 	req->sg = sg;
 
-	purple_request_action(gc, _("Whiteboard"), tmp, NULL, 1,
-				sg->account, sender->nickname, NULL, req, 2,
+	purple_request_action_with_hint(gc, _("Whiteboard"), tmp, NULL, 1,
+				sg->account, sender->nickname, NULL, PURPLE_REQUEST_UI_HINT_BLIST, req, 2,
 			    _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
 			    _("No"), G_CALLBACK(silcpurple_wb_request_cb));
 }
--- a/libpurple/protocols/silc10/buddy.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc10/buddy.c	Mon Oct 15 10:45:46 2007 +0000
@@ -309,9 +309,9 @@
 		a->hostname = strdup(hostname);
 	a->port = port;
 
-	purple_request_action(client->application, _("Key Agreement Request"), tmp,
+	purple_request_action_with_hint(client->application, _("Key Agreement Request"), tmp,
 			    hostname ? tmp2 : NULL, 1, gc->account, client_entry->nickname,
-				NULL, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
+				NULL, a, PURPLE_REQUEST_UI_HINT_BLIST, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
 			    _("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb));
 }
 
@@ -462,11 +462,11 @@
 	p->client = sg->client;
 	p->conn = sg->conn;
 	p->client_id = *clients[0]->id;
-	purple_request_input(gc, _("IM With Password"), NULL,
+	purple_request_input_with_hint(gc, _("IM With Password"), NULL,
 	                     _("Set IM Password"), NULL, FALSE, TRUE, NULL,
 	                     _("OK"), G_CALLBACK(silcpurple_buddy_privkey_cb),
 	                     _("Cancel"), G_CALLBACK(silcpurple_buddy_privkey_cb),
-	                     gc->account, NULL, NULL, p);
+	                     gc->account, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, p);
 
 	silc_free(clients);
 	silc_free(nickname);
@@ -1064,10 +1064,10 @@
 	}
 
 	/* Open file selector to select the public key. */
-	purple_request_file(r->client->application, _("Open..."), NULL, FALSE,
+	purple_request_file_with_hint(r->client->application, _("Open..."), NULL, FALSE,
 			  G_CALLBACK(silcpurple_add_buddy_ask_import),
 			  G_CALLBACK(silcpurple_add_buddy_ask_pk_cancel),
-			  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
+			  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, PURPLE_REQUEST_UI_HINT_BLIST, r);
 
 }
 
@@ -1077,10 +1077,10 @@
 	char tmp[512];
 	g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"),
 		   r->b->name);
-	purple_request_action(r->client->application, _("Add Buddy"), tmp,
+	purple_request_action_with_hint(r->client->application, _("Add Buddy"), tmp,
 			    _("To add the buddy you must import his/her public key. "
 			      "Press Import to import a public key."), 0,
-				  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r, 2,
+				  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, PURPLE_REQUEST_UI_HINT_BLIST, r, 2,
 			    _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb),
 			    _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb));
 }
@@ -1177,7 +1177,7 @@
 		silc_free(fingerprint);
 	}
 
-	purple_request_fields(r->client->application, _("Add Buddy"),
+	purple_request_fields_with_hint(r->client->application, _("Add Buddy"),
 				_("Select correct user"),
 				r->pubkey_search
 					? _("More than one user was found with the same public key. Select "
@@ -1187,7 +1187,7 @@
 				fields,
 				_("OK"), G_CALLBACK(silcpurple_add_buddy_select_cb),
 				_("Cancel"), G_CALLBACK(silcpurple_add_buddy_select_cancel),
-				purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
+				purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, PURPLE_REQUEST_UI_HINT_BLIST, r);
 }
 
 static void
--- a/libpurple/protocols/silc10/chat.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc10/chat.c	Mon Oct 15 10:45:46 2007 +0000
@@ -288,10 +288,10 @@
 	f = purple_request_fields_get_field(fields, "list");
 	if (!purple_request_field_list_get_selected(f)) {
 		/* Add new public key */
-		purple_request_file(sg->gc, _("Open Public Key..."), NULL, FALSE,
+		purple_request_file_with_hint(sg->gc, _("Open Public Key..."), NULL, FALSE,
 				  G_CALLBACK(silcpurple_chat_chpk_add),
 				  G_CALLBACK(silcpurple_chat_chpk_cancel),
-				  purple_connection_get_account(sg->gc), NULL, NULL, sgc);
+				  purple_connection_get_account(sg->gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, sgc);
 		return;
 	}
 
@@ -419,11 +419,11 @@
 	if (!channel_pubkeys) {
 		f = purple_request_field_list_new("list", NULL);
 		purple_request_field_group_add_field(g, f);
-		purple_request_fields(sg->gc, _("Channel Authentication"),
+		purple_request_fields_with_hint(sg->gc, _("Channel Authentication"),
 				    _("Channel Authentication"), t, fields,
 				    _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
 				    _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
-					purple_connection_get_account(sg->gc), NULL, NULL, sgc);
+					purple_connection_get_account(sg->gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, sgc);
 		return;
 	}
 	sgc->pubkeys = silc_buffer_copy(channel_pubkeys);
@@ -458,11 +458,11 @@
 	}
 
 	purple_request_field_list_set_multi_select(f, FALSE);
-	purple_request_fields(sg->gc, _("Channel Authentication"),
+	purple_request_fields_with_hint(sg->gc, _("Channel Authentication"),
 			    _("Channel Authentication"), t, fields,
 			    _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
 			    _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
-				purple_connection_get_account(sg->gc), NULL, NULL, sgc);
+				purple_connection_get_account(sg->gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, sgc);
 
 	silc_argument_payload_free(chpks);
 }
@@ -595,10 +595,10 @@
 	g_snprintf(tmp, sizeof(tmp),
 		   _("Please enter the %s channel private group name and passphrase."),
 		   p->channel);
-	purple_request_fields(gc, _("Add Channel Private Group"), NULL, tmp, fields,
+	purple_request_fields_with_hint(gc, _("Add Channel Private Group"), NULL, tmp, fields,
 			    _("Add"), G_CALLBACK(silcpurple_chat_prv_add),
 			    _("Cancel"), G_CALLBACK(silcpurple_chat_prv_cancel),
-				purple_connection_get_account(gc), NULL, NULL, p);
+				purple_connection_get_account(gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, p);
 }
 
 
@@ -723,12 +723,12 @@
 	s->channel = ch;
 	s->sg = sg;
 	g_snprintf(tmp, sizeof(tmp), "%d", (int)channel->user_limit);
-	purple_request_input(gc, _("User Limit"), NULL,
+	purple_request_input_with_hint(gc, _("User Limit"), NULL,
 			   _("Set user limit on channel. Set to zero to reset user limit."),
 			   tmp, FALSE, FALSE, NULL,
 			   _("OK"), G_CALLBACK(silcpurple_chat_ulimit_cb),
 			   _("Cancel"), G_CALLBACK(silcpurple_chat_ulimit_cb),
-			   purple_connection_get_account(gc), NULL, NULL, s);
+			   purple_connection_get_account(gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_CONV, s);
 }
 
 static void
--- a/libpurple/protocols/silc10/ops.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc10/ops.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1291,9 +1291,9 @@
 
 #if 0 /* XXX for now, let's not show attrs here */
 			if (client_entry->attrs)
-				purple_request_action(gc, _("User Information"),
+				purple_request_action_with_hint(gc, _("User Information"),
 						_("User Information"),
-						buf, 1, client_entry, 2,
+						buf, 1, PURPLE_REQUEST_UI_HINT_BLIST, client_entry, 2,
 						_("OK"), G_CALLBACK(silcpurple_whois_more),
 						_("_More..."), G_CALLBACK(silcpurple_whois_more), gc->account, NULL, NULL);
 			else
@@ -1898,11 +1898,11 @@
 		return;
 	internal->completion = completion;
 	internal->context = context;
-	purple_request_input(gc, _("Passphrase"), NULL,
+	purple_request_input_with_hint(gc, _("Passphrase"), NULL,
 			   _("Passphrase required"), NULL, FALSE, TRUE, NULL,
 			   _("OK"), G_CALLBACK(silc_ask_passphrase_cb),
 			   _("Cancel"), G_CALLBACK(silc_ask_passphrase_cb),
-			   purple_connection_get_account(gc), NULL, NULL, internal);
+			   purple_connection_get_account(gc), NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, internal);
 }
 
 
--- a/libpurple/protocols/silc10/pk.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc10/pk.c	Mon Oct 15 10:45:46 2007 +0000
@@ -113,9 +113,9 @@
 		   _("Fingerprint and babbleprint for the %s key are:\n\n"
 		     "%s\n%s\n"), entity, fingerprint, babbleprint);
 
-	purple_request_action(gc, _("Verify Public Key"), tmp, tmp2,
+	purple_request_action_with_hint(gc, _("Verify Public Key"), tmp, tmp2,
 						PURPLE_DEFAULT_ACTION_NONE,
-						purple_connection_get_account(gc), entity, NULL, verify, 3,
+						purple_connection_get_account(gc), entity, NULL, verify, PURPLE_REQUEST_UI_HINT_BLIST, 3,
 			    _("Yes"), G_CALLBACK(silcpurple_verify_cb),
 			    _("No"), G_CALLBACK(silcpurple_verify_cb),
 			    _("_View..."), G_CALLBACK(silcpurple_verify_details));
--- a/libpurple/protocols/silc10/silc.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc10/silc.c	Mon Oct 15 10:45:46 2007 +0000
@@ -726,7 +726,7 @@
 	purple_request_field_group_add_field(g, f);
 	purple_request_fields_add_group(fields, g);
 
-	purple_request_fields(gc, _("User Online Status Attributes"),
+	purple_request_fields_with_hint(gc, _("User Online Status Attributes"),
 			    _("User Online Status Attributes"),
 			    _("You can let other users see your online status information "
 			      "and your personal information. Please fill the information "
@@ -734,7 +734,7 @@
 			    fields,
 			    _("OK"), G_CALLBACK(silcpurple_attrs_cb),
 			    _("Cancel"), G_CALLBACK(silcpurple_attrs_cancel),
-				gc->account, NULL, NULL, gc);
+				gc->account, NULL, NULL, PURPLE_REQUEST_UI_HINT_BLIST, gc);
 }
 
 static void
@@ -940,7 +940,7 @@
 			    _("Create New SILC Key Pair"), NULL, fields,
 			    _("Generate Key Pair"), G_CALLBACK(silcpurple_create_keypair_cb),
 			    _("Cancel"), G_CALLBACK(silcpurple_create_keypair_cancel),
-				gc->account, NULL, NULL, gc);
+				gc->account, NULL, NULL, "blist", gc);
 
 	g_strfreev(u);
 	silc_free(hostname);
--- a/libpurple/protocols/silc10/util.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc10/util.c	Mon Oct 15 10:45:46 2007 +0000
@@ -371,10 +371,10 @@
 
 	buf = g_string_free(s, FALSE);
 
-	purple_request_action(sg->gc, _("Public Key Information"),
+	purple_request_action_with_hint(sg->gc, _("Public Key Information"),
 			    _("Public Key Information"),
 			    buf, 0, purple_connection_get_account(sg->gc),
-				NULL, NULL, context, 1, _("Close"), callback);
+				NULL, NULL, context, PURPLE_REQUEST_UI_HINT_BLIST, 1, _("Close"), callback);
 
 	g_free(buf);
 	silc_free(fingerprint);
--- a/libpurple/protocols/silc10/wb.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/silc10/wb.c	Mon Oct 15 10:45:46 2007 +0000
@@ -299,8 +299,8 @@
 	req->channel = channel;
 	req->sg = sg;
 
-	purple_request_action(gc, _("Whiteboard"), tmp, NULL, 1,
-				sg->account, sender->nickname, NULL, req, 2,
+	purple_request_action_with_hint(gc, _("Whiteboard"), tmp, NULL, 1,
+				sg->account, sender->nickname, NULL, PURPLE_REQUEST_UI_HINT_CONV, req, 2,
 			    _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
 			    _("No"), G_CALLBACK(silcpurple_wb_request_cb));
 }
--- a/libpurple/protocols/simple/simple.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/simple/simple.c	Mon Oct 15 10:45:46 2007 +0000
@@ -80,14 +80,15 @@
 static gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc);
 static void send_notify(struct simple_account_data *sip, struct simple_watcher *);
 
-static void send_publish(struct simple_account_data *sip);
+static void send_open_publish(struct simple_account_data *sip);
+static void send_closed_publish(struct simple_account_data *sip);
 
 static void do_notifies(struct simple_account_data *sip) {
 	GSList *tmp = sip->watcher;
 	purple_debug_info("simple", "do_notifies()\n");
 	if((sip->republish != -1) || sip->republish < time(NULL)) {
 		if(purple_account_get_bool(sip->account, "dopublish", TRUE)) {
-			send_publish(sip);
+			send_open_publish(sip);
 		}
 	}
 
@@ -1024,7 +1025,7 @@
 		case 200:
 			if(sip->registerstatus < SIMPLE_REGISTER_COMPLETE) { /* registered */
 				if(purple_account_get_bool(sip->account, "dopublish", TRUE)) {
-					send_publish(sip);
+					send_open_publish(sip);
 				}
 			}
 			sip->registerstatus = SIMPLE_REGISTER_COMPLETE;
@@ -1077,7 +1078,7 @@
 static void process_incoming_notify(struct simple_account_data *sip, struct sipmsg *msg) {
 	gchar *from;
 	gchar *fromhdr;
-	gchar *tmp2;
+	gchar *basicstatus_data;
 	xmlnode *pidf;
 	xmlnode *basicstatus = NULL, *tuple, *status;
 	gboolean isonline = FALSE;
@@ -1090,8 +1091,9 @@
 
 	if(!pidf) {
 		purple_debug_info("simple", "process_incoming_notify: no parseable pidf\n");
+		purple_prpl_got_user_status(sip->account, from, "offline", NULL);
+		send_sip_response(sip->gc, msg, 200, "OK", NULL);
 		g_free(from);
-		send_sip_response(sip->gc, msg, 200, "OK", NULL);
 		return;
 	}
 
@@ -1106,27 +1108,28 @@
 		return;
 	}
 
-	tmp2 = xmlnode_get_data(basicstatus);
+	basicstatus_data = xmlnode_get_data(basicstatus);
 
-	if(!tmp2) {
+	if(!basicstatus_data) {
 		purple_debug_info("simple", "process_incoming_notify: no basic data found\n");
 		xmlnode_free(pidf);
 		g_free(from);
 		return;
 	}
 
-	if(strstr(tmp2, "open")) {
+	if(strstr(basicstatus_data, "open"))
 		isonline = TRUE;
-	}
+
 
-	g_free(tmp2);
-
-	if(isonline) purple_prpl_got_user_status(sip->account, from, "available", NULL);
-	else purple_prpl_got_user_status(sip->account, from, "offline", NULL);
+	if(isonline) 
+		purple_prpl_got_user_status(sip->account, from, "available", NULL);
+	else 
+		purple_prpl_got_user_status(sip->account, from, "offline", NULL);
 
 	xmlnode_free(pidf);
+	g_free(from);
+	g_free(basicstatus_data);
 
-	g_free(from);
 	send_sip_response(sip->gc, msg, 200, "OK", NULL);
 }
 
@@ -1193,28 +1196,27 @@
 	return doc;
 }
 
-
-
-static gchar* gen_pidf(struct simple_account_data *sip) {
+static gchar* gen_pidf(struct simple_account_data *sip, gboolean open) {
 	gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
 			"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n"
 			"xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"\n"
 			"entity=\"sip:%s@%s\">\n"
 			"<tuple id=\"bs35r9f\">\n"
 			"<status>\n"
-			"<basic>open</basic>\n"
+			"<basic>%s</basic>\n"
 			"</status>\n"
 			"<note>%s</note>\n"
 			"</tuple>\n"
 			"</presence>",
 			sip->username,
 			sip->servername,
-			sip->status);
+			(open == TRUE) ? "open" : "closed",
+			(open == TRUE) ? sip->status : "");
 	return doc;
 }
 
 static void send_notify(struct simple_account_data *sip, struct simple_watcher *watcher) {
-	gchar *doc = watcher->needsxpidf ? gen_xpidf(sip) : gen_pidf(sip);
+	gchar *doc = watcher->needsxpidf ? gen_xpidf(sip) : gen_pidf(sip, TRUE);
 	gchar *hdr = watcher->needsxpidf ? "Event: presence\r\nContent-Type: application/xpidf+xml\r\n" : "Event: presence\r\nContent-Type: application/pidf+xml\r\n";
 	send_sip_request(sip->gc, "NOTIFY", watcher->name, watcher->name, hdr, doc, &watcher->dialog, NULL);
 	g_free(doc);
@@ -1228,9 +1230,9 @@
 	return TRUE;
 }
 
-static void send_publish(struct simple_account_data *sip) {
+static void send_open_publish(struct simple_account_data *sip) {
 	gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername);
-	gchar *doc = gen_pidf(sip);
+	gchar *doc = gen_pidf(sip, TRUE);
 	send_sip_request(sip->gc, "PUBLISH", uri, uri,
 		"Expires: 600\r\nEvent: presence\r\n"
 		"Content-Type: application/pidf+xml\r\n",
@@ -1240,6 +1242,18 @@
 	g_free(doc);
 }
 
+static void send_closed_publish(struct simple_account_data *sip) {
+	gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername);
+	gchar *doc = gen_pidf(sip, FALSE);
+	send_sip_request(sip->gc, "PUBLISH", uri, uri,
+		"Expires: 600\r\nEvent: presence\r\n"
+		"Content-Type: application/pidf+xml\r\n",
+		doc, NULL, process_publish_response);
+	/*sip->republish = time(NULL) + 500;*/
+	g_free(uri);
+	g_free(doc);
+}
+
 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) {
 	const char *from_hdr = sipmsg_find_header(msg, "From");
 	gchar *from = parse_from(from_hdr);
@@ -1760,7 +1774,14 @@
 	if(sip) {
 		/* unregister */
 		if (sip->registerstatus == SIMPLE_REGISTER_COMPLETE)
+		{
+			if(purple_account_get_bool(sip->account, 
+				"dopublish", 
+				TRUE))
+				send_closed_publish(sip);
+			
 			do_register_exp(sip, 0);
+		}
 		connection_free_all(sip);
 
 		if (sip->query_data != NULL)
--- a/libpurple/protocols/toc/toc.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/toc/toc.c	Mon Oct 15 10:45:46 2007 +0000
@@ -2216,8 +2216,8 @@
 		g_snprintf(buf, sizeof(buf), _("%s requests you to send them a file"), ft->user);
 	}
 
-	purple_request_accept_cancel(ft->gc, NULL, buf, NULL, 
-							   PURPLE_DEFAULT_ACTION_NONE, ft,
+	purple_request_accept_cancel_with_hint(ft->gc, NULL, buf, NULL, 
+							   PURPLE_DEFAULT_ACTION_NONE, PURPLE_REQUEST_UI_HINT_XFER, ft,
 							   G_CALLBACK(toc_accept_ft),
 							   G_CALLBACK(toc_reject_ft));
 }
--- a/libpurple/protocols/yahoo/yahoo.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1028,12 +1028,12 @@
 static void
 yahoo_buddy_add_deny_reason_cb(gpointer data) {
 	struct yahoo_add_request *add_req = data;
-	purple_request_input(add_req->gc, NULL, _("Authorization denied message:"),
+	purple_request_input_with_hint(add_req->gc, NULL, _("Authorization denied message:"),
 			NULL, _("No reason given."), TRUE, FALSE, NULL,
 			_("OK"), G_CALLBACK(yahoo_buddy_add_deny_cb),
 			_("Cancel"), G_CALLBACK(yahoo_buddy_add_deny_noreason_cb),
 			purple_connection_get_account(add_req->gc), add_req->who, NULL,
-			add_req);
+			PURPLE_REQUEST_UI_HINT_BLIST, add_req);
 }
 
 static void yahoo_buddy_denied_our_add(PurpleConnection *gc, const char *who, const char *reason)
@@ -2065,9 +2065,9 @@
 		g_snprintf(buf, sizeof(buf), _("You have tried to ignore %s, but the "
 					"user is on your buddy list.  Clicking \"Yes\" "
 					"will remove and ignore the buddy."), who);
-		purple_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0,
+		purple_request_yes_no_with_hint(gc, NULL, _("Ignore buddy?"), buf, 0,
 						gc->account, who, NULL,
-						b,
+						PURPLE_REQUEST_UI_HINT_BLIST, b,
 						G_CALLBACK(ignore_buddy),
 						G_CALLBACK(keep_buddy));
 		break;
@@ -3501,23 +3501,23 @@
 static void yahoo_show_act_id(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_request_input(gc, NULL, _("Activate which ID?"), NULL,
+	purple_request_input_with_hint(gc, NULL, _("Activate which ID?"), NULL,
 					   purple_connection_get_display_name(gc), FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(yahoo_act_id),
 					   _("Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_ACCOUNT, gc);
 }
 
 static void yahoo_show_chat_goto(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_request_input(gc, NULL, _("Join whom in chat?"), NULL,
+	purple_request_input_with_hint(gc, NULL, _("Join who in chat?"), NULL,
 					   "", FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(yahoo_chat_goto),
 					   _("Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
-					   gc);
+					   PURPLE_REQUEST_UI_HINT_CONV, gc);
 }
 
 static GList *yahoo_actions(PurplePlugin *plugin, gpointer context) {
--- a/libpurple/prpl.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/prpl.h	Mon Oct 15 10:45:46 2007 +0000
@@ -226,11 +226,17 @@
 	void (*tooltip_text)(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full);
 
 	/**
-	 * This must be implemented, and must add at least the offline
-	 * and online states.
+	 * Returns a list of #PurpleStatusType which exist for this account;
+	 * this must be implemented, and must add at least the offline and
+	 * online states.
 	 */
 	GList *(*status_types)(PurpleAccount *account);
 
+	/**
+	 * Returns a list of #PurpleMenuAction structs, which represent extra
+	 * actions to be shown in (for example) the right-click menu for @a
+	 * node.
+	 */
 	GList *(*blist_node_menu)(PurpleBlistNode *node);
 	GList *(*chat_info)(PurpleConnection *);
 	GHashTable *(*chat_info_defaults)(PurpleConnection *, const char *chat_name);
@@ -258,6 +264,10 @@
 
 	void (*set_info)(PurpleConnection *, const char *info);
 	unsigned int (*send_typing)(PurpleConnection *, const char *name, PurpleTypingState state);
+	/**
+	 * Should arrange for purple_notify_userinfo() to be called with
+	 * @a who's user info.
+	 */
 	void (*get_info)(PurpleConnection *, const char *who);
 	void (*set_status)(PurpleAccount *account, PurpleStatus *status);
 
@@ -287,8 +297,14 @@
 	/** new user registration */
 	void (*register_user)(PurpleAccount *);
 
-	/* get "chat buddy" info and away message */
+	/**
+	 * @deprecated Use #PurplePluginProtocolInfo.get_info instead.
+	 */
 	void (*get_cb_info)(PurpleConnection *, int, const char *who);
+	/**
+	 * @deprecated Use #PurplePluginProtocolInfo.get_cb_real_name and
+	 *             #PurplePluginProtocolInfo.status_text instead.
+	 */
 	void (*get_cb_away)(PurpleConnection *, int, const char *who);
 
 	/** save/store buddy's alias on server list/roster */
@@ -348,9 +364,12 @@
 	/* room list serialize */
 	char *(*roomlist_room_serialize)(PurpleRoomlistRoom *room);
 
-	/* Remove the user from the server. (This is only at the bottom to keep binary compatibility.)
-	 * The account can either be connected or disconnected. After the removal is finished,
-	 * the connection will stay open and has to be closed!
+	/** Remove the user from the server.  The account can either be
+	 * connected or disconnected. After the removal is finished, the
+	 * connection will stay open and has to be closed!
+	 */
+	/* This is here rather than next to register_user for API compatibility
+	 * reasons.
 	 */
 	void (*unregister_user)(PurpleAccount *, PurpleAccountUnregistrationCb cb, void *user_data);
 	
--- a/libpurple/request.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/request.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1228,6 +1228,20 @@
 				   PurpleAccount *account, const char *who, PurpleConversation *conv,
 				   void *user_data)
 {
+	return purple_request_input_with_hint(
+		handle, title, primary, secondary, default_value, multiline, masked, hint, ok_text, ok_cb,
+		cancel_text, cancel_cb, account, who, conv, PURPLE_REQUEST_UI_HINT_BLIST, user_data);
+}
+
+void *
+purple_request_input_with_hint(void *handle, const char *title, const char *primary,
+				   const char *secondary, const char *default_value,
+				   gboolean multiline, gboolean masked, gchar *hint,
+				   const char *ok_text, GCallback ok_cb,
+				   const char *cancel_text, GCallback cancel_cb,
+				   PurpleAccount *account, const char *who, PurpleConversation *conv,
+				   const char *ui_hint, void *user_data)
+{
 	PurpleRequestUiOps *ops;
 
 	g_return_val_if_fail(ok_text != NULL, NULL);
@@ -1247,7 +1261,7 @@
 											 ok_text, ok_cb,
 											 cancel_text, cancel_cb,
 											 account, who, conv,
-											 user_data);
+											 ui_hint, user_data);
 
 		handles = g_list_append(handles, info);
 
@@ -1272,10 +1286,34 @@
 	g_return_val_if_fail(ok_cb   != NULL,  NULL);
 
 	va_start(args, user_data);
-	ui_handle = purple_request_choice_varg(handle, title, primary, secondary,
+	ui_handle = purple_request_choice_varg_with_hint(handle, title, primary, secondary,
 					     default_value, ok_text, ok_cb,
 					     cancel_text, cancel_cb,
-					     account, who, conv, user_data, args);
+					     account, who, conv, PURPLE_REQUEST_UI_HINT_BLIST, user_data, args);
+	va_end(args);
+
+	return ui_handle;
+}
+
+void *
+purple_request_choice_with_hint(void *handle, const char *title, const char *primary,
+					const char *secondary, int default_value,
+					const char *ok_text, GCallback ok_cb,
+					const char *cancel_text, GCallback cancel_cb,
+					PurpleAccount *account, const char *who, PurpleConversation *conv,
+					const char *ui_hint, void *user_data, ...)
+{
+	void *ui_handle;
+	va_list args;
+
+	g_return_val_if_fail(ok_text != NULL,  NULL);
+	g_return_val_if_fail(ok_cb   != NULL,  NULL);
+
+	va_start(args, user_data);
+	ui_handle = purple_request_choice_varg_with_hint(handle, title, primary, secondary,
+					     default_value, ok_text, ok_cb,
+					     cancel_text, cancel_cb,
+					     account, who, conv, ui_hint, user_data, args);
 	va_end(args);
 
 	return ui_handle;
@@ -1290,6 +1328,20 @@
 			 PurpleAccount *account, const char *who, PurpleConversation *conv,
 			 void *user_data, va_list choices)
 {
+	return purple_request_choice_varg_with_hint(
+		handle, title, primary, secondary, default_value, ok_text, ok_cb,
+		cancel_text, cancel_cb, account, who, conv, PURPLE_REQUEST_UI_HINT_BLIST, user_data, choices);
+}
+
+void *
+purple_request_choice_varg_with_hint(void *handle, const char *title,
+			 const char *primary, const char *secondary,
+			 int default_value,
+			 const char *ok_text, GCallback ok_cb,
+			 const char *cancel_text, GCallback cancel_cb,
+			 PurpleAccount *account, const char *who, PurpleConversation *conv,
+			 const char *ui_hint, void *user_data, va_list choices)
+{
 	PurpleRequestUiOps *ops;
 
 	g_return_val_if_fail(ok_text != NULL,  NULL);
@@ -1308,7 +1360,7 @@
 						      ok_text, ok_cb,
 						      cancel_text, cancel_cb,
 							  account, who, conv,
-						      user_data, choices);
+						      ui_hint, user_data, choices);
 
 		handles = g_list_append(handles, info);
 
@@ -1330,9 +1382,29 @@
 	g_return_val_if_fail(action_count > 0, NULL);
 
 	va_start(args, action_count);
-	ui_handle = purple_request_action_varg(handle, title, primary, secondary,
+	ui_handle = purple_request_action_varg_with_hint(handle, title, primary, secondary,
 										 default_action, account, who, conv,
-										 user_data, action_count, args);
+										 PURPLE_REQUEST_UI_HINT_BLIST, user_data, action_count, args);
+	va_end(args);
+
+	return ui_handle;
+}
+
+void *
+purple_request_action_with_hint(void *handle, const char *title, const char *primary,
+					const char *secondary, int default_action,
+					PurpleAccount *account, const char *who, PurpleConversation *conv,
+					const char *ui_hint, void *user_data, size_t action_count, ...)
+{
+	void *ui_handle;
+	va_list args;
+
+	g_return_val_if_fail(action_count > 0, NULL);
+
+	va_start(args, action_count);
+	ui_handle = purple_request_action_varg_with_hint(handle, title, primary, secondary,
+										 default_action, account, who, conv,
+										 ui_hint, user_data, action_count, args);
 	va_end(args);
 
 	return ui_handle;
@@ -1343,7 +1415,19 @@
 						 const char *primary, const char *secondary,
 						 int default_action,
 						 PurpleAccount *account, const char *who, PurpleConversation *conv,
-						  void *user_data, size_t action_count, va_list actions)
+						 void *user_data, size_t action_count, va_list actions)
+{
+	return purple_request_action_varg_with_hint(
+		handle, title, primary, secondary, default_action, account, who, conv,
+		PURPLE_REQUEST_UI_HINT_BLIST, user_data, action_count, actions);
+}
+
+void *
+purple_request_action_varg_with_hint(void *handle, const char *title,
+						 const char *primary, const char *secondary,
+						 int default_action,
+						 PurpleAccount *account, const char *who, PurpleConversation *conv,
+						 const char *ui_hint, void *user_data, size_t action_count, va_list actions)
 {
 	PurpleRequestUiOps *ops;
 
@@ -1359,7 +1443,7 @@
 		info->handle    = handle;
 		info->ui_handle = ops->request_action(title, primary, secondary,
 											  default_action, account, who, conv,
-											  user_data, action_count, actions);
+											  ui_hint, user_data, action_count, actions);
 
 		handles = g_list_append(handles, info);
 
@@ -1377,6 +1461,19 @@
 					PurpleAccount *account, const char *who, PurpleConversation *conv,
 					void *user_data)
 {
+	return purple_request_fields_with_hint(
+		handle, title, primary, secondary, fields, ok_text, ok_cb,
+		cancel_text, cancel_cb, account, who, conv, PURPLE_REQUEST_UI_HINT_BLIST, user_data);
+}
+
+void *
+purple_request_fields_with_hint(void *handle, const char *title, const char *primary,
+					const char *secondary, PurpleRequestFields *fields,
+					const char *ok_text, GCallback ok_cb,
+					const char *cancel_text, GCallback cancel_cb,
+					PurpleAccount *account, const char *who, PurpleConversation *conv,
+					const char *ui_hint, void *user_data)
+{
 	PurpleRequestUiOps *ops;
 
 	g_return_val_if_fail(fields  != NULL, NULL);
@@ -1395,7 +1492,7 @@
 											  fields, ok_text, ok_cb,
 											  cancel_text, cancel_cb,
 											  account, who, conv,
-											  user_data);
+											  ui_hint, user_data);
 
 		handles = g_list_append(handles, info);
 
@@ -1412,6 +1509,17 @@
 				  PurpleAccount *account, const char *who, PurpleConversation *conv,
 				  void *user_data)
 {
+	return purple_request_file_with_hint(
+		handle, title, filename, savedialog, ok_cb, cancel_cb, account, who, conv, PURPLE_REQUEST_UI_HINT_BLIST, user_data);
+}
+
+void *
+purple_request_file_with_hint(void *handle, const char *title, const char *filename,
+				  gboolean savedialog,
+				  GCallback ok_cb, GCallback cancel_cb,
+				  PurpleAccount *account, const char *who, PurpleConversation *conv,
+				  const char *ui_hint, void *user_data)
+{
 	PurpleRequestUiOps *ops;
 
 	ops = purple_request_get_ui_ops();
@@ -1424,7 +1532,7 @@
 		info->handle    = handle;
 		info->ui_handle = ops->request_file(title, filename, savedialog,
 											ok_cb, cancel_cb,
-											account, who, conv, user_data);
+											account, who, conv, ui_hint, user_data);
 		handles = g_list_append(handles, info);
 		return info->ui_handle;
 	}
@@ -1438,6 +1546,16 @@
 				  PurpleAccount *account, const char *who, PurpleConversation *conv,
 				  void *user_data)
 {
+	return purple_request_folder_with_hint(
+		handle, title, dirname, ok_cb, cancel_cb, account, who, conv, PURPLE_REQUEST_UI_HINT_BLIST, user_data);
+}
+
+void *
+purple_request_folder_with_hint(void *handle, const char *title, const char *dirname,
+				  GCallback ok_cb, GCallback cancel_cb,
+				  PurpleAccount *account, const char *who, PurpleConversation *conv,
+				  const char *ui_hint, void *user_data)
+{
 	PurpleRequestUiOps *ops;
 
 	ops = purple_request_get_ui_ops();
@@ -1451,7 +1569,7 @@
 		info->ui_handle = ops->request_folder(title, dirname,
 											ok_cb, cancel_cb,
 											account, who, conv,
-											user_data);
+											ui_hint, user_data);
 		handles = g_list_append(handles, info);
 		return info->ui_handle;
 	}
--- a/libpurple/request.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/request.h	Mon Oct 15 10:45:46 2007 +0000
@@ -198,6 +198,77 @@
 
 } PurpleRequestField;
 
+/*
+ * UI hints for the request functions.  These are used by libpurple.
+ */
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_ACCOUNT  "account"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_BLIST    "blist"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_BUDDY    "buddy"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_CONV     "conversation"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_REGISTER "register-account"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_XFER     "xfer"
+
+
+/*
+ * UI hints for the request functions.  These are common hints used by UIs.
+ * UIs can still define any hints they like, but standardization is good.
+ */
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_ACCOUNTMGR "accountmgr"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_CERTMGR    "certmgr"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_PLUGINMGR  "pluginmgr"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_POUNCEMGR  "pouncemgr"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_PREFSMGR   "preferences"
+
+/**
+ * @since 2.3.0
+ */
+#define PURPLE_REQUEST_UI_HINT_STATUSMGR  "statusmgr"
+
+
 /**
  * Request UI operations.
  */
@@ -209,33 +280,33 @@
 						   const char *ok_text, GCallback ok_cb,
 						   const char *cancel_text, GCallback cancel_cb,
 						   PurpleAccount *account, const char *who, PurpleConversation *conv,
-						   void *user_data);
+						   const char *ui_hint, void *user_data);
 	void *(*request_choice)(const char *title, const char *primary,
 							const char *secondary, int default_value,
 							const char *ok_text, GCallback ok_cb,
 							const char *cancel_text, GCallback cancel_cb,
 							PurpleAccount *account, const char *who, PurpleConversation *conv,
-							void *user_data, va_list choices);
+							const char *ui_hint, void *user_data, va_list choices);
 	void *(*request_action)(const char *title, const char *primary,
 							const char *secondary, int default_action,
 							PurpleAccount *account, const char *who, PurpleConversation *conv,
-							void *user_data, size_t action_count,
+							const char *ui_hint, void *user_data, size_t action_count,
 							va_list actions);
 	void *(*request_fields)(const char *title, const char *primary,
 							const char *secondary, PurpleRequestFields *fields,
 							const char *ok_text, GCallback ok_cb,
 							const char *cancel_text, GCallback cancel_cb,
 							PurpleAccount *account, const char *who, PurpleConversation *conv,
-							void *user_data);
+							const char *ui_hint, void *user_data);
 	void *(*request_file)(const char *title, const char *filename,
 						  gboolean savedialog, GCallback ok_cb, GCallback cancel_cb,
 						  PurpleAccount *account, const char *who, PurpleConversation *conv,
-						  void *user_data);
+						  const char *ui_hint, void *user_data);
 	void (*close_request)(PurpleRequestType type, void *ui_handle);
 	void *(*request_folder)(const char *title, const char *dirname,
 							GCallback ok_cb, GCallback cancel_cb,
 							PurpleAccount *account, const char *who, PurpleConversation *conv,
-							void *user_data);
+							const char *ui_hint, void *user_data);
 
 	void (*_purple_reserved1)(void);
 	void (*_purple_reserved2)(void);
@@ -1299,9 +1370,60 @@
  * @param account		The PurpleAccount associated with this request, or NULL if none is
  * @param who			The username of the buddy assocaited with this request, or NULL if none is
  * @param conv			The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint       UI hint
  * @param user_data     The data to pass to the callback.
  *
  * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_input_with_hint(void *handle, const char *title,
+						 const char *primary, const char *secondary,
+						 const char *default_value,
+						 gboolean multiline, gboolean masked, gchar *hint,
+						 const char *ok_text, GCallback ok_cb,
+						 const char *cancel_text, GCallback cancel_cb,
+						 PurpleAccount *account, const char *who, PurpleConversation *conv,
+						 const char *ui_hint, void *user_data);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Prompts the user for text input.
+ *
+ * @param handle        The plugin or connection handle.  For some
+ *                      things this is EXTREMELY important.  The
+ *                      handle is used to programmatically close
+ *                      the request dialog when it is no longer
+ *                      needed.  For PRPLs this is often a pointer
+ *                      to the PurpleConnection instance.  For plugins
+ *                      this should be a similar, unique memory
+ *                      location.  This value is important because
+ *                      it allows a request to be closed, say, when
+ *                      you sign offline.  If the request is NOT
+ *                      closed it is VERY likely to cause a crash
+ *                      whenever the callback handler functions are
+ *                      triggered.
+ * @param title         The title of the message.
+ * @param primary       The main point of the message.
+ * @param secondary     The secondary information.
+ * @param default_value The default value.
+ * @param multiline     TRUE if the inputted text can span multiple lines.
+ * @param masked        TRUE if the inputted text should be masked in some way.
+ * @param hint          Optionally suggest how the input box should appear.
+ *                      Use "html," for example, to allow the user to enter
+ *                      HTML.
+ * @param ok_text       The text for the @c OK button.
+ * @param ok_cb         The callback for the @c OK button.
+ * @param cancel_text   The text for the @c Cancel button.
+ * @param cancel_cb     The callback for the @c Cancel button.
+ * @param account		The PurpleAccount associated with this request, or NULL if none is
+ * @param who			The username of the buddy assocaited with this request, or NULL if none is
+ * @param conv			The PurpleConversation associated with this request, or NULL if none is
+ * @param user_data     The data to pass to the callback.
+ *
+ * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_input_with_hint() instead.
  */
 void *purple_request_input(void *handle, const char *title,
 						 const char *primary, const char *secondary,
@@ -1311,6 +1433,7 @@
 						 const char *cancel_text, GCallback cancel_cb,
 						 PurpleAccount *account, const char *who, PurpleConversation *conv,
 						 void *user_data);
+#endif
 
 /**
  * Prompts the user for multiple-choice input.
@@ -1329,11 +1452,48 @@
  * @param account		The PurpleAccount associated with this request, or NULL if none is
  * @param who			The username of the buddy assocaited with this request, or NULL if none is
  * @param conv			The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint       UI hint
+ * @param user_data     The data to pass to the callback.
+ * @param ...           The choices.  This argument list should be
+ *                      terminated with a NULL parameter.
+ *
+ * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_choice_with_hint(void *handle, const char *title,
+						  const char *primary, const char *secondary,
+						  int default_value,
+						  const char *ok_text, GCallback ok_cb,
+						  const char *cancel_text, GCallback cancel_cb,
+						  PurpleAccount *account, const char *who, PurpleConversation *conv,
+						  const char *ui_hint, void *user_data, ...) G_GNUC_NULL_TERMINATED;
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Prompts the user for multiple-choice input.
+ *
+ * @param handle        The plugin or connection handle.  For some
+ *                      things this is EXTREMELY important.  See
+ *                      the comments on purple_request_input.
+ * @param title         The title of the message.
+ * @param primary       The main point of the message.
+ * @param secondary     The secondary information.
+ * @param default_value The default value.
+ * @param ok_text       The text for the @c OK button.
+ * @param ok_cb         The callback for the @c OK button.
+ * @param cancel_text   The text for the @c Cancel button.
+ * @param cancel_cb     The callback for the @c Cancel button.
+ * @param account		The PurpleAccount associated with this request, or NULL if none is
+ * @param who			The username of the buddy assocaited with this request, or NULL if none is
+ * @param conv			The PurpleConversation associated with this request, or NULL if none is
  * @param user_data     The data to pass to the callback.
  * @param ...           The choices.  This argument list should be
  *                      terminated with a NULL parameter.
  *
  * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_choice_with_hint() instead.
  */
 void *purple_request_choice(void *handle, const char *title,
 						  const char *primary, const char *secondary,
@@ -1342,6 +1502,7 @@
 						  const char *cancel_text, GCallback cancel_cb,
 						  PurpleAccount *account, const char *who, PurpleConversation *conv,
 						  void *user_data, ...) G_GNUC_NULL_TERMINATED;
+#endif
 
 /**
  * Prompts the user for multiple-choice input.
@@ -1360,11 +1521,48 @@
  * @param account		The PurpleAccount associated with this request, or NULL if none is
  * @param who			The username of the buddy assocaited with this request, or NULL if none is
  * @param conv			The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint       UI hint
+ * @param user_data     The data to pass to the callback.
+ * @param choices       The choices.  This argument list should be
+ *                      terminated with a @c NULL parameter.
+ *
+ * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_choice_varg_with_hint(void *handle, const char *title,
+							   const char *primary, const char *secondary,
+							   int default_value,
+							   const char *ok_text, GCallback ok_cb,
+							   const char *cancel_text, GCallback cancel_cb,
+							   PurpleAccount *account, const char *who, PurpleConversation *conv,
+							   const char *ui_hint, void *user_data, va_list choices);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Prompts the user for multiple-choice input.
+ *
+ * @param handle        The plugin or connection handle.  For some
+ *                      things this is EXTREMELY important.  See
+ *                      the comments on purple_request_input.
+ * @param title         The title of the message.
+ * @param primary       The main point of the message.
+ * @param secondary     The secondary information.
+ * @param default_value The default value.
+ * @param ok_text       The text for the @c OK button.
+ * @param ok_cb         The callback for the @c OK button.
+ * @param cancel_text   The text for the @c Cancel button.
+ * @param cancel_cb     The callback for the @c Cancel button.
+ * @param account		The PurpleAccount associated with this request, or NULL if none is
+ * @param who			The username of the buddy assocaited with this request, or NULL if none is
+ * @param conv			The PurpleConversation associated with this request, or NULL if none is
  * @param user_data     The data to pass to the callback.
  * @param choices       The choices.  This argument list should be
  *                      terminated with a @c NULL parameter.
  *
  * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_choice_varg_with_hint() instead.
  */
 void *purple_request_choice_varg(void *handle, const char *title,
 							   const char *primary, const char *secondary,
@@ -1373,6 +1571,7 @@
 							   const char *cancel_text, GCallback cancel_cb,
 							   PurpleAccount *account, const char *who, PurpleConversation *conv,
 							   void *user_data, va_list choices);
+#endif
 
 /**
  * Prompts the user for an action.
@@ -1389,6 +1588,43 @@
  * @param account		 The PurpleAccount associated with this request, or NULL if none is
  * @param who			 The username of the buddy assocaited with this request, or NULL if none is
  * @param conv			 The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint        UI hint
+ * @param user_data      The data to pass to the callback.
+ * @param action_count   The number of actions.
+ * @param ...            A list of actions.  These are pairs of
+ *                       arguments.  The first of each pair is the
+ *                       string that appears on the button.  It should
+ *                       have an underscore before the letter you want
+ *                       to use as the accelerator key for the button.
+ *                       The second of each pair is the callback
+ *                       function to use when the button is clicked.
+ *
+ * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_action_with_hint(void *handle, const char *title,
+						  const char *primary, const char *secondary,
+						  int default_action,
+						  PurpleAccount *account, const char *who, PurpleConversation *conv,
+						  const char *ui_hint, void *user_data, size_t action_count, ...);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Prompts the user for an action.
+ *
+ * This is often represented as a dialog with a button for each action.
+ *
+ * @param handle         The plugin or connection handle.  For some
+ *                       things this is EXTREMELY important.  See
+ *                       the comments on purple_request_input.
+ * @param title          The title of the message.
+ * @param primary        The main point of the message.
+ * @param secondary      The secondary information.
+ * @param default_action The default value.
+ * @param account		 The PurpleAccount associated with this request, or NULL if none is
+ * @param who			 The username of the buddy assocaited with this request, or NULL if none is
+ * @param conv			 The PurpleConversation associated with this request, or NULL if none is
  * @param user_data      The data to pass to the callback.
  * @param action_count   The number of actions.
  * @param ...            A list of actions.  These are pairs of
@@ -1400,12 +1636,15 @@
  *                       function to use when the button is clicked.
  *
  * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_action_with_hint() instead.
  */
 void *purple_request_action(void *handle, const char *title,
 						  const char *primary, const char *secondary,
 						  int default_action,
 						  PurpleAccount *account, const char *who, PurpleConversation *conv,
 						  void *user_data, size_t action_count, ...);
+#endif
 
 /**
  * Prompts the user for an action.
@@ -1422,11 +1661,45 @@
  * @param account		 The PurpleAccount associated with this request, or NULL if none is
  * @param who			 The username of the buddy assocaited with this request, or NULL if none is
  * @param conv			 The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint        UI hint
+ * @param user_data      The data to pass to the callback.
+ * @param action_count   The number of actions.
+ * @param actions        A list of actions and callbacks.
+ *
+ * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_action_varg_with_hint(void *handle, const char *title,
+							   const char *primary, const char *secondary,
+							   int default_action,
+							   PurpleAccount *account, const char *who, PurpleConversation *conv,
+							   const char *ui_hint, void *user_data, size_t action_count,
+							   va_list actions);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Prompts the user for an action.
+ *
+ * This is often represented as a dialog with a button for each action.
+ *
+ * @param handle         The plugin or connection handle.  For some
+ *                       things this is EXTREMELY important.  See
+ *                       the comments on purple_request_input.
+ * @param title          The title of the message.
+ * @param primary        The main point of the message.
+ * @param secondary      The secondary information.
+ * @param default_action The default value.
+ * @param account		 The PurpleAccount associated with this request, or NULL if none is
+ * @param who			 The username of the buddy assocaited with this request, or NULL if none is
+ * @param conv			 The PurpleConversation associated with this request, or NULL if none is
  * @param user_data      The data to pass to the callback.
  * @param action_count   The number of actions.
  * @param actions        A list of actions and callbacks.
  *
  * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_action_varg_with_hint() instead.
  */
 void *purple_request_action_varg(void *handle, const char *title,
 							   const char *primary, const char *secondary,
@@ -1434,6 +1707,7 @@
 							   PurpleAccount *account, const char *who, PurpleConversation *conv,
 							   void *user_data, size_t action_count,
 							   va_list actions);
+#endif
 
 /**
  * Displays groups of fields for the user to fill in.
@@ -1452,9 +1726,44 @@
  * @param account	  The PurpleAccount associated with this request, or NULL if none is
  * @param who		  The username of the buddy associated with this request, or NULL if none is
  * @param conv		  The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint     UI hint
+ * @param user_data   The data to pass to the callback.
+ *
+ * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_fields_with_hint(void *handle, const char *title,
+						  const char *primary, const char *secondary,
+						  PurpleRequestFields *fields,
+						  const char *ok_text, GCallback ok_cb,
+						  const char *cancel_text, GCallback cancel_cb,
+						  PurpleAccount *account, const char *who, PurpleConversation *conv,
+						  const char *ui_hint, void *user_data);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Displays groups of fields for the user to fill in.
+ *
+ * @param handle      The plugin or connection handle.  For some
+ *                    things this is EXTREMELY important.  See
+ *                    the comments on purple_request_input.
+ * @param title       The title of the message.
+ * @param primary     The main point of the message.
+ * @param secondary   The secondary information.
+ * @param fields      The list of fields.
+ * @param ok_text     The text for the @c OK button.
+ * @param ok_cb       The callback for the @c OK button.
+ * @param cancel_text The text for the @c Cancel button.
+ * @param cancel_cb   The callback for the @c Cancel button.
+ * @param account	  The PurpleAccount associated with this request, or NULL if none is
+ * @param who		  The username of the buddy associated with this request, or NULL if none is
+ * @param conv		  The PurpleConversation associated with this request, or NULL if none is
  * @param user_data   The data to pass to the callback.
  *
  * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_fields_with_hint() instead.
  */
 void *purple_request_fields(void *handle, const char *title,
 						  const char *primary, const char *secondary,
@@ -1463,6 +1772,7 @@
 						  const char *cancel_text, GCallback cancel_cb,
 						  PurpleAccount *account, const char *who, PurpleConversation *conv,
 						  void *user_data);
+#endif
 
 /**
  * Closes a request.
@@ -1481,6 +1791,21 @@
 
 /**
  * A wrapper for purple_request_action() that uses @c Yes and @c No buttons.
+ *
+ * @since 2.3.0
+ */
+#define purple_request_yes_no_with_hint(handle, title, primary, secondary, \
+							default_action, account, who, conv, \
+							ui_hint, user_data, yes_cb, no_cb) \
+	purple_request_action_with_hint((handle), (title), (primary), (secondary), \
+						(default_action), account, who, conv, (ui_hint), (user_data), 2, \
+						_("_Yes"), (yes_cb), _("_No"), (no_cb))
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * A wrapper for purple_request_action() that uses @c Yes and @c No buttons.
+ *
+ * @deprecated Please use purple_request_yes_no_with_hint instead.
  */
 #define purple_request_yes_no(handle, title, primary, secondary, \
 							default_action, account, who, conv, \
@@ -1488,9 +1813,25 @@
 	purple_request_action((handle), (title), (primary), (secondary), \
 						(default_action), account, who, conv, (user_data), 2, \
 						_("_Yes"), (yes_cb), _("_No"), (no_cb))
+#endif
 
 /**
  * A wrapper for purple_request_action() that uses @c OK and @c Cancel buttons.
+ *
+ * @since 2.3.0
+ */
+#define purple_request_ok_cancel_with_hint(handle, title, primary, secondary, \
+							default_action, account, who, conv, \
+						    ui_hint, user_data, ok_cb, cancel_cb) \
+	purple_request_action_with_hint((handle), (title), (primary), (secondary), \
+						(default_action), account, who, conv, (ui_hint), (user_data), 2, \
+						_("_OK"), (ok_cb), _("_Cancel"), (cancel_cb))
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * A wrapper for purple_request_action() that uses @c OK and @c Cancel buttons.
+ *
+ * @deprecated Please use purple_request_ok_cancel_with_hint instead.
  */
 #define purple_request_ok_cancel(handle, title, primary, secondary, \
 							default_action, account, who, conv, \
@@ -1498,9 +1839,25 @@
 	purple_request_action((handle), (title), (primary), (secondary), \
 						(default_action), account, who, conv, (user_data), 2, \
 						_("_OK"), (ok_cb), _("_Cancel"), (cancel_cb))
+#endif
 
 /**
  * A wrapper for purple_request_action() that uses Accept and Cancel buttons.
+ *
+ * @since 2.3.0
+ */
+#define purple_request_accept_cancel_with_hint(handle, title, primary, secondary, \
+								   default_action, account, who, conv, \
+								   ui_hint, user_data, accept_cb, cancel_cb) \
+	purple_request_action_with_hint((handle), (title), (primary), (secondary), \
+						(default_action), account, who, conv, (ui_hint), (user_data), 2, \
+						_("_Accept"), (accept_cb), _("_Cancel"), (cancel_cb))
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * A wrapper for purple_request_action() that uses Accept and Cancel buttons.
+ *
+ * @deprecated Please use purple_request_accept_cancel_with_hint instead.
  */
 #define purple_request_accept_cancel(handle, title, primary, secondary, \
 								   default_action, account, who, conv, \
@@ -1508,6 +1865,7 @@
 	purple_request_action((handle), (title), (primary), (secondary), \
 						(default_action), account, who, conv, (user_data), 2, \
 						_("_Accept"), (accept_cb), _("_Cancel"), (cancel_cb))
+#endif
 
 /**
  * Displays a file selector request dialog.  Returns the selected filename to
@@ -1525,15 +1883,48 @@
  * @param account	  The PurpleAccount associated with this request, or NULL if none is
  * @param who		  The username of the buddy assocaited with this request, or NULL if none is
  * @param conv		  The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint     UI hint
+ * @param user_data   The data to pass to the callback.
+ *
+ * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_file_with_hint(void *handle, const char *title, const char *filename,
+						gboolean savedialog,
+						GCallback ok_cb, GCallback cancel_cb,
+						PurpleAccount *account, const char *who, PurpleConversation *conv,
+						const char *ui_hint, void *user_data);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Displays a file selector request dialog.  Returns the selected filename to
+ * the callback.  Can be used for either opening a file or saving a file.
+ *
+ * @param handle      The plugin or connection handle.  For some
+ *                    things this is EXTREMELY important.  See
+ *                    the comments on purple_request_input.
+ * @param title       The title for the dialog (may be @c NULL)
+ * @param filename    The default filename (may be @c NULL)
+ * @param savedialog  True if this dialog is being used to save a file.
+ *                    False if it is being used to open a file.
+ * @param ok_cb       The callback for the @c OK button.
+ * @param cancel_cb   The callback for the @c Cancel button.
+ * @param account	  The PurpleAccount associated with this request, or NULL if none is
+ * @param who		  The username of the buddy assocaited with this request, or NULL if none is
+ * @param conv		  The PurpleConversation associated with this request, or NULL if none is
  * @param user_data   The data to pass to the callback.
  *
  * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_file_with_hint() instead.
  */
 void *purple_request_file(void *handle, const char *title, const char *filename,
 						gboolean savedialog,
 						GCallback ok_cb, GCallback cancel_cb,
 						PurpleAccount *account, const char *who, PurpleConversation *conv,
 						void *user_data);
+#endif
 
 /**
  * Displays a folder select dialog. Returns the selected filename to
@@ -1549,14 +1940,44 @@
  * @param account	  The PurpleAccount associated with this request, or NULL if none is
  * @param who		  The username of the buddy assocaited with this request, or NULL if none is
  * @param conv		  The PurpleConversation associated with this request, or NULL if none is
+ * @param ui_hint     UI hint
+ * @param user_data   The data to pass to the callback.
+ *
+ * @return A UI-specific handle.
+ *
+ * @since 2.3.0
+ */
+void *purple_request_folder_with_hint(void *handle, const char *title, const char *dirname,
+						GCallback ok_cb, GCallback cancel_cb,
+						PurpleAccount *account, const char *who, PurpleConversation *conv,
+						const char *ui_hint, void *user_data);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Displays a folder select dialog. Returns the selected filename to
+ * the callback.
+ *
+ * @param handle      The plugin or connection handle.  For some
+ *                    things this is EXTREMELY important.  See
+ *                    the comments on purple_request_input.
+ * @param title       The title for the dialog (may be @c NULL)
+ * @param dirname     The default directory name (may be @c NULL)
+ * @param ok_cb       The callback for the @c OK button.
+ * @param cancel_cb   The callback for the @c Cancel button.
+ * @param account	  The PurpleAccount associated with this request, or NULL if none is
+ * @param who		  The username of the buddy assocaited with this request, or NULL if none is
+ * @param conv		  The PurpleConversation associated with this request, or NULL if none is
  * @param user_data   The data to pass to the callback.
  *
  * @return A UI-specific handle.
+ *
+ * @deprecated Please use purple_request_folder_with_hint() instead.
  */
 void *purple_request_folder(void *handle, const char *title, const char *dirname,
 						GCallback ok_cb, GCallback cancel_cb,
 						PurpleAccount *account, const char *who, PurpleConversation *conv,
 						void *user_data);
+#endif
 
 /*@}*/
 
--- a/libpurple/server.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/server.c	Mon Oct 15 10:45:46 2007 +0000
@@ -799,9 +799,9 @@
 				   who, purple_account_get_username(account), name);
 
 
-		purple_request_accept_cancel(gc, NULL, _("Accept chat invitation?"), buf2,
+		purple_request_accept_cancel_with_hint(gc, NULL, _("Accept chat invitation?"), buf2,
 							   PURPLE_DEFAULT_ACTION_NONE, account, who, NULL,
-							   cid, G_CALLBACK(chat_invite_accept),
+							   "chat", cid, G_CALLBACK(chat_invite_accept),
 							   G_CALLBACK(chat_invite_reject));
 	}
 	else if (plugin_return > 0)
--- a/libpurple/util.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/util.c	Mon Oct 15 10:45:46 2007 +0000
@@ -70,6 +70,7 @@
 static char *custom_user_dir = NULL;
 static char *user_dir = NULL;
 
+
 PurpleMenuAction *
 purple_menu_action_new(const char *label, PurpleCallback callback, gpointer data,
                      GList *children)
@@ -91,6 +92,25 @@
 	g_free(act);
 }
 
+void
+purple_util_init(void)
+{
+	/* This does nothing right now.  It exists for symmetry with 
+	 * purple_util_uninit() and forwards compatibility. */
+}
+
+void
+purple_util_uninit(void)
+{
+	/* Free these so we don't have leaks at shutdown. */
+
+	g_free(custom_user_dir);
+	custom_user_dir = NULL;
+
+	g_free(user_dir);
+	user_dir = NULL;
+}
+
 /**************************************************************************
  * Base16 Functions
  **************************************************************************/
@@ -2565,6 +2585,8 @@
 	purple_debug_info("util", "Writing file %s\n",
 					filename_full);
 
+	g_return_val_if_fail((size >= -1), FALSE);
+
 	filename_temp = g_strdup_printf("%s.save", filename_full);
 
 	/* Remove an old temporary file, if one exists */
@@ -2590,7 +2612,7 @@
 	}
 
 	/* Write to file */
-	real_size = (size == -1) ? strlen(data) : size;
+	real_size = (size == -1) ? strlen(data) : (size_t) size;
 	byteswritten = fwrite(data, 1, real_size, file);
 
 	/* Close file */
--- a/libpurple/util.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/libpurple/util.h	Mon Oct 15 10:45:46 2007 +0000
@@ -86,6 +86,27 @@
 void purple_menu_action_free(PurpleMenuAction *act);
 
 /**************************************************************************/
+/** @name Utility Subsystem                                               */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Initializes the utility subsystem.
+ *
+ * @since 2.3.0
+ */
+void purple_util_init(void);
+
+/**
+ * Uninitializes the util subsystem.
+ *
+ * @since 2.3.0
+ */
+void purple_util_uninit(void);
+
+/*@}*/
+
+/**************************************************************************/
 /** @name Base16 Functions                                                */
 /**************************************************************************/
 /*@{*/
--- a/pidgin/gtkaccount.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkaccount.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1902,9 +1902,9 @@
 							  purple_account_get_username(account));
 
 		purple_request_close_with_handle(account);
-		purple_request_action(account, NULL, buf, NULL, 0,
+		purple_request_action_with_hint(account, NULL, buf, NULL, 0,
 							account, NULL, NULL,
-							account, 2,
+							PURPLE_REQUEST_UI_HINT_ACCOUNTMGR, account, 2,
 							_("Delete"), delete_account_cb,
 							_("Cancel"), NULL);
 		g_free(buf);
--- a/pidgin/gtkblist.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkblist.c	Mon Oct 15 10:45:46 2007 +0000
@@ -522,9 +522,9 @@
 	if (i > 1)
 	{
 		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. "
+		purple_request_action_with_hint(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));
+				      PURPLE_REQUEST_UI_HINT_BLIST, merges, 2, _("_Merge"), PURPLE_CALLBACK(gtk_blist_do_personize), _("_Cancel"), PURPLE_CALLBACK(g_list_free));
 		g_free(msg);
 	} else
 		g_list_free(merges);
@@ -617,7 +617,7 @@
 
 static void gtk_blist_menu_bp_cb(GtkWidget *w, PurpleBuddy *b)
 {
-	pidgin_pounce_editor_show(b->account, b->name, NULL);
+	pidgin_pounce_editor_show_with_parent(GTK_WINDOW(gtkblist->window), b->account, b->name, NULL);
 }
 
 static void gtk_blist_menu_showlog_cb(GtkWidget *w, PurpleBlistNode *node)
@@ -643,7 +643,7 @@
 			name = prpl_info->get_chat_name(c->components);
 		}
 	} else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
-		pidgin_log_show_contact((PurpleContact *)node);
+		pidgin_log_show_contact_with_parent(GTK_WINDOW(gtkblist->window), (PurpleContact *)node);
 		pidgin_clear_cursor(gtkblist->window);
 		return;
 	} else {
@@ -655,7 +655,7 @@
 	}
 
 	if (name && account) {
-		pidgin_log_show(type, name, account);
+		pidgin_log_show_with_parent(GTK_WINDOW(gtkblist->window), type, name, account);
 		g_free(name);
 
 		pidgin_clear_cursor(gtkblist->window);
@@ -682,11 +682,6 @@
 	pidgin_blist_update(purple_get_blist(), node);
 }
 
-static void gtk_blist_show_systemlog_cb()
-{
-	pidgin_syslog_show();
-}
-
 static void gtk_blist_show_onlinehelp_cb()
 {
 	purple_notify_uri(NULL, PURPLE_WEBSITE "documentation");
@@ -3057,6 +3052,11 @@
 			!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled"));
 }
 
+static void
+pidgin_blist_show_with_parent(gpointer data1, void (*callback)(GtkWindow *parent), gpointer data3)
+{
+	callback(GTK_WINDOW(gtkblist->window));
+}
 
 /***************************************************
  *            Crap                                 *
@@ -3090,15 +3090,15 @@
 
 	/* Tools */
 	{ N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL },
-	{ N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 0, "<Item>", NULL },
+	{ N_("/Tools/Buddy _Pounces"), NULL, pidgin_blist_show_with_parent, (int)pidgin_pounces_manager_show_with_parent, "<Item>", NULL },
 	{ N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL },
-	{ N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
+	{ N_("/Tools/Plu_gins"), "<CTL>U", pidgin_blist_show_with_parent, (int)pidgin_plugin_dialog_show_with_parent, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
 	{ N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES },
 	{ N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL },
 	{ "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<Item>", NULL },
 	{ N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL },
-	{ N_("/Tools/System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, "<Item>", NULL },
+	{ N_("/Tools/System _Log"), NULL, pidgin_blist_show_with_parent, (int)pidgin_syslog_show_with_parent, "<Item>", NULL },
 	{ "/Tools/sep3", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Tools/Mute _Sounds"), "<CTL>S", pidgin_blist_mute_sounds_cb, 0, "<CheckItem>", NULL },
 	/* Help */
@@ -3106,9 +3106,9 @@
 	{ N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP },
 	{ N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<Item>", NULL },
 #if GTK_CHECK_VERSION(2,6,0)
-	{ N_("/Help/_About"), NULL, pidgin_dialogs_about, 0,  "<StockItem>", GTK_STOCK_ABOUT },
+	{ N_("/Help/_About"), NULL, pidgin_blist_show_with_parent, (int)pidgin_dialogs_about_with_parent, "<StockItem>", GTK_STOCK_ABOUT },
 #else
-	{ N_("/Help/_About"), NULL, pidgin_dialogs_about, 0,  "<Item>", NULL },
+	{ N_("/Help/_About"), NULL, pidgin_blist_show_with_parent, (int)pidgin_dialogs_about_with_parent, "<Item>", NULL },
 #endif
 };
 
@@ -4323,9 +4323,9 @@
 	text = g_hash_table_lookup(gtkblist->connection_errors, account);
 
 	enabled = purple_account_get_enabled(account, purple_core_get_ui());
-	purple_request_action(account, _("Connection Error"), primary, text, 2,
+	purple_request_action_with_hint(account, _("Connection Error"), primary, text, 2,
 						account, NULL, NULL,
-						account, 3,
+						PURPLE_REQUEST_UI_HINT_ACCOUNT, account, 3,
 						_("OK"), NULL,
 						_("Modify Account"), PURPLE_CALLBACK(ce_modify_account_cb),
 						enabled ? _("Connect") : _("Re-enable Account"),
@@ -5787,11 +5787,13 @@
 	gtkblist = PIDGIN_BLIST(purple_get_blist());
 
 	data->window = gtk_dialog_new_with_buttons(_("Add Buddy"),
-			NULL, GTK_DIALOG_NO_SEPARATOR,
+			gtkblist ? GTK_WINDOW(gtkblist->window) : NULL, GTK_DIALOG_NO_SEPARATOR,
 			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 			GTK_STOCK_ADD, GTK_RESPONSE_OK,
 			NULL);
 
+	if (gtkblist)
+		gtk_window_set_transient_for(GTK_WINDOW(data->window), GTK_WINDOW(gtkblist->window));
 	gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK);
 	gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE);
 	gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE);
@@ -6169,11 +6171,13 @@
 	data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
 	data->window = gtk_dialog_new_with_buttons(_("Add Chat"),
-		NULL, GTK_DIALOG_NO_SEPARATOR,
+		gtkblist ? GTK_WINDOW(gtkblist->window) : NULL, GTK_DIALOG_NO_SEPARATOR,
 		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 		GTK_STOCK_ADD, GTK_RESPONSE_OK,
 		NULL);
 
+	if (gtkblist)
+		gtk_window_set_transient_for(GTK_WINDOW(data->window), GTK_WINDOW(gtkblist->window));
 	gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK);
 	gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE);
 	gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE);
@@ -6277,13 +6281,13 @@
 static void
 pidgin_blist_request_add_group(void)
 {
-	purple_request_input(NULL, _("Add Group"), NULL,
+	purple_request_input_with_hint(NULL, _("Add Group"), NULL,
 					   _("Please enter the name of the group to be added."),
 					   NULL, FALSE, FALSE, NULL,
 					   _("Add"), G_CALLBACK(add_group_cb),
 					   _("Cancel"), NULL,
 					   NULL, NULL, NULL,
-					   NULL);
+					   PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 void
--- a/pidgin/gtkcertmgr.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkcertmgr.c	Mon Oct 15 10:45:46 2007 +0000
@@ -184,7 +184,7 @@
 		   if the window gets closed unusually, such as by handle
 		   deletion */
 		/* TODO: Display some more information on the certificate? */
-		purple_request_input(tpm_dat,
+		purple_request_input_with_hint(tpm_dat,
 				     _("Certificate Import"),
 				     _("Specify a hostname"),
 				     _("Type the host name this certificate is for."),
@@ -197,7 +197,7 @@
 				     _("Cancel"),
 				     G_CALLBACK(tls_peers_mgmt_import_cancel2_cb),
 				     NULL, NULL, NULL, /* No account/who/conv*/
-				     crt    /* Pass cert instance to callback*/
+				     PURPLE_REQUEST_UI_HINT_CERTMGR, crt    /* Pass cert instance to callback*/
 				     );
 		
 		g_free(default_hostname);
@@ -220,13 +220,13 @@
 tls_peers_mgmt_import_cb(GtkWidget *button, gpointer data)
 {
 	/* TODO: need to tell the user that we want a .PEM file! */
-	purple_request_file(tpm_dat,
+	purple_request_file_with_hint(tpm_dat,
 			    _("Select a PEM certificate"),
 			    "certificate.pem",
 			    FALSE, /* Not a save dialog */
 			    G_CALLBACK(tls_peers_mgmt_import_ok_cb),
 			    NULL,  /* Do nothing if cancelled */
-			    NULL, NULL, NULL, NULL );/* No account,conv,etc. */
+			    NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_CERTMGR, NULL );/* No account,conv,etc. */
 }
 
 static void
@@ -295,14 +295,14 @@
 
 	
 	/* TODO: inform user that it will be a PEM? */
-	purple_request_file(tpm_dat,
+	purple_request_file_with_hint(tpm_dat,
 			    _("PEM X.509 Certificate Export"),
 			    "certificate.pem",
 			    TRUE, /* Is a save dialog */
 			    G_CALLBACK(tls_peers_mgmt_export_ok_cb),
 			    G_CALLBACK(tls_peers_mgmt_export_cancel_cb),
 			    NULL, NULL, NULL, /* No account,conv,etc. */
-			    crt); /* Pass the certificate on to the callback */
+			    PURPLE_REQUEST_UI_HINT_CERTMGR, crt); /* Pass the certificate on to the callback */
 }
 
 static void
@@ -371,10 +371,11 @@
 		primary = g_strdup_printf(
 			_("Really delete certificate for %s?"), id );
 		
-		purple_request_yes_no(tpm_dat, _("Confirm certificate delete"),
+		purple_request_yes_no_with_hint(tpm_dat, _("Confirm certificate delete"),
 				      primary, NULL, /* Can this be NULL? */
 				      2, /* NO is default action */
 				      NULL, NULL, NULL,
+				      PURPLE_REQUEST_UI_HINT_CERTMGR,
 				      id, /* id ownership passed to callback */
 				      tls_peers_mgmt_delete_confirm_cb,
 				      tls_peers_mgmt_delete_confirm_cb );
--- a/pidgin/gtkconv.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkconv.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1029,11 +1029,11 @@
 		if (*c == '/' || *c == '\\')
 			*c = ' ';
 	}
-	purple_request_file(PIDGIN_CONVERSATION(conv), _("Save Conversation"),
+	purple_request_file_with_hint(PIDGIN_CONVERSATION(conv), _("Save Conversation"),
 					  buf,
 					  TRUE, G_CALLBACK(savelog_writefile_cb), NULL,
 					  NULL, NULL, conv,
-					  conv);
+					  PURPLE_REQUEST_UI_HINT_BLIST, conv);
 
 	g_free(buf);
 }
@@ -1081,7 +1081,7 @@
 		PurpleBlistNode *node = cur->data;
 		if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
 		{
-			pidgin_log_show_contact((PurpleContact *)node->parent);
+			pidgin_log_show_contact_with_parent(GTK_WINDOW(win->window), (PurpleContact *)node->parent);
 			g_slist_free(buddies);
 			gdk_window_set_cursor(gtkblist->window->window, NULL);
 			gdk_window_set_cursor(win->window->window, NULL);
@@ -1090,7 +1090,7 @@
 	}
 	g_slist_free(buddies);
 
-	pidgin_log_show(type, name, account);
+	pidgin_log_show_with_parent(GTK_WINDOW(win->window), type, name, account);
 
 	gdk_window_set_cursor(gtkblist->window->window, NULL);
 	gdk_window_set_cursor(win->window->window, NULL);
@@ -1236,7 +1236,7 @@
 
 	conv = pidgin_conv_window_get_active_gtkconv(win)->active_conv;
 
-	pidgin_pounce_editor_show(purple_conversation_get_account(conv),
+	pidgin_pounce_editor_show_with_parent(GTK_WINDOW(win->window), purple_conversation_get_account(conv),
 								purple_conversation_get_name(conv), NULL);
 }
 
@@ -2718,10 +2718,10 @@
 
 	buf = g_strdup_printf("%s.%s", purple_normalize(conv->account, conv->name), ext);
 
-	purple_request_file(gtkconv, _("Save Icon"), buf, TRUE,
+	purple_request_file_with_hint(gtkconv, _("Save Icon"), buf, TRUE,
 					 G_CALLBACK(saveicon_writefile_cb), NULL,
 					conv->account, NULL, conv,
-					gtkconv);
+					PURPLE_REQUEST_UI_HINT_BLIST, gtkconv);
 
 	g_free(buf);
 }
@@ -6519,6 +6519,7 @@
 		AtkObject *accessibility_obj;
 		/* I think this is a little longer than it needs to be but I'm lazy. */
 		char *style;
+		gboolean bold = FALSE;
 
 		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
 			im = PURPLE_CONV_IM(conv);
@@ -6552,7 +6553,7 @@
 		gtk_list_store_set(gtkconv->infopane_model, &(gtkconv->infopane_iter),
 				CONV_TEXT_COLUMN, markup, -1);
 	        /* XXX seanegan Why do I have to do this? */
-        	gtk_widget_queue_draw(gtkconv->infopane);
+		gtk_widget_queue_draw(gtkconv->infopane);
 	
 		if (title != markup)
 			g_free(markup);
@@ -6571,31 +6572,41 @@
 			style = "color=\"#c4a000\"";
 		} else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK)	{
 			atk_object_set_description(accessibility_obj, _("Nick Said"));
-			style = "color=\"#204a87\" weight=\"bold\"";
+			style = "color=\"#cc0000\"";
 		} else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT)	{
 			atk_object_set_description(accessibility_obj, _("Unread Messages"));
-			style = "color=\"#cc0000\" weight=\"bold\"";
+			if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT)
+				style = "color=\"#204a87\" weight=\"bold\"";
+			else
+				style = "color=\"#cc0000\" weight=\"bold\"";
 		} else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) {
 			atk_object_set_description(accessibility_obj, _("New Event"));
-			style = "color=\"#888a85\" weight=\"bold\"";
+			style = "color=\"#888a85\"";
 		} else {
-			style = "";
-		}
+			style = NULL;
+		}
+
+		if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT ||
+				gtkconv->unseen_state == PIDGIN_UNSEEN_NICK ||
+				gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT)
+			bold = TRUE;
 		
-		if (*style != '\0')
+		if (style || bold)
 		{
 			char *html_title,*label;
 
 			html_title = g_markup_escape_text(title, -1);
-			label = g_strdup_printf("<span %s>%s</span>",
-			                        style, html_title);
+			label = g_strdup_printf("<span %s %s>%s</span>",
+			                        style ? style : "",
+			                        bold ? "weight=\"bold\"" : "",
+			                        html_title);
 			g_free(html_title);
 			gtk_label_set_markup(GTK_LABEL(gtkconv->tab_label), label);
 			g_free(label);
 		}
 		else
 			gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title);
-		
+
 		if (pidgin_conv_window_is_active_conversation(conv))
 			update_typing_icon(gtkconv);
 
--- a/pidgin/gtkdebug.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkdebug.c	Mon Oct 15 10:45:46 2007 +0000
@@ -36,6 +36,7 @@
 #include "gtkimhtml.h"
 #include "gtkutils.h"
 #include "pidginstock.h"
+#include "gtkblist.h"
 
 #ifdef HAVE_REGEX_H
 # include <regex.h>
@@ -231,10 +232,10 @@
 static void
 save_cb(GtkWidget *w, DebugWindow *win)
 {
-	purple_request_file(win, _("Save Debug Log"), "purple-debug.log", TRUE,
+	purple_request_file_with_hint(win, _("Save Debug Log"), "purple-debug.log", TRUE,
 					  G_CALLBACK(save_writefile_cb), NULL,
 					  NULL, NULL, NULL,
-					  win);
+					  PURPLE_REQUEST_UI_HINT_BLIST, win);
 }
 
 static void
@@ -673,6 +674,7 @@
 static DebugWindow *
 debug_window_new(void)
 {
+	PidginBuddyList *blist;
 	DebugWindow *win;
 	GtkWidget *vbox;
 	GtkWidget *toolbar;
@@ -687,6 +689,9 @@
 	height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/height");
 
 	PIDGIN_DIALOG(win->window);
+	if ((blist = pidgin_blist_get_default_gtk_blist()) != NULL)
+		if (blist->window)
+			gtk_window_set_transient_for(GTK_WINDOW(win->window), GTK_WINDOW(blist->window));
 	purple_debug_info("gtkdebug", "Setting dimensions to %d, %d\n",
 					width, height);
 
--- a/pidgin/gtkdialogs.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkdialogs.c	Mon Oct 15 10:45:46 2007 +0000
@@ -334,6 +334,13 @@
 
 void pidgin_dialogs_about()
 {
+	PidginBuddyList *blist = pidgin_blist_get_default_gtk_blist();
+
+	pidgin_dialogs_about_with_parent(blist ? GTK_WINDOW(blist->window) : NULL);
+}
+
+void pidgin_dialogs_about_with_parent(GtkWindow *parent)
+{
 	GtkWidget *hbox;
 	GtkWidget *vbox;
 	GtkWidget *logo;
@@ -349,11 +356,15 @@
 	GdkPixbuf *pixbuf;
 
 	if (about != NULL) {
+		if (parent)
+			gtk_window_set_transient_for(GTK_WINDOW(about), parent);
 		gtk_window_present(GTK_WINDOW(about));
 		return;
 	}
 
 	PIDGIN_DIALOG(about);
+	if (parent)
+		gtk_window_set_transient_for(GTK_WINDOW(about), parent);
 	tmp = g_strdup_printf(_("About %s"), PIDGIN_NAME);
 	gtk_window_set_title(GTK_WINDOW(about), tmp);
 	g_free(tmp);
@@ -768,7 +779,7 @@
 	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(purple_get_blist(), _("New Instant Message"),
+	purple_request_fields_with_hint(purple_get_blist(), _("New Instant Message"),
 						NULL,
 						_("Please enter the screen name or alias of the person "
 						  "you would like to IM."),
@@ -776,7 +787,7 @@
 						_("OK"), G_CALLBACK(pidgin_dialogs_im_cb),
 						_("Cancel"), NULL,
 						NULL, NULL, NULL,
-						NULL);
+						PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 void
@@ -907,7 +918,7 @@
 	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(purple_get_blist(), _("Get User Info"),
+	purple_request_fields_with_hint(purple_get_blist(), _("Get User Info"),
 						NULL,
 						_("Please enter the screen name or alias of the person "
 						  "whose info you would like to view."),
@@ -915,7 +926,7 @@
 						_("OK"), G_CALLBACK(pidgin_dialogs_info_cb),
 						_("Cancel"), NULL,
 						NULL, NULL, NULL,
-						NULL);
+						PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 static void
@@ -943,7 +954,7 @@
 			PurpleBlistNode *node = cur->data;
 			if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
 			{
-				pidgin_log_show_contact((PurpleContact *)node->parent);
+				pidgin_log_show_contact_with_parent(GTK_WINDOW(gtkblist->window), (PurpleContact *)node->parent);
 				g_slist_free(buddies);
 				pidgin_clear_cursor(gtkblist->window);
 				g_free(username);
@@ -952,7 +963,7 @@
 		}
 		g_slist_free(buddies);
 
-		pidgin_log_show(PURPLE_LOG_IM, username, account);
+		pidgin_log_show_with_parent(GTK_WINDOW(gtkblist->window), PURPLE_LOG_IM, username, account);
 
 		pidgin_clear_cursor(gtkblist->window);
 	}
@@ -999,7 +1010,7 @@
 	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
-	purple_request_fields(purple_get_blist(), _("View User Log"),
+	purple_request_fields_with_hint(purple_get_blist(), _("View User Log"),
 						NULL,
 						_("Please enter the screen name or alias of the person "
 						  "whose log you would like to view."),
@@ -1007,7 +1018,7 @@
 						_("OK"), G_CALLBACK(pidgin_dialogs_log_cb),
 						_("Cancel"), NULL,
 						NULL, NULL, NULL,
-						NULL);
+						PURPLE_REQUEST_UI_HINT_BLIST, NULL);
 }
 
 static void
@@ -1021,13 +1032,13 @@
 {
 	g_return_if_fail(contact != NULL);
 
-	purple_request_input(NULL, _("Alias Contact"), NULL,
+	purple_request_input_with_hint(NULL, _("Alias Contact"), NULL,
 					   _("Enter an alias for this contact."),
 					   contact->alias, FALSE, FALSE, NULL,
 					   _("Alias"), G_CALLBACK(pidgin_dialogs_alias_contact_cb),
 					   _("Cancel"), NULL,
 					   NULL, purple_contact_get_alias(contact), NULL,
-					   contact);
+					   PURPLE_REQUEST_UI_HINT_BLIST, contact);
 }
 
 static void
@@ -1046,12 +1057,12 @@
 
 	secondary = g_strdup_printf(_("Enter an alias for %s."), buddy->name);
 
-	purple_request_input(NULL, _("Alias Buddy"), NULL,
+	purple_request_input_with_hint(NULL, _("Alias Buddy"), NULL,
 					   secondary, buddy->alias, FALSE, FALSE, NULL,
 					   _("Alias"), G_CALLBACK(pidgin_dialogs_alias_buddy_cb),
 					   _("Cancel"), NULL,
 					   purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), NULL,
-					   buddy);
+					   PURPLE_REQUEST_UI_HINT_BLIST, buddy);
 
 	g_free(secondary);
 }
@@ -1067,13 +1078,13 @@
 {
 	g_return_if_fail(chat != NULL);
 
-	purple_request_input(NULL, _("Alias Chat"), NULL,
+	purple_request_input_with_hint(NULL, _("Alias Chat"), NULL,
 					   _("Enter an alias for this chat."),
 					   chat->alias, FALSE, FALSE, NULL,
 					   _("Alias"), G_CALLBACK(pidgin_dialogs_alias_chat_cb),
 					   _("Cancel"), NULL,
 					   chat->account, NULL, NULL,
-					   chat);
+					   PURPLE_REQUEST_UI_HINT_BLIST, chat);
 }
 
 static void
@@ -1115,9 +1126,9 @@
 						"want to continue?", contact->totalsize - 1),
 					buddy->name, contact->totalsize - 1);
 
-		purple_request_action(contact, NULL, _("Remove Contact"), text, 0,
+		purple_request_action_with_hint(contact, NULL, _("Remove Contact"), text, 0,
 				NULL, purple_contact_get_alias(contact), NULL,
-				contact, 2,
+				PURPLE_REQUEST_UI_HINT_BLIST, contact, 2,
 				_("_Remove Contact"), G_CALLBACK(pidgin_dialogs_remove_contact_cb),
 				_("Cancel"),
 				NULL);
@@ -1156,9 +1167,9 @@
 	ggp->parent = source;
 	ggp->new_name = g_strdup(new_name);
 	
-	purple_request_action(source, NULL, _("Merge Groups"), text, 0,
+	purple_request_action_with_hint(source, NULL, _("Merge Groups"), text, 0,
 			NULL, NULL, NULL,
-			ggp, 2,
+			PURPLE_REQUEST_UI_HINT_BLIST, ggp, 2,
 			_("_Merge Groups"), G_CALLBACK(pidgin_dialogs_merge_groups_cb),
 			_("Cancel"), G_CALLBACK(free_ggmo));
 
@@ -1212,9 +1223,9 @@
 	text = g_strdup_printf(_("You are about to remove the group %s and all its members from your buddy list.  Do you want to continue?"),
 						   group->name);
 
-	purple_request_action(group, NULL, _("Remove Group"), text, 0,
+	purple_request_action_with_hint(group, NULL, _("Remove Group"), text, 0,
 						NULL, NULL, NULL,
-						group, 2,
+						PURPLE_REQUEST_UI_HINT_BLIST, group, 2,
 						_("_Remove Group"), G_CALLBACK(pidgin_dialogs_remove_group_cb),
 						_("Cancel"), NULL);
 
@@ -1251,9 +1262,9 @@
 	text = g_strdup_printf(_("You are about to remove %s from your buddy list.  Do you want to continue?"),
 						   buddy->name);
 
-	purple_request_action(buddy, NULL, _("Remove Buddy"), text, 0,
+	purple_request_action_with_hint(buddy, NULL, _("Remove Buddy"), text, 0,
 						purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), NULL,
-						buddy, 2,
+						PURPLE_REQUEST_UI_HINT_BLIST, buddy, 2,
 						_("_Remove Buddy"), G_CALLBACK(pidgin_dialogs_remove_buddy_cb),
 						_("Cancel"), NULL);
 
@@ -1278,9 +1289,9 @@
 	text = g_strdup_printf(_("You are about to remove the chat %s from your buddy list.  Do you want to continue?"),
 			name ? name : "");
 
-	purple_request_action(chat, NULL, _("Remove Chat"), text, 0,
+	purple_request_action_with_hint(chat, NULL, _("Remove Chat"), text, 0,
 						chat->account, NULL, NULL,
-						chat, 2,
+						PURPLE_REQUEST_UI_HINT_BLIST, chat, 2,
 						_("_Remove Chat"), G_CALLBACK(pidgin_dialogs_remove_chat_cb),
 						_("Cancel"), NULL);
 
--- a/pidgin/gtkdialogs.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkdialogs.h	Mon Oct 15 10:45:46 2007 +0000
@@ -31,18 +31,33 @@
 #include "conversation.h"
 
 /* Functions in gtkdialogs.c (these should actually stay in this file) */
+
 void pidgin_dialogs_destroy_all(void);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * @deprecated Use pidgin_dialogs_about_with_parent() instead.
+ */
 void pidgin_dialogs_about(void);
+#endif
+
+/**
+ * @since 2.3.0
+ */
+void pidgin_dialogs_about_with_parent(GtkWindow *parent);
+
 void pidgin_dialogs_im(void);
 void pidgin_dialogs_im_with_user(PurpleAccount *, const char *);
 void pidgin_dialogs_info(void);
 void pidgin_dialogs_log(void);
 
+#ifndef PURPLE_DISABLE_DEPRECATED
 /**
  * @deprecated This function is no longer used and will be removed in
  *             Pidgin 3.0.0 unless there is sufficient demand to keep it.
  */
 void pidgin_dialogs_alias_contact(PurpleContact *);
+#endif
 
 void pidgin_dialogs_alias_buddy(PurpleBuddy *);
 void pidgin_dialogs_alias_chat(PurpleChat *);
--- a/pidgin/gtkdocklet.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkdocklet.c	Mon Oct 15 10:45:46 2007 +0000
@@ -407,7 +407,7 @@
 	GdkPixbuf *pixbuf;
 	GtkWidget *image;
 
-	menuitem = gtk_image_menu_item_new_with_mnemonic(str);
+	menuitem = gtk_image_menu_item_new_with_label(str);
 
 	if (menu)
 		gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
@@ -474,6 +474,7 @@
 }
 
 
+
 static void
 plugin_act(GtkObject *obj, PurplePluginAction *pam)
 {
@@ -553,7 +554,6 @@
 		pidgin_separator(menu);
 }
 
-
 static void
 docklet_menu() {
 	static GtkWidget *menu = NULL;
--- a/pidgin/gtkimhtmltoolbar.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Mon Oct 15 10:45:46 2007 +0000
@@ -184,6 +184,8 @@
 			g_signal_connect_after(G_OBJECT(toolbar->font_dialog), "realize",
 							 G_CALLBACK(realize_toolbar_font), toolbar);
 		}
+		gtk_window_set_transient_for(GTK_WINDOW(toolbar->font_dialog),
+		    GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(toolbar))));
 		gtk_window_present(GTK_WINDOW(toolbar->font_dialog));
 	} else {
 		cancel_toolbar_font(font, toolbar);
@@ -427,14 +429,14 @@
 		}
 
 		toolbar->link_dialog =
-			purple_request_fields(toolbar, _("Insert Link"),
+			purple_request_fields_with_hint(toolbar, _("Insert Link"),
 					    NULL,
-						msg,
+					    msg,
 					    fields,
 					    _("_Insert"), G_CALLBACK(do_insert_link_cb),
 					    _("Cancel"), G_CALLBACK(cancel_link_cb),
-						NULL, NULL, NULL,
-					    toolbar);
+					    NULL, NULL, NULL,
+					    PURPLE_REQUEST_UI_HINT_CONV, toolbar);
 		g_free(msg);
 		g_free(desc);
 	} else {
@@ -709,6 +711,8 @@
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
 	gtk_window_set_role(GTK_WINDOW(dialog), "smiley_dialog");
 	gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
+	gtk_window_set_transient_for(GTK_WINDOW(dialog),
+	    GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(toolbar))));
 
 	if (unique_smileys != NULL) {
 		struct smiley_button_list *ls, *it, *it_tmp;
--- a/pidgin/gtklog.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtklog.c	Mon Oct 15 10:45:46 2007 +0000
@@ -321,9 +321,9 @@
 	data2[0] = lv->treestore;
 	data2[1] = data[3]; /* iter */
 	data2[2] = log;
-	purple_request_action(lv, NULL, "Delete Log?", tmp, 0, 
+	purple_request_action_with_hint(lv, NULL, "Delete Log?", tmp, 0, 
 						NULL, NULL, NULL,
-						data2, 2,
+						"log_viewer", data2, 2,
 						_("Delete"), delete_log_cb,
 						_("Cancel"), delete_log_cleanup_cb);
 	g_free(tmp);
@@ -523,7 +523,7 @@
 	}
 }
 
-static PidginLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *logs,
+static PidginLogViewer *display_log_viewer(GtkWindow *parent, struct log_viewer_hash_t *ht, GList *logs,
 						const char *title, GtkWidget *icon, int log_size)
 {
 	PidginLogViewer *lv;
@@ -569,7 +569,7 @@
 		g_hash_table_insert(log_viewers, ht, lv);
 
 	/* Window ***********/
-	lv->window = gtk_dialog_new_with_buttons(title, NULL, 0,
+	lv->window = gtk_dialog_new_with_buttons(title, parent, 0,
 					     GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
 #ifdef _WIN32
 	/* Steal the "HELP" response and use it to trigger browsing to the logs folder */
@@ -676,6 +676,10 @@
 }
 
 void pidgin_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account) {
+	pidgin_log_show_with_parent(NULL, type, screenname, account);
+}
+
+void pidgin_log_show_with_parent(GtkWindow *parent, PurpleLogType type, const char *screenname, PurpleAccount *account) {
 	struct log_viewer_hash_t *ht;
 	PidginLogViewer *lv = NULL;
 	const char *name = screenname;
@@ -720,7 +724,7 @@
 
 	prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);
 
-	display_log_viewer(ht, purple_log_get_logs(type, screenname, account),
+	display_log_viewer(parent, ht, purple_log_get_logs(type, screenname, account),
 			title, gtk_image_new_from_pixbuf(prpl_icon),
 			purple_log_get_total_size(type, screenname, account));
 
@@ -730,6 +734,10 @@
 }
 
 void pidgin_log_show_contact(PurpleContact *contact) {
+	pidgin_log_show_contact_with_parent(NULL, contact);
+}
+
+void pidgin_log_show_contact_with_parent(GtkWindow *parent, PurpleContact *contact) {
 	struct log_viewer_hash_t *ht = g_new0(struct log_viewer_hash_t, 1);
 	PurpleBlistNode *child;
 	PidginLogViewer *lv = NULL;
@@ -783,11 +791,16 @@
 	}
 
 	title = g_strdup_printf(_("Conversations with %s"), name);
-	display_log_viewer(ht, logs, title, image, total_log_size);
+	display_log_viewer(parent, ht, logs, title, image, total_log_size);
 	g_free(title);
 }
 
-void pidgin_syslog_show()
+void pidgin_syslog_show(void)
+{
+	pidgin_syslog_show_with_parent(NULL);
+}
+
+void pidgin_syslog_show_with_parent(GtkWindow *parent)
 {
 	GList *accounts = NULL;
 	GList *logs = NULL;
@@ -807,7 +820,7 @@
 	}
 	logs = g_list_sort(logs, purple_log_compare);
 
-	syslog_viewer = display_log_viewer(NULL, logs, _("System Log"), NULL, 0);
+	syslog_viewer = display_log_viewer(parent, NULL, logs, _("System Log"), NULL, 0);
 }
 
 /****************************************************************************
--- a/pidgin/gtklog.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtklog.h	Mon Oct 15 10:45:46 2007 +0000
@@ -52,11 +52,41 @@
 };
 
 
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * @deprecated Use pidgin_log_show_with_parent() instead.
+ */
+void pidgin_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account);
+#endif
 
-void pidgin_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account);
+/**
+ * @since 2.3.0
+ */
+void pidgin_log_show_with_parent(GtkWindow *parent, PurpleLogType type, const char *screenname, PurpleAccount *account);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * @deprecated pidgin_log_show_contact_with_parent() instead.
+ */
 void pidgin_log_show_contact(PurpleContact *contact);
+#endif
 
+/**
+ * @since 2.3.0
+ */
+void pidgin_log_show_contact_with_parent(GtkWindow *parent, PurpleContact *contact);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * @deprecated Use pidgin_syslog_show_with_parent() instead.
+ */
 void pidgin_syslog_show(void);
+#endif
+
+/**
+ * @since 2.3.0
+ */
+void pidgin_syslog_show_with_parent(GtkWindow *parent);
 
 /**************************************************************************/
 /** @name GTK+ Log Subsystem                                              */
--- a/pidgin/gtknotify.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtknotify.c	Mon Oct 15 10:45:46 2007 +0000
@@ -741,7 +741,7 @@
 	GtkListStore *model;
 	GtkCellRenderer *renderer;
 	guint col_num;
-	GList *column;
+	GList *columniter;
 	guint i;
 
 	GtkWidget *vbox;
@@ -825,11 +825,12 @@
 					-1, "", renderer, "pixbuf", 0, NULL);
 
 	i = 1;
-	for (column = results->columns; column != NULL; column = column->next) {
+	for (columniter = results->columns; columniter != NULL; columniter = columniter->next) {
+		PurpleNotifySearchColumn *column = columniter->data;
 		renderer = gtk_cell_renderer_text_new();
 
 		gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1,
-				column->data, renderer, "text", i, NULL);
+				column->title, renderer, "text", i, NULL);
 		i++;
 	}
 
--- a/pidgin/gtkplugin.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkplugin.c	Mon Oct 15 10:45:46 2007 +0000
@@ -280,11 +280,11 @@
 			cb_data[1] = model;
 			cb_data[2] = iter;
 
-			purple_request_action(plugin_dialog, NULL,
+			purple_request_action_with_hint(plugin_dialog, NULL,
 			                    _("Multiple plugins will be unloaded."),
 			                    tmp->str, 0,
-								NULL, NULL, NULL,
-								cb_data, 2,
+			                    NULL, NULL, NULL,
+			                    PURPLE_REQUEST_UI_HINT_PLUGINMGR, cb_data, 2,
 			                    _("Unload Plugins"), G_CALLBACK(plugin_unload_confirm_cb),
 			                    _("Cancel"), g_free);
 			g_string_free(tmp, TRUE);
@@ -533,6 +533,11 @@
 
 void pidgin_plugin_dialog_show()
 {
+	pidgin_plugin_dialog_show_with_parent(NULL);
+}
+
+void pidgin_plugin_dialog_show_with_parent(GtkWindow *parent)
+{
 	GtkWidget *sw;
 	GtkWidget *event_view;
 	GtkListStore *ls;
@@ -541,6 +546,8 @@
 	GtkTreeSelection *sel;
 
 	if (plugin_dialog != NULL) {
+		if (parent)
+			gtk_window_set_transient_for(GTK_WINDOW(plugin_dialog), parent);
 		gtk_window_present(GTK_WINDOW(plugin_dialog));
 		return;
 	}
@@ -549,6 +556,8 @@
 						    NULL,
 						    GTK_DIALOG_NO_SEPARATOR,
 						    NULL);
+	if (parent)
+		gtk_window_set_transient_for(GTK_WINDOW(plugin_dialog), parent);
 	pref_button = gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
 						_("Configure Pl_ugin"), PIDGIN_RESPONSE_CONFIGURE);
 	gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
--- a/pidgin/gtkplugin.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkplugin.h	Mon Oct 15 10:45:46 2007 +0000
@@ -72,9 +72,20 @@
  */
 void pidgin_plugins_save(void);
 
+#ifndef PURPLE_DISABLE_DEPRECATED
 /**
  * Shows the Plugins dialog
+ *
+ * @deprecated Use pidgin_plugin_dialog_show_with_parent() instead.
  */
 void pidgin_plugin_dialog_show(void);
+#endif
+
+/**
+ * Shows the Plugins dialog, transient to a parent window
+ *
+ * @since 2.3.0
+ */
+void pidgin_plugin_dialog_show_with_parent(GtkWindow *parent);
 
 #endif /* _PIDGINPLUGIN_H_ */
--- a/pidgin/gtkpounce.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkpounce.c	Mon Oct 15 10:45:46 2007 +0000
@@ -154,10 +154,10 @@
 	entry = (GtkWidget *)data;
 	name = gtk_entry_get_text(GTK_ENTRY(entry));
 
-	purple_request_file(entry, _("Select a file"), name, FALSE,
+	purple_request_file_with_hint(entry, _("Select a file"), name, FALSE,
 					  G_CALLBACK(pounce_update_entry_fields), NULL,
 					  NULL, NULL, NULL,
-					  entry);
+					  "buddy_pounce", entry);
 	g_signal_connect_swapped(G_OBJECT(entry), "destroy",
 			G_CALLBACK(purple_request_close_with_handle), entry);
 }
@@ -472,6 +472,13 @@
 pidgin_pounce_editor_show(PurpleAccount *account, const char *name,
 							PurplePounce *cur_pounce)
 {
+	pidgin_pounce_editor_show_with_parent(NULL, account, name, cur_pounce);
+}
+
+void
+pidgin_pounce_editor_show_with_parent(GtkWindow *parent, PurpleAccount *account, const char *name,
+							PurplePounce *cur_pounce)
+{
 	PidginPounceDialog *dialog;
 	GtkWidget *window;
 	GtkWidget *label;
@@ -1050,7 +1057,7 @@
 static void
 pounces_manager_add_cb(GtkButton *button, gpointer user_data)
 {
-	pidgin_pounce_editor_show(NULL, NULL, NULL);
+	pidgin_pounce_editor_show_with_parent(GTK_WINDOW(pounces_manager->window), NULL, NULL, NULL);
 }
 
 static void
@@ -1060,7 +1067,7 @@
 	PurplePounce *pounce;
 
 	gtk_tree_model_get(model, iter, POUNCES_MANAGER_COLUMN_POUNCE, &pounce, -1);
-	pidgin_pounce_editor_show(NULL, NULL, pounce);
+	pidgin_pounce_editor_show_with_parent(GTK_WINDOW(pounces_manager->window), NULL, NULL, pounce);
 }
 
 static void
@@ -1101,9 +1108,9 @@
 	pouncee = purple_pounce_get_pouncee(pounce);
 
 	buf = g_strdup_printf(_("Are you sure you want to delete the pounce on %s for %s?"), pouncee, pouncer);
-	purple_request_action(pounce, NULL, buf, NULL, 0,
+	purple_request_action_with_hint(pounce, NULL, buf, NULL, 0,
 						account, pouncee, NULL,
-						pounce, 2,
+						PURPLE_REQUEST_UI_HINT_POUNCEMGR, pounce, 2,
 						_("Delete"), pounces_manager_delete_confirm_cb,
 						_("Cancel"), NULL);
 	g_free(buf);
@@ -1160,7 +1167,7 @@
 	if ((pounce != NULL) && (event->button == 1) &&
 		(event->type == GDK_2BUTTON_PRESS))
 	{
-		pidgin_pounce_editor_show(NULL, NULL, pounce);
+		pidgin_pounce_editor_show_with_parent(GTK_WINDOW(pounces_manager->window), NULL, NULL, pounce);
 		return TRUE;
 	}
 
@@ -1311,6 +1318,12 @@
 void
 pidgin_pounces_manager_show(void)
 {
+	pidgin_pounces_manager_show_with_parent(NULL);
+}
+
+void
+pidgin_pounces_manager_show_with_parent(GtkWindow *parent)
+{
 	PouncesManager *dialog;
 	GtkWidget *bbox;
 	GtkWidget *button;
@@ -1321,6 +1334,7 @@
 
 	if (pounces_manager != NULL) {
 		gtk_window_present(GTK_WINDOW(pounces_manager->window));
+		gtk_window_set_transient_for(GTK_WINDOW(pounces_manager->window), parent);
 		return;
 	}
 
@@ -1331,6 +1345,7 @@
 
 	dialog->window = win = pidgin_create_window(_("Buddy Pounces"), PIDGIN_HIG_BORDER, "pounces", TRUE);
 	gtk_window_set_default_size(GTK_WINDOW(win), width, height);
+	gtk_window_set_transient_for(GTK_WINDOW(win), parent);
 
 	g_signal_connect(G_OBJECT(win), "delete_event",
 					 G_CALLBACK(pounces_manager_destroy_cb), dialog);
--- a/pidgin/gtkpounce.h	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkpounce.h	Mon Oct 15 10:45:46 2007 +0000
@@ -28,20 +28,48 @@
 
 #include "pounce.h"
 
+#ifndef PURPLE_DISABLE_DEPRECATED
 /**
  * Displays a New Buddy Pounce or Edit Buddy Pounce dialog.
  *
  * @param account    The optional account to use.
  * @param name       The optional name to pounce on.
  * @param cur_pounce The current buddy pounce, if editing an existing one.
+ *
+ * @deprecated Use pidgin_pounce_editor_show_with_parent() instead.
  */
 void pidgin_pounce_editor_show(PurpleAccount *account, const char *name,
 								PurplePounce *cur_pounce);
+#endif
+
+/**
+ * Displays a New Buddy Pounce or Edit Buddy Pounce dialog.
+ *
+ * @param parent     The parent window.
+ * @param account    The optional account to use.
+ * @param name       The optional name to pounce on.
+ * @param cur_pounce The current buddy pounce, if editing an existing one.
+ *
+ * @since 2.3.0
+ */
+void pidgin_pounce_editor_show_with_parent(GtkWindow *parent, PurpleAccount *account, const char *name,
+								PurplePounce *cur_pounce);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * Shows the pounces manager window.
+ *
+ * @deprecated Use pidgin_pounces_manager_show_with_parent() instead.
+ */
+void pidgin_pounces_manager_show(void);
+#endif
 
 /**
  * Shows the pounces manager window.
+ *
+ * @since 2.3.0
  */
-void pidgin_pounces_manager_show(void);
+void pidgin_pounces_manager_show_with_parent(GtkWindow *parent);
 
 /**
  * Hides the pounces manager window.
--- a/pidgin/gtkprefs.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkprefs.c	Mon Oct 15 10:45:46 2007 +0000
@@ -641,7 +641,8 @@
 static void
 add_theme_button_clicked_cb(GtkWidget *widget, gpointer null)
 {
-	purple_request_file(NULL, _("Install Theme"), NULL, FALSE, (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, NULL) ;
+	purple_request_file_with_hint(NULL, _("Install Theme"), NULL, FALSE,
+	    (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_PREFSMGR, NULL) ;
 }
 
 static void
@@ -1624,9 +1625,9 @@
 	if (*filename == '\0')
 		filename = NULL;
 
-	purple_request_file(prefs, _("Sound Selection"), filename, FALSE,
+	purple_request_file_with_hint(prefs, _("Sound Selection"), filename, FALSE,
 					  G_CALLBACK(sound_chosen_cb), NULL,
-					  NULL, NULL, NULL,
+					  NULL, NULL, NULL, PURPLE_REQUEST_UI_HINT_PREFSMGR,
 					  GINT_TO_POINTER(sound_row_sel));
 }
 
--- a/pidgin/gtkprivacy.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkprivacy.c	Mon Oct 15 10:45:46 2007 +0000
@@ -88,6 +88,8 @@
 
 static PidginPrivacyDialog *privacy_dialog = NULL;
 
+#define PIDGIN_REQUEST_HINT_PRIVACY "privacy"
+
 static void
 rebuild_allow_list(PidginPrivacyDialog *dialog)
 {
@@ -367,7 +369,7 @@
 
 	dialog = g_new0(PidginPrivacyDialog, 1);
 
-	dialog->win = pidgin_create_window(_("Privacy"), PIDGIN_HIG_BORDER, "privacy", TRUE);
+	dialog->win = pidgin_create_window(_("Privacy"), PIDGIN_HIG_BORDER, PIDGIN_REQUEST_HINT_PRIVACY, TRUE);
 
 	g_signal_connect(G_OBJECT(dialog->win), "delete_event",
 					 G_CALLBACK(destroy_cb), dialog);
@@ -554,7 +556,7 @@
 	data->block   = FALSE;
 
 	if (name == NULL) {
-		purple_request_input(account, _("Permit User"),
+		purple_request_input_with_hint(account, _("Permit User"),
 			_("Type a user you permit to contact you."),
 			_("Please enter the name of the user you wish to be "
 			  "able to contact you."),
@@ -562,7 +564,7 @@
 			_("_Permit"), G_CALLBACK(add_permit_block_cb),
 			_("Cancel"), G_CALLBACK(destroy_request_data),
 			account, name, NULL,
-			data);
+			PIDGIN_REQUEST_HINT_PRIVACY, data);
 	}
 	else {
 		char *primary = g_strdup_printf(_("Allow %s to contact you?"), name);
@@ -571,10 +573,10 @@
 							  "%s to contact you?"), name);
 
 
-		purple_request_action(account, _("Permit User"), primary, secondary,
+		purple_request_action_with_hint(account, _("Permit User"), primary, secondary,
 							0,
 							account, name, NULL,
-							data, 2,
+							PIDGIN_REQUEST_HINT_PRIVACY, data, 2,
 							_("_Permit"), G_CALLBACK(confirm_permit_block_cb),
 							_("Cancel"), G_CALLBACK(destroy_request_data));
 
@@ -596,24 +598,24 @@
 	data->block   = TRUE;
 
 	if (name == NULL) {
-		purple_request_input(account, _("Block User"),
+		purple_request_input_with_hint(account, _("Block User"),
 			_("Type a user to block."),
 			_("Please enter the name of the user you wish to block."),
 			NULL, FALSE, FALSE, NULL,
 			_("_Block"), G_CALLBACK(add_permit_block_cb),
 			_("Cancel"), G_CALLBACK(destroy_request_data),
 			account, name, NULL,
-			data);
+			PIDGIN_REQUEST_HINT_PRIVACY, data);
 	}
 	else {
 		char *primary = g_strdup_printf(_("Block %s?"), name);
 		char *secondary =
 			g_strdup_printf(_("Are you sure you want to block %s?"), name);
 
-		purple_request_action(account, _("Block User"), primary, secondary,
+		purple_request_action_with_hint(account, _("Block User"), primary, secondary,
 							0,
 							account, name, NULL,
-							data, 2,
+							PIDGIN_REQUEST_HINT_PRIVACY, data, 2,
 							_("_Block"), G_CALLBACK(confirm_permit_block_cb),
 							_("Cancel"), G_CALLBACK(destroy_request_data));
 
--- a/pidgin/gtkrequest.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkrequest.c	Mon Oct 15 10:45:46 2007 +0000
@@ -35,6 +35,7 @@
 #include "gtkrequest.h"
 #include "gtkutils.h"
 #include "pidginstock.h"
+#include "gtkblist.h"
 
 #include <gdk/gdkkeysyms.h>
 
@@ -80,6 +81,55 @@
 
 } PidginRequestData;
 
+static GtkWindow *
+find_toplevel(GList *ll_toplevels, const char *role)
+{
+	const char *window_role = NULL;
+	GList *ll_itr = NULL;
+
+	for (ll_itr = ll_toplevels ; ll_itr ; ll_itr = ll_itr->next) {
+		if ((window_role = gtk_window_get_role(GTK_WINDOW(ll_itr->data))) != NULL) {
+			if (!strcmp(window_role, role))
+				return GTK_WINDOW(ll_itr->data);
+		}
+	}
+
+	return NULL;
+}
+
+static GtkWindow *
+get_request_parent(const char *ui_hint, PidginConversation *convo)
+{
+	GtkWindow *toplevel = NULL;
+	PidginBuddyList *blist = NULL;
+
+	if (convo)
+		return GTK_WINDOW(convo->win->window);
+
+	if (strcmp(ui_hint, PURPLE_REQUEST_UI_HINT_BLIST)) {
+		GList *ll_toplevels = NULL;
+
+		ll_toplevels = gtk_window_list_toplevels();
+
+		if (!(toplevel = find_toplevel(ll_toplevels, ui_hint))) {
+			if (!strcmp(ui_hint, PURPLE_REQUEST_UI_HINT_REGISTER))
+				toplevel = find_toplevel(ll_toplevels, "account");
+			else
+			if (!strcmp(ui_hint, PURPLE_REQUEST_UI_HINT_XFER))
+				toplevel = find_toplevel(ll_toplevels, "file transfer");
+		}
+		
+		g_list_free(ll_toplevels);
+	}
+
+	/* Takes care of "pidgin-statusbox" as well */
+	if (!toplevel)
+		if ((blist = pidgin_blist_get_default_gtk_blist()) != NULL)
+			return GTK_WINDOW(blist->window);
+
+	return toplevel;
+}
+
 static void
 generic_response_start(PidginRequestData *data)
 {
@@ -288,7 +338,7 @@
 					   const char *ok_text, GCallback ok_cb,
 					   const char *cancel_text, GCallback cancel_cb,
 					   PurpleAccount *account, const char *who, PurpleConversation *conv,
-					   void *user_data)
+					   const char *ui_hint, void *user_data)
 {
 	PidginRequestData *data;
 	GtkWidget *dialog;
@@ -313,7 +363,7 @@
 
 	/* Create the dialog. */
 	dialog = gtk_dialog_new_with_buttons(title ? title : PIDGIN_ALERT_TITLE,
-					     NULL, 0,
+					     get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL), 0,
 					     text_to_stock(cancel_text), 1,
 					     text_to_stock(ok_text),     0,
 					     NULL);
@@ -451,7 +501,7 @@
 			const char *ok_text, GCallback ok_cb,
 			const char *cancel_text, GCallback cancel_cb,
 			PurpleAccount *account, const char *who, PurpleConversation *conv,
-			void *user_data, va_list args)
+			const char *ui_hint, void *user_data, va_list args)
 {
 	PidginRequestData *data;
 	GtkWidget *dialog;
@@ -475,6 +525,8 @@
 
 	/* Create the dialog. */
 	data->dialog = dialog = gtk_dialog_new();
+	gtk_window_set_transient_for(GTK_WINDOW(dialog),
+		get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL));
 
 	if (title != NULL)
 		gtk_window_set_title(GTK_WINDOW(dialog), title);
@@ -555,7 +607,7 @@
 pidgin_request_action(const char *title, const char *primary,
 						const char *secondary, int default_action,
 					    PurpleAccount *account, const char *who, PurpleConversation *conv,
-						void *user_data, size_t action_count, va_list actions)
+						const char *ui_hint, void *user_data, size_t action_count, va_list actions)
 {
 	PidginRequestData *data;
 	GtkWidget *dialog;
@@ -585,6 +637,8 @@
 
 	/* Create the dialog. */
 	data->dialog = dialog = gtk_dialog_new();
+	gtk_window_set_transient_for(GTK_WINDOW(dialog),
+		get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL));
 
 #if GTK_CHECK_VERSION(2,10,0)
 	gtk_window_set_deletable(GTK_WINDOW(data->dialog), FALSE);
@@ -1138,7 +1192,7 @@
 						const char *ok_text, GCallback ok_cb,
 						const char *cancel_text, GCallback cancel_cb,
 					    PurpleAccount *account, const char *who, PurpleConversation *conv,
-						void *user_data)
+						const char *ui_hint, void *user_data)
 {
 	PidginRequestData *data;
 	GtkWidget *win;
@@ -1179,6 +1233,8 @@
 #else /* !_WIN32 */
 	data->dialog = win = pidgin_create_window(title, PIDGIN_HIG_BORDER, "multifield", TRUE) ;
 #endif /* _WIN32 */
+	gtk_window_set_transient_for(GTK_WINDOW(win),
+		get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL));
 
 	g_signal_connect(G_OBJECT(win), "delete_event",
 					 G_CALLBACK(destroy_multifield_cb), data);
@@ -1593,10 +1649,10 @@
 
 	if ((data->u.file.savedialog == TRUE) &&
 		(g_file_test(data->u.file.name, G_FILE_TEST_EXISTS))) {
-		purple_request_action(data, NULL, _("That file already exists"),
+		purple_request_action_with_hint(data, NULL, _("That file already exists"),
 							_("Would you like to overwrite it?"), 0,
 							NULL, NULL, NULL,
-							data, 2,
+							"pidgin-request-file", data, 2,
 							_("Overwrite"), G_CALLBACK(file_yes_no_cb),
 							_("Choose New Name"), G_CALLBACK(file_yes_no_cb));
 	} else
@@ -1621,7 +1677,7 @@
 					  gboolean savedialog,
 					  GCallback ok_cb, GCallback cancel_cb,
 					  PurpleAccount *account, const char *who, PurpleConversation *conv,
-					  void *user_data)
+					  const char *ui_hint, void *user_data)
 {
 	PidginRequestData *data;
 	GtkWidget *filesel;
@@ -1709,6 +1765,9 @@
 	g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked",
 					 G_CALLBACK(file_ok_check_if_exists_cb), data);
 #endif /* FILECHOOSER */
+	gtk_window_set_role(GTK_WINDOW(filesel), "pidgin-request-file");
+	gtk_window_set_transient_for(GTK_WINDOW(filesel),
+		get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL));
 
 	data->dialog = filesel;
 	gtk_widget_show(filesel);
@@ -1720,7 +1779,7 @@
 pidgin_request_folder(const char *title, const char *dirname,
 					  GCallback ok_cb, GCallback cancel_cb,
 					  PurpleAccount *account, const char *who, PurpleConversation *conv,
-					  void *user_data)
+					  const char *ui_hint, void *user_data)
 {
 	PidginRequestData *data;
 	GtkWidget *dirsel;
@@ -1759,6 +1818,9 @@
 	g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dirsel)->ok_button), "clicked",
 					 G_CALLBACK(file_ok_check_if_exists_cb), data);
 #endif
+	gtk_window_set_role(GTK_WINDOW(dirsel), "pidgin-request-dir");
+	gtk_window_set_transient_for(GTK_WINDOW(dirsel),
+		get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL));
 
 	data->dialog = dirsel;
 	gtk_widget_show(dirsel);
--- a/pidgin/gtksavedstatuses.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtksavedstatuses.c	Mon Oct 15 10:45:46 2007 +0000
@@ -338,9 +338,9 @@
 		handle = dialog;
 	}
 
-	purple_request_action(handle, NULL, title, NULL, 0,
+	purple_request_action_with_hint(handle, NULL, title, NULL, 0,
 		 NULL, NULL, NULL,
-		 sel_titles, 2,
+		 PURPLE_REQUEST_UI_HINT_STATUSMGR, sel_titles, 2,
 		_("Delete"), status_window_delete_confirm_cb,
 		_("Cancel"), status_window_delete_cancel_cb);
 
--- a/pidgin/gtksound.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtksound.c	Mon Oct 15 10:45:46 2007 +0000
@@ -118,12 +118,9 @@
 	if (conv != NULL && PIDGIN_IS_PIDGIN_CONVERSATION(conv))
 	{
 		PidginConversation *gtkconv;
-		PidginWindow *win;
 		gboolean has_focus;
 
 		gtkconv = PIDGIN_CONVERSATION(conv);
-		win = gtkconv->win;
-
 		has_focus = purple_conversation_has_focus(conv);
 
 		if (!gtkconv->make_sound ||
--- a/pidgin/gtkstatusbox.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkstatusbox.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1586,9 +1586,9 @@
 
 	msg = g_strdup_printf(_("Are you sure you want to delete %s?"), purple_savedstatus_get_title(saved));
 
-	purple_request_action(saved, NULL, msg, NULL, 0,
+	purple_request_action_with_hint(saved, NULL, msg, NULL, 0,
 		NULL, NULL, NULL,
-		data, 2,
+		"pidgin-statusbox", data, 2,
 		_("Delete"), tree_view_delete_current_selection_cb,
 		_("Cancel"), NULL);
 
--- a/pidgin/gtkutils.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/gtkutils.c	Mon Oct 15 10:45:46 2007 +0000
@@ -1526,28 +1526,30 @@
 
 			if (prpl_info && prpl_info->can_receive_file)
 				ft = prpl_info->can_receive_file(gc, who);
+			else if (prpl_info && prpl_info->send_file)
+				ft = TRUE;
 
 			if (im && ft)
-				purple_request_choice(NULL, NULL,
+				purple_request_choice_with_hint(NULL, NULL,
 						    _("You have dragged an image"),
 						    _("You can send this image as a file transfer, "
 						      "embed it into this message, or use it as the buddy icon for this user."),
 						    DND_FILE_TRANSFER, "OK", (GCallback)dnd_image_ok_callback,
 						    "Cancel", (GCallback)dnd_image_cancel_callback,
 							account, who, NULL,
-							data,
+							PURPLE_REQUEST_UI_HINT_CONV, data,
 							_("Set as buddy icon"), DND_BUDDY_ICON,
 						    _("Send image file"), DND_FILE_TRANSFER,
 						    _("Insert in message"), DND_IM_IMAGE,
 							NULL);
 			else if (!(im || ft))
-				purple_request_yes_no(NULL, NULL, _("You have dragged an image"),
+				purple_request_yes_no_with_hint(NULL, NULL, _("You have dragged an image"),
 							_("Would you like to set it as the buddy icon for this user?"),
 							0,
 							account, who, NULL,
-							data, (GCallback)dnd_set_icon_ok_cb, (GCallback)dnd_set_icon_cancel_cb);
+							PURPLE_REQUEST_UI_HINT_CONV, data, (GCallback)dnd_set_icon_ok_cb, (GCallback)dnd_set_icon_cancel_cb);
 			else
-				purple_request_choice(NULL, NULL,
+				purple_request_choice_with_hint(NULL, NULL,
 						    _("You have dragged an image"),
 						    (ft ? _("You can send this image as a file transfer, or use it as the buddy icon for this user.") :
 						    _("You can insert this image into this message, or use it as the buddy icon for this user")),
@@ -1555,10 +1557,11 @@
 							"OK", (GCallback)dnd_image_ok_callback,
 						    "Cancel", (GCallback)dnd_image_cancel_callback,
 							account, who, NULL,
-							data,
+							PURPLE_REQUEST_UI_HINT_CONV, data,
 						    _("Set as buddy icon"), DND_BUDDY_ICON,
 						    (ft ? _("Send image file") : _("Insert in message")), (ft ? DND_FILE_TRANSFER : DND_IM_IMAGE),
 							NULL);
+			gdk_pixbuf_unref(pb);
 			return;
 		}
 
--- a/pidgin/plugins/history.c	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/plugins/history.c	Mon Oct 15 10:45:46 2007 +0000
@@ -42,6 +42,7 @@
 	GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS;
 	char *header;
 	char *protocol;
+	char *escaped_alias;
 
 	convtype = purple_conversation_get_type(c);
 	gtkconv = PIDGIN_CONVERSATION(c);
@@ -120,10 +121,12 @@
 	if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml))))
 		gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", options);
 
-	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), alias,
+	escaped_alias = g_markup_escape_text(alias, -1);
+	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias,
 							 purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time)));
 	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), header, options);
 	g_free(header);
+	g_free(escaped_alias);
 
 	g_strchomp(history);
 	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), history, options);
--- a/pidgin/plugins/perl/common/GtkDialogs.xs	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/plugins/perl/common/GtkDialogs.xs	Mon Oct 15 10:45:46 2007 +0000
@@ -10,6 +10,10 @@
 pidgin_dialogs_about()
 
 void
+pidgin_dialogs_about_with_parent(parent)
+	void * parent
+
+void
 pidgin_dialogs_im()
 
 void
--- a/pidgin/plugins/perl/common/GtkLog.xs	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/plugins/perl/common/GtkLog.xs	Mon Oct 15 10:45:46 2007 +0000
@@ -13,11 +13,27 @@
 	Purple::Account account
 
 void
+pidgin_log_show_with_parent(parent, type, screenname, account)
+	void * parent
+	Purple::LogType type
+	const char * screenname
+	Purple::Account account
+
+void
 pidgin_log_show_contact(contact)
 	Purple::BuddyList::Contact contact
 
+void
+pidgin_log_show_contact_with_parent(parent, contact)
+	void * parent
+	Purple::BuddyList::Contact contact
+
 MODULE = Pidgin::Log  PACKAGE = Pidgin::SysLog  PREFIX = pidgin_syslog_
 PROTOTYPES: ENABLE
 
 void
 pidgin_syslog_show()
+
+void
+pidgin_syslog_show_with_parent(parent)
+	void * parent
--- a/pidgin/plugins/perl/common/GtkPlugin.xs	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/plugins/perl/common/GtkPlugin.xs	Mon Oct 15 10:45:46 2007 +0000
@@ -11,3 +11,7 @@
 
 void
 pidgin_plugin_dialog_show()
+
+void
+pidgin_plugin_dialog_show_with_parent(parent)
+	void * parent
--- a/pidgin/plugins/perl/common/GtkPounce.xs	Sun Oct 14 21:20:50 2007 +0000
+++ b/pidgin/plugins/perl/common/GtkPounce.xs	Mon Oct 15 10:45:46 2007 +0000
@@ -9,6 +9,13 @@
 	const char * name
 	Purple::Pounce cur_pounce
 
+void
+pidgin_pounce_editor_show_with_parent(parent, account, name, cur_pounce)
+	void * parent
+	Purple::Account account
+	const char * name
+	Purple::Pounce cur_pounce
+
 MODULE = Pidgin::Pounce  PACKAGE = Pidgin::Pounces  PREFIX = pidgin_pounces_
 PROTOTYPES: ENABLE
 
@@ -22,4 +29,8 @@
 pidgin_pounces_manager_show()
 
 void
+pidgin_pounces_manager_show_with_parent(parent)
+	void * parent
+
+void
 pidgin_pounces_manager_hide()