changeset 18067:098a1d6896be

merge of '34fbe2d8a258b1b4700cb7c8d8fcd02d07bc4d14' and 'd6951b577ca382935275d65ba6c87792a3ca80d5'
author Luke Schierer <lschiere@pidgin.im>
date Thu, 07 Jun 2007 12:33:23 +0000
parents c3b4adf3efe6 (diff) 5c4efa98e8dd (current diff)
children 0b3d6ea61760
files
diffstat 58 files changed, 354 insertions(+), 241 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.API	Thu Jun 07 02:39:48 2007 +0000
+++ b/ChangeLog.API	Thu Jun 07 12:33:23 2007 +0000
@@ -1,44 +1,71 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
 version 2.1.0 (??/??/????):
-	Added:
-	* purple-remote: added getstatus command
-	* OPT_PROTO_SLASH_COMMANDS_NATIVE protocol option to indicate that
-	  slash commands are "native" to the protocol
-	* PURPLE_MESSAGE_NO_LINKIFY message flag to indicate that the message
-	  should not be auto-linkified
-	* PurpleEventLoopUiOps.timeout_add_seconds
-	    UIs can now use better scheduling for whole-second timers.  For
-	    example, clients based on the glib event loop can now use
-	    g_timeout_add_seconds().
-	* pidgin_create_window()
-	* purple_core_ensure_single_instance()
-	    This is for UIs to use to ensure only one copy is running.
-	* purple_dbus_is_owner()
-	* purple_image_data_calculate_filename()
-	* purple_timeout_add_seconds()
-	    Callers should prefer this to purple_timeout_add() for timers
-	    longer than 1 second away.  Be aware of the rounding, though.
-	* purple_timeout_add_seconds()
-	    Callers should prefer this to purple_timeout_add() for timers
-	    longer than 1 second away.  Be aware of the rounding, though.
-	* purple_conversation_get_extended_menu
-	* purple_conversation_do_command
-	* pidgin_retrieve_user_info, shows immediate feedback when getting
-	  information about a user.
-	* gtk_imhtml_setup_entry
-	* purple_xfer_get_remote_user
-	* purple_blist_node_get_type
+	libpurple:
+		Added:
+		* purple-remote: added getstatus command
+		* conversation-extended-menu signal (See Doxygen docs)
+		* OPT_PROTO_SLASH_COMMANDS_NATIVE protocol option to indicate that
+		  slash commands are "native" to the protocol
+		* PURPLE_MESSAGE_NO_LINKIFY message flag to indicate that the message
+		  should not be auto-linkified
+		* PurpleEventLoopUiOps.timeout_add_seconds
+		    UIs can now use better scheduling for whole-second timers.  For
+		    example, clients based on the glib event loop can now use
+		    g_timeout_add_seconds.
+		* gtk_imhtml_setup_entry
+		* pidgin_create_window
+		* purple_blist_node_get_type
+		* purple_conversation_do_command
+		* purple_conversation_get_extended_menu
+		* purple_core_ensure_single_instance
+		    This is for UIs to use to ensure only one copy is running.
+		* purple_dbus_is_owner
+		* purple_dbusify_const_GList
+		* purple_dbusify_const_GSList
+		* purple_const_GList_to_array
+		* purple_const_GSList_to_array
+		* purple_image_data_calculate_filename
+		* pidgin_retrieve_user_info, shows immediate feedback when getting
+		  information about a user.
+		* purple_timeout_add_seconds
+		    Callers should prefer this to purple_timeout_add for timers
+		    longer than 1 second away.  Be aware of the rounding, though.
+		* purple_timeout_add_seconds
+		    Callers should prefer this to purple_timeout_add for timers
+		    longer than 1 second away.  Be aware of the rounding, though.
+		* purple_xfer_get_remote_user
 
-	Changed:
-	* pidgin_separator returns the separator added to the menu.
-	* pidgin_append_menu_action returns the menuitem added to the menu.
+		Changed:
+		* Mark some return types const:
+			* purple_accounts_get_all
+			* purple_connections_get_all
+			* purple_connections_get_connecting
+			* purple_conv_chat_get_ignored
+			* purple_conv_chat_get_users
+			* purple_get_chats
+			* purple_get_conversations
+			* purple_get_ims
+			* purple_notify_user_info_get_entries
 
-	Signals - Added: (See the Doxygen docs for details on all signals.)
-	* "conversation-extended-menu"
+		Deprecated:
+		* purple_dbusify_GList:  Use purple_dbusify_const_GList (and
+		  g_list_free if needed) if depending on 2.1.0 is okay.
+		* purple_dbusify_GSList:  Use purple_dbusify_const_GSList (and
+		  g_slist_free if needed) if depending on 2.1.0 is okay..
+		* purple_GList_to_array:  Use purple_const_GList_to_array (and
+		  g_list_free if needed) if depending on 2.1.0 is okay..
+		* purple_GSList_to_array:  Use purple_const_GSList_to_array (and
+		  g_slist_free if needed) if depending on 2.1.0 is okay..
 
-	Finch - Added:
-	* finch_retrieve_user_info
+	Pidgin:
+		Changed:
+		* pidgin_append_menu_action returns the menuitem added to the menu.
+		* pidgin_separator returns the separator added to the menu.
+
+	Finch:
+		Added:
+		* finch_retrieve_user_info
 
 version 2.0.0 (5/3/2007):
 	Please note all functions, defines, and data structures have been
--- a/finch/gntaccount.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/finch/gntaccount.c	Thu Jun 07 12:33:23 2007 +0000
@@ -641,7 +641,7 @@
 
 void finch_accounts_show_all()
 {
-	GList *iter;
+	const GList *iter;
 	GntWidget *box, *button;
 
 	if (accounts.window)
@@ -734,7 +734,7 @@
 
 void finch_accounts_init()
 {
-	GList *iter;
+	const GList *iter;
 
 	purple_signal_connect(purple_accounts_get_handle(), "account-added",
 			finch_accounts_get_handle(), PURPLE_CALLBACK(account_added_callback),
@@ -831,7 +831,7 @@
 {
 	PurpleConnection *gc = purple_account_get_connection(data->account);
 
-	if (g_list_find(purple_connections_get_all(), gc))
+	if (g_list_find((GList *)purple_connections_get_all(), gc))
 	{
 		purple_blist_request_add_buddy(data->account, data->username,
 									 NULL, data->alias);
--- a/finch/gntpounce.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/finch/gntpounce.c	Thu Jun 07 12:33:23 2007 +0000
@@ -288,7 +288,7 @@
 	GntWidget *hbox, *vbox;
 	GntWidget *button;
 	GntWidget *combo;
-	GList *list;
+	const GList *list;
 
 	g_return_if_fail((cur_pounce != NULL) ||
 	                 (account != NULL) ||
@@ -303,7 +303,7 @@
 		dialog->pounce  = NULL;
 		dialog->account = account;
 	} else {
-		GList *connections = purple_connections_get_all();
+		const GList *connections = purple_connections_get_all();
 		PurpleConnection *gc;
 
 		if (connections != NULL) {
--- a/finch/gntrequest.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/finch/gntrequest.c	Thu Jun 07 12:33:23 2007 +0000
@@ -490,7 +490,7 @@
 			{
 				gboolean all;
 				PurpleAccount *def;
-				GList *list;
+				const GList *list;
 				GntWidget *combo = gnt_combo_box_new();
 				gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
 				gnt_box_add_widget(GNT_BOX(hbox), combo);
--- a/finch/gntstatus.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/finch/gntstatus.c	Thu Jun 07 12:33:23 2007 +0000
@@ -497,7 +497,7 @@
 	GntWidget *window, *box, *button, *entry, *combo, *label, *tree;
 	PurpleStatusPrimitive prims[] = {PURPLE_STATUS_AVAILABLE, PURPLE_STATUS_AWAY,
 		PURPLE_STATUS_INVISIBLE, PURPLE_STATUS_OFFLINE, PURPLE_STATUS_UNSET}, current;
-	GList *iter;
+	const GList *iter;
 	int i;
 
 	if (saved)
--- a/finch/libgnt/gntkeys.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/finch/libgnt/gntkeys.c	Thu Jun 07 12:33:23 2007 +0000
@@ -206,8 +206,8 @@
 		node->flags |= IS_END;
 		return;
 	}
-	while (*path && node->next[*path]) {
-		node = node->next[*path];
+	while (*path && node->next[(unsigned char)*path]) {
+		node = node->next[(unsigned char)*path];
 		node->ref++;
 		path++;
 	}
@@ -215,7 +215,7 @@
 		return;
 	n = g_new0(struct _node, 1);
 	n->ref = 1;
-	node->next[*path++] = n;
+	node->next[(unsigned char)*path++] = n;
 	add_path(n, path);
 }
 
@@ -230,13 +230,13 @@
 
 	if (!*path)
 		return;
-	next = node->next[*path];
+	next = node->next[(unsigned char)*path];
 	if (!next)
 		return;
 	del_path(next, path + 1);
 	next->ref--;
 	if (next->ref == 0) {
-		node->next[*path] = NULL;
+		node->next[(unsigned char)*path] = NULL;
 		g_free(next);
 	}
 }
@@ -252,12 +252,12 @@
 	struct _node *n = &root;
 
 	root.flags &= ~IS_END;
-	while (*path && n->next[*path] && !(n->flags & IS_END)) {
+	while (*path && n->next[(unsigned char)*path] && !(n->flags & IS_END)) {
 		if (!g_ascii_isspace(*path) &&
 				!g_ascii_iscntrl(*path) &&
 				!g_ascii_isgraph(*path))
 			return 0;
-		n = n->next[*path++];
+		n = n->next[(unsigned char)*path++];
 		depth++;
 	}
 
--- a/libpurple/account.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/account.c	Thu Jun 07 12:33:23 2007 +0000
@@ -371,7 +371,7 @@
 accounts_to_xmlnode(void)
 {
 	xmlnode *node, *child;
-	GList *cur;
+	const GList *cur;
 
 	node = xmlnode_new("account");
 	xmlnode_set_attrib(node, "version", "1.0");
@@ -877,7 +877,7 @@
 void
 purple_account_destroy(PurpleAccount *account)
 {
-	GList *l;
+	const GList *l;
 
 	g_return_if_fail(account != NULL);
 
@@ -2272,7 +2272,7 @@
 	schedule_accounts_save();
 }
 
-GList *
+const GList *
 purple_accounts_get_all(void)
 {
 	return accounts;
@@ -2282,7 +2282,7 @@
 purple_accounts_get_all_active(void)
 {
 	GList *list = NULL;
-	GList *all = purple_accounts_get_all();
+	const GList *all = purple_accounts_get_all();
 
 	while (all != NULL) {
 		PurpleAccount *account = all->data;
@@ -2300,7 +2300,7 @@
 purple_accounts_find(const char *name, const char *protocol_id)
 {
 	PurpleAccount *account = NULL;
-	GList *l;
+	const GList *l;
 	char *who;
 
 	g_return_val_if_fail(name != NULL, NULL);
@@ -2327,7 +2327,7 @@
 void
 purple_accounts_restore_current_statuses()
 {
-	GList *l;
+	const GList *l;
 	PurpleAccount *account;
 
 	/* If we're not connected to the Internet right now, we bail on this */
--- a/libpurple/account.h	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/account.h	Thu Jun 07 12:33:23 2007 +0000
@@ -886,7 +886,7 @@
  *
  * @return A list of all accounts.
  */
-GList *purple_accounts_get_all(void);
+const GList *purple_accounts_get_all(void);
 
 /**
  * Returns a list of all enabled accounts
--- a/libpurple/blist.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/blist.c	Thu Jun 07 12:33:23 2007 +0000
@@ -304,7 +304,7 @@
 {
 	xmlnode *node, *child, *grandchild;
 	PurpleBlistNode *gnode;
-	GList *cur;
+	const GList *cur;
 
 	node = xmlnode_new("purple");
 	xmlnode_set_attrib(node, "version", "1.0");
@@ -1893,7 +1893,7 @@
 {
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 	PurpleBlistNode *node;
-	GList *l;
+	const GList *l;
 
 	g_return_if_fail(group != NULL);
 
--- a/libpurple/buddyicon.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/buddyicon.c	Thu Jun 07 12:33:23 2007 +0000
@@ -1021,7 +1021,7 @@
 _purple_buddy_icons_account_loaded_cb()
 {
 	const char *dirname = purple_buddy_icons_get_cache_dir();
-	GList *cur;
+	const GList *cur;
 
 	for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
 	{
--- a/libpurple/connection.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/connection.c	Thu Jun 07 12:33:23 2007 +0000
@@ -456,7 +456,7 @@
 void
 purple_connections_disconnect_all(void)
 {
-	GList *l;
+	const GList *l;
 	PurpleConnection *gc;
 
 	while ((l = purple_connections_get_all()) != NULL) {
@@ -466,13 +466,13 @@
 	}
 }
 
-GList *
+const GList *
 purple_connections_get_all(void)
 {
 	return connections;
 }
 
-GList *
+const GList *
 purple_connections_get_connecting(void)
 {
 	return connections_connecting;
--- a/libpurple/connection.h	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/connection.h	Thu Jun 07 12:33:23 2007 +0000
@@ -261,14 +261,14 @@
  *
  * @return A list of all active connections.
  */
-GList *purple_connections_get_all(void);
+const GList *purple_connections_get_all(void);
 
 /**
  * Returns a list of all connections in the process of connecting.
  *
  * @return A list of connecting connections.
  */
-GList *purple_connections_get_connecting(void);
+const GList *purple_connections_get_connecting(void);
 
 /**
  * Checks if gc is still a valid pointer to a gc.
@@ -279,7 +279,7 @@
  * TODO: Eventually this bad boy will be removed, because it is
  *       a gross fix for a crashy problem.
  */
-#define PURPLE_CONNECTION_IS_VALID(gc) (g_list_find(purple_connections_get_all(), (gc)) != NULL)
+#define PURPLE_CONNECTION_IS_VALID(gc) (g_list_find((GList *)purple_connections_get_all(), (gc)) != NULL)
 
 /*@}*/
 
--- a/libpurple/conversation.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/conversation.c	Thu Jun 07 12:33:23 2007 +0000
@@ -631,7 +631,7 @@
 purple_conversation_foreach(void (*func)(PurpleConversation *conv))
 {
 	PurpleConversation *conv;
-	GList *l;
+	const GList *l;
 
 	g_return_if_fail(func != NULL);
 
@@ -732,19 +732,19 @@
 	return g_hash_table_lookup(conv->data, key);
 }
 
-GList *
+const GList *
 purple_get_conversations(void)
 {
 	return conversations;
 }
 
-GList *
+const GList *
 purple_get_ims(void)
 {
 	return ims;
 }
 
-GList *
+const GList *
 purple_get_chats(void)
 {
 	return chats;
@@ -759,7 +759,7 @@
 	PurpleConversation *c = NULL;
 	gchar *name1;
 	const gchar *name2;
-	GList *cnv;
+	const GList *cnv;
 
 	g_return_val_if_fail(name != NULL, NULL);
 
@@ -819,7 +819,7 @@
 		return;
 
 	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
-		!g_list_find(purple_get_conversations(), conv))
+		!g_list_find((GList *)purple_get_conversations(), conv))
 		return;
 
 	displayed = g_strdup(message);
@@ -1250,7 +1250,7 @@
 	return users;
 }
 
-GList *
+const GList *
 purple_conv_chat_get_users(const PurpleConvChat *chat)
 {
 	g_return_val_if_fail(chat != NULL, NULL);
@@ -1269,7 +1269,7 @@
 		return;
 
 	purple_conv_chat_set_ignored(chat,
-		g_list_append(purple_conv_chat_get_ignored(chat), g_strdup(name)));
+		g_list_append(chat->ignored, g_strdup(name)));
 }
 
 void
@@ -1284,11 +1284,11 @@
 	if (!purple_conv_chat_is_user_ignored(chat, name))
 		return;
 
-	item = g_list_find(purple_conv_chat_get_ignored(chat),
+	item = g_list_find((GList *)purple_conv_chat_get_ignored(chat),
 					   purple_conv_chat_get_ignored_user(chat, name));
 
 	purple_conv_chat_set_ignored(chat,
-		g_list_remove_link(purple_conv_chat_get_ignored(chat), item));
+		g_list_remove_link(chat->ignored, item));
 
 	g_free(item->data);
 	g_list_free_1(item);
@@ -1304,7 +1304,7 @@
 	return ignored;
 }
 
-GList *
+const GList *
 purple_conv_chat_get_ignored(const PurpleConvChat *chat)
 {
 	g_return_val_if_fail(chat != NULL, NULL);
@@ -1315,7 +1315,7 @@
 const char *
 purple_conv_chat_get_ignored_user(const PurpleConvChat *chat, const char *user)
 {
-	GList *ignored;
+	const GList *ignored;
 
 	g_return_val_if_fail(chat != NULL, NULL);
 	g_return_val_if_fail(user != NULL, NULL);
@@ -1565,7 +1565,7 @@
 		cbuddy = purple_conv_chat_cb_new(user, alias, flag);
 		/* This seems dumb. Why should we set users thousands of times? */
 		purple_conv_chat_set_users(chat,
-				g_list_prepend(purple_conv_chat_get_users(chat), cbuddy));
+				g_list_prepend(chat->in_room, cbuddy));
 
 		cbuddies = g_list_prepend(cbuddies, cbuddy);
 
@@ -1634,7 +1634,7 @@
 	flags = purple_conv_chat_user_get_flags(chat, old_user);
 	cb = purple_conv_chat_cb_new(new_user, NULL, flags);
 	purple_conv_chat_set_users(chat,
-		g_list_prepend(purple_conv_chat_get_users(chat), cb));
+		g_list_prepend(chat->in_room, cb));
 
 	if (!strcmp(chat->nick, purple_normalize(conv->account, old_user))) {
 		const char *alias;
@@ -1666,7 +1666,7 @@
 
 	if (cb) {
 		purple_conv_chat_set_users(chat,
-				g_list_remove(purple_conv_chat_get_users(chat), cb));
+				g_list_remove(chat->in_room, cb));
 		purple_conv_chat_cb_destroy(cb);
 	}
 
@@ -1760,7 +1760,7 @@
 
 		if (cb) {
 			purple_conv_chat_set_users(chat,
-					g_list_remove(purple_conv_chat_get_users(chat), cb));
+					g_list_remove(chat->in_room, cb));
 			purple_conv_chat_cb_destroy(cb);
 		}
 
@@ -1809,14 +1809,15 @@
 {
 	PurpleConversation *conv;
 	PurpleConversationUiOps *ops;
-	GList *users, *names = NULL;
-	GList *l;
+	GList *users;
+	const GList *l;
+	GList *names = NULL;
 
 	g_return_if_fail(chat != NULL);
 
 	conv  = purple_conv_chat_get_conversation(chat);
 	ops   = purple_conversation_get_ui_ops(conv);
-	users = purple_conv_chat_get_users(chat);
+	users = chat->in_room;
 
 	if (ops != NULL && ops->chat_remove_users != NULL) {
 		for (l = users; l; l = l->next) {
@@ -1918,7 +1919,7 @@
 PurpleConversation *
 purple_find_chat(const PurpleConnection *gc, int id)
 {
-	GList *l;
+	const GList *l;
 	PurpleConversation *conv;
 
 	for (l = purple_get_chats(); l != NULL; l = l->next) {
@@ -1967,7 +1968,7 @@
 PurpleConvChatBuddy *
 purple_conv_chat_cb_find(PurpleConvChat *chat, const char *name)
 {
-	GList *l;
+	const GList *l;
 	PurpleConvChatBuddy *cb = NULL;
 
 	g_return_val_if_fail(chat != NULL, NULL);
--- a/libpurple/conversation.h	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/conversation.h	Thu Jun 07 12:33:23 2007 +0000
@@ -504,21 +504,21 @@
  *
  * @return A GList of all conversations.
  */
-GList *purple_get_conversations(void);
+const GList *purple_get_conversations(void);
 
 /**
  * Returns a list of all IMs.
  *
  * @return A GList of all IMs.
  */
-GList *purple_get_ims(void);
+const GList *purple_get_ims(void);
 
 /**
  * Returns a list of all chats.
  *
  * @return A GList of all chats.
  */
-GList *purple_get_chats(void);
+const GList *purple_get_chats(void);
 
 /**
  * Finds a conversation with the specified type, name, and Purple account.
@@ -877,7 +877,7 @@
  *
  * @return The list of users.
  */
-GList *purple_conv_chat_get_users(const PurpleConvChat *chat);
+const GList *purple_conv_chat_get_users(const PurpleConvChat *chat);
 
 /**
  * Ignores a user in a chat room.
@@ -912,7 +912,7 @@
  *
  * @return The list of ignored users.
  */
-GList *purple_conv_chat_get_ignored(const PurpleConvChat *chat);
+const GList *purple_conv_chat_get_ignored(const PurpleConvChat *chat);
 
 /**
  * Returns the actual name of the specified ignored user, if it exists in
--- a/libpurple/dbus-analyze-functions.py	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/dbus-analyze-functions.py	Thu Jun 07 12:33:23 2007 +0000
@@ -33,9 +33,13 @@
     ]
 
 # This is a list of functions that return a GList* whose elements are
-# string, not pointers to objects.  Don't put any functions here, it
-# won't work.
-stringlists = []
+# string, not pointers to objects.
+stringlists = [
+    "purple_prefs_get_path_list",
+    "purple_prefs_get_string_list",
+    "purple_uri_list_extract_filenames",
+    "purple_uri_list_extract_uris",
+]
 
 pointer = "#pointer#"
 myexception = "My Exception"
@@ -148,7 +152,7 @@
                 return self.outputpurplestructure(type, name)
 
             if type[0] in ["GList", "GSList"]:
-                return self.outputlist(type, name)
+                return self.outputlist(type, name, const)
 
         raise myexception
     
@@ -250,7 +254,7 @@
         self.returncode.append("return (%s*) GINT_TO_POINTER(%s);" % (type[0], name));
         self.definepurplestructure(type)
 
-    def outputlist(self, type, name):
+    def outputlist(self, type, name, const):
         self.functiontype = "%s*" % type[0]
         self.decls.append("GArray *%s;" % name)
         self.outputparams.append(('dbus_g_type_get_collection("GArray", G_TYPE_INT)', name))
@@ -385,28 +389,40 @@
         self.addouttype("i", name)
 
     # GList*, GSList*, assume that list is a list of objects
-
-    # fixme: at the moment, we do NOT free the memory occupied by
-    # the list, we should free it if the list has NOT been declared const
-
-    # fixme: we assume that this is a list of objects, not a list
-    # of strings
-
-    def outputlist(self, type, name):
+    # unless the function is in stringlists
+    def outputlist(self, type, name, const):
         self.cdecls.append("\tdbus_int32_t %s_LEN;" % name)
         self.ccodeout.append("\tg_free(%s);" % name)
 
+        if const:
+            const_prefix = "const_"
+        else:
+            const_prefix = ""
+
+        if (const):
+            self.cdecls.append("\tconst %s *list;" % type[0]);
+        else:
+            self.cdecls.append("\t%s *list;" % type[0]);
+
         if self.function.name in stringlists:
             self.cdecls.append("\tchar **%s;" % name)
-            self.ccode.append("\t%s = purple_%s_to_array(%s, FALSE, &%s_LEN);" % \
-                         (name, type[0], self.call, name))
+            self.ccode.append("\tlist = %s;" % self.call)
+            self.ccode.append("\t%s = (char **)purple_const_%s_to_array(list, &%s_LEN);" % \
+                         (name, type[0], name))
             self.cparamsout.append("\tDBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &%s, %s_LEN" \
                           % (name, name))
+            if (not const):
+                type_name = type[0].lower()[1:]
+                self.ccodeout.append("\tg_%s_foreach(list, (GFunc)g_free, NULL);" % type_name)
+                self.ccodeout.append("\tg_%s_free(list);" % type_name)
             self.addouttype("as", name)
         else:
             self.cdecls.append("\tdbus_int32_t *%s;" % name)
-            self.ccode.append("\t%s = purple_dbusify_%s(%s, FALSE, &%s_LEN);" % \
-                         (name, type[0], self.call, name))
+            self.ccode.append("\tlist = %s;" % self.call)
+            self.ccode.append("\t%s = purple_dbusify_const_%s(list, &%s_LEN);" % \
+                         (name, type[0], name))
+            if (not const):
+                self.ccode.append("\tg_%s_free(list);" % type[0].lower()[1:])
             self.cparamsout.append("\tDBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \
                               % (name, name))
             self.addouttype("ai", name)
--- a/libpurple/dbus-bindings.h	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/dbus-bindings.h	Thu Jun 07 12:33:23 2007 +0000
@@ -83,14 +83,52 @@
 					int              first_arg_type,
 					va_list          var_args);
 
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_dbusify_const_GList().
+ */
 dbus_int32_t* purple_dbusify_GList(GList *list, gboolean free_memory, 
 				 dbus_int32_t *len);
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_dbusify_const_GSList().
+ */
 dbus_int32_t* purple_dbusify_GSList(GSList *list, gboolean free_memory,
 				  dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+dbus_int32_t* purple_dbusify_const_GList(const GList *list, dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+dbus_int32_t* purple_dbusify_const_GSList(const GSList *list, dbus_int32_t *len);
+
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_const_GList_to_array().
+ */
 gpointer* purple_GList_to_array(GList *list, gboolean free_memory,
 			      dbus_int32_t *len);
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_const_GSList_to_array().
+ */
 gpointer* purple_GSList_to_array(GSList *list, gboolean free_memory,
 			      dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+gpointer* purple_const_GList_to_array(const GList *list, dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+gpointer* purple_const_GSList_to_array(const GSList *list, dbus_int32_t *len);
+
 GHashTable *purple_dbus_iter_hash_table(DBusMessageIter *iter, DBusError *error);
 
 const char* empty_to_null(const char *str);
--- a/libpurple/dbus-server.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/dbus-server.c	Thu Jun 07 12:33:23 2007 +0000
@@ -290,19 +290,45 @@
 }
 
 dbus_int32_t *
-purple_dbusify_GList(GList *list, gboolean free_memory, dbus_int32_t *len)
+purple_dbusify_const_GList(const GList *list, dbus_int32_t *len)
 {
 	dbus_int32_t *array;
 	int i;
-	GList *elem;
+	const GList *elem;
 
-	*len = g_list_length(list);
-	array = g_new0(dbus_int32_t, g_list_length(list));
+	/* g_list_length() should really take a const GList */
+	*len = g_list_length((GList *)list);
+	array = g_new0(dbus_int32_t, *len);
 	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
 		array[i] = purple_dbus_pointer_to_id(elem->data);
 
-	if (free_memory)
-		g_list_free(list);
+	return array;
+}
+
+dbus_int32_t *
+purple_dbusify_GList(GList *list, gboolean free_memory, dbus_int32_t *len)
+{
+	dbus_int32_t *array = purple_dbusify_const_GList(list, len);
+
+	if (!free_memory)
+		return array;
+
+	g_list_free(list);
+	return array;
+}
+
+dbus_int32_t *
+purple_dbusify_const_GSList(const GSList *list, dbus_int32_t *len)
+{
+	dbus_int32_t *array;
+	int i;
+	const GSList *elem;
+
+	/* g_slist_length should really take a const GSList */
+	*len = g_slist_length((GSList *)list);
+	array = g_new0(dbus_int32_t, *len);
+	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
+		array[i] = purple_dbus_pointer_to_id(elem->data);
 
 	return array;
 }
@@ -310,17 +336,26 @@
 dbus_int32_t *
 purple_dbusify_GSList(GSList *list, gboolean free_memory, dbus_int32_t *len)
 {
-	dbus_int32_t *array;
-	int i;
-	GSList *elem;
+	dbus_int32_t *array = purple_dbusify_const_GSList(list, len);
+
+	if (!free_memory)
+		return array;
+
+	g_slist_free(list);
+	return array;
+}
 
-	*len = g_slist_length(list);
-	array = g_new0(dbus_int32_t, g_slist_length(list));
+gpointer *
+purple_const_GList_to_array(const GList *list, dbus_int32_t *len)
+{
+	gpointer *array;
+	int i;
+	const GList *elem;
+
+	*len = g_list_length((GList *)list);
+	array = g_new0(gpointer, *len);
 	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
-		array[i] = purple_dbus_pointer_to_id(elem->data);
-
-	if (free_memory)
-		g_slist_free(list);
+		array[i] = elem->data;
 
 	return array;
 }
@@ -328,36 +363,39 @@
 gpointer *
 purple_GList_to_array(GList *list, gboolean free_memory, dbus_int32_t *len)
 {
+	gpointer *array = purple_const_GList_to_array(list, len);
+
+	if (!free_memory)
+		return array;
+
+	g_list_free(list);
+	return array;
+}
+
+gpointer *
+purple_const_GSList_to_array(const GSList *list, dbus_int32_t *len)
+{
 	gpointer *array;
 	int i;
-	GList *elem;
+	const GSList *elem;
 
-	*len = g_list_length(list);
-	array = g_new0(gpointer, g_list_length(list));
+	*len = g_slist_length((GSList *)list);
+	array = g_new0(gpointer, *len);
 	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
 		array[i] = elem->data;
 
-	if (free_memory)
-		g_list_free(list);
-
 	return array;
 }
 
 gpointer *
 purple_GSList_to_array(GSList *list, gboolean free_memory, dbus_int32_t *len)
 {
-	gpointer *array;
-	int i;
-	GSList *elem;
+	gpointer *array = purple_const_GSList_to_array(list, len);
 
-	*len = g_slist_length(list);
-	array = g_new0(gpointer, g_slist_length(list));
-	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
-		array[i] = elem->data;
+	if (!free_memory)
+		return array;
 
-	if (free_memory)
-		g_slist_free(list);
-
+	g_slist_free(list);
 	return array;
 }
 
--- a/libpurple/dbus-useful.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/dbus-useful.c	Thu Jun 07 12:33:23 2007 +0000
@@ -11,7 +11,7 @@
 		       gboolean (*account_test)(const PurpleAccount *account))
 {
 	PurpleAccount *result = NULL;
-	GList *l;
+	const GList *l;
 	char *who;
 
 	if (name)
--- a/libpurple/idle.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/idle.c	Thu Jun 07 12:33:23 2007 +0000
@@ -199,7 +199,7 @@
 	/* Idle reporting stuff */
 	if (report_idle && (time_idle >= IDLEMARK))
 	{
-		GList *l;
+		const GList *l;
 		for (l = purple_connections_get_all(); l != NULL; l = l->next)
 		{
 			PurpleConnection *gc = l->data;
--- a/libpurple/log.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/log.c	Thu Jun 07 12:33:23 2007 +0000
@@ -984,7 +984,7 @@
 		GDir *protocol_dir;
 		const gchar *username;
 		gchar *protocol_unescaped;
-		GList *account_iter;
+		const GList *account_iter;
 		GList *accounts = NULL;
 
 		if ((protocol_dir = g_dir_open(protocol_path, 0, NULL)) == NULL) {
--- a/libpurple/notify.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/notify.c	Thu Jun 07 12:33:23 2007 +0000
@@ -530,7 +530,7 @@
 	g_free(user_info);
 }
 
-GList *
+const GList *
 purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info)
 {
 	g_return_val_if_fail(user_info != NULL, NULL);
--- a/libpurple/notify.h	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/notify.h	Thu Jun 07 12:33:23 2007 +0000
@@ -458,7 +458,7 @@
  *
  * @result                   A GList of PurpleNotifyUserInfoEntry objects
  */
-GList *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info);
+const GList *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info);
 
 /**
  * Create a textual representation of a PurpleNotifyUserInfo, separating entries with newline
--- a/libpurple/plugins/joinpart.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/plugins/joinpart.c	Thu Jun 07 12:33:23 2007 +0000
@@ -86,7 +86,7 @@
 	/* If the room is small, don't bother. */
 	chat = PURPLE_CONV_CHAT(conv);
 	threshold = purple_prefs_get_int(THRESHOLD_PREF);
-	if (g_list_length(purple_conv_chat_get_users(chat)) < threshold)
+	if (g_list_length((GList *)purple_conv_chat_get_users(chat)) < threshold)
 		return FALSE;
 
 	/* We always care about our buddies! */
--- a/libpurple/plugins/perl/common/Account.xs	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/plugins/perl/common/Account.xs	Thu Jun 07 12:33:23 2007 +0000
@@ -290,7 +290,7 @@
 void
 purple_accounts_get_all()
 PREINIT:
-    GList *l;
+    const GList *l;
 PPCODE:
     for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
         XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Account")));
--- a/libpurple/plugins/perl/common/Connection.xs	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/plugins/perl/common/Connection.xs	Thu Jun 07 12:33:23 2007 +0000
@@ -72,7 +72,7 @@
 void
 purple_connections_get_all()
 PREINIT:
-	GList *l;
+	const GList *l;
 PPCODE:
 	for (l = purple_connections_get_all(); l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Connection")));
@@ -81,7 +81,7 @@
 void
 purple_connections_get_connecting()
 PREINIT:
-	GList *l;
+	const GList *l;
 PPCODE:
 	for (l = purple_connections_get_connecting(); l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Connection")));
--- a/libpurple/plugins/perl/common/Conversation.xs	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/plugins/perl/common/Conversation.xs	Thu Jun 07 12:33:23 2007 +0000
@@ -93,7 +93,7 @@
 void
 purple_get_ims()
 PREINIT:
-	GList *l;
+	const GList *l;
 PPCODE:
 	for (l = purple_get_ims(); l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Conversation")));
@@ -102,7 +102,7 @@
 void
 purple_get_conversations()
 PREINIT:
-	GList *l;
+	const GList *l;
 PPCODE:
 	for (l = purple_get_conversations(); l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Conversation")));
@@ -111,7 +111,7 @@
 void
 purple_get_chats()
 PREINIT:
-	GList *l;
+	const GList *l;
 PPCODE:
 	for (l = purple_get_chats(); l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Conversation")));
@@ -354,7 +354,7 @@
 purple_conv_chat_get_users(chat)
 	Purple::Conversation::Chat chat
 PREINIT:
-	GList *l;
+	const GList *l;
 PPCODE:
 	for (l = purple_conv_chat_get_users(chat); l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ListEntry")));
@@ -394,7 +394,7 @@
 purple_conv_chat_get_ignored(chat)
 	Purple::Conversation::Chat chat
 PREINIT:
-	GList *l;
+	const GList *l;
 PPCODE:
 	for (l = purple_conv_chat_get_ignored(chat); l != NULL; l = l->next) {
 		XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ListEntry")));
--- a/libpurple/plugins/tcl/tcl_cmds.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/plugins/tcl/tcl_cmds.c	Thu Jun 07 12:33:23 2007 +0000
@@ -43,7 +43,7 @@
 static PurpleAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp)
 {
 	PurpleAccount *account;
-	GList *cur;
+	const GList *cur;
 
 	account = purple_tcl_ref_get(interp, obj, PurpleTclRefAccount);
 
@@ -62,7 +62,7 @@
 static PurpleConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp)
 {
 	PurpleConversation *convo;
-	GList *cur;
+	const GList *cur;
 
 	convo = purple_tcl_ref_get(interp, obj, PurpleTclRefConversation);
 
@@ -81,7 +81,7 @@
 static PurpleConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp)
 {
 	PurpleConnection *gc;
-	GList *cur;
+	const GList *cur;
 
 	gc = purple_tcl_ref_get(interp, obj, PurpleTclRefConnection);
 
@@ -612,7 +612,7 @@
 	const char *cmds[] = { "account", "displayname", "handle", "list", NULL };
 	enum { CMD_CONN_ACCOUNT, CMD_CONN_DISPLAYNAME, CMD_CONN_HANDLE, CMD_CONN_LIST } cmd;
 	int error;
-	GList *cur;
+	const GList *cur;
 	PurpleConnection *gc;
 
 	if (objc < 2) {
@@ -680,7 +680,7 @@
 	PurpleConversation *convo;
 	PurpleAccount *account;
 	PurpleConversationType type;
-	GList *cur;
+	const GList *cur;
 	char *opt, *from, *what;
 	int error, argsused, flags = 0;
 
--- a/libpurple/protocols/irc/irc.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/protocols/irc/irc.c	Thu Jun 07 12:33:23 2007 +0000
@@ -592,7 +592,7 @@
 	struct irc_conn *irc = gc->proto_data;
 	int len;
 
-	if(!g_list_find(purple_connections_get_all(), gc)) {
+	if(!g_list_find((GList *)purple_connections_get_all(), gc)) {
 		purple_ssl_close(gsc);
 		return;
 	}
--- a/libpurple/protocols/jabber/jutil.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/protocols/jabber/jutil.c	Thu Jun 07 12:33:23 2007 +0000
@@ -221,7 +221,7 @@
 jabber_find_unnormalized_conv(const char *name, PurpleAccount *account)
 {
 	PurpleConversation *c = NULL;
-	GList *cnv;
+	const GList *cnv;
 
 	g_return_val_if_fail(name != NULL, NULL);
 
--- a/libpurple/protocols/msn/msn.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/protocols/msn/msn.c	Thu Jun 07 12:33:23 2007 +0000
@@ -1463,7 +1463,7 @@
 	purple_debug_info("msn", "In msn_got_info\n");
 
 	/* Make sure the connection is still valid */
-	if (g_list_find(purple_connections_get_all(), info_data->gc) == NULL)
+	if (g_list_find((GList *)purple_connections_get_all(), info_data->gc) == NULL)
 	{
 		purple_debug_warning("msn", "invalid connection. ignoring buddy info.\n");
 		g_free(info_data->name);
@@ -1883,7 +1883,7 @@
 
 	/* Make sure the connection is still valid if we got here by fetching a photo url */
 	if (url_text && (error_message != NULL ||
-					 g_list_find(purple_connections_get_all(), info_data->gc) == NULL))
+					 g_list_find((GList *)purple_connections_get_all(), info_data->gc) == NULL))
 	{
 		purple_debug_warning("msn", "invalid connection. ignoring buddy photo info.\n");
 		g_free(stripped);
@@ -1982,7 +1982,7 @@
 		if (acct && !purple_account_is_connected(acct))
 			acct = NULL;
 	} else { /* Otherwise find an active account for the protocol */
-		GList *l = purple_accounts_get_all();
+		const GList *l = purple_accounts_get_all();
 		while (l) {
 			if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
 					&& purple_account_is_connected(l->data)) {
--- a/libpurple/protocols/oscar/oscar.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu Jun 07 12:33:23 2007 +0000
@@ -6493,7 +6493,7 @@
 		if (acct && !purple_account_is_connected(acct))
 			acct = NULL;
 	} else { /* Otherwise find an active account for the protocol */
-		GList *l = purple_accounts_get_all();
+		const GList *l = purple_accounts_get_all();
 		while (l) {
 			if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
 					&& purple_account_is_connected(l->data)) {
--- a/libpurple/protocols/yahoo/yahoo.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Thu Jun 07 12:33:23 2007 +0000
@@ -3861,7 +3861,7 @@
 		if (acct && !purple_account_is_connected(acct))
 			acct = NULL;
 	} else { /* Otherwise find an active account for the protocol */
-		GList *l = purple_accounts_get_all();
+		const GList *l = purple_accounts_get_all();
 		while (l) {
 			if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
 					&& purple_account_is_connected(l->data)) {
--- a/libpurple/protocols/yahoo/yahoochat.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Thu Jun 07 12:33:23 2007 +0000
@@ -633,10 +633,10 @@
  * I think conference names are always ascii.
  */
 
-void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, GList *who)
+void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, const GList *who)
 {
 	struct yahoo_packet *pkt;
-	GList *w;
+	const GList *w;
 
 	purple_debug_misc("yahoo", "leaving conference %s\n", room);
 	
@@ -653,11 +653,11 @@
 }
 
 static int yahoo_conf_send(PurpleConnection *gc, const char *dn, const char *room,
-							GList *members, const char *what)
+							const GList *members, const char *what)
 {
 	struct yahoo_data *yd = gc->proto_data;
 	struct yahoo_packet *pkt;
-	GList *who;
+	const GList *who;
 	char *msg, *msg2;
 	int utf8 = 1;
 
@@ -714,7 +714,7 @@
 {
 	struct yahoo_data *yd = gc->proto_data;
 	struct yahoo_packet *pkt;
-	GList *members;
+	const GList *members;
 	char *msg2 = NULL;
 
 	if (msg)
--- a/libpurple/protocols/yahoo/yahoochat.h	Thu Jun 07 02:39:48 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.h	Thu Jun 07 12:33:23 2007 +0000
@@ -50,7 +50,7 @@
 char *yahoo_get_chat_name(GHashTable *data);
 void yahoo_c_invite(PurpleConnection *gc, int id, const char *msg, const char *name);
 
-void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, GList *who);
+void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, const GList *who);
 
 void yahoo_chat_goto(PurpleConnection *gc, const char *name);
 
--- a/pidgin/gtkaccount.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkaccount.c	Thu Jun 07 12:33:23 2007 +0000
@@ -1585,7 +1585,7 @@
 
 	account = purple_connection_get_account(gc);
 	model = GTK_TREE_MODEL(accounts_window->model);
-	index = g_list_index(purple_accounts_get_all(), account);
+	index = g_list_index((GList *)purple_accounts_get_all(), account);
 
 	if (gtk_tree_model_iter_nth_child(model, &iter, NULL, index))
 	{
@@ -1788,13 +1788,13 @@
 				case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
 					move_account_after(dialog->model, &dialog->drag_iter,
 									   &iter);
-					dest_index = g_list_index(purple_accounts_get_all(),
+					dest_index = g_list_index((GList *)purple_accounts_get_all(),
 											  account) + 1;
 					break;
 
 				case GTK_TREE_VIEW_DROP_BEFORE:
 				case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
-					dest_index = g_list_index(purple_accounts_get_all(),
+					dest_index = g_list_index((GList *)purple_accounts_get_all(),
 											  account);
 
 					move_account_before(dialog->model, &dialog->drag_iter,
@@ -2093,7 +2093,7 @@
 static gboolean
 populate_accounts_list(AccountsWindow *dialog)
 {
-	GList *l;
+	const GList *l;
 	gboolean ret = FALSE;
 	GdkPixbuf *global_buddyicon = NULL;
 	const char *path;
@@ -2297,7 +2297,7 @@
 global_buddyicon_changed(const char *name, PurplePrefType type,
 			gconstpointer value, gpointer window)
 {
-	GList *list;
+	const GList *list;
 	for (list = purple_accounts_get_all(); list; list = list->next) {
 		account_modified_cb(list->data, window);
 	}
@@ -2428,7 +2428,7 @@
 {
 	PurpleConnection *gc = purple_account_get_connection(data->account);
 
-	if (g_list_find(purple_connections_get_all(), gc))
+	if (g_list_find((GList *)purple_connections_get_all(), gc))
 	{
 		purple_blist_request_add_buddy(data->account, data->username,
 									 NULL, data->alias);
--- a/pidgin/gtkblist.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkblist.c	Thu Jun 07 12:33:23 2007 +0000
@@ -681,7 +681,7 @@
 gboolean
 pidgin_blist_joinchat_is_showable()
 {
-	GList *c;
+	const GList *c;
 	PurpleConnection *gc;
 
 	for (c = purple_connections_get_all(); c != NULL; c = c->next) {
@@ -1536,7 +1536,7 @@
 add_buddies_from_vcard(const char *prpl_id, PurpleGroup *group, GList *list,
 					   const char *alias)
 {
-	GList *l;
+	const GList *l;
 	PurpleAccount *account = NULL;
 	PurpleConnection *gc;
 
@@ -2889,7 +2889,7 @@
 		prpl = purple_find_prpl(purple_account_get_protocol_id(chat->account));
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-		if (g_list_length(purple_connections_get_all()) > 1)
+		if (g_list_length((GList *)purple_connections_get_all()) > 1)
 		{
 			tmp = g_markup_escape_text(chat->account->username, -1);
 			g_string_append_printf(str, _("\n<b>Account:</b> %s"), tmp);
@@ -2954,7 +2954,7 @@
 		user_info = purple_notify_user_info_new();
 
 		/* Account */
-		if (full && g_list_length(purple_connections_get_all()) > 1)
+		if (full && g_list_length((GList *)purple_connections_get_all()) > 1)
 		{
 			tmp = g_markup_escape_text(purple_account_get_username(
 									   purple_buddy_get_account(b)), -1);
@@ -5689,7 +5689,7 @@
 {
 	PidginAddChatData *data;
 	PidginBuddyList *gtkblist;
-	GList *l;
+	const GList *l;
 	PurpleConnection *gc;
 	GtkWidget *label;
 	GtkWidget *rowbox;
@@ -6456,7 +6456,8 @@
 {
 	GtkWidget *menuitem = NULL, *submenu = NULL;
 	GtkAccelGroup *accel_group = NULL;
-	GList *l = NULL, *accounts = NULL;
+	GList *l = NULL;
+	const GList *accounts;
 	gboolean disabled_accounts = FALSE;
 
 	if (accountmenu == NULL)
--- a/pidgin/gtkconv.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkconv.c	Thu Jun 07 12:33:23 2007 +0000
@@ -2645,7 +2645,7 @@
 										gboolean hidden_only,
 										guint max_count)
 {
-	GList *l;
+	const GList *l;
 	GList *r = NULL;
 	guint c = 0;
 
@@ -3751,7 +3751,7 @@
 		g_list_free(list);
 	} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
 		PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
-		GList *l = purple_conv_chat_get_users(chat);
+		const GList *l = purple_conv_chat_get_users(chat);
 		GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list));
 		GtkTreeIter iter;
 		int f;
@@ -5345,7 +5345,7 @@
 	gtkconv = PIDGIN_CONVERSATION(conv);
 	gtkchat = gtkconv->u.chat;
 
-	num_users = g_list_length(purple_conv_chat_get_users(chat));
+	num_users = g_list_length((GList *)purple_conv_chat_get_users(chat));
 
 	g_snprintf(tmp, sizeof(tmp),
 			   ngettext("%d person in room", "%d people in room",
@@ -5439,7 +5439,7 @@
 	gtkconv = PIDGIN_CONVERSATION(conv);
 	gtkchat = gtkconv->u.chat;
 
-	num_users = g_list_length(purple_conv_chat_get_users(chat));
+	num_users = g_list_length((GList *)purple_conv_chat_get_users(chat));
 
 	for (l = users; l != NULL; l = l->next) {
 		model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -6428,7 +6428,7 @@
 close_on_tabs_pref_cb(const char *name, PurplePrefType type,
 					  gconstpointer value, gpointer data)
 {
-	GList *l;
+	const GList *l;
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
 
@@ -6452,7 +6452,7 @@
 				   gconstpointer value, gpointer data)
 {
 #ifdef USE_GTKSPELL
-	GList *cl;
+	const GList *cl;
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
 	GtkSpell *spell;
@@ -6499,7 +6499,7 @@
 show_timestamps_pref_cb(const char *name, PurplePrefType type,
 						gconstpointer value, gpointer data)
 {
-	GList *l;
+	const GList *l;
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
 	PidginWindow *win;
@@ -6527,7 +6527,7 @@
 show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type,
 								gconstpointer value, gpointer data)
 {
-	GList *l;
+	const GList *l;
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
 	PidginWindow *win;
@@ -6557,7 +6557,7 @@
 animate_buddy_icons_pref_cb(const char *name, PurplePrefType type,
 							gconstpointer value, gpointer data)
 {
-	GList *l;
+	const GList *l;
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
 	PidginWindow *win;
@@ -6584,7 +6584,7 @@
 show_buddy_icons_pref_cb(const char *name, PurplePrefType type,
 						 gconstpointer value, gpointer data)
 {
-	GList *l;
+	const GList *l;
 
 	for (l = purple_get_conversations(); l != NULL; l = l->next) {
 		PurpleConversation *conv = l->data;
@@ -6710,7 +6710,7 @@
 static void
 account_signed_off_cb(PurpleConnection *gc, gpointer event)
 {
-	GList *iter;
+	const GList *iter;
 
 	for (iter = purple_get_conversations(); iter; iter = iter->next)
 	{
--- a/pidgin/gtkdocklet.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkdocklet.c	Thu Jun 07 12:33:23 2007 +0000
@@ -109,7 +109,8 @@
 static gboolean
 docklet_update_status()
 {
-	GList *convs, *l;
+	GList *convs;
+	const GList *l;
 	int count;
 	PurpleSavedStatus *saved_status;
 	PurpleStatusPrimitive newstatus = PURPLE_STATUS_OFFLINE;
@@ -213,8 +214,7 @@
 static gboolean
 online_account_supports_chat()
 {
-	GList *c = NULL;
-	c = purple_connections_get_all();
+	const GList *c = purple_connections_get_all();
 
 	while(c != NULL) {
 		PurpleConnection *gc = c->data;
--- a/pidgin/gtkimhtml.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkimhtml.c	Thu Jun 07 12:33:23 2007 +0000
@@ -27,6 +27,9 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
+#include "pidgin.h"
+
 #include "debug.h"
 #include "util.h"
 #include "gtkimhtml.h"
--- a/pidgin/gtkimhtmltoolbar.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Thu Jun 07 12:33:23 2007 +0000
@@ -1238,19 +1238,3 @@
 	g_free(toolbar->sml);
 	toolbar->sml = g_strdup(proto_id);
 }
-	g_signal_connect(G_OBJECT(imhtml), "format_function_update", G_CALLBACK(update_format_cb), toolbar);
-	g_signal_connect_after(G_OBJECT(GTK_IMHTML(imhtml)->text_buffer), "mark-set", G_CALLBACK(mark_set_cb), toolbar);
-
-	buttons = gtk_imhtml_get_format_functions(GTK_IMHTML(imhtml));
-	update_buttons_cb(GTK_IMHTML(imhtml), buttons, toolbar);
-
-	gtk_imhtml_get_current_format(GTK_IMHTML(imhtml), &bold, &italic, &underline);
-
-	update_buttons(toolbar);
-}
-
-void gtk_imhtmltoolbar_associate_smileys(GtkIMHtmlToolbar *toolbar, const char *proto_id)
-{
-	g_free(toolbar->sml);
-	toolbar->sml = g_strdup(proto_id);
-}
--- a/pidgin/gtklog.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtklog.c	Thu Jun 07 12:33:23 2007 +0000
@@ -757,7 +757,7 @@
 
 void pidgin_syslog_show()
 {
-	GList *accounts = NULL;
+	const GList *accounts;
 	GList *logs = NULL;
 
 	if (syslog_viewer != NULL) {
--- a/pidgin/gtkmain.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkmain.c	Thu Jun 07 12:33:23 2007 +0000
@@ -127,7 +127,7 @@
 		}
 		g_strfreev(names);
 	} else { /* no name given, use the first account */
-		GList *accounts;
+		const GList *accounts;
 
 		accounts = purple_accounts_get_all();
 		if (accounts != NULL)
@@ -441,7 +441,7 @@
 	char *opt_session_arg = NULL;
 	int dologin_ret = -1;
 	char *search_path;
-	GList *accounts;
+	const GList *accounts;
 #ifdef HAVE_SIGNAL_H
 	int sig_indx;	/* for setting up signal catching */
 	sigset_t sigset;
@@ -456,6 +456,7 @@
 	gboolean gui_check;
 	gboolean debug_enabled;
 	gboolean migration_failed = FALSE;
+	GList *active_accounts;
 
 	struct option long_options[] = {
 		{"config",   required_argument, NULL, 'c'},
@@ -828,13 +829,13 @@
 		purple_accounts_restore_current_statuses();
 	}
 
-	if ((accounts = purple_accounts_get_all_active()) == NULL)
+	if ((active_accounts = purple_accounts_get_all_active()) == NULL)
 	{
 		pidgin_accounts_window_show();
 	}
 	else
 	{
-		g_list_free(accounts);
+		g_list_free(active_accounts);
 	}
 
 #ifdef HAVE_STARTUP_NOTIFICATION
--- a/pidgin/gtkpounce.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkpounce.c	Thu Jun 07 12:33:23 2007 +0000
@@ -496,7 +496,7 @@
 	}
 	else
 	{
-		GList *connections = purple_connections_get_all();
+		const GList *connections = purple_connections_get_all();
 		PurpleConnection *gc;
 
 		if (connections != NULL)
--- a/pidgin/gtkroomlist.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkroomlist.c	Thu Jun 07 12:33:23 2007 +0000
@@ -343,7 +343,7 @@
 gboolean
 pidgin_roomlist_is_showable()
 {
-	GList *c;
+	const GList *c;
 	PurpleConnection *gc;
 
 	for (c = purple_connections_get_all(); c != NULL; c = c->next) {
--- a/pidgin/gtksavedstatuses.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtksavedstatuses.c	Thu Jun 07 12:33:23 2007 +0000
@@ -1012,7 +1012,7 @@
 static void
 status_editor_populate_list(StatusEditor *dialog, PurpleSavedStatus *saved_status)
 {
-	GList *iter;
+	const GList *iter;
 	PurpleSavedStatusSub *substatus;
 
 	gtk_list_store_clear(dialog->model);
--- a/pidgin/gtkstatusbox.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkstatusbox.c	Thu Jun 07 12:33:23 2007 +0000
@@ -1434,7 +1434,7 @@
 			}
 		}
 	} else {
-		GList *accounts;
+		const GList *accounts;
 		for (accounts = purple_accounts_get_all(); accounts != NULL; accounts = accounts->next) {
 			PurpleAccount *account = accounts->data;
 			PurplePlugin *plug = purple_find_prpl(purple_account_get_protocol_id(account));
--- a/pidgin/gtkthemes.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkthemes.c	Thu Jun 07 12:33:23 2007 +0000
@@ -237,7 +237,7 @@
 	}
 
 	if (load) {
-		GList *cnv;
+		const GList *cnv;
 
 		if (current_smiley_theme)
 			pidgin_themes_destroy_smiley_theme(current_smiley_theme);
--- a/pidgin/gtkutils.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/gtkutils.c	Thu Jun 07 12:33:23 2007 +0000
@@ -687,8 +687,8 @@
 	AopMenu *aop_menu = NULL;
 	PurpleAccount *account;
 	GdkPixbuf *pixbuf = NULL;
-	GList *list;
-	GList *p;
+	const GList *list;
+	const GList *p;
 	GtkSizeGroup *sg;
 	int i;
 	char buf[256];
@@ -995,9 +995,9 @@
 		/* Check for a compatible account. */
 		if (ret_account != NULL)
 		{
-			GList *list;
+			const GList *list;
 			PurpleAccount *account = NULL;
-			GList *l;
+			const GList *l;
 			const char *protoname;
 
 			if (all_accounts)
--- a/pidgin/pidginstock.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/pidginstock.c	Thu Jun 07 12:33:23 2007 +0000
@@ -151,6 +151,7 @@
 	{ PIDGIN_STOCK_TOOLBAR_FONT_FACE, "toolbar", "font-face.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, "toolbar", "font-size-down.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, "toolbar", "font-size-up.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
+	{ PIDGIN_STOCK_TOOLBAR_INSERT, "toolbar", "insert.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, "toolbar", "insert-image.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_INSERT_LINK, "toolbar", "insert-link.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
 	{ PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, "toolbar", "message-new.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL  },
--- a/pidgin/pidginstock.h	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/pidginstock.h	Thu Jun 07 12:33:23 2007 +0000
@@ -116,6 +116,7 @@
 #define PIDGIN_STOCK_TOOLBAR_FONT_FACE	  "pidgin-font-face"
 #define PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER "pidgin-text-smaller"
 #define PIDGIN_STOCK_TOOLBAR_TEXT_LARGER  "pidgin-text-larger"
+#define PIDGIN_STOCK_TOOLBAR_INSERT       "pidgin-insert"
 #define PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE "pidgin-insert-image"
 #define PIDGIN_STOCK_TOOLBAR_INSERT_LINK  "pidgin-insert-link"
 #define PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW  "pidgin-message-new"
--- a/pidgin/pixmaps/toolbar/16/Makefile.am	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/pixmaps/toolbar/16/Makefile.am	Thu Jun 07 12:33:23 2007 +0000
@@ -6,6 +6,7 @@
 		font-face.png \
 		font-size-down.png \
 		font-size-up.png \
+		insert.png \
 		insert-image.png \
 		insert-link.png \
 		message-new.png \
--- a/pidgin/plugins/gestures/gestures.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/plugins/gestures/gestures.c	Thu Jun 07 12:33:23 2007 +0000
@@ -176,7 +176,7 @@
 plugin_load(PurplePlugin *plugin)
 {
 	PurpleConversation *conv;
-	GList *l;
+	const GList *l;
 
 	for (l = purple_get_conversations(); l != NULL; l = l->next) {
 		conv = (PurpleConversation *)l->data;
@@ -199,7 +199,7 @@
 {
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
-	GList *l;
+	const GList *l;
 
 	for (l = purple_get_conversations(); l != NULL; l = l->next) {
 		conv = (PurpleConversation *)l->data;
--- a/pidgin/plugins/gevolution/add_buddy_dialog.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/plugins/gevolution/add_buddy_dialog.c	Thu Jun 07 12:33:23 2007 +0000
@@ -162,7 +162,7 @@
 		GList *list, const char *id)
 {
 	PurpleAccount *account = NULL;
-	GList *l;
+	const GList *l;
 	GtkTreeIter iter;
 	GdkPixbuf *pixbuf;
 
--- a/pidgin/plugins/gevolution/gevolution.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/plugins/gevolution/gevolution.c	Thu Jun 07 12:33:23 2007 +0000
@@ -69,7 +69,8 @@
 						const char *prpl_id, EContactField field)
 {
 	GList *ims = e_contact_get(contact, field);
-	GList *l, *l2;
+	const GList *l;
+	const GList *l2;
 
 	if (ims == NULL)
 		return;
@@ -400,7 +401,7 @@
 	GtkCellRenderer *renderer;
 	GdkPixbuf *pixbuf;
 	GtkListStore *model;
-	GList *l;
+	const GList *l;
 
 	/* Outside container */
 	ret = gtk_vbox_new(FALSE, 18);
--- a/pidgin/plugins/notify.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/plugins/notify.c	Thu Jun 07 12:33:23 2007 +0000
@@ -624,7 +624,7 @@
 static void
 apply_method()
 {
-	GList *convs;
+	const GList *convs;
 	PidginWindow *purplewin = NULL;
 
 	for (convs = purple_get_conversations(); convs != NULL;
@@ -644,7 +644,7 @@
 static void
 apply_notify()
 {
-	GList *convs = purple_get_conversations();
+	const GList *convs = purple_get_conversations();
 
 	while (convs) {
 		PurpleConversation *conv = (PurpleConversation *)convs->data;
@@ -818,7 +818,7 @@
 static gboolean
 plugin_load(PurplePlugin *plugin)
 {
-	GList *convs = purple_get_conversations();
+	const GList *convs = purple_get_conversations();
 	void *conv_handle = purple_conversations_get_handle();
 	void *gtk_conv_handle = pidgin_conversations_get_handle();
 
@@ -860,7 +860,7 @@
 static gboolean
 plugin_unload(PurplePlugin *plugin)
 {
-	GList *convs = purple_get_conversations();
+	const GList *convs = purple_get_conversations();
 
 	while (convs) {
 		PurpleConversation *conv = (PurpleConversation *)convs->data;
--- a/pidgin/plugins/spellchk.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/plugins/spellchk.c	Thu Jun 07 12:33:23 2007 +0000
@@ -2118,7 +2118,7 @@
 plugin_load(PurplePlugin *plugin)
 {
 	void *conv_handle = purple_conversations_get_handle();
-	GList *convs;
+	const GList *convs;
 
 	load_conf();
 
@@ -2137,7 +2137,7 @@
 static gboolean
 plugin_unload(PurplePlugin *plugin)
 {
-	GList *convs;
+	const GList *convs;
 
 	/* Detach from existing conversations */
 	for (convs = purple_get_conversations(); convs != NULL; convs = convs->next)
--- a/pidgin/plugins/timestamp.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/plugins/timestamp.c	Thu Jun 07 12:33:23 2007 +0000
@@ -77,7 +77,7 @@
 	time_t now = time(NULL) / interval * interval;
 	time_t then;
 
-	if (!g_list_find(purple_get_conversations(), conv))
+	if (!g_list_find((GList *)purple_get_conversations(), conv))
 		return FALSE;
 
 	then = GPOINTER_TO_INT(purple_conversation_get_data(
@@ -98,7 +98,7 @@
 	PidginConversation *gtk_conv = PIDGIN_CONVERSATION(conv);
 	GtkTextBuffer *buffer;
 
-	if (!g_list_find(purple_get_conversations(), conv))
+	if (!g_list_find((GList *)purple_get_conversations(), conv))
 		return;
 
 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_conv->imhtml));
--- a/pidgin/plugins/xmppconsole.c	Thu Jun 07 02:39:48 2007 +0000
+++ b/pidgin/plugins/xmppconsole.c	Thu Jun 07 12:33:23 2007 +0000
@@ -731,7 +731,7 @@
 	GtkWidget *label;
 	GtkTextBuffer *buffer;
 	GtkWidget *toolbar;
-	GList *connections;
+	const GList *connections;
 #if GTK_CHECK_VERSION(2,4,0)
 	GtkToolItem *button;
 #endif