changeset 26636:548871664d3b

PidginBlistTheme now copies all its parameters instead of taking ownership. This was needed so that we can ensure the GdkColor*s we're freeing were allocated using gdk_color_copy() so gdk_color_free() will work (it uses the slice allocator). FontColorPair's parameters are const /mostly/ to silence warnings in the loader since we're using the strings directly from the xmlnodes. However, it seems right that anyone wanting to muck with them should use the PidginBlistTheme API
author Paul Aurich <paul@darkrain42.org>
date Sun, 12 Apr 2009 23:46:55 +0000
parents 842b3034d4c6
children 6559bf971fcd
files pidgin/gtkblist-theme-loader.c pidgin/gtkblist-theme.c pidgin/gtkblist-theme.h pidgin/gtkblist.c
diffstat 4 files changed, 137 insertions(+), 157 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkblist-theme-loader.c	Sun Apr 12 22:34:07 2009 +0000
+++ b/pidgin/gtkblist-theme-loader.c	Sun Apr 12 23:46:55 2009 +0000
@@ -21,6 +21,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "xmlnode.h"
 
@@ -44,10 +45,10 @@
 	gchar *filename_full, *data;
 	const gchar *temp;
 	gboolean success = TRUE;
-	GdkColor *bgcolor, *expanded_bgcolor, *collapsed_bgcolor, *contact_color;
+	GdkColor bgcolor, expanded_bgcolor, collapsed_bgcolor, contact_color;
 	GdkColor color;
-	FontColorPair *expanded, *collapsed, *contact, *online, *away, *offline, *idle, *message, *message_nick_said, *status;
-	PidginBlistLayout *layout;
+	FontColorPair expanded, collapsed, contact, online, away, offline, idle, message, message_nick_said, status;
+	PidginBlistLayout layout;
 	PidginBlistTheme *theme;
 
 	/* Find the theme file */
@@ -63,145 +64,117 @@
 	sub_node = xmlnode_get_child(root_node, "description");
 	data = xmlnode_get_data(sub_node);
 
-	/* init all structs and colors */
-	bgcolor = g_new0(GdkColor, 1);
-	expanded_bgcolor = g_new0(GdkColor, 1);
-	collapsed_bgcolor = g_new0(GdkColor, 1);
-
-	layout = g_new0(PidginBlistLayout, 1);
-
-	contact_color = g_new0(GdkColor, 1);
-
-	expanded = g_new0(FontColorPair, 1);
-	collapsed = g_new0(FontColorPair, 1);
-	contact = g_new0(FontColorPair, 1);
-	online = g_new0(FontColorPair, 1);
-	away = g_new0(FontColorPair, 1);
-	offline = g_new0(FontColorPair, 1);
-	idle = g_new0(FontColorPair, 1);
-	message = g_new0(FontColorPair, 1);
-	message_nick_said = g_new0(FontColorPair, 1);
-	status = g_new0(FontColorPair, 1);
-
 	/* <blist> */
 	if ((success = (sub_node = xmlnode_get_child(root_node, "blist")) != NULL)) {
-		if ((temp = xmlnode_get_attrib(sub_node, "color")) != NULL && gdk_color_parse(temp, bgcolor))
-			gdk_colormap_alloc_color(gdk_colormap_get_system(), bgcolor, FALSE, TRUE);
-		else {
-			g_free(bgcolor);
-			bgcolor = NULL;
-		}
+		if ((temp = xmlnode_get_attrib(sub_node, "color")) != NULL && gdk_color_parse(temp, &bgcolor))
+			gdk_colormap_alloc_color(gdk_colormap_get_system(), &bgcolor, FALSE, TRUE);
+		else
+			memset(&bgcolor, 0, sizeof(GdkColor));
 	}
 
 	/* <groups> */
 	if ((success = (success && (sub_node = xmlnode_get_child(root_node, "groups")) != NULL
 		     && (sub_sub_node = xmlnode_get_child(sub_node, "expanded")) != NULL)))
 	{
-		expanded->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		expanded.font = xmlnode_get_attrib(sub_sub_node, "font");
 
 		if ((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color))
-			expanded->color = g_strdup(temp);
-		else expanded->color = g_strdup(DEFAULT_TEXT_COLOR);
+			expanded.color = temp;
+		else expanded.color = DEFAULT_TEXT_COLOR;
 
-		if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, expanded_bgcolor))
-			gdk_colormap_alloc_color(gdk_colormap_get_system(), expanded_bgcolor, FALSE, TRUE);
-		else {
-			g_free(expanded_bgcolor);
-			expanded_bgcolor = NULL;
-		}
+		if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, &expanded_bgcolor))
+			gdk_colormap_alloc_color(gdk_colormap_get_system(), &expanded_bgcolor, FALSE, TRUE);
+		else
+			memset(&expanded_bgcolor, 0, sizeof(GdkColor));
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "collapsed")) != NULL)))
 	{
-		collapsed->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		collapsed.font = xmlnode_get_attrib(sub_sub_node, "font");
 
 		if((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color))
-			collapsed->color = g_strdup(temp);
-		else collapsed->color = g_strdup(DEFAULT_TEXT_COLOR);
+			collapsed.color = temp;
+		else collapsed.color = DEFAULT_TEXT_COLOR;
 
-		if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, collapsed_bgcolor))
-			gdk_colormap_alloc_color(gdk_colormap_get_system(), collapsed_bgcolor, FALSE, TRUE);
-		else {
-			g_free(collapsed_bgcolor);
-			collapsed_bgcolor = NULL;
-		}
+		if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, &collapsed_bgcolor))
+			gdk_colormap_alloc_color(gdk_colormap_get_system(), &collapsed_bgcolor, FALSE, TRUE);
+		else
+			memset(&collapsed_bgcolor, 0, sizeof(GdkColor));
 	}
 
 	/* <buddys> */
 	if ((success = (success && (sub_node = xmlnode_get_child(root_node, "buddys")) != NULL &&
 		     (sub_sub_node = xmlnode_get_child(sub_node, "placement")) != NULL)))
 	{
-		layout->status_icon = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) : 0;
-		layout->text = (temp = xmlnode_get_attrib(sub_sub_node, "name")) != NULL ? atoi(temp) : 1;
-		layout->emblem = (temp = xmlnode_get_attrib(sub_sub_node, "emblem")) != NULL ? atoi(temp) : 2;
-		layout->protocol_icon = (temp = xmlnode_get_attrib(sub_sub_node, "protocol_icon")) != NULL ? atoi(temp) : 3;
-		layout->buddy_icon = (temp = xmlnode_get_attrib(sub_sub_node, "buddy_icon")) != NULL ? atoi(temp) : 4;
-		layout->show_status = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) != 0 : 1;
+		layout.status_icon = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) : 0;
+		layout.text = (temp = xmlnode_get_attrib(sub_sub_node, "name")) != NULL ? atoi(temp) : 1;
+		layout.emblem = (temp = xmlnode_get_attrib(sub_sub_node, "emblem")) != NULL ? atoi(temp) : 2;
+		layout.protocol_icon = (temp = xmlnode_get_attrib(sub_sub_node, "protocol_icon")) != NULL ? atoi(temp) : 3;
+		layout.buddy_icon = (temp = xmlnode_get_attrib(sub_sub_node, "buddy_icon")) != NULL ? atoi(temp) : 4;
+		layout.show_status = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) != 0 : 1;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "background")) != NULL))) {
-		if(gdk_color_parse(xmlnode_get_attrib(sub_sub_node, "color"), contact_color))
-			gdk_colormap_alloc_color(gdk_colormap_get_system(), contact_color, FALSE, TRUE);
-		else {
-			g_free(contact_color);
-			contact_color = NULL;
-		}
+		if(gdk_color_parse(xmlnode_get_attrib(sub_sub_node, "color"), &contact_color))
+			gdk_colormap_alloc_color(gdk_colormap_get_system(), &contact_color, FALSE, TRUE);
+		else
+			memset(&contact_color, 0, sizeof(GdkColor));
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "contact_text")) != NULL))) {
-		contact->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		contact.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			contact->color = g_strdup(temp);
-		else contact->color = g_strdup(DEFAULT_TEXT_COLOR);
+			contact.color = temp;
+		else contact.color = DEFAULT_TEXT_COLOR;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "online_text")) != NULL))) {
-		online->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		online.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			online->color = g_strdup(temp);
-		else online->color = g_strdup(DEFAULT_TEXT_COLOR);
+			online.color = temp;
+		else online.color = DEFAULT_TEXT_COLOR;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "away_text")) != NULL))) {
-		away->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		away.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			away->color = g_strdup(temp);
-		else away->color = g_strdup(DEFAULT_TEXT_COLOR);
+			away.color = temp;
+		else away.color = DEFAULT_TEXT_COLOR;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "offline_text")) != NULL))) {
-		offline->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		offline.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			offline->color = g_strdup(temp);
-		else offline->color = g_strdup(DEFAULT_TEXT_COLOR);
+			offline.color = temp;
+		else offline.color = DEFAULT_TEXT_COLOR;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "idle_text")) != NULL))) {
-		idle->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		idle.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			idle->color = g_strdup(temp);
-		else idle->color = g_strdup(DEFAULT_TEXT_COLOR);
+			idle.color = temp;
+		else idle.color = DEFAULT_TEXT_COLOR;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_text")) != NULL))) {
-		message->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		message.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			message->color = g_strdup(temp);
-		else message->color = g_strdup(DEFAULT_TEXT_COLOR);
+			message.color = temp;
+		else message.color = DEFAULT_TEXT_COLOR;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_nick_said_text")) != NULL))) {
-		message_nick_said->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		message_nick_said.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			message_nick_said->color = g_strdup(temp);
-		else message_nick_said->color = g_strdup(DEFAULT_TEXT_COLOR);
+			message_nick_said.color = temp;
+		else message_nick_said.color = DEFAULT_TEXT_COLOR;
 	}
 
 	if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "status_text")) != NULL))) {
-		status->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
+		status.font = xmlnode_get_attrib(sub_sub_node, "font");
 		if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
-			status->color = g_strdup(temp);
-		else status->color = g_strdup(DEFAULT_TEXT_COLOR);
+			status.color = temp;
+		else status.color = DEFAULT_TEXT_COLOR;
 	}
 
 	/* name is required for theme manager */
@@ -215,21 +188,21 @@
 			"image", xmlnode_get_attrib(root_node, "image"),
 			"directory", dir,
 			"description", data,
-			"background-color", bgcolor,
-			"layout", layout,
-			"expanded-color", expanded_bgcolor,
-			"expanded-text", expanded,
-			"collapsed-color", collapsed_bgcolor,
-			"collapsed-text", collapsed,
-			"contact-color", contact_color,
-			"contact", contact,
-			"online", online,
-			"away", away,
-			"offline", offline,
-			"idle", idle,
-			"message", message,
-			"message_nick_said", message_nick_said,
-			"status", status, NULL);
+			"background-color", &bgcolor,
+			"layout", &layout,
+			"expanded-color", &expanded_bgcolor,
+			"expanded-text", &expanded,
+			"collapsed-color", &collapsed_bgcolor,
+			"collapsed-text", &collapsed,
+			"contact-color", &contact_color,
+			"contact", &contact,
+			"online", &online,
+			"away", &away,
+			"offline", &offline,
+			"idle", &idle,
+			"message", &message,
+			"message_nick_said", &message_nick_said,
+			"status", &status, NULL);
 
 	xmlnode_free(root_node);
 	g_free(data);
--- a/pidgin/gtkblist-theme.c	Sun Apr 12 22:34:07 2009 +0000
+++ b/pidgin/gtkblist-theme.c	Sun Apr 12 23:46:55 2009 +0000
@@ -96,14 +96,21 @@
 free_font_and_color(FontColorPair *pair)
 {
 	if (pair != NULL) {
-		if (pair->font)
-			g_free(pair->font);
-		if (pair->color)
-			g_free(pair->color);
+		g_free((gchar *)pair->font);
+		g_free((gchar *)pair->color);
 		g_free(pair);
 	}
 }
 
+static FontColorPair *
+copy_font_and_color(const FontColorPair *pair)
+{
+	FontColorPair *copy = g_new0(FontColorPair, 1);
+	copy->font  = g_strdup(pair->font);
+	copy->color = g_strdup(pair->color);
+	return copy;
+}
+
 /******************************************************************************
  * GObject Stuff
  *****************************************************************************/
@@ -249,13 +256,13 @@
 	g_free(priv->layout);
 
 	/* Group */
-	g_free(priv->expanded_color);
+	gdk_color_free(priv->expanded_color);
 	free_font_and_color(priv->expanded);
-	g_free(priv->collapsed_color);
+	gdk_color_free(priv->collapsed_color);
 	free_font_and_color(priv->collapsed);
 
 	/* Buddy */
-	g_free(priv->contact_color);
+	gdk_color_free(priv->contact_color);
 	free_font_and_color(priv->contact);
 	free_font_and_color(priv->online);
 	free_font_and_color(priv->away);
@@ -586,7 +593,7 @@
 
 /* Set Methods */
 void
-pidgin_blist_theme_set_background_color(PidginBlistTheme *theme, GdkColor *color)
+pidgin_blist_theme_set_background_color(PidginBlistTheme *theme, const GdkColor *color)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -594,8 +601,8 @@
 
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
-	g_free(priv->bgcolor);
-	priv->bgcolor = color;
+	gdk_color_free(priv->bgcolor);
+	priv->bgcolor = gdk_color_copy(color);
 }
 
 void
@@ -611,7 +618,7 @@
 }
 
 void
-pidgin_blist_theme_set_layout(PidginBlistTheme *theme, PidginBlistLayout *layout)
+pidgin_blist_theme_set_layout(PidginBlistTheme *theme, const PidginBlistLayout *layout)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -620,11 +627,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	g_free(priv->layout);
-	priv->layout = layout;
+	priv->layout = g_memdup(layout, sizeof(PidginBlistLayout));
 }
 
 void
-pidgin_blist_theme_set_expanded_background_color(PidginBlistTheme *theme, GdkColor *color)
+pidgin_blist_theme_set_expanded_background_color(PidginBlistTheme *theme, const GdkColor *color)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -632,12 +639,12 @@
 
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
-	g_free(priv->expanded_color);
-	priv->expanded_color = color;
+	gdk_color_free(priv->expanded_color);
+	priv->expanded_color = gdk_color_copy(color);
 }
 
 void
-pidgin_blist_theme_set_expanded_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_expanded_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -646,11 +653,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->expanded);
-	priv->expanded = pair;
+	priv->expanded = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_collapsed_background_color(PidginBlistTheme *theme, GdkColor *color)
+pidgin_blist_theme_set_collapsed_background_color(PidginBlistTheme *theme, const GdkColor *color)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -658,12 +665,12 @@
 
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
-	g_free(priv->collapsed_color);
-	priv->collapsed_color = color;
+	gdk_color_free(priv->collapsed_color);
+	priv->collapsed_color = gdk_color_copy(color);
 }
 
 void
-pidgin_blist_theme_set_collapsed_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_collapsed_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -672,11 +679,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->collapsed);
-	priv->collapsed = pair;
+	priv->collapsed = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_contact_color(PidginBlistTheme *theme, GdkColor *color)
+pidgin_blist_theme_set_contact_color(PidginBlistTheme *theme, const GdkColor *color)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -684,12 +691,12 @@
 
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
-	g_free(priv->contact_color);
-	priv->contact_color = color;
+	gdk_color_free(priv->contact_color);
+	priv->contact_color = gdk_color_copy(color);
 }
 
 void
-pidgin_blist_theme_set_contact_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_contact_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -698,11 +705,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->contact);
-	priv->contact = pair;
+	priv->contact = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_online_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_online_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -711,11 +718,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->online);
-	priv->online = pair;
+	priv->online = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_away_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_away_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -724,11 +731,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->away);
-	priv->away = pair;
+	priv->away = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_offline_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_offline_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -737,11 +744,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->offline);
-	priv->offline = pair;
+	priv->offline = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_idle_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_idle_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -750,11 +757,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->idle);
-	priv->idle = pair;
+	priv->idle = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_unread_message_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_unread_message_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -763,11 +770,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->message);
-	priv->message = pair;
+	priv->message = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -776,11 +783,11 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->message_nick_said);
-	priv->message_nick_said = pair;
+	priv->message_nick_said = copy_font_and_color(pair);
 }
 
 void
-pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, FontColorPair *pair)
+pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, const FontColorPair *pair)
 {
 	PidginBlistThemePrivate *priv;
 
@@ -789,5 +796,5 @@
 	priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
 
 	free_font_and_color(priv->status);
-	priv->status = pair;
+	priv->status = copy_font_and_color(pair);
 }
--- a/pidgin/gtkblist-theme.h	Sun Apr 12 22:34:07 2009 +0000
+++ b/pidgin/gtkblist-theme.h	Sun Apr 12 23:46:55 2009 +0000
@@ -61,8 +61,8 @@
 
 typedef struct
 {
-	gchar *font;
-	gchar *color;
+	const gchar *font;
+	const gchar *color;
 
 } FontColorPair;
 
@@ -220,7 +220,7 @@
  *
  * @param color The new background color.
  */
-void pidgin_blist_theme_set_background_color(PidginBlistTheme *theme, GdkColor *color);
+void pidgin_blist_theme_set_background_color(PidginBlistTheme *theme, const GdkColor *color);
 
 /**
  * Sets the opacity to be used for this buddy list theme.
@@ -234,84 +234,84 @@
  *
  * @param layout The new layout.
  */
-void pidgin_blist_theme_set_layout(PidginBlistTheme *theme, PidginBlistLayout *layout);
+void pidgin_blist_theme_set_layout(PidginBlistTheme *theme, const PidginBlistLayout *layout);
 
 /**
  * Sets the background color to be used for expanded groups.
  *
  * @param color The new background color.
  */
-void pidgin_blist_theme_set_expanded_background_color(PidginBlistTheme *theme, GdkColor *color);
+void pidgin_blist_theme_set_expanded_background_color(PidginBlistTheme *theme, const GdkColor *color);
 
 /**
  * Sets the text color and font to be used for expanded groups.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_expanded_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_expanded_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the background color to be used for collapsed groups.
  *
  * @param color The new background color.
  */
-void pidgin_blist_theme_set_collapsed_background_color(PidginBlistTheme *theme, GdkColor *color);
+void pidgin_blist_theme_set_collapsed_background_color(PidginBlistTheme *theme, const GdkColor *color);
 
 /**
  * Sets the text color and font to be used for expanded groups.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_collapsed_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_collapsed_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the background color to be used for contacts and chats.
  *
  * @param color The color to use for contacts and chats.
  */
-void pidgin_blist_theme_set_contact_color(PidginBlistTheme *theme, GdkColor *color);
+void pidgin_blist_theme_set_contact_color(PidginBlistTheme *theme, const GdkColor *color);
 
 /**
  * Sets the text color and font to be used for expanded contacts.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_contact_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_contact_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the text color and font to be used for online buddies.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_online_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_online_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the text color and font to be used for away and idle buddies.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_away_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_away_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the text color and font to be used for offline buddies.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_offline_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_offline_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the text color and font to be used for idle buddies.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_idle_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_idle_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the text color and font to be used for buddies with unread messages.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_unread_message_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_unread_message_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the text color and font to be used for a chat with unread messages
@@ -319,14 +319,14 @@
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 /**
  * Sets the text color and font to be used for buddy status messages.
  *
  * @param pair The new text font at color pair.
  */
-void pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, FontColorPair *pair);
+void pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, const FontColorPair *pair);
 
 G_END_DECLS
 #endif /* PIDGIN_BLIST_THEME_H */
--- a/pidgin/gtkblist.c	Sun Apr 12 22:34:07 2009 +0000
+++ b/pidgin/gtkblist.c	Sun Apr 12 23:46:55 2009 +0000
@@ -6197,7 +6197,7 @@
 	PurpleBlistNode *selected_node = NULL;
 	GtkTreeIter iter;
 	FontColorPair *pair;
-	gchar *text_color, *text_font;
+	gchar const *text_color, *text_font;
 	PidginBlistTheme *theme;
 
 	group = (PurpleGroup*)gnode;