changeset 22031:9bfdf68d185c

merge of '5fc55e3a78ccb0a463df332592e62c5a371cd8b4' and 'ca3452eca310a510c6932f9a618b79da824d796a'
author Mark Doliner <mark@kingant.net>
date Mon, 07 Jan 2008 16:28:25 +0000
parents 21ed56853648 (diff) 31a631d08d46 (current diff)
children 64d6bcc9d619
files
diffstat 106 files changed, 1112 insertions(+), 592 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Mon Jan 07 16:28:12 2008 +0000
+++ b/COPYRIGHT	Mon Jan 07 16:28:25 2008 +0000
@@ -168,6 +168,7 @@
 Nick Hebner
 Mike Heffner
 Justin Heiner
+Moos Heintzen
 Benjamin Herrenschmidt
 Fernando Herrera
 hjheins
@@ -349,6 +350,7 @@
 Scott Shedden
 Dossy Shiobara
 Michael Shkutkov
+Shreevatsa R
 Ettore Simone
 John Silvestri
 Craig Slusher
--- a/ChangeLog	Mon Jan 07 16:28:12 2008 +0000
+++ b/ChangeLog	Mon Jan 07 16:28:25 2008 +0000
@@ -14,8 +14,10 @@
 	* Added the ability to theme conversation name colors (red and blue)
 	  through your GTK+ theme, and exposed those theme settings to the 
 	  Pidgin GTK+ Theme Control plugin (Dustin Howett)
-	* Fixed having multiple alias edit areas in the infopane (Elliott Sales de
-	  Andrade)
+	* Fixed having multiple alias edit areas in the infopane (Elliott Sales
+	  de Andrade)
+	* Save the conversation "Enable Logging" option per-contact (Moos
+	  Heintzen)
 
 	Finch:
 	* Color is used in the buddylist to indicate status, and the conversation
@@ -24,6 +26,11 @@
 	* The default keybinding for dump-screen is now M-D and uses a file
 	  request dialog. M-d will properly delete-forward-word, and M-f has been
 	  fixed to imitate readline's behavior.
+	* New bindings alt+tab and alt+shift+tab to help navigating between the
+	  higlighted windows (details on the man-page).
+	* Recently signed on (or off) buddies blink in the buddy list.
+	* New action 'Room List' in the action-list can be used to get the list of
+	  available chat rooms for an online account.
 
 version 2.3.1 (12/7/2007):
 	http://developer.pidgin.im/query?status=closed&milestone=2.3.1
--- a/ChangeLog.API	Mon Jan 07 16:28:12 2008 +0000
+++ b/ChangeLog.API	Mon Jan 07 16:28:25 2008 +0000
@@ -8,6 +8,16 @@
 		* purple_major_version, purple_minor_version,
 		  purple_micro_version variables are exported by version.h,
 		  giving the version of libpurple in use at runtime.
+		* purple_util_set_current_song, purple_util_format_song_info
+		* Some accessor functions to the Roomlist API:
+			* purple_roomlist_get_fields
+			* purple_roomlist_room_get_type
+			* purple_roomlist_room_get_name
+			* purple_roomlist_room_get_parent
+			* purple_roomlist_room_get_fields
+			* purple_roomlist_field_get_type
+			* purple_roomlist_field_get_label
+			* purple_roomlist_field_get_hidden
 
 	Pidgin:
 		Added:
@@ -24,11 +34,17 @@
 		* pidgin_tooltip_setup_for_treeview, pidgin_tooltip_destroy,
 		  pidgin_tooltip_show and pidgin_tooltip_setup_for_widget to simplify
 		  the process of drawing tooltips.
+		* pidgin_add_widget_to_vbox to simplify adding a labeled widget to a
+		  window.
 
-	        Deprecated:
-	        * PIDGIN_DIALOG
+		Deprecated:
+		* PIDGIN_DIALOG
 
 	Finch:
+		* finch_roomlist_get_ui_ops and finch_roomlist_show_all
+		* finch_request_field_get_widget to get the widget for a request
+		  field.
+
 		libgnt:
 		* Added gnt_tree_set_row_color to set the color for a row in a tree.
 		* Added gnt_style_get_string_list
--- a/config.h.mingw	Mon Jan 07 16:28:12 2008 +0000
+++ b/config.h.mingw	Mon Jan 07 16:28:25 2008 +0000
@@ -355,7 +355,7 @@
 
 /* Loads static protocol plugin module initialization functions. */
 #ifndef STATIC_PROTO_INIT
-#define STATIC_PROTO_INIT static void static_proto_init() {  }
+#define STATIC_PROTO_INIT static void static_proto_init(void) {  }
 #endif
 
 /* Define to 1 if you have the ANSI C header files. */
--- a/configure.ac	Mon Jan 07 16:28:12 2008 +0000
+++ b/configure.ac	Mon Jan 07 16:28:25 2008 +0000
@@ -142,7 +142,7 @@
 dnl If we don't have msgfmt, then po/ is going to fail -- ensure that
 dnl AM_GLIB_GNU_GETTEXT found it.
 
-if test x$MSGFMT = xno -o x$MSGFMT$GMSGFMT = x
+if test x$MSGFMT = xno -o x$MSGFMT$GMSGFMT$INTLTOOL_MSGFMT = x
 then
 	AC_ERROR([
 
@@ -978,7 +978,7 @@
 AM_CONDITIONAL(STATIC_YAHOO, test "x$static_yahoo" = "xyes")
 AM_CONDITIONAL(STATIC_ZEPHYR, test "x$static_zephyr" = "xyes")
 AC_SUBST(STATIC_LINK_LIBS)
-AC_DEFINE_UNQUOTED(STATIC_PROTO_INIT, $extern_init static void static_proto_init() { $load_proto },
+AC_DEFINE_UNQUOTED(STATIC_PROTO_INIT, $extern_init static void static_proto_init(void) { $load_proto },
 	[Loads static protocol plugin module initialization functions.])
 
 AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`])
--- a/finch/Makefile.am	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/Makefile.am	Mon Jan 07 16:28:25 2008 +0000
@@ -30,6 +30,7 @@
 	gntpounce.c \
 	gntprefs.c \
 	gntrequest.c \
+	gntroomlist.c \
 	gntsound.c \
 	gntstatus.c \
 	gntui.c
@@ -49,6 +50,7 @@
 	gntpounce.h \
 	gntprefs.h \
 	gntrequest.h \
+	gntroomlist.h \
 	gntsound.h \
 	gntstatus.h \
 	gntui.h
--- a/finch/finch.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/finch.c	Mon Jan 07 16:28:25 2008 +0000
@@ -49,14 +49,14 @@
 #include "config.h"
 
 static void
-debug_init()
+debug_init(void)
 {
 	finch_debug_init();
 	purple_debug_set_ui_ops(finch_debug_get_ui_ops());
 }
 
 static GHashTable *ui_info = NULL;
-static GHashTable *finch_ui_get_info()
+static GHashTable *finch_ui_get_info(void)
 {
 	if (ui_info == NULL) {
 		ui_info = g_hash_table_new(g_str_hash, g_str_equal);
@@ -91,7 +91,7 @@
 };
 
 static PurpleCoreUiOps *
-gnt_core_get_ui_ops()
+gnt_core_get_ui_ops(void)
 {
 	return &core_ops;
 }
--- a/finch/gntaccount.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntaccount.c	Mon Jan 07 16:28:25 2008 +0000
@@ -722,7 +722,7 @@
 }
 
 static gpointer
-finch_accounts_get_handle()
+finch_accounts_get_handle(void)
 {
 	static int handle;
 
--- a/finch/gntblist.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntblist.c	Mon Jan 07 16:28:25 2008 +0000
@@ -540,7 +540,7 @@
 }
 
 static void
-finch_request_add_group()
+finch_request_add_group(void)
 {
 	purple_request_input(NULL, _("Add Group"), NULL, _("Enter the name of the group"),
 			NULL, FALSE, FALSE, NULL,
@@ -568,7 +568,7 @@
 };
 
 static gpointer
-finch_blist_get_handle()
+finch_blist_get_handle(void)
 {
 	static int handle;
 
@@ -1702,7 +1702,7 @@
 }
 
 static void
-populate_buddylist()
+populate_buddylist(void)
 {
 	PurpleBlistNode *node;
 	PurpleBuddyList *list;
@@ -1735,7 +1735,7 @@
 }
 
 static void
-populate_status_dropdown()
+populate_status_dropdown(void)
 {
 	int i;
 	GList *iter;
@@ -2207,7 +2207,7 @@
 }
 
 static void
-reconstruct_plugins_menu()
+reconstruct_plugins_menu(void)
 {
 	GntWidget *sub;
 	GntMenuItem *plg;
@@ -2239,7 +2239,7 @@
 }
 
 static void
-reconstruct_accounts_menu()
+reconstruct_accounts_menu(void)
 {
 	GntWidget *sub;
 	GntMenuItem *acc, *item;
@@ -2439,7 +2439,7 @@
 }
 
 static void
-create_menu()
+create_menu(void)
 {
 	GntWidget *menu, *sub, *subsub;
 	GntMenuItem *item;
--- a/finch/gntcertmgr.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntcertmgr.c	Mon Jan 07 16:28:25 2008 +0000
@@ -246,7 +246,7 @@
 
 /* populate the list */
 static void
-populate_cert_list()
+populate_cert_list(void)
 {
 	GList *idlist, *l;
 
--- a/finch/gntconv.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntconv.c	Mon Jan 07 16:28:25 2008 +0000
@@ -350,7 +350,7 @@
 }
 
 static gpointer
-finch_conv_get_handle()
+finch_conv_get_handle(void)
 {
 	static int handle;
 	return &handle;
@@ -1119,7 +1119,7 @@
 static PurpleCmdRet
 cmd_show_window(PurpleConversation *conv, const char *cmd, char **args, char **error, gpointer data)
 {
-	void (*callback)() = data;
+	void (*callback)(void) = data;
 	callback();
 	return PURPLE_CMD_STATUS_OK;
 }
--- a/finch/gntft.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntft.c	Mon Jan 07 16:28:25 2008 +0000
@@ -85,7 +85,7 @@
  **************************************************************************/
 
 static void
-update_title_progress()
+update_title_progress(void)
 {
 	GList *list;
 	int num_active_xfers = 0;
--- a/finch/gntft.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntft.h	Mon Jan 07 16:28:25 2008 +0000
@@ -55,7 +55,7 @@
 /**
  * Hides the file transfer dialog.
  */
-void finch_xfer_dialog_hide();
+void finch_xfer_dialog_hide(void);
 
 /**
  * Adds a file transfer to the dialog.
--- a/finch/gntidle.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntidle.c	Mon Jan 07 16:28:25 2008 +0000
@@ -28,7 +28,7 @@
 #include "idle.h"
 
 static time_t
-finch_get_idle_time()
+finch_get_idle_time(void)
 {
 	return gnt_wm_get_idle_time();
 }
--- a/finch/gntnotify.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntnotify.c	Mon Jan 07 16:28:25 2008 +0000
@@ -147,14 +147,14 @@
 }
 
 static void
-reset_email_dialog()
+reset_email_dialog(void)
 {
 	emaildialog.window = NULL;
 	emaildialog.tree = NULL;
 }
 
 static void
-setup_email_dialog()
+setup_email_dialog(void)
 {
 	GntWidget *box, *tree, *button;
 	if (emaildialog.window)
--- a/finch/gntplugin.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntplugin.c	Mon Jan 07 16:28:25 2008 +0000
@@ -171,7 +171,7 @@
 }
 
 static void
-confwin_init()
+confwin_init(void)
 {
 	confwins = g_hash_table_new(g_direct_hash, g_direct_equal);
 }
--- a/finch/gntplugin.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntplugin.h	Mon Jan 07 16:28:25 2008 +0000
@@ -40,7 +40,7 @@
  **********************************************************************/
 /*@{*/
 
-typedef GntWidget* (*FinchPluginFrame) ();
+typedef GntWidget* (*FinchPluginFrame) (void);
 
 /* Guess where these came from */
 #define FINCH_PLUGIN_TYPE FINCH_UI
--- a/finch/gntprefs.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntprefs.c	Mon Jan 07 16:28:25 2008 +0000
@@ -76,17 +76,17 @@
 	PurplePrefType type;
 	const char *pref;
 	const char *label;
-	GList *(*lv)();   /* If the value is to be selected from a number of choices */
+	GList *(*lv)(void);   /* If the value is to be selected from a number of choices */
 } Prefs;
 
 static GList *
-get_log_options()
+get_log_options(void)
 {
 	return purple_log_logger_get_options();
 }
 
 static GList *
-get_idle_options()
+get_idle_options(void)
 {
 	GList *list = NULL;
 	list = g_list_append(list, (char *)_("Based on keyboard use"));
@@ -99,7 +99,7 @@
 }
 
 static GList *
-get_status_titles()
+get_status_titles(void)
 {
 	GList *list = NULL;
 	GList *iter;
@@ -212,7 +212,7 @@
 };
 
 static void
-free_strings()
+free_strings(void)
 {
 	g_list_foreach(pref_request.freestrings, (GFunc)g_free, NULL);
 	g_list_free(pref_request.freestrings);
--- a/finch/gntrequest.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntrequest.c	Mon Jan 07 16:28:25 2008 +0000
@@ -36,6 +36,7 @@
 
 #include "finch.h"
 #include "gntrequest.h"
+#include "debug.h"
 #include "util.h"
 
 typedef struct
@@ -824,3 +825,32 @@
 	}
 }
 
+GntWidget *finch_request_field_get_widget(PurpleRequestField *field)
+{
+	GntWidget *ret = NULL;
+	switch (purple_request_field_get_type(field)) {
+		case PURPLE_REQUEST_FIELD_BOOLEAN:
+			ret = create_boolean_field(field);
+			break;
+		case PURPLE_REQUEST_FIELD_STRING:
+			ret = create_string_field(field, NULL);
+			break;
+		case PURPLE_REQUEST_FIELD_INTEGER:
+			ret = create_integer_field(field);
+			break;
+		case PURPLE_REQUEST_FIELD_CHOICE:
+			ret = create_choice_field(field);
+			break;
+		case PURPLE_REQUEST_FIELD_LIST:
+			ret = create_list_field(field);
+			break;
+		case PURPLE_REQUEST_FIELD_ACCOUNT:
+			ret = create_account_field(field);
+			break;
+		default:
+			purple_debug_error("GntRequest", "Unimplemented request-field %d\n", purple_request_field_get_type(field));
+			break;
+	}
+	return ret;
+}
+
--- a/finch/gntrequest.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntrequest.h	Mon Jan 07 16:28:25 2008 +0000
@@ -27,6 +27,7 @@
 #define _GNT_REQUEST_H
 
 #include "request.h"
+#include "gnt.h"
 
 /**********************************************************************
  * @name GNT Request API
@@ -56,6 +57,15 @@
  */
 void finch_request_save_in_prefs(gpointer null, PurpleRequestFields *fields);
 
+/**
+ * Create a widget field for a request-field.
+ *
+ * @param field   The request field.
+ *
+ * @return A GntWidget for the request field.
+ * @since 2.4.0
+ */
+GntWidget *finch_request_field_get_widget(PurpleRequestField *field);
 /*@}*/
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/gntroomlist.c	Mon Jan 07 16:28:25 2008 +0000
@@ -0,0 +1,415 @@
+/**
+ * @file gntroomlist.c GNT Room List API
+ * @ingroup finch
+ */
+
+/* finch
+ *
+ * Finch is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#include"internal.h"
+
+#include "gntrequest.h"
+#include "gntroomlist.h"
+
+#include "gntbox.h"
+#include "gntbutton.h"
+#include "gntcombobox.h"
+#include "gnttextview.h"
+#include "gnttree.h"
+#include "gntwindow.h"
+
+#include "debug.h"
+
+#define PREF_ROOT "/finch/roomlist"
+
+/* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
+struct _FinchRoomlist
+{
+	GntWidget *window;
+
+	GntWidget *accounts;
+	GntWidget *tree;
+	GntWidget *details;
+
+	GntWidget *getlist;
+	GntWidget *add;
+	GntWidget *join;
+	GntWidget *stop;
+	GntWidget *close;
+
+	PurpleAccount *account;
+	PurpleRoomlist *roomlist;
+} froomlist;
+
+typedef struct _FinchRoomlist FinchRoomlist;
+
+static void
+unset_roomlist(gpointer null)
+{
+	froomlist.window = NULL;
+	if (froomlist.roomlist)
+		purple_roomlist_unref(froomlist.roomlist);
+}
+
+static void
+update_roomlist(PurpleRoomlist *list)
+{
+	if (froomlist.roomlist == list)
+		return;
+
+	if (froomlist.roomlist)
+		purple_roomlist_unref(froomlist.roomlist);
+
+	if ((froomlist.roomlist = list) != NULL)
+		purple_roomlist_ref(list);
+}
+
+static void fl_stop(GntWidget *button, gpointer null)
+{
+	if (froomlist.roomlist &&
+			purple_roomlist_get_in_progress(froomlist.roomlist))
+		purple_roomlist_cancel_get_list(froomlist.roomlist);
+}
+
+static void fl_get_list(GntWidget *button, gpointer null)
+{
+	PurpleAccount *account = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist.accounts));
+	PurpleConnection *gc = purple_account_get_connection(account);
+
+	if (!gc)
+		return;
+
+	froomlist.roomlist = purple_roomlist_get_list(gc);
+	gnt_box_give_focus_to_child(GNT_BOX(froomlist.window), froomlist.tree);
+}
+
+static void fl_add_chat(GntWidget *button, gpointer null)
+{
+	char *name;
+	PurpleRoomlistRoom *room = gnt_tree_get_selection_data(GNT_TREE(froomlist.tree));
+	PurpleConnection *gc = purple_account_get_connection(froomlist.account);
+	PurplePluginProtocolInfo *prpl_info = NULL;
+
+	if (gc == NULL || room == NULL)
+		return;
+
+	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+
+	if(prpl_info != NULL && prpl_info->roomlist_room_serialize)
+		name = prpl_info->roomlist_room_serialize(room);
+	else
+		name = g_strdup(purple_roomlist_room_get_name(room));
+
+	purple_blist_request_add_chat(froomlist.account, NULL, NULL, name);
+
+	g_free(name);
+}
+
+static void fl_close(GntWidget *button, gpointer null)
+{
+	gnt_widget_destroy(froomlist.window);
+}
+
+static void
+roomlist_activated(GntWidget *widget)
+{
+	PurpleRoomlistRoom *room = gnt_tree_get_selection_data(GNT_TREE(widget));
+	if (!room)
+		return;
+
+	switch (purple_roomlist_room_get_type(room)) {
+		case PURPLE_ROOMLIST_ROOMTYPE_ROOM:
+			purple_roomlist_room_join(froomlist.roomlist, room);
+			break;
+		case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY:
+			if (!room->expanded_once) {
+				purple_roomlist_expand_category(froomlist.roomlist, room);
+				room->expanded_once = TRUE;
+			}
+			break;
+	}
+	gnt_tree_set_expanded(GNT_TREE(widget), room, TRUE);
+}
+
+static void
+roomlist_selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
+{
+	GList *iter, *field;
+	PurpleRoomlistRoom *room = current;
+	GntTextView *tv = GNT_TEXT_VIEW(froomlist.details);
+	gboolean first = TRUE;
+
+	gnt_text_view_clear(tv);
+
+	if (!room)
+		return;
+
+	for (iter = purple_roomlist_room_get_fields(room),
+			field = purple_roomlist_get_fields(froomlist.roomlist);
+			iter && field;
+			iter = iter->next, field = field->next) {
+		PurpleRoomlistField *f = field->data;
+		char *label = NULL;
+
+		if (purple_roomlist_field_get_hidden(f)) {
+			continue;
+		}
+
+		if (!first)
+			gnt_text_view_append_text_with_flags(tv, "\n", GNT_TEXT_FLAG_NORMAL);
+
+		gnt_text_view_append_text_with_flags(tv,
+				purple_roomlist_field_get_label(f), GNT_TEXT_FLAG_BOLD);
+		gnt_text_view_append_text_with_flags(tv, ": ", GNT_TEXT_FLAG_BOLD);
+
+		switch (purple_roomlist_field_get_type(f)) {
+			case PURPLE_ROOMLIST_FIELD_BOOL:
+				label = g_strdup(iter->data ? "True" : "False");
+				break;
+			case PURPLE_ROOMLIST_FIELD_INT:
+				label = g_strdup_printf("%d", (int)iter->data);
+				break;
+			case PURPLE_ROOMLIST_FIELD_STRING:
+				label = g_strdup(iter->data);
+				break;
+		}
+		gnt_text_view_append_text_with_flags(tv, label, GNT_TEXT_FLAG_NORMAL);
+		g_free(label);
+		first = FALSE;
+	}
+
+	if (purple_roomlist_room_get_type(room) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
+		if (!first)
+			gnt_text_view_append_text_with_flags(tv, "\n", GNT_TEXT_FLAG_NORMAL);
+		gnt_text_view_append_text_with_flags(tv,
+				_("Hit 'Enter' to find more rooms of this category."),
+				GNT_TEXT_FLAG_NORMAL);
+	}
+}
+
+static void
+roomlist_account_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
+{
+	if (froomlist.account == current) {
+		return;
+	}
+
+	froomlist.account = current;
+	if (froomlist.roomlist) {
+		if (purple_roomlist_get_in_progress(froomlist.roomlist))
+			purple_roomlist_cancel_get_list(froomlist.roomlist);
+		update_roomlist(NULL);
+	}
+
+	gnt_tree_remove_all(GNT_TREE(froomlist.tree));
+	gnt_widget_draw(froomlist.tree);
+}
+
+static void
+reset_account_list(PurpleAccount *account)
+{
+	GList *list;
+	GntComboBox *accounts = GNT_COMBO_BOX(froomlist.accounts);
+	gnt_combo_box_remove_all(accounts);
+	for (list = purple_connections_get_all(); list; list = list->next) {
+		PurplePluginProtocolInfo *prpl_info = NULL;
+		PurpleConnection *gc = list->data;
+
+		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+		if (prpl_info->roomlist_get_list != NULL) {
+			PurpleAccount *account = purple_connection_get_account(gc);
+			char *text = g_strdup_printf("%s (%s)",
+					purple_account_get_username(account),
+					purple_account_get_protocol_name(account));
+			gnt_combo_box_add_data(accounts, account, text);
+			g_free(text);
+		}
+	}
+}
+
+static void
+size_changed_cb(GntWidget *widget, int oldw, int oldh)
+{
+	int w, h;
+	gnt_widget_get_size(widget, &w, &h);
+	purple_prefs_set_int(PREF_ROOT "/size/width", w);
+	purple_prefs_set_int(PREF_ROOT "/size/height", h);
+}
+
+static void
+setup_roomlist(PurpleAccount *account)
+{
+	GntWidget *window, *tree, *hbox, *accounts;
+	int iter;
+	struct {
+		const char *label;
+		GCallback callback;
+		GntWidget **widget;
+	} buttons[] = {
+		{_("Stop"), G_CALLBACK(fl_stop), &froomlist.stop},
+		{_("Get"), G_CALLBACK(fl_get_list), &froomlist.getlist},
+		{_("Add"), G_CALLBACK(fl_add_chat), &froomlist.add},
+		{_("Close"), G_CALLBACK(fl_close), &froomlist.close},
+		{NULL, NULL, NULL}
+	};
+
+	if (froomlist.window)
+		return;
+
+	froomlist.window = window = gnt_window_new();
+	g_object_set(G_OBJECT(window), "vertical", TRUE, NULL);
+	gnt_box_set_pad(GNT_BOX(window), 0);
+	gnt_box_set_title(GNT_BOX(window), _("Room List"));
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+
+	froomlist.accounts = accounts = gnt_combo_box_new();
+	reset_account_list(account);
+	gnt_box_add_widget(GNT_BOX(window), froomlist.accounts);
+	g_signal_connect(G_OBJECT(froomlist.accounts), "selection-changed",
+			G_CALLBACK(roomlist_account_changed), NULL);
+	froomlist.account = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist.accounts));
+
+	froomlist.tree = tree = gnt_tree_new_with_columns(2);
+	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
+	g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(roomlist_activated), NULL);
+	gnt_tree_set_column_titles(GNT_TREE(tree), _("Name"), "");
+	gnt_tree_set_show_separator(GNT_TREE(tree), FALSE);
+	gnt_tree_set_col_width(GNT_TREE(tree), 1, 1);
+	gnt_tree_set_column_resizable(GNT_TREE(tree), 1, FALSE);
+	gnt_tree_set_search_column(GNT_TREE(tree), 0);
+
+	gnt_box_add_widget(GNT_BOX(window), tree);
+
+	froomlist.details = gnt_text_view_new();
+	gnt_text_view_set_flag(GNT_TEXT_VIEW(froomlist.details), GNT_TEXT_VIEW_TOP_ALIGN);
+	gnt_box_add_widget(GNT_BOX(window), froomlist.details);
+	gnt_widget_set_size(froomlist.details, -1, 8);
+
+	hbox = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), hbox);
+
+	for (iter = 0; buttons[iter].label; iter++) {
+		GntWidget *button = gnt_button_new(buttons[iter].label);
+		gnt_box_add_widget(GNT_BOX(hbox), button);
+		g_signal_connect(G_OBJECT(button), "activate", buttons[iter].callback, NULL);
+		*buttons[iter].widget = button;
+		gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(froomlist.details), button);
+	}
+
+	g_signal_connect(G_OBJECT(tree), "selection-changed", G_CALLBACK(roomlist_selection_changed), NULL);
+
+	g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(unset_roomlist), NULL);
+}
+
+static void
+fl_show_with_account(PurpleAccount *account)
+{
+	setup_roomlist(account);
+	g_signal_handlers_disconnect_matched(G_OBJECT(froomlist.window), G_SIGNAL_MATCH_FUNC,
+			0, 0, NULL, G_CALLBACK(size_changed_cb), NULL);
+	gnt_widget_show(froomlist.window);
+	gnt_screen_resize_widget(froomlist.window,
+			purple_prefs_get_int(PREF_ROOT "/size/width"),
+			purple_prefs_get_int(PREF_ROOT "/size/height"));
+	g_signal_connect(G_OBJECT(froomlist.window), "size_changed", G_CALLBACK(size_changed_cb), NULL);
+	gnt_window_present(froomlist.window);
+}
+
+static void
+fl_create(PurpleRoomlist *list)
+{
+	list->ui_data = &froomlist;
+	setup_roomlist(NULL);
+	update_roomlist(list);
+}
+
+static void
+fl_set_fields(PurpleRoomlist *list, GList *fields)
+{
+}
+
+static void
+fl_add_room(PurpleRoomlist *roomlist, PurpleRoomlistRoom *room)
+{
+	gboolean category;
+	if (froomlist.roomlist != roomlist)
+		return;
+
+	category = (purple_roomlist_room_get_type(room) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY);
+	gnt_tree_remove(GNT_TREE(froomlist.tree), room);
+	gnt_tree_add_row_after(GNT_TREE(froomlist.tree), room,
+			gnt_tree_create_row(GNT_TREE(froomlist.tree),
+				purple_roomlist_room_get_name(room),
+				category ? "<" : ""),
+			purple_roomlist_room_get_parent(room), NULL);
+	gnt_tree_set_expanded(GNT_TREE(froomlist.tree), room, !category);
+}
+
+static void
+fl_destroy(PurpleRoomlist *list)
+{
+	if (!froomlist.window)
+		return;
+
+	if (froomlist.roomlist == list) {
+		froomlist.roomlist = NULL;
+		gnt_tree_remove_all(GNT_TREE(froomlist.tree));
+		gnt_widget_draw(froomlist.tree);
+	}
+}
+
+static PurpleRoomlistUiOps ui_ops =
+{
+	fl_show_with_account, /* void (*show_with_account)(PurpleAccount *account); **< Force the ui to pop up a dialog and get the list */
+	fl_create, /* void (*create)(PurpleRoomlist *list); **< A new list was created. */
+	fl_set_fields, /* void (*set_fields)(PurpleRoomlist *list, GList *fields); **< Sets the columns. */
+	fl_add_room, /* void (*add_room)(PurpleRoomlist *list, PurpleRoomlistRoom *room); **< Add a room to the list. */
+	NULL, /* void (*in_progress)(PurpleRoomlist *list, gboolean flag); **< Are we fetching stuff still? */
+	fl_destroy, /* void (*destroy)(PurpleRoomlist *list); **< We're destroying list. */
+
+	NULL, /* void (*_purple_reserved1)(void); */
+	NULL, /* void (*_purple_reserved2)(void); */
+	NULL, /* void (*_purple_reserved3)(void); */
+	NULL /* void (*_purple_reserved4)(void); */
+};
+
+PurpleRoomlistUiOps *finch_roomlist_get_ui_ops(void)
+{
+	return &ui_ops;
+}
+
+void finch_roomlist_show_all(void)
+{
+	purple_roomlist_show_with_account(NULL);
+}
+
+void finch_roomlist_init(void)
+{
+	purple_prefs_add_none(PREF_ROOT);
+	purple_prefs_add_none(PREF_ROOT "/size");
+	purple_prefs_add_int(PREF_ROOT "/size/width", 60);
+	purple_prefs_add_int(PREF_ROOT "/size/height", 15);
+}
+
+void finch_roomlist_uninit(void)
+{
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/gntroomlist.h	Mon Jan 07 16:28:25 2008 +0000
@@ -0,0 +1,61 @@
+/**
+ * @file gntroomlist.h GNT Room List API
+ * @ingroup finch
+ */
+
+/* finch
+ *
+ * Finch is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+#ifndef _GNT_ROOMLIST_H
+#define _GNT_ROOMLIST_H
+
+#include "roomlist.h"
+
+/**********************************************************************
+ * @name GNT Room List API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Initialize the roomlist subsystem.
+ */
+void finch_roomlist_init(void);
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The PurpleRoomlistUiOps structure populated with the appropriate functions.
+ */
+PurpleRoomlistUiOps *finch_roomlist_get_ui_ops(void);
+
+/**
+ * Show the roomlist dialog.
+ */
+void finch_roomlist_show_all(void);
+
+/**
+ * Uninitialize the roomlist subsystem.
+ */
+void finch_roomlist_uninit(void);
+
+/*@}*/
+
+#endif
+
--- a/finch/gntsound.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntsound.c	Mon Jan 07 16:28:25 2008 +0000
@@ -286,7 +286,7 @@
 }
 
 static void *
-finch_sound_get_handle()
+finch_sound_get_handle(void)
 {
 	static int handle;
 
--- a/finch/gntui.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/gntui.c	Mon Jan 07 16:28:25 2008 +0000
@@ -35,6 +35,7 @@
 #include "gntpounce.h"
 #include "gntprefs.h"
 #include "gntrequest.h"
+#include "gntroomlist.h"
 #include "gntstatus.h"
 #include "gntsound.h"
 
@@ -71,14 +72,21 @@
 	finch_notify_init();
 	purple_notify_set_ui_ops(finch_notify_get_ui_ops());
 
+	/* Request */
 	finch_request_init();
 	purple_request_set_ui_ops(finch_request_get_ui_ops());
 
+	/* Pounce */
 	finch_pounces_init();
 
+	/* File transfer */
 	finch_xfers_init();
 	purple_xfers_set_ui_ops(finch_xfers_get_ui_ops());
 
+	/* Roomlist */
+	finch_roomlist_init();
+	purple_roomlist_set_ui_ops(finch_roomlist_get_ui_ops());
+
 	gnt_register_action(_("Accounts"), finch_accounts_show_all);
 	gnt_register_action(_("Buddy List"), finch_blist_show);
 	gnt_register_action(_("Buddy Pounces"), finch_pounces_manager_show);
@@ -86,6 +94,7 @@
 	gnt_register_action(_("Debug Window"), finch_debug_window_show);
 	gnt_register_action(_("File Transfers"), finch_xfer_dialog_show);
 	gnt_register_action(_("Plugins"), finch_plugins_show_all);
+	gnt_register_action(_("Room List"), finch_roomlist_show_all);
 	gnt_register_action(_("Sounds"), finch_sounds_show_all);
 	gnt_register_action(_("Preferences"), finch_prefs_show_all);
 	gnt_register_action(_("Statuses"), finch_savedstatus_show_all);
@@ -118,6 +127,9 @@
 	finch_xfers_uninit();
 	purple_xfers_set_ui_ops(NULL);
 
+	finch_roomlist_uninit();
+	purple_roomlist_set_ui_ops(NULL);
+
 	gnt_quit();
 #endif
 }
--- a/finch/libgnt/gnt.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gnt.h	Mon Jan 07 16:28:25 2008 +0000
@@ -141,7 +141,7 @@
  * @param label      The user-visible label for the action.
  * @param callback   The callback function for the action.
  */
-void gnt_register_action(const char *label, void (*callback)());
+void gnt_register_action(const char *label, void (*callback)(void));
 
 /**
  * Show a menu.
--- a/finch/libgnt/gntbindable.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gntbindable.c	Mon Jan 07 16:28:25 2008 +0000
@@ -45,7 +45,7 @@
 } rebind_info;
 
 static void 
-gnt_bindable_free_rebind_info()
+gnt_bindable_free_rebind_info(void)
 {
 	g_free(rebind_info.name);
 	g_free(rebind_info.keys);
--- a/finch/libgnt/gntcolors.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gntcolors.c	Mon Jan 07 16:28:25 2008 +0000
@@ -40,7 +40,7 @@
 } colors[GNT_TOTAL_COLORS];
 
 static void
-backup_colors()
+backup_colors(void)
 {
 	short i;
 	for (i = 0; i < GNT_TOTAL_COLORS; i++)
@@ -51,13 +51,13 @@
 }
 
 static gboolean
-can_use_custom_color()
+can_use_custom_color(void)
 {
 	return (gnt_style_get_bool(GNT_STYLE_COLOR, FALSE) && can_change_color());
 }
 
 static void
-restore_colors()
+restore_colors(void)
 {
 	short i;
 	for (i = 0; i < GNT_TOTAL_COLORS; i++)
--- a/finch/libgnt/gntentry.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gntentry.c	Mon Jan 07 16:28:25 2008 +0000
@@ -916,7 +916,7 @@
 }
 
 static GntEntryKillRing *
-new_killring()
+new_killring(void)
 {
 	GntEntryKillRing *kr = g_new0(GntEntryKillRing, 1);
 	kr->buffer = g_string_new(NULL);
--- a/finch/libgnt/gntmain.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gntmain.c	Mon Jan 07 16:28:25 2008 +0000
@@ -72,7 +72,7 @@
 
 static void setup_io(void);
 
-static gboolean refresh_screen();
+static gboolean refresh_screen(void);
 
 static GntWM *wm;
 static GntClipboard *clipboard;
@@ -326,7 +326,7 @@
 }
 
 static gboolean
-refresh_screen()
+refresh_screen(void)
 {
 	gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "refresh-screen", NULL);
 	return FALSE;
@@ -363,7 +363,7 @@
 }
 
 static void
-ask_before_exit()
+ask_before_exit(void)
 {
 	static GntWidget *win = NULL;
 	GntWidget *bbox, *button;
@@ -412,7 +412,7 @@
 #ifdef SIGWINCH
 	case SIGWINCH:
 		erase();
-		g_idle_add(refresh_screen, NULL);
+		g_idle_add((GSourceFunc)refresh_screen, NULL);
 		if (org_winch_handler)
 			org_winch_handler(sig);
 		signal(SIGWINCH, sighandler);
@@ -430,7 +430,7 @@
 }
 
 static void
-init_wm()
+init_wm(void)
 {
 	const char *name = gnt_style_get(GNT_STYLE_WM);
 	gpointer handle;
@@ -614,7 +614,7 @@
 	gnt_wm_update_window(wm, widget);
 }
 
-void gnt_register_action(const char *label, void (*callback)())
+void gnt_register_action(const char *label, void (*callback)(void))
 {
 	GntAction *action = g_new0(GntAction, 1);
 	action->label = g_strdup(label);
--- a/finch/libgnt/gnttextview.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gnttextview.c	Mon Jan 07 16:28:25 2008 +0000
@@ -830,7 +830,7 @@
 
 
 static void
-cleanup_pageditor()
+cleanup_pageditor(void)
 {
 	unlink(pageditor.file);
 	g_free(pageditor.file);
--- a/finch/libgnt/gntwm.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gntwm.c	Mon Jan 07 16:28:25 2008 +0000
@@ -135,7 +135,7 @@
  * to expose the entire character, it is not always redrawn.
  */
 static void
-work_around_for_ncurses_bug()
+work_around_for_ncurses_bug(void)
 {
 #ifndef NO_WIDECHAR
 	PANEL *panel = NULL;
@@ -183,7 +183,7 @@
 }
 
 static void
-update_act_msg()
+update_act_msg(void)
 {
 	GntWidget *label;
 	GList *iter;
--- a/finch/libgnt/gntwm.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/gntwm.h	Mon Jan 07 16:28:25 2008 +0000
@@ -73,7 +73,7 @@
 typedef struct _GntAction
 {
 	const char *label;
-	void (*callback)();
+	void (*callback)(void);
 } GntAction;
 
 struct _GntWM
--- a/finch/libgnt/pygnt/test.py	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/libgnt/pygnt/test.py	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 import gobject
 import gnt
 
--- a/finch/plugins/gntgf.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/finch/plugins/gntgf.c	Mon Jan 07 16:28:25 2008 +0000
@@ -122,7 +122,7 @@
 }
 
 static void
-urgent()
+urgent(void)
 {
 	/* This is from deryni/tuomov's urgent_test.c */
 	Display *dpy;
@@ -322,7 +322,7 @@
 }
 
 static GntWidget *
-config_frame()
+config_frame(void)
 {
 	GntWidget *window, *tree, *check;
 	int i;
--- a/libpurple/account.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/account.c	Mon Jan 07 16:28:25 2008 +0000
@@ -467,7 +467,7 @@
 }
 
 static void
-schedule_accounts_save()
+schedule_accounts_save(void)
 {
 	if (save_timer == 0)
 		save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
--- a/libpurple/blist.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/blist.c	Mon Jan 07 16:28:25 2008 +0000
@@ -298,7 +298,7 @@
 }
 
 static xmlnode *
-blist_to_xmlnode()
+blist_to_xmlnode(void)
 {
 	xmlnode *node, *child, *grandchild;
 	PurpleBlistNode *gnode;
@@ -332,7 +332,7 @@
 }
 
 static void
-purple_blist_sync()
+purple_blist_sync(void)
 {
 	xmlnode *node;
 	char *data;
--- a/libpurple/buddyicon.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/buddyicon.c	Mon Jan 07 16:28:25 2008 +0000
@@ -49,6 +49,8 @@
 static GHashTable *icon_data_cache = NULL;
 static GHashTable *icon_file_cache = NULL;
 
+static void delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name);
+
 /* This one is used for both custom buddy icons
  * on PurpleContacts and account icons. */
 static GHashTable *pointer_icon_cache = NULL;
@@ -614,6 +616,10 @@
 				checksum = purple_blist_node_get_string((PurpleBlistNode*)b, "icon_checksum");
 				purple_buddy_icon_set_data(icon, data, len, checksum);
 			}
+			else
+			{
+				delete_buddy_icon_settings((PurpleBlistNode*)b, "buddy_icon");
+			}
 			g_free(path);
 		}
 
--- a/libpurple/cipher.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/cipher.c	Mon Jan 07 16:28:25 2008 +0000
@@ -775,7 +775,7 @@
 static void
 hmac_set_key(PurpleCipherContext *context, const guchar * key)
 {
-	hmac_set_key_with_len(context, key, strlen(key));
+	hmac_set_key_with_len(context, key, strlen((char *)key));
 }
 
 static size_t 
--- a/libpurple/core.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/core.h	Mon Jan 07 16:28:25 2008 +0000
@@ -67,13 +67,14 @@
  * Calls purple_core_quit().  This can be used as the function 
  * passed to purple_timeout_add() when you want to shutdown Purple 
  * in a specified amount of time.  When shutting down Purple 
- * from a plugin, you must use this with a timeout value of 0: 
+ * from a plugin, you must use this instead of purple_core_quit();
+ * for an immediate exit, use a timeout value of 0: 
  *   purple_timeout_add(0, purple_core_quitcb, NULL);
  * This is ensures that code from your plugin is not being 
- * executed when purple_core_quit() is called.  Otherwise you 
- * would get a core dump after purple_core_quit() executes and 
- * control returns to your plugin because purple_core_quit() frees 
- * all plugins.
+ * executed when purple_core_quit() is called.  If the plugin
+ * called purple_core_quit() directly, you would get a core dump
+ * after purple_core_quit() executes and control returns to your
+ * plugin because purple_core_quit() frees all plugins.
  */
 gboolean purple_core_quit_cb(gpointer unused);
 
--- a/libpurple/dnsquery.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/dnsquery.c	Mon Jan 07 16:28:25 2008 +0000
@@ -142,7 +142,7 @@
  */
 #ifdef HAVE_SIGNAL_H
 G_GNUC_NORETURN static void
-trap_gdb_bug()
+trap_gdb_bug(int sig)
 {
 	const char *message =
 		"Purple's DNS child got a SIGTRAP signal.\n"
@@ -286,7 +286,7 @@
  * Begin the functions for dealing with the DNS child processes.
  */
 static void
-cope_with_gdb_brokenness()
+cope_with_gdb_brokenness(void)
 {
 #ifdef __linux__
 	static gboolean already_done = FALSE;
@@ -460,7 +460,7 @@
 static void host_resolved(gpointer data, gint source, PurpleInputCondition cond);
 
 static void
-handle_next_queued_request()
+handle_next_queued_request(void)
 {
 	PurpleDnsQueryData *query_data;
 	PurpleDnsQueryResolverProcess *resolver;
--- a/libpurple/example/nullclient.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/example/nullclient.c	Mon Jan 07 16:28:25 2008 +0000
@@ -167,7 +167,7 @@
 };
 
 static void
-null_ui_init()
+null_ui_init(void)
 {
 	/**
 	 * This should initialize the UI components for all the modules. Here we
@@ -191,7 +191,7 @@
 };
 
 static void
-init_libpurple()
+init_libpurple(void)
 {
 	/* Set a custom user directory (optional) */
 	purple_util_set_user_dir(CUSTOM_USER_DIRECTORY);
@@ -250,14 +250,14 @@
 }
 
 static void
-connect_to_signals_for_demonstration_purposes_only()
+connect_to_signals_for_demonstration_purposes_only(void)
 {
 	static int handle;
 	purple_signal_connect(purple_connections_get_handle(), "signed-on", &handle,
 				PURPLE_CALLBACK(signed_on), NULL);
 }
 
-int main()
+int main(int argc, char *argv[])
 {
 	GList *iter;
 	int i, num;
--- a/libpurple/idle.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/idle.c	Mon Jan 07 16:28:25 2008 +0000
@@ -215,8 +215,8 @@
 /*
  * Check idle and set the timer to fire at the next idle-worth event 
  */
-static gint
-check_idleness_timer()
+static gboolean
+check_idleness_timer(void)
 {
 	check_idleness();
 	if (time_until_next_idle_event == 0)
@@ -225,7 +225,7 @@
 	{
 		/* +1 for the boundary,
 		 * +1 more for g_timeout_add_seconds rounding. */
-		idle_timer = purple_timeout_add_seconds(time_until_next_idle_event + 2, check_idleness_timer, NULL);
+		idle_timer = purple_timeout_add_seconds(time_until_next_idle_event + 2, (GSourceFunc)check_idleness_timer, NULL);
 	}
 	return FALSE;
 }
@@ -295,7 +295,7 @@
 }
 
 static void *
-purple_idle_get_handle()
+purple_idle_get_handle(void)
 {
 	static int handle;
 
@@ -307,7 +307,7 @@
 	int idle_poll_minutes = purple_prefs_get_int("/purple/away/mins_before_away");
 
 	 /* +1 more for g_timeout_add_seconds rounding. */
-	idle_timer = purple_timeout_add_seconds((idle_poll_minutes * 60) + 2, check_idleness_timer, NULL);
+	idle_timer = purple_timeout_add_seconds((idle_poll_minutes * 60) + 2, (GSourceFunc)check_idleness_timer, NULL);
 
 	purple_idle_touch();
 
--- a/libpurple/plugins/ciphertest.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/plugins/ciphertest.c	Mon Jan 07 16:28:25 2008 +0000
@@ -61,7 +61,7 @@
 };
 
 static void
-cipher_test_md5() {
+cipher_test_md5(void) {
 	PurpleCipher *cipher;
 	PurpleCipherContext *context;
 	gchar digest[33];
@@ -113,12 +113,12 @@
 	{"a", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"},
 	{"abc", "a9993e364706816aba3e25717850c26c9cd0d89d"} ,
 	{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "84983e441c3bd26ebaae4aa1f95129e5e54670f1"} ,
-    {NULL, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"},
+	{NULL, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"},
 	{NULL, NULL}
 };
 
 static void
-cipher_test_sha1() {
+cipher_test_sha1(void) {
 	PurpleCipher *cipher;
 	PurpleCipherContext *context;
 	gchar digest[41];
@@ -176,7 +176,7 @@
 }
 
 static void
-cipher_test_digest()
+cipher_test_digest(void)
 {
 	const gchar *nonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093";
 	const gchar *client_nonce = "0a4f113b";
--- a/libpurple/plugins/log_reader.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/plugins/log_reader.c	Mon Jan 07 16:28:25 2008 +0000
@@ -2426,7 +2426,7 @@
 
 }
 
-static void log_reader_init_prefs() {
+static void log_reader_init_prefs(void) {
 	char *path;
 #ifdef _WIN32
 	char *folder;
--- a/libpurple/plugins/perl/common/fallback/const-c.inc	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/plugins/perl/common/fallback/const-c.inc	Mon Jan 07 16:28:25 2008 +0000
@@ -33,7 +33,7 @@
      Regenerate these constant functions by feeding this entire source file to
      perl -x
 
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
 use ExtUtils::Constant qw (constant_types C_constant XS_constant);
 
 my $types = {map {($_, 1)} qw(IV)};
--- a/libpurple/plugins/ssl/ssl-nss.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/plugins/ssl/ssl-nss.c	Mon Jan 07 16:28:25 2008 +0000
@@ -109,7 +109,7 @@
 	}
 }
 
-static gchar *get_error_text()
+static gchar *get_error_text(void)
 {
 	PRInt32 len = PR_GetErrorTextLength();
 	gchar *ret = NULL;
--- a/libpurple/plugins/tcl/tcl.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/plugins/tcl/tcl.c	Mon Jan 07 16:28:25 2008 +0000
@@ -149,7 +149,7 @@
 	return 0;
 }
 
-static Tcl_Interp *tcl_create_interp()
+static Tcl_Interp *tcl_create_interp(void)
 {
 	Tcl_Interp *interp;
 
--- a/libpurple/plugins/test.pl	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/plugins/test.pl	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
 
 use Gaim;
 
--- a/libpurple/protocols/bonjour/bonjour.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/bonjour/bonjour.c	Mon Jan 07 16:28:25 2008 +0000
@@ -617,7 +617,7 @@
 #endif
 
 static void
-initialize_default_account_values()
+initialize_default_account_values(void)
 {
 #ifndef _WIN32
 	struct passwd *info;
--- a/libpurple/protocols/bonjour/parser.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/bonjour/parser.c	Mon Jan 07 16:28:25 2008 +0000
@@ -39,7 +39,7 @@
 	for(i=0; i < nb_attributes * 5; i+=5) {
 		if(!xmlStrcmp(attributes[i], (xmlChar*) "from")) {
 			int len = attributes[i+4] - attributes[i+3];
-			bconv->buddy_name = g_strndup(attributes[i+3], len);
+			bconv->buddy_name = g_strndup((char *)attributes[i+3], len);
 			bonjour_jabber_conv_match_by_name(bconv);
 
 			return (bconv->pb != NULL);
--- a/libpurple/protocols/jabber/jabber.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Mon Jan 07 16:28:25 2008 +0000
@@ -1523,10 +1523,16 @@
 				} else
 					purple_notify_user_info_add_pair(user_info, _("Mood"), mood);
 			}
-			if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {	
+			if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {
 				PurpleStatus *tune = purple_presence_get_status(presence, "tune");
 				const char *title = purple_status_get_attr_string(tune, PURPLE_TUNE_TITLE);
-				purple_notify_user_info_add_pair(user_info, _("Current media"), title);
+				const char *artist = purple_status_get_attr_string(tune, PURPLE_TUNE_ARTIST);
+				const char *album = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM);
+				char *playing = purple_util_format_song_info(title, artist, album, NULL);
+				if (playing) {
+					purple_notify_user_info_add_pair(user_info, _("Now Listening"), playing);
+					g_free(playing);
+				}
 			}
 		}
 
--- a/libpurple/protocols/msn/msn.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/msn/msn.c	Mon Jan 07 16:28:25 2008 +0000
@@ -593,8 +593,8 @@
 			PurpleStatus *tune = purple_presence_get_status(presence, "tune");
 			const char *title = purple_status_get_attr_string(tune, PURPLE_TUNE_TITLE);
 			const char *artist = purple_status_get_attr_string(tune, PURPLE_TUNE_ARTIST);
-			currentmedia = g_strdup_printf("%s%s%s", title, artist ? " - " : "",
-					artist ? artist : "");
+			const char *album = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM);
+			currentmedia = purple_util_format_song_info(title, artist, album, NULL);
 			/* We could probably just use user->media.title etc. here */
 		}
 
@@ -643,9 +643,7 @@
 		}
 
 		if (currentmedia) {
-			tmp = g_markup_escape_text(currentmedia, -1);
-			purple_notify_user_info_add_pair(user_info, _("Current media"), tmp);
-			g_free(tmp);
+			purple_notify_user_info_add_pair(user_info, _("Now Listening"), currentmedia);
 			g_free(currentmedia);
 		}
 	}
--- a/libpurple/protocols/msnp9/slpcall.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/msnp9/slpcall.c	Mon Jan 07 16:28:25 2008 +0000
@@ -34,7 +34,7 @@
  **************************************************************************/
 
 static char *
-rand_guid()
+rand_guid(void)
 {
 	return g_strdup_printf("%4X%4X-%4X-%4X-%4X-%4X%4X%4X",
 			rand() % 0xAAFF + 0x1111,
--- a/libpurple/protocols/novell/novell.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/novell/novell.c	Mon Jan 07 16:28:25 2008 +0000
@@ -1029,7 +1029,7 @@
  ******************************************************************************/
 
 static char *
-_user_agent_string()
+_user_agent_string(void)
 {
 
 #if !defined(_WIN32)
--- a/libpurple/protocols/qq/file_trans.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/qq/file_trans.c	Mon Jan 07 16:28:25 2008 +0000
@@ -59,7 +59,7 @@
 	return key;
 }
 		
-static guint32 _gen_file_key()
+static guint32 _gen_file_key(void)
 {
 	guint8 seed;
 	
--- a/libpurple/protocols/sametime/sametime.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Mon Jan 07 16:28:25 2008 +0000
@@ -3806,7 +3806,7 @@
 }
 
 
-static int mw_rand() {
+static int mw_rand(void) {
   static int seed = 0;
 
   /* for diversity, not security. don't touch */
@@ -3818,7 +3818,7 @@
 
 
 /** generates a random-ish content id string */
-static char *im_mime_content_id() {
+static char *im_mime_content_id(void) {
   return g_strdup_printf("%03x@%05xmeanwhile",
 			 mw_rand() & 0xfff, mw_rand() & 0xfffff);
 }
@@ -3826,7 +3826,7 @@
 
 /** generates a multipart/related content type with a random-ish
     boundary value */
-static char *im_mime_content_type() {
+static char *im_mime_content_type(void) {
   return g_strdup_printf("multipart/related; boundary=related_MW%03x_%04x",
                          mw_rand() & 0xfff, mw_rand() & 0xffff);
 }
--- a/libpurple/protocols/simple/simple.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/simple/simple.c	Mon Jan 07 16:28:25 2008 +0000
@@ -45,17 +45,17 @@
 #include "dnssrv.h"
 #include "ntlm.h"
 
-static char *gentag() {
+static char *gentag(void) {
 	return g_strdup_printf("%04d%04d", rand() & 0xFFFF, rand() & 0xFFFF);
 }
 
-static char *genbranch() {
+static char *genbranch(void) {
 	return g_strdup_printf("z9hG4bK%04X%04X%04X%04X%04X",
 		rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF,
 		rand() & 0xFFFF, rand() & 0xFFFF);
 }
 
-static char *gencallid() {
+static char *gencallid(void) {
 	return g_strdup_printf("%04Xg%04Xa%04Xi%04Xm%04Xt%04Xb%04Xx%04Xx",
 		rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF,
 		rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF,
--- a/libpurple/protocols/zephyr/ZSendList.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/zephyr/ZSendList.c	Mon Jan 07 16:28:25 2008 +0000
@@ -24,7 +24,7 @@
     char *list[];
     int nitems;
     Z_AuthProc cert_routine;
-    Code_t (*send_routine)();
+    Code_t (*send_routine)(void);
 {
     Code_t retval;
     ZNotice_t newnotice;
--- a/libpurple/protocols/zephyr/ZSendNot.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/zephyr/ZSendNot.c	Mon Jan 07 16:28:25 2008 +0000
@@ -20,7 +20,7 @@
 Code_t ZSrvSendNotice(notice, cert_routine, send_routine)
     ZNotice_t *notice;
     Z_AuthProc cert_routine;
-    Code_t (*send_routine)();
+    Code_t (*send_routine)(void);
 {    
     Code_t retval;
     ZNotice_t newnotice;
--- a/libpurple/protocols/zephyr/Zinternal.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/zephyr/Zinternal.c	Mon Jan 07 16:28:25 2008 +0000
@@ -33,8 +33,6 @@
 #include <utmp.h>
 #endif
 
-extern char *inet_ntoa ();
-
 int __Zephyr_fd = -1;
 int __Zephyr_open;
 int __Zephyr_port = -1;
@@ -144,7 +142,7 @@
 
 /* Return 1 if there is a packet waiting, 0 otherwise */
 
-static int Z_PacketWaiting()
+static int Z_PacketWaiting(void)
 {
     struct timeval tv;
     fd_set read;
@@ -158,7 +156,7 @@
 
 /* Wait for a complete notice to become available */
 
-Code_t Z_WaitForComplete()
+Code_t Z_WaitForComplete(void)
 {
     Code_t retval;
 
@@ -195,9 +193,7 @@
  * notices that haven't been touched in a while
  */
 
-static struct _Z_InputQ *Z_SearchQueue(uid, kind)
-    ZUnique_Id_t *uid;
-    ZNotice_Kind_t kind;
+static struct _Z_InputQ *Z_SearchQueue(ZUnique_Id_t *uid, ZNotice_Kind_t kind)
 {
     register struct _Z_InputQ *qptr;
     struct _Z_InputQ *next;
--- a/libpurple/protocols/zephyr/zephyr.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Mon Jan 07 16:28:25 2008 +0000
@@ -53,7 +53,7 @@
 
 extern Code_t ZGetLocations(ZLocations_t *, int *);
 extern Code_t ZSetLocation(char *);
-extern Code_t ZUnsetLocation();
+extern Code_t ZUnsetLocation(void);
 extern Code_t ZGetSubscriptions(ZSubscription_t *, int*);
 extern char __Zephyr_realm[];
 typedef struct _zframe zframe;
@@ -1386,7 +1386,7 @@
 
 #endif /* WIN32 */
 
-static char *get_exposure_level()
+static char *get_exposure_level(void)
 {
 	/* XXX add real error reporting */
 	char *exposure = ZGetVariable("exposure");
@@ -2058,7 +2058,7 @@
 static int zephyr_send_message(zephyr_account *zephyr,char* zclass, char* instance, char* recipient, const char *im, 
 			       const char *sig, char *opcode) ;
 
-static const char * zephyr_get_signature()
+static const char * zephyr_get_signature(void)
 {
 	/* XXX add zephyr error reporting */
 	const char * sig =ZGetVariable("zwrite-signature");
@@ -2676,7 +2676,7 @@
 		return PURPLE_CMD_RET_FAILED;
 }
 
-static void zephyr_register_slash_commands()
+static void zephyr_register_slash_commands(void)
 {
 
 	purple_cmd_register("msg","ws", PURPLE_CMD_P_PRPL,
--- a/libpurple/protocols/zephyr/zephyr.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/protocols/zephyr/zephyr.h	Mon Jan 07 16:28:25 2008 +0000
@@ -163,9 +163,9 @@
 Code_t ZReadAscii16 ZP((char *, int, unsigned short *));
 Code_t ZSendPacket ZP((char*, int, int));
 Code_t ZSendList ZP((ZNotice_t*, char *[], int, Z_AuthProc));
-Code_t ZSrvSendList ZP((ZNotice_t*, char*[], int, Z_AuthProc, Code_t (*)()));
+Code_t ZSrvSendList ZP((ZNotice_t*, char*[], int, Z_AuthProc, Code_t (*)(void)));
 Code_t ZSendNotice ZP((ZNotice_t *, Z_AuthProc));
-Code_t ZSrvSendNotice ZP((ZNotice_t*, Z_AuthProc, Code_t (*)()));
+Code_t ZSrvSendNotice ZP((ZNotice_t*, Z_AuthProc, Code_t (*)(void)));
 Code_t ZFormatNotice ZP((ZNotice_t*, char**, int*, Z_AuthProc));
 Code_t ZFormatSmallNotice ZP((ZNotice_t*, ZPacket_t, int*, Z_AuthProc));
 Code_t ZFormatRawNoticeList ZP((ZNotice_t *notice, char *list[], int nitems,
--- a/libpurple/purple-remote	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/purple-remote	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 import dbus
 import re
--- a/libpurple/purple-send	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/purple-send	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 
 METHOD_NAME=$1
 
--- a/libpurple/purple-send-async	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/purple-send-async	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 
 METHOD_NAME=$1
 
--- a/libpurple/purple-url-handler	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/purple-url-handler	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 import dbus
 import re
--- a/libpurple/roomlist.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/roomlist.c	Mon Jan 07 16:28:25 2008 +0000
@@ -218,6 +218,11 @@
 		prpl_info->roomlist_expand_category(list, category);
 }
 
+GList * purple_roomlist_get_fields(PurpleRoomlist *list)
+{
+	return list->fields;
+}
+
 /*@}*/
 
 /**************************************************************************/
@@ -293,6 +298,26 @@
 	g_hash_table_destroy(components);
 }
 
+PurpleRoomlistRoomType purple_roomlist_room_get_type(PurpleRoomlistRoom *room)
+{
+	return room->type;
+}
+
+const char * purple_roomlist_room_get_name(PurpleRoomlistRoom *room)
+{
+	return room->name;
+}
+
+PurpleRoomlistRoom * purple_roomlist_room_get_parent(PurpleRoomlistRoom *room)
+{
+	return room->parent;
+}
+
+GList * purple_roomlist_room_get_fields(PurpleRoomlistRoom *room)
+{
+	return room->fields;
+}
+
 /*@}*/
 
 /**************************************************************************/
@@ -319,6 +344,21 @@
 	return f;
 }
 
+PurpleRoomlistFieldType purple_roomlist_field_get_type(PurpleRoomlistField *field)
+{
+	return field->type;
+}
+
+const char * purple_roomlist_field_get_label(PurpleRoomlistField *field)
+{
+	return field->label;
+}
+
+gboolean purple_roomlist_field_get_hidden(PurpleRoomlistField *field)
+{
+	return field->hidden;
+}
+
 /*@}*/
 
 /**************************************************************************/
--- a/libpurple/roomlist.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/roomlist.h	Mon Jan 07 16:28:25 2008 +0000
@@ -237,6 +237,15 @@
  */
 void purple_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category);
 
+/**
+ * Get the list of fields for a roomlist.
+ *
+ * @param roomlist  The roomlist, which must not be @c NULL.
+ * @constreturn A list of fields
+ * @since 2.4.0
+ */
+GList * purple_roomlist_get_fields(PurpleRoomlist *roomlist);
+
 /*@}*/
 
 /**************************************************************************/
@@ -273,6 +282,39 @@
  */
 void purple_roomlist_room_join(PurpleRoomlist *list, PurpleRoomlistRoom *room);
 
+/**
+ * Get the type of a room.
+ * @param room  The room, which must not be @c NULL.
+ * @return The type of the room.
+ * @since 2.4.0
+ */
+PurpleRoomlistRoomType purple_roomlist_room_get_type(PurpleRoomlistRoom *room);
+
+/**
+ * Get the name of a room.
+ * @param room  The room, which must not be @c NULL.
+ * @return The name of the room.
+ * @since 2.4.0
+ */
+const char * purple_roomlist_room_get_name(PurpleRoomlistRoom *room);
+
+/**
+ * Get the parent of a room.
+ * @param room  The room, which must not be @c NULL.
+ * @return The parent of the room, which can be @c NULL.
+ * @since 2.4.0
+ */
+PurpleRoomlistRoom * purple_roomlist_room_get_parent(PurpleRoomlistRoom *room);
+
+/**
+ * Get the list of fields for a room.
+ *
+ * @param room  The room, which must not be @c NULL.
+ * @constreturn A list of fields
+ * @since 2.4.0
+ */
+GList * purple_roomlist_room_get_fields(PurpleRoomlistRoom *room);
+
 /*@}*/
 
 /**************************************************************************/
@@ -294,6 +336,36 @@
 PurpleRoomlistField *purple_roomlist_field_new(PurpleRoomlistFieldType type,
                                            const gchar *label, const gchar *name,
                                            gboolean hidden);
+
+/**
+ * Get the type of a field.
+ *
+ * @param field  A PurpleRoomlistField, which must not be @c NULL.
+ *
+ * @return  The type of the field.
+ * @since 2.4.0
+ */
+PurpleRoomlistFieldType purple_roomlist_field_get_type(PurpleRoomlistField *field);
+
+/**
+ * Get the label of a field.
+ *
+ * @param field  A PurpleRoomlistField, which must not be @c NULL.
+ *
+ * @return  The label of the field.
+ * @since 2.4.0
+ */
+const char * purple_roomlist_field_get_label(PurpleRoomlistField *field);
+
+/**
+ * Check whether a roomlist-field is hidden.
+ * @param field  A PurpleRoomlistField, which must not be @c NULL.
+ *
+ * @return  @c TRUE if the field is hidden, @c FALSE otherwise.
+ * @since 2.4.0
+ */
+gboolean purple_roomlist_field_get_hidden(PurpleRoomlistField *field);
+
 /*@}*/
 
 /**************************************************************************/
--- a/libpurple/savedstatuses.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/savedstatuses.c	Mon Jan 07 16:28:25 2008 +0000
@@ -190,7 +190,7 @@
  * does the expiration.
  */
 static void
-remove_old_transient_statuses()
+remove_old_transient_statuses(void)
 {
 	GList *l, *next;
 	PurpleSavedStatus *saved_status, *current_status;
--- a/libpurple/stun.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/stun.c	Mon Jan 07 16:28:25 2008 +0000
@@ -104,7 +104,7 @@
 	g_free(sc);
 }
 
-static void do_callbacks() {
+static void do_callbacks(void) {
 	while(callbacks) {
 		StunCallback cb = callbacks->data;
 		if(cb)
--- a/libpurple/upnp.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/upnp.c	Mon Jan 07 16:28:25 2008 +0000
@@ -777,7 +777,7 @@
 
 /* TODO: This could be exported */
 static const gchar *
-purple_upnp_get_internal_ip()
+purple_upnp_get_internal_ip(void)
 {
 	if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED
 			&& control_info.internalip
--- a/libpurple/util.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/util.c	Mon Jan 07 16:28:25 2008 +0000
@@ -4628,3 +4628,57 @@
 #endif /* HAVE_SIGNAL_H */
 #endif /* !_WIN32 */
 }
+
+void purple_util_set_current_song(const char *title, const char *artist, const char *album)
+{
+	GList *list = purple_accounts_get_all();
+	for (; list; list = list->next) {
+		PurplePresence *presence;
+		PurpleStatus *tune;
+		PurpleAccount *account = list->data;
+		if (!purple_account_get_enabled(account, purple_core_get_ui()))
+			continue;
+
+		presence = purple_account_get_presence(account);
+		tune = purple_presence_get_status(presence, "tune");
+		if (!tune)
+			continue;
+		if (title) {
+			purple_status_set_active(tune, TRUE);
+			purple_status_set_attr_string(tune, PURPLE_TUNE_TITLE, title);
+			purple_status_set_attr_string(tune, PURPLE_TUNE_ARTIST, artist);
+			purple_status_set_attr_string(tune, PURPLE_TUNE_ALBUM, album);
+		} else {
+			purple_status_set_active(tune, FALSE);
+		}
+	}
+}
+
+char * purple_util_format_song_info(const char *title, const char *artist, const char *album, gpointer unused)
+{
+	GString *string;
+	char *esc;
+
+	if (!title)
+		return NULL;
+
+	esc = g_markup_escape_text(title, -1);
+	string = g_string_new("");
+	g_string_append_printf(string, "%s", esc);
+	g_free(esc);
+
+	if (artist) {
+		esc = g_markup_escape_text(artist, -1);
+		g_string_append_printf(string, _(" - %s"), esc);
+		g_free(esc);
+	}
+
+	if (album) {
+		esc = g_markup_escape_text(album, -1);
+		g_string_append_printf(string, _(" (%s)"), esc);
+		g_free(esc);
+	}
+
+	return g_string_free(string, FALSE);
+}
+
--- a/libpurple/util.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/libpurple/util.h	Mon Jan 07 16:28:25 2008 +0000
@@ -85,6 +85,31 @@
  */
 void purple_menu_action_free(PurpleMenuAction *act);
 
+/**
+ * Set the appropriate presence values for the currently playing song.
+ *
+ * @param title     The title of the song, @c NULL to unset the value.
+ * @param artist    The artist of the song, can be @c NULL.
+ * @param album     The album of the song, can be @c NULL.
+ * @since 2.4.0
+ */
+void purple_util_set_current_song(const char *title, const char *artist,
+		const char *album);
+
+/**
+ * Format song information.
+ *
+ * @param title     The title of the song, @c NULL to unset the value.
+ * @param artist    The artist of the song, can be @c NULL.
+ * @param album     The album of the song, can be @c NULL.
+ * @param unused    Currently unused, must be @c NULL.
+ *
+ * @return   The formatted string. The caller must #g_free the returned string.
+ * @since 2.4.0
+ */
+char * purple_util_format_song_info(const char *title, const char *artist,
+		const char *album, gpointer unused);
+
 /**************************************************************************/
 /** @name Utility Subsystem                                               */
 /**************************************************************************/
--- a/pidgin/gtkaccount.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkaccount.c	Mon Jan 07 16:28:25 2008 +0000
@@ -158,25 +158,7 @@
 add_pref_box(AccountPrefsDialog *dialog, GtkWidget *parent,
 			 const char *text, GtkWidget *widget)
 {
-	GtkWidget *hbox;
-	GtkWidget *label;
-
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(parent), hbox, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
-
-	label = gtk_label_new_with_mnemonic(text);
-	gtk_size_group_add_widget(dialog->sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget);
-	gtk_widget_show(label);
-
-	gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, PIDGIN_HIG_BORDER);
-	gtk_widget_show(widget);
-	pidgin_set_accessible_label (widget, label);
-
-	return hbox;
+	return pidgin_add_widget_to_vbox(GTK_BOX(parent), text, dialog->sg, widget, TRUE, NULL);
 }
 
 static void
--- a/pidgin/gtkblist.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkblist.c	Mon Jan 07 16:28:25 2008 +0000
@@ -177,7 +177,7 @@
 } PidginBlistNode;
 
 static char dim_grey_string[8] = "";
-static char *dim_grey()
+static char *dim_grey(void)
 {
 	if (!gtkblist)
 		return "dim grey";
@@ -708,12 +708,12 @@
 	pidgin_blist_update(purple_get_blist(), node);
 }
 
-static void gtk_blist_show_systemlog_cb()
+static void gtk_blist_show_systemlog_cb(void)
 {
 	pidgin_syslog_show();
 }
 
-static void gtk_blist_show_onlinehelp_cb()
+static void gtk_blist_show_onlinehelp_cb(void)
 {
 	purple_notify_uri(NULL, PURPLE_WEBSITE "documentation");
 }
@@ -843,20 +843,10 @@
 
 	for (tmp = list; tmp; tmp = tmp->next)
 	{
-		GtkWidget *label;
-		GtkWidget *rowbox;
 		GtkWidget *input;
 
 		pce = tmp->data;
 
-		rowbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-		gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0);
-
-		label = gtk_label_new_with_mnemonic(pce->label);
-		gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-		gtk_size_group_add_widget(data->sg, label);
-		gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
-
 		if (pce->is_int)
 		{
 			GtkObject *adjust;
@@ -864,7 +854,7 @@
 										1, 10, 10);
 			input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
 			gtk_widget_set_size_request(input, 50, -1);
-			gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0);
+			pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, FALSE, NULL);
 		}
 		else
 		{
@@ -880,7 +870,7 @@
 				if (gtk_entry_get_invisible_char(GTK_ENTRY(input)) == '*')
 					gtk_entry_set_invisible_char(GTK_ENTRY(input), PIDGIN_INVISIBLE_CHAR);
 			}
-			gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0);
+			pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, TRUE, NULL);
 			g_signal_connect(G_OBJECT(input), "changed",
 							 G_CALLBACK(joinchat_set_sensitive_if_input_cb), data);
 		}
@@ -891,8 +881,6 @@
 			gtk_widget_grab_focus(input);
 			focus = FALSE;
 		}
-		gtk_label_set_mnemonic_widget(GTK_LABEL(label), input);
-		pidgin_set_accessible_label(input, label);
 		g_object_set_data(G_OBJECT(input), "identifier", (gpointer)pce->identifier);
 		g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int));
 		g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required));
@@ -988,23 +976,14 @@
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
-	rowbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_box_pack_start(GTK_BOX(vbox), rowbox, TRUE, TRUE, 0);
-
 	data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
-	label = gtk_label_new_with_mnemonic(_("_Account:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(data->sg, label);
-
 	data->account_menu = pidgin_account_option_menu_new(NULL, FALSE,
 			G_CALLBACK(joinchat_select_account_cb),
 			chat_account_filter_func, data);
 	gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label),
-								  GTK_WIDGET(data->account_menu));
-	pidgin_set_accessible_label (data->account_menu, label);
+
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Account:"), data->sg, data->account_menu, TRUE, NULL);
 
 	data->entries_box = gtk_vbox_new(FALSE, 5);
 	gtk_container_add(GTK_CONTAINER(vbox), data->entries_box);
@@ -1117,7 +1096,7 @@
 	}
 }
 
-static void pidgin_blist_add_chat_cb()
+static void pidgin_blist_add_chat_cb(void)
 {
 	GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview));
 	GtkTreeIter iter;
@@ -1137,7 +1116,7 @@
 	}
 }
 
-static void pidgin_blist_add_buddy_cb()
+static void pidgin_blist_add_buddy_cb(void)
 {
 	GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview));
 	GtkTreeIter iter;
@@ -2787,7 +2766,7 @@
 }
 
 static void
-pidgin_blist_destroy_tooltip_data()
+pidgin_blist_destroy_tooltip_data(void)
 {
 	while(gtkblist->tooltipdata) {
 		struct tooltip_data *td = gtkblist->tooltipdata->data;
@@ -3787,7 +3766,7 @@
 	return text;
 }
 
-static void pidgin_blist_restore_position()
+static void pidgin_blist_restore_position(void)
 {
 	int blist_x, blist_y, blist_width, blist_height;
 
@@ -3934,7 +3913,7 @@
 }
 
 static void
-unseen_conv_menu()
+unseen_conv_menu(void)
 {
 	static GtkWidget *menu = NULL;
 	GList *convs = NULL;
@@ -4220,7 +4199,8 @@
 	pidgin_blist_sort_method_set(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type"));
 }
 
-static void _prefs_change_redo_list()
+static void _prefs_change_redo_list(const char *name, PurplePrefType type,
+                                    gconstpointer val, gpointer data)
 {
 	GtkTreeSelection *sel;
 	GtkTreeIter iter;
@@ -6516,20 +6496,10 @@
 
 	for (tmp = list; tmp; tmp = tmp->next)
 	{
-		GtkWidget *label;
-		GtkWidget *rowbox;
 		GtkWidget *input;
 
 		pce = tmp->data;
 
-		rowbox = gtk_hbox_new(FALSE, 5);
-		gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0);
-
-		label = gtk_label_new_with_mnemonic(pce->label);
-		gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-		gtk_size_group_add_widget(data->sg, label);
-		gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
-
 		if (pce->is_int)
 		{
 			GtkObject *adjust;
@@ -6537,7 +6507,7 @@
 										1, 10, 10);
 			input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
 			gtk_widget_set_size_request(input, 50, -1);
-			gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0);
+			pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, FALSE, NULL);
 		}
 		else
 		{
@@ -6553,7 +6523,7 @@
 				if (gtk_entry_get_invisible_char(GTK_ENTRY(input)) == '*')
 					gtk_entry_set_invisible_char(GTK_ENTRY(input), PIDGIN_INVISIBLE_CHAR);
 			}
-			gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0);
+			pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, TRUE, NULL);
 			g_signal_connect(G_OBJECT(input), "changed",
 							 G_CALLBACK(addchat_set_sensitive_if_input_cb), data);
 		}
@@ -6564,8 +6534,6 @@
 			gtk_widget_grab_focus(input);
 			focus = FALSE;
 		}
-		gtk_label_set_mnemonic_widget(GTK_LABEL(label), input);
-		pidgin_set_accessible_label(input, label);
 		g_object_set_data(G_OBJECT(input), "identifier", (gpointer)pce->identifier);
 		g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int));
 		g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required));
@@ -6608,7 +6576,6 @@
 	GList *l;
 	PurpleConnection *gc;
 	GtkWidget *label;
-	GtkWidget *rowbox;
 	GtkWidget *hbox;
 	GtkWidget *vbox;
 	GtkWidget *img;
@@ -6684,20 +6651,10 @@
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
-	rowbox = gtk_hbox_new(FALSE, 5);
-	gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("_Account:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_size_group_add_widget(data->sg, label);
-	gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
-
 	data->account_menu = pidgin_account_option_menu_new(account, FALSE,
 			G_CALLBACK(addchat_select_account_cb),
 			chat_account_filter_func, data);
-	gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), data->account_menu);
-	pidgin_set_accessible_label (data->account_menu, label);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Account:"), data->sg, data->account_menu, TRUE, NULL);
 
 	data->entries_box = gtk_vbox_new(FALSE, 5);
 	gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0);
@@ -6705,36 +6662,17 @@
 
 	rebuild_addchat_entries(data);
 
-	rowbox = gtk_hbox_new(FALSE, 5);
-	gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("A_lias:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_size_group_add_widget(data->sg, label);
-	gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
-
 	data->alias_entry = gtk_entry_new();
 	if (alias != NULL)
 		gtk_entry_set_text(GTK_ENTRY(data->alias_entry), alias);
-	gtk_box_pack_end(GTK_BOX(rowbox), data->alias_entry, TRUE, TRUE, 0);
 	gtk_entry_set_activates_default(GTK_ENTRY(data->alias_entry), TRUE);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), data->alias_entry);
-	pidgin_set_accessible_label (data->alias_entry, label);
+
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("A_lias:"), data->sg, data->alias_entry, TRUE, NULL);
 	if (name != NULL)
 		gtk_widget_grab_focus(data->alias_entry);
 
-	rowbox = gtk_hbox_new(FALSE, 5);
-	gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("_Group:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_size_group_add_widget(data->sg, label);
-	gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
-
 	data->group_combo = pidgin_text_combo_box_entry_new(group ? group->name : NULL, groups_tree());
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_BIN(data->group_combo)->child);
-	pidgin_set_accessible_label (data->group_combo, label);
-	gtk_box_pack_end(GTK_BOX(rowbox), data->group_combo, TRUE, TRUE, 0);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Group:"), data->sg, data->group_combo, TRUE, NULL);
 	
 	data->autojoin = gtk_check_button_new_with_mnemonic(_("Auto_join when account becomes online."));
 	data->persistent = gtk_check_button_new_with_mnemonic(_("_Hide chat when the window is closed."));
--- a/pidgin/gtkconn.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkconn.c	Mon Jan 07 16:28:25 2008 +0000
@@ -177,7 +177,7 @@
 	}
 }
 
-static void pidgin_connection_network_connected ()
+static void pidgin_connection_network_connected (void)
 {
 	GList *list, *l;
 	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
@@ -196,7 +196,7 @@
 	g_list_free(list);
 }
 
-static void pidgin_connection_network_disconnected ()
+static void pidgin_connection_network_disconnected (void)
 {
 	GList *list, *l;
 	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
--- a/pidgin/gtkconv.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkconv.c	Mon Jan 07 16:28:25 2008 +0000
@@ -1350,6 +1350,7 @@
 	PidginWindow *win = data;
 	PurpleConversation *conv;
 	gboolean logging;
+	PurpleBlistNode *node;
 
 	conv = pidgin_conv_window_get_active_conversation(win);
 
@@ -1360,6 +1361,8 @@
 
 	if (logging == purple_conversation_is_logging(conv))
 		return;
+	
+	node = get_conversation_blist_node(conv);
 
 	if (logging)
 	{
@@ -1383,6 +1386,27 @@
 		/* Disable the logging second, so that the above message can be logged. */
 		purple_conversation_set_logging(conv, FALSE);
 	}
+
+	/* Save the setting IFF it's different than the pref. */
+	switch (conv->type)
+	{
+		case PURPLE_CONV_TYPE_IM:
+			if (logging == purple_prefs_get_bool("/purple/logging/log_ims"))
+				purple_blist_node_remove_setting(node, "enable-logging");
+			else
+				purple_blist_node_set_bool(node, "enable-logging", logging);
+			break;
+
+		case PURPLE_CONV_TYPE_CHAT:
+			if (logging == purple_prefs_get_bool("/purple/logging/log_chats"))
+				purple_blist_node_remove_setting(node, "enable-logging");
+			else
+				purple_blist_node_set_bool(node, "enable-logging", logging);
+			break;
+
+		default:
+			break;
+	}
 }
 
 static void
@@ -4911,6 +4935,7 @@
 	GtkWidget *pane = NULL;
 	GtkWidget *tab_cont;
 	PurpleBlistNode *convnode;
+	PurpleValue *value;
 
 	if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
 		conv->ui_data = gtkconv;
@@ -4998,6 +5023,13 @@
 	if (convnode == NULL || !purple_blist_node_get_bool(convnode, "gtk-mute-sound"))
 		gtkconv->make_sound = TRUE;
 
+	if (convnode != NULL &&
+	    (value = g_hash_table_lookup(convnode->settings, "enable-logging")) &&
+	    purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
+	{
+		purple_conversation_set_logging(conv, purple_value_get_boolean(value));
+	}
+
 	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"))
 		gtk_widget_show(gtkconv->toolbar);
 	else
--- a/pidgin/gtkdialogs.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkdialogs.c	Mon Jan 07 16:28:25 2008 +0000
@@ -288,7 +288,7 @@
 	}
 }
 
-static void destroy_about()
+static void destroy_about(void)
 {
 	if (about != NULL)
 		gtk_widget_destroy(about);
--- a/pidgin/gtkdocklet-x11.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkdocklet-x11.c	Mon Jan 07 16:28:25 2008 +0000
@@ -48,7 +48,7 @@
 static void docklet_x11_create(gboolean);
 
 static gboolean
-docklet_x11_recreate_cb()
+docklet_x11_recreate_cb(gpointer data)
 {
 	docklet_x11_create(TRUE);
 
@@ -147,7 +147,7 @@
 }
 
 static void
-docklet_x11_blank_icon()
+docklet_x11_blank_icon(void)
 {
 	if (!blank_icon) {
 		GtkIconSize size = GTK_ICON_SIZE_LARGE_TOOLBAR;
@@ -205,7 +205,7 @@
 #endif
 
 static void
-docklet_x11_destroy()
+docklet_x11_destroy(void)
 {
 	g_return_if_fail(docklet != NULL);
 
@@ -230,7 +230,7 @@
 }
 
 static gboolean
-docklet_x11_embed_timeout_cb()
+docklet_x11_embed_timeout_cb(gpointer data)
 {
 	/* The docklet was not embedded within the timeout.
 	 * Remove it as a visibility manager, but leave the plugin
@@ -301,7 +301,7 @@
 }
 
 static void
-docklet_x11_create_ui_op()
+docklet_x11_create_ui_op(void)
 {
 	docklet_x11_create(FALSE);
 }
--- a/pidgin/gtkdocklet.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkdocklet.c	Mon Jan 07 16:28:25 2008 +0000
@@ -62,7 +62,7 @@
  * docklet status and utility functions
  **************************************************************************/
 static gboolean
-docklet_blink_icon()
+docklet_blink_icon(gpointer data)
 {
 	static gboolean blinked = FALSE;
 	gboolean ret = FALSE; /* by default, don't keep blinking */
@@ -108,7 +108,7 @@
 }
 
 static gboolean
-docklet_update_status()
+docklet_update_status(void)
 {
 	GList *convs, *l;
 	int count;
@@ -219,7 +219,7 @@
 }
 
 static gboolean
-online_account_supports_chat()
+online_account_supports_chat(void)
 {
 	GList *c = NULL;
 	c = purple_connections_get_all();
@@ -523,7 +523,7 @@
 }
 
 static GtkWidget *
-docklet_status_submenu()
+docklet_status_submenu(void)
 {
 	GtkWidget *submenu, *menuitem;
 	GList *popular_statuses, *cur;
@@ -667,7 +667,8 @@
 }
 
 static void
-docklet_menu() {
+docklet_menu(void)
+{
 	static GtkWidget *menu = NULL;
 	GtkWidget *menuitem;
 
--- a/pidgin/gtkidle.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkidle.c	Mon Jan 07 16:28:25 2008 +0000
@@ -69,7 +69,7 @@
  */
 #if defined(USE_SCREENSAVER) || defined(HAVE_IOKIT)
 static time_t
-pidgin_get_time_idle()
+pidgin_get_time_idle(void)
 {
 # ifdef HAVE_IOKIT
 	/* Query the IOKit API */
--- a/pidgin/gtkimhtml.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkimhtml.c	Mon Jan 07 16:28:25 2008 +0000
@@ -289,7 +289,7 @@
 #endif
 
 static GtkSmileyTree*
-gtk_smiley_tree_new ()
+gtk_smiley_tree_new (void)
 {
 	return g_new0 (GtkSmileyTree, 1);
 }
--- a/pidgin/gtkmain.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkmain.c	Mon Jan 07 16:28:25 2008 +0000
@@ -174,7 +174,7 @@
  * be wise to move this code into gtksound.c.
  */
 static void
-clean_pid()
+clean_pid(void)
 {
 	int status;
 	pid_t pid;
@@ -241,7 +241,7 @@
 #endif
 
 static int
-ui_main()
+ui_main(void)
 {
 #ifndef _WIN32
 	GList *icons = NULL;
@@ -359,7 +359,7 @@
 	gtk_main_quit();
 }
 
-static GHashTable *pidgin_ui_get_info()
+static GHashTable *pidgin_ui_get_info(void)
 {
 	if(NULL == ui_info) {
 		ui_info = g_hash_table_new(g_str_hash, g_str_equal);
--- a/pidgin/gtknotify.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtknotify.c	Mon Jan 07 16:28:25 2008 +0000
@@ -332,7 +332,7 @@
 }
 
 static GtkWidget *
-pidgin_get_mail_dialog()
+pidgin_get_mail_dialog(void)
 {
 	if (mail_dialog == NULL) {
 		GtkWidget *dialog = NULL;
@@ -604,7 +604,7 @@
 }
 
 static GtkIMHtmlOptions
-notify_imhtml_options()
+notify_imhtml_options(void)
 {
 	GtkIMHtmlOptions options = 0;
 
--- a/pidgin/gtkpluginpref.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkpluginpref.c	Mon Jan 07 16:28:25 2008 +0000
@@ -93,22 +93,6 @@
 		case PURPLE_PLUGIN_PREF_NONE:
 		default:
 			if (format == PURPLE_STRING_FORMAT_TYPE_NONE)
-				box = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-			else
-				box = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-
-			gtk_widget_show(box);
-			gtk_box_pack_start(GTK_BOX(parent), box, FALSE, FALSE, 0);
-
-			gtk_label = gtk_label_new_with_mnemonic(pref_label);
-			gtk_misc_set_alignment(GTK_MISC(gtk_label), 0, 0.5);
-			gtk_widget_show(gtk_label);
-			gtk_box_pack_start(GTK_BOX(box), gtk_label, FALSE, FALSE, 0);
-
-			if(sg)
-				gtk_size_group_add_widget(sg, gtk_label);
-
-			if (format == PURPLE_STRING_FORMAT_TYPE_NONE)
 			{				
 				entry = gtk_entry_new();
 				gtk_entry_set_text(GTK_ENTRY(entry), purple_prefs_get_string(pref_name));
@@ -123,9 +107,7 @@
 				g_signal_connect(G_OBJECT(entry), "changed",
 								 G_CALLBACK(entry_cb),
 								 (gpointer)pref_name);
-				gtk_label_set_mnemonic_widget(GTK_LABEL(gtk_label), entry);
-				gtk_widget_show(entry);
-				gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
+				pidgin_add_widget_to_vbox(GTK_BOX(parent), pref_label, sg, entry, TRUE, NULL);
 			}
 			else
 			{
@@ -135,6 +117,19 @@
 				GtkWidget *toolbar;
 				GtkWidget *frame;
 
+				box = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+
+				gtk_widget_show(box);
+				gtk_box_pack_start(GTK_BOX(parent), box, FALSE, FALSE, 0);
+
+				gtk_label = gtk_label_new_with_mnemonic(pref_label);
+				gtk_misc_set_alignment(GTK_MISC(gtk_label), 0, 0.5);
+				gtk_widget_show(gtk_label);
+				gtk_box_pack_start(GTK_BOX(box), gtk_label, FALSE, FALSE, 0);
+
+				if(sg)
+					gtk_size_group_add_widget(sg, gtk_label);
+
 				hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
 				gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
 				gtk_widget_show(hbox);
--- a/pidgin/gtkprefs.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkprefs.c	Mon Jan 07 16:28:25 2008 +0000
@@ -89,23 +89,12 @@
 pidgin_prefs_labeled_spin_button(GtkWidget *box, const gchar *title,
 		const char *key, int min, int max, GtkSizeGroup *sg)
 {
-	GtkWidget *hbox;
-	GtkWidget *label;
 	GtkWidget *spin;
 	GtkObject *adjust;
 	int val;
 
 	val = purple_prefs_get_int(key);
 
-	hbox = gtk_hbox_new(FALSE, 5);
-	gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 5);
-	gtk_widget_show(hbox);
-
-	label = gtk_label_new_with_mnemonic(title);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_widget_show(label);
-
 	adjust = gtk_adjustment_new(val, min, max, 1, 1, 1);
 	spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
 	g_object_set_data(G_OBJECT(spin), "val", (char *)key);
@@ -113,21 +102,11 @@
 		gtk_widget_set_size_request(spin, 50, -1);
 	else
 		gtk_widget_set_size_request(spin, 60, -1);
-	gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
 	g_signal_connect(G_OBJECT(adjust), "value-changed",
 					 G_CALLBACK(update_spin_value), GTK_WIDGET(spin));
 	gtk_widget_show(spin);
 
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), spin);
-
-	if (sg) {
-		gtk_size_group_add_widget(sg, label);
-		gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-	}
-
-	pidgin_set_accessible_label (spin, label);
-
-	return hbox;
+	return pidgin_add_widget_to_vbox(GTK_BOX(box), title, sg, spin, FALSE, NULL);
 }
 
 static void
@@ -141,37 +120,18 @@
 pidgin_prefs_labeled_entry(GtkWidget *page, const gchar *title,
 							 const char *key, GtkSizeGroup *sg)
 {
-	GtkWidget *hbox, *label, *entry;
+	GtkWidget *entry;
 	const gchar *value;
 
 	value = purple_prefs_get_string(key);
 
-	hbox = gtk_hbox_new(FALSE, 5);
-	gtk_box_pack_start(GTK_BOX(page), hbox, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
-
-	label = gtk_label_new_with_mnemonic(title);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_widget_show(label);
-
 	entry = gtk_entry_new();
 	gtk_entry_set_text(GTK_ENTRY(entry), value);
-	gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
 	g_signal_connect(G_OBJECT(entry), "changed",
 					 G_CALLBACK(entry_set), (char*)key);
 	gtk_widget_show(entry);
 
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
-
-	if(sg) {
-		gtk_size_group_add_widget(sg, label);
-		gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-	}
-
-	pidgin_set_accessible_label(entry, label);
-
-	return hbox;
+	return pidgin_add_widget_to_vbox(GTK_BOX(page), title, sg, entry, TRUE, NULL);
 }
 
 static void
@@ -205,7 +165,6 @@
 {
 	GtkWidget  *dropdown, *opt, *menu;
 	GtkWidget  *label = NULL;
-	GtkWidget  *hbox;
 	gchar      *text;
 	const char *stored_str = NULL;
 	int         stored_int = 0;
@@ -215,19 +174,6 @@
 
 	g_return_val_if_fail(menuitems != NULL, NULL);
 
-	if (title != NULL) {
-		hbox = gtk_hbox_new(FALSE, 5);
-		/*gtk_container_add (GTK_CONTAINER (box), hbox);*/
-		gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
-		gtk_widget_show(hbox);
-
-		label = gtk_label_new_with_mnemonic(title);
-		gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-		gtk_widget_show(label);
-	} else {
-		hbox = box;
-	}
-
 #if 0 /* GTK_CHECK_VERSION(2,4,0) */
 	if(type == PURPLE_PREF_INT)
 		model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
@@ -239,11 +185,6 @@
 	menu = gtk_menu_new();
 #endif
 
-	if (label != NULL) {
-		gtk_label_set_mnemonic_widget(GTK_LABEL(label), dropdown);
-		pidgin_set_accessible_relations (dropdown, label);
-	}
-
 	if (type == PURPLE_PREF_INT)
 		stored_int = purple_prefs_get_int(key);
 	else if (type == PURPLE_PREF_STRING)
@@ -293,8 +234,8 @@
 	}
 
 	gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
-	gtk_box_pack_start(GTK_BOX(hbox), dropdown, FALSE, FALSE, 0);
-	gtk_widget_show(dropdown);
+
+	pidgin_add_widget_to_vbox(GTK_BOX(box), title, NULL, dropdown, FALSE, &label);
 
 	return label;
 }
@@ -412,7 +353,7 @@
 	gtk_tree_path_free(path);
 }
 
-static GtkTreeRowReference *theme_refresh_theme_list()
+static GtkTreeRowReference *theme_refresh_theme_list(void)
 {
 	GdkPixbuf *pixbuf;
 	GSList *themes;
@@ -676,7 +617,7 @@
 }
 
 static GtkWidget *
-theme_page()
+theme_page(void)
 {
 	GtkWidget *add_button, *remove_button;
 	GtkWidget *hbox_buttons;
@@ -877,7 +818,7 @@
 }
 
 static GtkWidget *
-interface_page()
+interface_page(void)
 {
 	GtkWidget *ret;
 	GtkWidget *vbox;
@@ -970,7 +911,7 @@
 #endif
 
 static GtkWidget *
-conv_page()
+conv_page(void)
 {
 	GtkWidget *ret;
 	GtkWidget *vbox;
@@ -983,7 +924,6 @@
 
 #if GTK_CHECK_VERSION(2,4,0)
 	GtkWidget *hbox;
-	GtkWidget *label;
 	GtkWidget *font_button;
 	const char *font_name;
 #endif
@@ -1026,19 +966,15 @@
 		fontpref = pidgin_prefs_checkbox(_("Use document font from _theme"), PIDGIN_PREFS_ROOT "/conversations/use_theme_font", vbox);
 	else
 		fontpref = pidgin_prefs_checkbox(_("Use font from _theme"), PIDGIN_PREFS_ROOT "/conversations/use_theme_font", vbox);
-	hbox = gtk_hbox_new(FALSE, 3);
-	label = gtk_label_new_with_mnemonic(_("Conversation _font:"));
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
 	font_name = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font");
 	font_button = gtk_font_button_new_with_font(font_name ? font_name : NULL);
 	gtk_font_button_set_show_style(GTK_FONT_BUTTON(font_button), TRUE);
-	gtk_box_pack_start(GTK_BOX(hbox), font_button, FALSE, FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+	hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Conversation _font:"), NULL, font_button, FALSE, NULL);
 	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font"))
 		gtk_widget_set_sensitive(hbox, FALSE);
 	g_signal_connect(G_OBJECT(fontpref), "clicked", G_CALLBACK(pidgin_toggle_sensitive), hbox);
 	g_signal_connect(G_OBJECT(font_button), "font-set", G_CALLBACK(pidgin_custom_font_set), NULL);
-	gtk_widget_show_all(hbox);
 #endif
 
 	vbox = pidgin_make_frame(ret, _("Default Formatting"));
@@ -1137,7 +1073,7 @@
 }
 
 static GtkWidget *
-network_page()
+network_page(void)
 {
 	GtkWidget *ret;
 	GtkWidget *vbox, *hbox, *entry;
@@ -1411,7 +1347,7 @@
 	return FALSE;
 }
 
-static GList *get_available_browsers()
+static GList *get_available_browsers(void)
 {
 	struct browser {
 		char *name;
@@ -1477,7 +1413,7 @@
 }
 
 static GtkWidget *
-browser_page()
+browser_page(void)
 {
 	GtkWidget *ret;
 	GtkWidget *vbox;
@@ -1520,28 +1456,16 @@
 									browser_changed1_cb, hbox);
 	}
 
-	hbox = gtk_hbox_new(FALSE, 5);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	label = gtk_label_new_with_mnemonic(_("_Manual:\n(%s for URL)"));
-	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-	gtk_size_group_add_widget(sg, label);
-
 	entry = gtk_entry_new();
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
-
 	if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
 		gtk_widget_set_sensitive(hbox, FALSE);
 	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser",
 								browser_changed2_cb, hbox);
-
-	gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
-
 	gtk_entry_set_text(GTK_ENTRY(entry),
 					   purple_prefs_get_path(PIDGIN_PREFS_ROOT "/browsers/command"));
 	g_signal_connect(G_OBJECT(entry), "focus-out-event",
 					 G_CALLBACK(manual_browser_set), NULL);
-	pidgin_set_accessible_label (entry, label);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Manual:\n(%s for URL)"), sg, entry, TRUE, NULL);
 
 	gtk_widget_show_all(ret);
 	g_object_unref(sg);
@@ -1550,7 +1474,7 @@
 #endif /*_WIN32*/
 
 static GtkWidget *
-logging_page()
+logging_page(void)
 {
 	GtkWidget *ret;
 	GtkWidget *vbox;
@@ -1778,7 +1702,7 @@
 }
 
 static GtkWidget *
-sound_page()
+sound_page(void)
 {
 	GtkWidget *ret;
 	GtkWidget *vbox, *sw, *button;
@@ -1824,33 +1748,20 @@
 	gtk_size_group_add_widget(sg, dd);
 	gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5);
 
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("Sound c_ommand:\n(%s for filename)"));
-	gtk_size_group_add_widget(sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
 	entry = gtk_entry_new();
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
-
 	gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE);
 	cmd = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/sound/command");
 	if(cmd)
 		gtk_entry_set_text(GTK_ENTRY(entry), cmd);
-
-	gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
 	g_signal_connect(G_OBJECT(entry), "changed",
 					 G_CALLBACK(sound_cmd_yeah), NULL);
 
+	hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Sound c_ommand:\n(%s for filename)"), sg, entry, TRUE, NULL);
 	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
 								sound_changed1_cb, hbox);
 	gtk_widget_set_sensitive(hbox,
 			!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"),
 					"custom"));
-
-	pidgin_set_accessible_label (entry, label);
 #endif /* _WIN32 */
 
 	vbox = pidgin_make_frame (ret, _("Sound Options"));
@@ -1864,13 +1775,6 @@
 				NULL);
 
 #ifdef USE_GSTREAMER
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("Volume:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
 	sw = gtk_hscale_new_with_range(0.0, 100.0, 5.0);
 	gtk_range_set_increments(GTK_RANGE(sw), 5.0, 25.0);
 	gtk_range_set_value(GTK_RANGE(sw), purple_prefs_get_int(PIDGIN_PREFS_ROOT "/sound/volume"));
@@ -1880,7 +1784,7 @@
 	g_signal_connect (G_OBJECT (sw), "value-changed",
 			  G_CALLBACK (prefs_sound_volume_changed),
 			  NULL);
-	gtk_box_pack_start(GTK_BOX(hbox), sw, TRUE, TRUE, 0);
+	hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Volume:"), NULL, sw, TRUE, NULL);
 
 	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
 								sound_changed3_cb, hbox);
@@ -2005,11 +1909,10 @@
 }
 
 static GtkWidget *
-away_page()
+away_page(void)
 {
 	GtkWidget *ret;
 	GtkWidget *vbox;
-	GtkWidget *hbox;
 	GtkWidget *dd;
 	GtkWidget *label;
 	GtkWidget *button;
@@ -2060,22 +1963,13 @@
 	g_signal_connect(G_OBJECT(button), "clicked",
 					 G_CALLBACK(pidgin_toggle_sensitive), select);
 
-	hbox = gtk_hbox_new(FALSE, 0);
-	gtk_container_add(GTK_CONTAINER(vbox), hbox);
-
-	label = gtk_label_new_with_mnemonic(_("Change _status to:"));
-	gtk_size_group_add_widget(sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+	/* TODO: Show something useful if we don't have any saved statuses. */
+	menu = pidgin_status_menu(purple_savedstatus_get_idleaway(), G_CALLBACK(set_idle_away));
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Change _status to:"), sg, menu, TRUE, &label);
+	g_signal_connect(G_OBJECT(button), "clicked",
+			 G_CALLBACK(pidgin_toggle_sensitive), menu);
 	g_signal_connect(G_OBJECT(button), "clicked",
 					 G_CALLBACK(pidgin_toggle_sensitive), label);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
-	/* TODO: Show something useful if we don't have any saved statuses. */
-	menu = pidgin_status_menu(purple_savedstatus_get_idleaway(), G_CALLBACK(set_idle_away));
-	gtk_box_pack_start(GTK_BOX(hbox), menu, FALSE, FALSE, 0);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(pidgin_toggle_sensitive), menu);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), menu);
 
 	if (!purple_prefs_get_bool("/purple/away/away_when_idle")) {
 		gtk_widget_set_sensitive(GTK_WIDGET(menu), FALSE);
@@ -2089,22 +1983,13 @@
 	button = pidgin_prefs_checkbox(_("Use status from last _exit at startup"),
 		"/purple/savedstatus/startup_current_status", vbox);
 
-	hbox = gtk_hbox_new(FALSE, 0);
-	gtk_container_add(GTK_CONTAINER(vbox), hbox);
-
-	label = gtk_label_new_with_mnemonic(_("Status to a_pply at startup:"));
-	gtk_size_group_add_widget(sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+	/* TODO: Show something useful if we don't have any saved statuses. */
+	menu = pidgin_status_menu(purple_savedstatus_get_startup(), G_CALLBACK(set_startupstatus));
+	g_signal_connect(G_OBJECT(button), "clicked",
+			 G_CALLBACK(pidgin_toggle_sensitive), menu);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Status to a_pply at startup:"), sg, menu, TRUE, &label);
 	g_signal_connect(G_OBJECT(button), "clicked",
 					 G_CALLBACK(pidgin_toggle_sensitive), label);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
-	/* TODO: Show something useful if we don't have any saved statuses. */
-	menu = pidgin_status_menu(purple_savedstatus_get_startup(), G_CALLBACK(set_startupstatus));
-	gtk_box_pack_start(GTK_BOX(hbox), menu, FALSE, FALSE, 0);
-	g_signal_connect(G_OBJECT(button), "clicked",
-			 G_CALLBACK(pidgin_toggle_sensitive), menu);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), menu);
 
 	if (purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) {
 		gtk_widget_set_sensitive(GTK_WIDGET(menu), FALSE);
@@ -2130,7 +2015,7 @@
 #endif
 }
 
-static void prefs_notebook_init() {
+static void prefs_notebook_init(void) {
 	prefs_notebook_add_page(_("Interface"), interface_page(), notebook_page++);
 	prefs_notebook_add_page(_("Conversations"), conv_page(), notebook_page++);
 	prefs_notebook_add_page(_("Smiley Themes"), theme_page(), notebook_page++);
--- a/pidgin/gtkprivacy.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkprivacy.c	Mon Jan 07 16:28:25 2008 +0000
@@ -359,7 +359,6 @@
 privacy_dialog_new(void)
 {
 	PidginPrivacyDialog *dialog;
-	GtkWidget *hbox;
 	GtkWidget *vbox;
 	GtkWidget *button;
 	GtkWidget *dropdown;
@@ -386,22 +385,10 @@
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_widget_show(label);
 
-	/* Hbox for the accounts drop-down and label. */
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
-
-	/* "Set privacy for:" label */
-	label = gtk_label_new(_("Set privacy for:"));
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_widget_show(label);
-
 	/* Accounts drop-down */
 	dropdown = pidgin_account_option_menu_new(NULL, FALSE,
 												G_CALLBACK(select_account_cb), NULL, dialog);
-	gtk_box_pack_start(GTK_BOX(hbox), dropdown, FALSE, FALSE, 0);
-	gtk_widget_show(dropdown);
-	pidgin_set_accessible_label (dropdown, label);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Set privacy for:"), NULL, dropdown, TRUE, NULL);
 	dialog->account = pidgin_account_option_menu_get_selected(dropdown);
 
 	/* Add the drop-down list with the allow/block types. */
--- a/pidgin/gtkroomlist.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkroomlist.c	Mon Jan 07 16:28:25 2008 +0000
@@ -521,9 +521,7 @@
 	GtkWidget *window;
 	GtkWidget *vbox;
 	GtkWidget *vbox2;
-	GtkWidget *account_hbox;
 	GtkWidget *bbox;
-	GtkWidget *label;
 
 	dialog = g_new0(PidginRoomlistDialog, 1);
 	dialog->account = account;
@@ -542,25 +540,11 @@
 	gtk_widget_show(vbox2);
 
 	/* accounts dropdown list */
-	account_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox2), account_hbox, FALSE, FALSE, 0);
-	gtk_widget_show(account_hbox);
-
-	label = gtk_label_new(NULL);
-	gtk_box_pack_start(GTK_BOX(account_hbox), label, FALSE, FALSE, 0);
-	gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Account:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_widget_show(label);
-
 	dialog->account_widget = pidgin_account_option_menu_new(dialog->account, FALSE,
 	                         G_CALLBACK(dialog_select_account_cb), account_filter_func, dialog);
-
 	if (!dialog->account) /* this is normally null, and we normally don't care what the first selected item is */
 		dialog->account = pidgin_account_option_menu_get_selected(dialog->account_widget);
-
-	gtk_box_pack_start(GTK_BOX(account_hbox), dialog->account_widget, TRUE, TRUE, 0);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(dialog->account_widget));
-	gtk_widget_show(dialog->account_widget);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox2), _("_Account:"), NULL, dialog->account_widget, TRUE, NULL);
 
 	/* scrolled window */
 	dialog->sw = gtk_scrolled_window_new(NULL, NULL);
--- a/pidgin/gtksavedstatuses.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtksavedstatuses.c	Mon Jan 07 16:28:25 2008 +0000
@@ -1092,7 +1092,6 @@
 	GtkWidget *entry;
 	GtkWidget *frame;
 	GtkWidget *hbox;
-	GtkWidget *label;
 	GtkWidget *sw;
 	GtkWidget *text;
 	GtkWidget *toolbar;
@@ -1141,52 +1140,29 @@
 	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
 	/* Title */
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("_Title:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(sg, label);
-
 	entry = gtk_entry_new();
 	dialog->title = GTK_ENTRY(entry);
 	if ((saved_status != NULL)
 			&& !purple_savedstatus_is_transient(saved_status)
 			&& (purple_savedstatus_get_title(saved_status) != NULL))
 		gtk_entry_set_text(GTK_ENTRY(entry), purple_savedstatus_get_title(saved_status));
-	gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
 	g_signal_connect(G_OBJECT(entry), "changed",
 					 G_CALLBACK(editor_title_changed_cb), dialog);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Title:"), sg, entry, TRUE, NULL);
 
 	/* Status type */
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("_Status:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(sg, label);
-
 	if (saved_status != NULL)
 		dropdown = create_status_type_menu(purple_savedstatus_get_type(saved_status));
 	else
 		dropdown = create_status_type_menu(PURPLE_STATUS_AWAY);
 	dialog->type = GTK_OPTION_MENU(dropdown);
-	gtk_box_pack_start(GTK_BOX(hbox), dropdown, TRUE, TRUE, 0);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Status:"), sg, dropdown, TRUE, NULL);
 
 	/* Status message */
-	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
-
-	label = gtk_label_new_with_mnemonic(_("_Message:"));
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(sg, label);
-
 	frame = pidgin_create_imhtml(TRUE, &text, &toolbar, NULL);
 	dialog->message = GTK_IMHTML(text);
-	gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
+	hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Message:"), sg, frame, TRUE, NULL);
+	gtk_container_child_set(GTK_CONTAINER(vbox), hbox, "expand", TRUE, "fill", TRUE, NULL);
 	focus_chain = g_list_prepend(focus_chain, dialog->message);
 	gtk_container_set_focus_chain(GTK_CONTAINER(hbox), focus_chain);
 	g_list_free(focus_chain);
--- a/pidgin/gtksession.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtksession.c	Mon Jan 07 16:28:25 2008 +0000
@@ -124,7 +124,7 @@
 	purple_debug(PURPLE_DEBUG_INFO, NULL, "done.\n");
 }
 
-static void ice_init() {
+static void ice_init(void) {
 	IceIOErrorHandler default_handler;
 
 	ice_installed_io_error_handler = IceSetIOErrorHandler(NULL);
--- a/pidgin/gtkstatusbox.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkstatusbox.c	Mon Jan 07 16:28:25 2008 +0000
@@ -949,7 +949,7 @@
 
 /* This returns NULL if the active accounts don't have identical
  * statuses and a token account if they do */
-static PurpleAccount* check_active_accounts_for_identical_statuses()
+static PurpleAccount* check_active_accounts_for_identical_statuses(void)
 {
 	PurpleAccount *acct = NULL, *acct2;
 	GList *tmp, *tmp2, *active_accts = purple_accounts_get_all_active();
--- a/pidgin/gtkthemes.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkthemes.c	Mon Jan 07 16:28:25 2008 +0000
@@ -168,7 +168,7 @@
 }
 
 static void
-pidgin_smiley_themes_remove_non_existing()
+pidgin_smiley_themes_remove_non_existing(void)
 {
 	static struct smiley_theme *theme = NULL;
 	GSList *iter = NULL;
--- a/pidgin/gtkutils.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkutils.c	Mon Jan 07 16:28:25 2008 +0000
@@ -1701,23 +1701,23 @@
 	GdkPixbuf *pixbuf = NULL;
 
 	if (prim == PURPLE_STATUS_UNAVAILABLE)
-        	pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_BUSY,
-                                                 icon_size, "GtkWidget");
-        else if (prim == PURPLE_STATUS_AWAY)
-                pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_AWAY,
-                                                 icon_size, "GtkWidget");
-        else if (prim == PURPLE_STATUS_EXTENDED_AWAY)
-                pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_XA,
-                                                 icon_size, "GtkWidget");
-        else if (prim == PURPLE_STATUS_INVISIBLE)
-                pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_INVISIBLE,
-                                                 icon_size, "GtkWidget");
-        else if (prim == PURPLE_STATUS_OFFLINE)
-                pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_OFFLINE,
-                                                 icon_size, "GtkWidget");
-        else
-                pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_AVAILABLE,
-                                                 icon_size, "GtkWidget");
+		pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_BUSY,
+				icon_size, "GtkWidget");
+	else if (prim == PURPLE_STATUS_AWAY)
+		pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_AWAY,
+				icon_size, "GtkWidget");
+	else if (prim == PURPLE_STATUS_EXTENDED_AWAY)
+		pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_XA,
+				icon_size, "GtkWidget");
+	else if (prim == PURPLE_STATUS_INVISIBLE)
+		pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_INVISIBLE,
+				icon_size, "GtkWidget");
+	else if (prim == PURPLE_STATUS_OFFLINE)
+		pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_OFFLINE,
+				icon_size, "GtkWidget");
+	else
+		pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_AVAILABLE,
+				icon_size, "GtkWidget");
 	return pixbuf;
 
 }
@@ -2947,7 +2947,7 @@
 GSList *minidialogs = NULL;
 
 static void *
-pidgin_utils_get_handle()
+pidgin_utils_get_handle(void)
 {
 	static int handle;
 
@@ -3321,6 +3321,40 @@
 	gtk_entry_set_text(GTK_ENTRY(GTK_BIN((widget))->child), (text));
 }
 
+GtkWidget *
+pidgin_add_widget_to_vbox(GtkBox *vbox, const char *widget_label, GtkSizeGroup *sg, GtkWidget *widget, gboolean expand, GtkWidget **p_label)
+{
+	GtkWidget *hbox;
+	GtkWidget *label = NULL;
+
+	if (widget_label) {
+		hbox = gtk_hbox_new(FALSE, 5);
+		gtk_widget_show(hbox);
+		gtk_box_pack_start(vbox, hbox, FALSE, FALSE, 0);
+
+		label = gtk_label_new_with_mnemonic(widget_label);
+		gtk_widget_show(label);
+		if (sg) {
+			gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+			gtk_size_group_add_widget(sg, label);
+		}
+		gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	} else {
+		hbox = GTK_WIDGET(vbox);
+	}
+
+	gtk_widget_show(widget);
+	gtk_box_pack_start(GTK_BOX(hbox), widget, expand, TRUE, 0);
+	if (label) {
+		gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget);
+		pidgin_set_accessible_label (widget, label);
+	}
+
+	if (p_label)
+		(*p_label) = label;
+	return hbox;
+}
+
 gboolean pidgin_auto_parent_window(GtkWidget *widget)
 {
 #if 0
--- a/pidgin/gtkutils.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/gtkutils.h	Mon Jan 07 16:28:25 2008 +0000
@@ -794,5 +794,20 @@
  */
 gboolean pidgin_auto_parent_window(GtkWidget *window);
 
+/**
+ * Add a labelled widget to a GtkVBox
+ *
+ * @param vbox         The GtkVBox to add the widget to.
+ * @param widget_label The label to give the widget.
+ * @param sg           The GtkSizeGroup to add the label to.
+ * @param widget       The GtkWidget to add
+ * @param expand       Whether to expand the widget horizontally.
+ * @param p_label      Place to store a pointer to the GtkLabel, or NULL if you don't care.
+ *
+ * @return  A GtkHBox already added to the GtkVBox containing the GtkLabel and the GtkWidget.
+ * @since 2.4.0
+ */
+GtkWidget *pidgin_add_widget_to_vbox(GtkBox *vbox, const char *widget_label, GtkSizeGroup *sg, GtkWidget *widget, gboolean expand, GtkWidget **p_label);
+
 #endif /* _PIDGINUTILS_H_ */
 
--- a/pidgin/pidgintooltip.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/pidgintooltip.c	Mon Jan 07 16:28:25 2008 +0000
@@ -86,7 +86,7 @@
 }
 
 static GtkWidget*
-setup_tooltip_window()
+setup_tooltip_window(void)
 {
 	const char *name;
 	GtkWidget *tipwindow;
--- a/pidgin/plugins/cap/cap.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/plugins/cap/cap.c	Mon Jan 07 16:28:25 2008 +0000
@@ -434,26 +434,6 @@
 	stats->last_seen = time(NULL);
 }
 
-static void buddy_idle(PurpleBuddy *buddy, gboolean old_idle, gboolean idle) {
-}
-
-#if 0
-static void blist_node_extended_menu(PurpleBlistNode *node, GList **menu) {
-	PurpleBuddy *buddy;
-	PurpleMenuAction *menu_action;
-	purple_debug_info("cap", "got extended blist menu\n");
-	purple_debug_info("cap", "is buddy: %d\n", PURPLE_BLIST_NODE_IS_BUDDY(node));
-	purple_debug_info("cap", "is contact: %d\n", PURPLE_BLIST_NODE_IS_CONTACT(node));
-	purple_debug_info("cap", "is group: %d\n", PURPLE_BLIST_NODE_IS_GROUP(node));
-	/* Probably only concerned with buddy/contact types. Contacts = meta-buddies (grouped msn/jabber/etc.) */
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-	buddy = (PurpleBuddy *)node;
-	menu_action = purple_menu_action_new(_("Display Statistics"),
-			PURPLE_CALLBACK(display_statistics_action_cb), NULL, NULL);
-	*menu = g_list_append(*menu, menu_action);
-}
-#endif
-
 /* drawing-tooltip */
 static void drawing_tooltip(PurpleBlistNode *node, GString *text, gboolean full) {
 	if(node->type == PURPLE_BLIST_BUDDY_NODE) {
@@ -662,15 +642,6 @@
 	/* result = dbi_conn_queryf(_conn, "insert into cap_message values(\'%s\', \'%s\', %d, now());", sender, receiver, count); */
 }
 
-/* Callbacks */
-void display_statistics_action_cb(PurpleBlistNode *node, gpointer data) {
-	PurpleBuddy *buddy;
-
-	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-	buddy = (PurpleBuddy *)node;
-	purple_debug_info("cap", "Statistics for %s requested.\n", buddy->name);
-}
-
 /* Purple plugin specific code */
 
 static gboolean plugin_load(PurplePlugin *plugin) {
@@ -714,9 +685,6 @@
 	purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", plugin,
 			PURPLE_CALLBACK(buddy_signed_off), NULL);
 
-	/*purple_signal_connect(purple_blist_get_handle(), "blist-node-extended-menu", plugin,
-			PURPLE_CALLBACK(blist_node_extended_menu), NULL);*/
-
 	purple_signal_connect(pidgin_blist_get_handle(), "drawing-tooltip", plugin,
 			PURPLE_CALLBACK(drawing_tooltip), NULL);
 
@@ -726,9 +694,6 @@
 	purple_signal_connect(purple_connections_get_handle(), "signed-off", plugin,
 			PURPLE_CALLBACK(signed_off), NULL);
 
-	purple_signal_connect(purple_blist_get_handle(), "buddy-idle-changed", plugin,
-			PURPLE_CALLBACK(buddy_idle), NULL);
-
 	_signals_connected = TRUE;
 }
 
@@ -765,9 +730,6 @@
 	purple_signal_disconnect(purple_blist_get_handle(), "buddy-signed-off", plugin,
 			PURPLE_CALLBACK(buddy_signed_off));
 
-	/*purple_signal_disconnect(purple_blist_get_handle(), "blist-node-extended-menu", plugin,
-			PURPLE_CALLBACK(blist_node_extended_menu));*/
-
 	purple_signal_disconnect(pidgin_blist_get_handle(), "drawing-tooltip", plugin,
 			PURPLE_CALLBACK(drawing_tooltip));
 
@@ -777,9 +739,6 @@
 	purple_signal_disconnect(purple_connections_get_handle(), "signed-off", plugin,
 			PURPLE_CALLBACK(signed_off));
 
-	purple_signal_disconnect(purple_blist_get_handle(), "buddy-idle-changed", plugin,
-			PURPLE_CALLBACK(buddy_idle));
-
 	_signals_connected = FALSE;
 }
 
--- a/pidgin/plugins/cap/cap.h	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/plugins/cap/cap.h	Mon Jan 07 16:28:25 2008 +0000
@@ -98,7 +98,6 @@
 static void buddy_signed_on(PurpleBuddy *buddy);
 /* buddy-signed-off */
 static void buddy_signed_off(PurpleBuddy *buddy);
-static void buddy_idle(PurpleBuddy *buddy, gboolean old_idle, gboolean idle);
 /* drawing-tooltip */
 static void drawing_tooltip(PurpleBlistNode *node, GString *text, gboolean full);
 /* signed-on */
@@ -107,21 +106,20 @@
 static void signed_off(PurpleConnection *gc);
 static void reset_all_last_message_times(gpointer key, gpointer value, gpointer user_data);
 static PurpleStatus * get_status_for(PurpleBuddy *buddy);
-static void create_tables();
-static gboolean create_database_connection();
-static void destroy_database_connection();
+static void create_tables(void);
+static gboolean create_database_connection(void);
+static void destroy_database_connection(void);
 static guint word_count(const gchar *string);
 static void insert_status_change(CapStatistics *statistics);
 static void insert_status_change_from_purple_status(CapStatistics *statistics, PurpleStatus *status);
 static void insert_word_count(const char *sender, const char *receiver, guint count);
-void display_statistics_action_cb(PurpleBlistNode *node, gpointer data);
 static gboolean plugin_load(PurplePlugin *plugin);
 static void add_plugin_functionality(PurplePlugin *plugin);
 static void cancel_conversation_timeouts(gpointer key, gpointer value, gpointer user_data);
 static void remove_plugin_functionality(PurplePlugin *plugin);
 static void write_stats_on_unload(gpointer key, gpointer value, gpointer user_data);
 static gboolean plugin_unload(PurplePlugin *plugin);
-static CapPrefsUI * create_cap_prefs_ui();
+static CapPrefsUI * create_cap_prefs_ui(void);
 static void cap_prefs_ui_destroy_cb(GtkObject *object, gpointer user_data);
 static void numeric_spinner_prefs_cb(GtkSpinButton *spinbutton, gpointer user_data);
 static GtkWidget * get_config_frame(PurplePlugin *plugin);
--- a/pidgin/plugins/markerline.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/plugins/markerline.c	Mon Jan 07 16:28:25 2008 +0000
@@ -190,13 +190,13 @@
 }
 
 static void
-detach_from_all_windows()
+detach_from_all_windows(void)
 {
 	g_list_foreach(pidgin_conv_windows_get_list(), (GFunc)detach_from_pidgin_window, NULL);
 }
 
 static void
-attach_to_all_windows()
+attach_to_all_windows(void)
 {
 	g_list_foreach(pidgin_conv_windows_get_list(), (GFunc)attach_to_pidgin_window, NULL);
 }
--- a/pidgin/plugins/pidginrc.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/plugins/pidginrc.c	Mon Jan 07 16:28:25 2008 +0000
@@ -95,7 +95,7 @@
 */
 
 static GString *
-make_gtkrc_string()
+make_gtkrc_string(void)
 {
 	gint i;
 	gchar *prefbase = NULL;
@@ -185,7 +185,7 @@
 }
 
 static void
-purplerc_make_changes()
+purplerc_make_changes(void)
 {
 	GString *str = make_gtkrc_string();
 #if GTK_CHECK_VERSION(2,4,0)
--- a/pidgin/plugins/spellchk.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/plugins/spellchk.c	Mon Jan 07 16:28:25 2008 +0000
@@ -695,7 +695,7 @@
 	return 1;
 }
 
-static void load_conf()
+static void load_conf(void)
 {
 	/* Corrections to change "...", "(c)", "(r)", and "(tm)" to their
 	 * Unicode character equivalents were not added here even though
@@ -1912,7 +1912,7 @@
 	save_list();
 }
 
-static void list_add_new()
+static void list_add_new(void)
 {
 	GtkTreeIter iter;
 	const char *word = gtk_entry_get_text(GTK_ENTRY(bad_entry));
@@ -2015,7 +2015,7 @@
 	gtk_tree_row_reference_free(row_reference);
 }
 
-static void list_delete()
+static void list_delete(void)
 {
 	GtkTreeSelection *sel;
 	GSList *list = NULL;
@@ -2161,14 +2161,13 @@
 get_config_frame(PurplePlugin *plugin)
 {
 	GtkWidget *ret, *vbox, *win;
-	GtkWidget *hbox, *label;
+	GtkWidget *hbox;
 	GtkWidget *button;
 	GtkSizeGroup *sg;
 	GtkSizeGroup *sg2;
 	GtkCellRenderer *renderer;
 	GtkTreeViewColumn *column;
 	GtkWidget *vbox2;
-	GtkWidget *hbox2;
 	GtkWidget *vbox3;
 
 	ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
@@ -2275,37 +2274,15 @@
 	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 	sg2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
-	hbox2 = gtk_hbox_new(FALSE, 2);
-	gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);
-	gtk_widget_show(hbox2);
-
-	label = gtk_label_new_with_mnemonic(_("You _type:"));
-	gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-
 	bad_entry = gtk_entry_new();
 	/* Set a minimum size. Since they're in a size group, the other entry will match up. */
 	gtk_widget_set_size_request(bad_entry, 350, -1);
-	gtk_box_pack_start(GTK_BOX(hbox2), bad_entry, TRUE, TRUE, 0);
 	gtk_size_group_add_widget(sg2, bad_entry);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), bad_entry);
-	gtk_widget_show(bad_entry);
-
-	hbox2 = gtk_hbox_new(FALSE, 2);
-	gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);
-	gtk_widget_show(hbox2);
-
-	label = gtk_label_new_with_mnemonic(_("You _send:"));
-	gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(sg, label);
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox2), _("You _type:"), sg, bad_entry, FALSE, NULL);
 
 	good_entry = gtk_entry_new();
-	gtk_box_pack_start(GTK_BOX(hbox2), good_entry, TRUE, TRUE, 0);
 	gtk_size_group_add_widget(sg2, good_entry);
-	gtk_label_set_mnemonic_widget(GTK_LABEL(label), good_entry);
-	gtk_widget_show(good_entry);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox2), _("You _send:"), sg, good_entry, FALSE, NULL);
 
 	/* Created here so it can be passed to whole_words_button_toggled. */
 	case_toggle = gtk_check_button_new_with_mnemonic(_("_Exact case match (uncheck for automatic case handling)"));
--- a/pidgin/plugins/ticker/ticker.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/plugins/ticker/ticker.c	Mon Jan 07 16:28:25 2008 +0000
@@ -65,7 +65,7 @@
 	return TRUE; /* don't actually destroy the window */
 }
 
-static void buddy_ticker_create_window() {
+static void buddy_ticker_create_window(void) {
 	if(tickerwindow) {
 		gtk_widget_show(tickerwindow);
 		return;
@@ -215,7 +215,7 @@
 	buddy_ticker_update_contact(c);
 }
 
-static void buddy_ticker_show()
+static void buddy_ticker_show(void)
 {
 	PurpleBuddyList *list = purple_get_blist();
 	PurpleBlistNode *gnode, *cnode, *bnode;
--- a/pidgin/plugins/xmppconsole.c	Mon Jan 07 16:28:12 2008 +0000
+++ b/pidgin/plugins/xmppconsole.c	Mon Jan 07 16:28:25 2008 +0000
@@ -727,7 +727,7 @@
 }
 
 static void 
-create_console() 
+create_console(PurplePluginAction *action) 
 {
 	GtkWidget *vbox = gtk_vbox_new(FALSE, 6);
 	GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
--- a/po/POTFILES.in	Mon Jan 07 16:28:12 2008 +0000
+++ b/po/POTFILES.in	Mon Jan 07 16:28:25 2008 +0000
@@ -12,6 +12,7 @@
 finch/gntpounce.c
 finch/gntprefs.c
 finch/gntrequest.c
+finch/gntroomlist.c
 finch/gntsound.c
 finch/gntstatus.c
 finch/gntui.c
--- a/po/check_po.pl	Mon Jan 07 16:28:12 2008 +0000
+++ b/po/check_po.pl	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
 #
 # check_po.pl  -  check po file translations for likely errors
 #
--- a/po/de.po	Mon Jan 07 16:28:12 2008 +0000
+++ b/po/de.po	Mon Jan 07 16:28:25 2008 +0000
@@ -11,9 +11,9 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-01-04 15:36+0100\n"
-"PO-Revision-Date: 2008-01-04 15:21+0100\n"
-"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
+"POT-Creation-Date: 2008-01-05 13:31+0100\n"
+"PO-Revision-Date: 2008-01-05 13:31+0100\n"
+"Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -3975,8 +3975,8 @@
 msgid "Mood"
 msgstr "Stimmung"
 
-msgid "Current media"
-msgstr "Aktuelles Medium"
+msgid "Now Listening"
+msgstr ""
 
 msgid "Mood Text"
 msgstr "Stimmungstext"
@@ -9636,6 +9636,14 @@
 msgid "Unable to connect to %s: %s"
 msgstr "Verbindung zu %s nicht möglich: %s"
 
+#, c-format
+msgid " - %s"
+msgstr " - %s"
+
+#, c-format
+msgid " (%s)"
+msgstr " (%s)"
+
 #. 10053
 #, c-format
 msgid "Connection interrupted by other software on your computer."
@@ -10019,12 +10027,8 @@
 msgstr "/Hilfe/Ü_ber"
 
 #, c-format
-msgid ""
-"\n"
-"<b>Account:</b> %s"
-msgstr ""
-"\n"
-"<b>Konto:</b> %s"
+msgid "<b>Account:</b> %s"
+msgstr "<b>Konto:</b> %s"
 
 #, c-format
 msgid ""
@@ -11125,21 +11129,21 @@
 "Farbe zum Darstellen von Hyperlinks, wenn sich die Maus darüber befindet."
 
 msgid "Sent Message Name Color"
-msgstr "Farbnane für gesendete Nachrichten"
+msgstr "Farbe des Absendernamens für gesendete Nachrichten"
 
 msgid "Color to draw the name of a message you sent."
 msgstr ""
 "Farbe, mit der der Name in einer gesendeten Nachricht dargestellt wird."
 
 msgid "Received Message Name Color"
-msgstr "Farbname für empfangene Nachrichten"
+msgstr "Farbe des Absendernamens für empfangene Nachrichten"
 
 msgid "Color to draw the name of a message you received."
 msgstr ""
 "Farbe, mit der der Name in einer empfangenen Nachricht dargestellt wird."
 
 msgid "\"Attention\" Name Color"
-msgstr "Farbname für \"Achtung\"-Nachrichten"
+msgstr "Farbe des Absendernamens für \"Achtung\"-Nachrichten"
 
 msgid "Color to draw the name of a message you received containing your name."
 msgstr ""
@@ -11147,7 +11151,7 @@
 "enthält."
 
 msgid "Action Message Name Color"
-msgstr "Farbname für Aktions-Nachrichten"
+msgstr "Farbe des Absendernamens für Aktions-Nachrichten"
 
 msgid "Color to draw the name of an action message."
 msgstr "Farbe, mit der der Name in einer Aktions-Nachricht dargestellt wird."
@@ -12043,7 +12047,6 @@
 msgid "Changes to privacy settings take effect immediately."
 msgstr "Einstellungen bzgl. der Privatsphäre werden sofort wirksam."
 
-#. "Set privacy for:" label
 msgid "Set privacy for:"
 msgstr "Setze Privatsphäre für:"
 
@@ -12865,7 +12868,7 @@
 msgstr "Hyperlink-Farbe"
 
 msgid "Highlighted Message Name Color"
-msgstr "Farbname für hervorgehobene Nachrichten"
+msgstr "Farbe des Absendernamens für hervorgehobene Nachrichten"
 
 msgid "GtkTreeView Horizontal Separation"
 msgstr "GtkTreeview horizontaler Abstand"
--- a/po/stats.pl	Mon Jan 07 16:28:12 2008 +0000
+++ b/po/stats.pl	Mon Jan 07 16:28:25 2008 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
 
 # Copyright 2003-2005 Nathan Walp <faceprint@faceprint.com>
 #