gobjectification: b5610bfa: Use GValues rather than PurpleValues in ...

resiak at pidgin.im resiak at pidgin.im
Wed Jul 9 06:05:58 EDT 2008


-----------------------------------------------------------------
Revision: b5610bfaad1cd99641345c501c48e47c92a45d4d
Ancestor: 34e8537729fee64a89e63458ff2460a8e1c883e7
Author: resiak at pidgin.im
Date: 2008-07-06T21:53:53
Branch: im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/b5610bfaad1cd99641345c501c48e47c92a45d4d

Modified files:
        libpurple/account.c libpurple/accountmanager.c
        libpurple/dbus-analyze-functions.py
        libpurple/plugins/perl/common/Status.xs
        libpurple/plugins/tcl/tcl_cmds.c
        libpurple/protocols/bonjour/bonjour.c
        libpurple/protocols/gg/gg.c libpurple/protocols/irc/irc.c
        libpurple/protocols/jabber/jabber.c
        libpurple/protocols/msn/msn.c
        libpurple/protocols/myspace/myspace.c
        libpurple/protocols/novell/novell.c
        libpurple/protocols/null/nullprpl.c
        libpurple/protocols/oscar/oscar.c
        libpurple/protocols/sametime/sametime.c
        libpurple/protocols/simple/simple.c
        libpurple/protocols/yahoo/yahoo.c
        libpurple/protocols/zephyr/zephyr.c libpurple/status.c
        libpurple/status.h

ChangeLog: 

Use GValues rather than PurpleValues in the status API.

-------------- next part --------------
============================================================
--- libpurple/account.c	ab2c4d87a0fa357f925b90f5d2ab4650309a3686
+++ libpurple/account.c	48e94e7879a76e60a3d8fc973240863a857427f3
@@ -174,17 +174,17 @@ status_attr_to_xmlnode(const PurpleStatu
 	xmlnode *node;
 	const char *id;
 	char *value = NULL;
-	PurpleStatusAttr *default_attr;
-	PurpleValue *default_value;
-	PurpleType attr_type;
-	PurpleValue *attr_value;
+	const PurpleStatusAttr *default_attr;
+	const GValue *default_value;
+	GType attr_type;
+	const GValue *attr_value;
 
 	id = purple_status_attr_get_id(attr);
 	g_return_val_if_fail(id, NULL);
 
 	attr_value = purple_status_get_attr_value(status, id);
 	g_return_val_if_fail(attr_value, NULL);
-	attr_type = purple_value_get_type(attr_value);
+	attr_type = G_VALUE_TYPE(attr_value);
 
 	/*
 	 * If attr_value is a different type than it should be
@@ -192,34 +192,32 @@ status_attr_to_xmlnode(const PurpleStatu
 	 */
 	default_attr = purple_status_type_get_attr(type, id);
 	default_value = purple_status_attr_get_value(default_attr);
-	if (attr_type != purple_value_get_type(default_value))
+	if (attr_type != G_VALUE_TYPE(default_value))
 		return NULL;
 
 	/*
 	 * If attr_value is the same as the default for this status
 	 * then there is no need to write it to the file.
 	 */
-	if (attr_type == PURPLE_TYPE_STRING)
+	if (attr_type == G_TYPE_STRING)
 	{
-		const char *string_value = purple_value_get_string(attr_value);
-		const char *default_string_value = purple_value_get_string(default_value);
-		if (((string_value == NULL) && (default_string_value == NULL)) ||
-			((string_value != NULL) && (default_string_value != NULL) &&
-			 !strcmp(string_value, default_string_value)))
+		const char *string_value = g_value_get_string(attr_value);
+		const char *default_string_value = g_value_get_string(default_value);
+		if (purple_util_strings_equal(string_value, default_string_value))
 			return NULL;
-		value = g_strdup(purple_value_get_string(attr_value));
+		value = g_value_dup_string(attr_value);
 	}
-	else if (attr_type == PURPLE_TYPE_INT)
+	else if (attr_type == G_TYPE_INT)
 	{
-		int int_value = purple_value_get_int(attr_value);
-		if (int_value == purple_value_get_int(default_value))
+		int int_value = g_value_get_int(attr_value);
+		if (int_value == g_value_get_int(default_value))
 			return NULL;
 		value = g_strdup_printf("%d", int_value);
 	}
-	else if (attr_type == PURPLE_TYPE_BOOLEAN)
+	else if (attr_type == G_TYPE_BOOLEAN)
 	{
-		gboolean boolean_value = purple_value_get_boolean(attr_value);
-		if (boolean_value == purple_value_get_boolean(default_value))
+		gboolean boolean_value = g_value_get_boolean(attr_value);
+		if (boolean_value == g_value_get_boolean(default_value))
 			return NULL;
 		value = g_strdup(boolean_value ? "true" : "false");
 	}
============================================================
--- libpurple/accountmanager.c	006585516500209f4b24707233660646e3095605
+++ libpurple/accountmanager.c	cd7e3d75d01c32b94e8708ad0d996ce34d3627e0
@@ -261,7 +261,7 @@ parse_status_attrs(xmlnode *node, Purple
 {
 	GList *list = NULL;
 	xmlnode *child;
-	PurpleValue *attr_value;
+	const GValue *attr_value;
 
 	for (child = xmlnode_get_child(node, "attribute"); child != NULL;
 			child = xmlnode_get_next_twin(child))
@@ -278,13 +278,13 @@ parse_status_attrs(xmlnode *node, Purple
 
 		list = g_list_append(list, (char *)id);
 
-		switch (purple_value_get_type(attr_value))
+		switch (G_VALUE_TYPE(attr_value))
 		{
-			case PURPLE_TYPE_STRING:
+			case G_TYPE_STRING:
 				list = g_list_append(list, (char *)value);
 				break;
-			case PURPLE_TYPE_INT:
-			case PURPLE_TYPE_BOOLEAN:
+			case G_TYPE_INT:
+			case G_TYPE_BOOLEAN:
 			{
 				int v;
 				if (sscanf(value, "%d", &v) == 1)
============================================================
--- libpurple/dbus-analyze-functions.py	c3fe2b742d4fa6961173c420815d936ad3315082
+++ libpurple/dbus-analyze-functions.py	b79eba755ee7612ef0ac89b97569d7d5602bab37
@@ -38,6 +38,11 @@ excluded = [\
 
     # This is excluded because it'd be a ridiculous function to export.
     "purple_g_value_slice_free",
+
+    # Excluding a couple of functions which use GValues; they could be
+    # magically bound to D-Bus variants at some point.
+    "purple_status_type_add_attr",
+    "purple_status_attr_new",
     ]
 
 # This is a list of functions that return a GList* or GSList * whose elements
============================================================
--- libpurple/plugins/perl/common/Status.xs	e82b21edc6bb1c5f1b5955b4fb1d2a9a363f9d71
+++ libpurple/plugins/perl/common/Status.xs	d3f683081f927c8f5766f12165067b37d27b9910
@@ -7,7 +7,7 @@ purple_status_type_add_attrs(status_type
 	Purple::StatusType status_type
 	const char *id
 	const char *name
-	Purple::Value value
+	GValue *value
 	...
 
 Purple::StatusType
@@ -20,7 +20,7 @@ purple_status_type_new_with_attrs(primit
 	gboolean independent
 	const char *attr_id
 	const char *attr_name
-	Purple::Value attr_value
+	GValue *attr_value
 	...
 
 */
@@ -239,7 +239,7 @@ purple_status_attr_get_name(attr)
 purple_status_attr_get_name(attr)
 	Purple::StatusAttr attr
 
-Purple::Value
+GValue *
 purple_status_attr_get_value(attr)
 	Purple::StatusAttr attr
 
@@ -247,7 +247,7 @@ purple_status_attr_new(id, name, value_t
 purple_status_attr_new(id, name, value_type)
 	const char *id
 	const char *name
-	Purple::Value value_type
+	GValue *value_type
 
 MODULE = Purple::Status  PACKAGE = Purple::Status  PREFIX = purple_status_
 PROTOTYPES: ENABLE
@@ -276,7 +276,7 @@ purple_status_get_attr_string(status, id
 	Purple::Status status
 	const char *id
 
-Purple::Value
+GValue *
 purple_status_get_attr_value(status, id)
 	Purple::Status status
 	const char *id
@@ -356,7 +356,7 @@ purple_status_type_add_attr(status_type,
 	Purple::StatusType status_type
 	const char *id
 	const char *name
-	Purple::Value value
+	GValue *value
 
 void
 purple_status_type_destroy(status_type)
============================================================
--- libpurple/plugins/tcl/tcl_cmds.c	fbbc0799737a278b4210d0b11294d9f15081a541
+++ libpurple/plugins/tcl/tcl_cmds.c	2b87d6de38fe35d0ce61a4db0e590d64988a72b5
@@ -118,7 +118,7 @@ int tcl_cmd_account(ClientData unused, T
 	PurpleAccount *account;
 	PurpleStatus *status;
 	PurpleStatusType *status_type;
-	PurpleValue *value;
+	const GValue *value;
 	char *attr_id;
 	int error;
 	int b, i;
@@ -291,22 +291,22 @@ int tcl_cmd_account(ClientData unused, T
 					Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid attribute for account", -1));
 					return TCL_ERROR;
 				}
-				switch (purple_value_get_type(value)) {
-				case PURPLE_TYPE_BOOLEAN:
+				switch (g_value_get_type(value)) {
+				case G_TYPE_BOOLEAN:
 					error = Tcl_GetBooleanFromObj(interp, objv[i + 1], &b);
 					if (error != TCL_OK)
 						return error;
 					l = g_list_append(l, attr_id);
 					l = g_list_append(l, GINT_TO_POINTER(b));
 					break;
-				case PURPLE_TYPE_INT:
+				case G_TYPE_INT:
 					error = Tcl_GetIntFromObj(interp, objv[i + 1], &b);
 					if (error != TCL_OK)
 						return error;
 					l = g_list_append(l, attr_id);
 					l = g_list_append(l, GINT_TO_POINTER(b));
 					break;
-				case PURPLE_TYPE_STRING:
+				case G_TYPE_STRING:
 					l = g_list_append(l, attr_id);
 					l = g_list_append(l, Tcl_GetString(objv[i + 1]));
 					break;
@@ -1489,7 +1489,7 @@ int tcl_cmd_status(ClientData unused, Tc
 	enum { CMD_STATUS_ATTR, CMD_STATUS_TYPE } cmd;
 	PurpleStatus *status;
 	PurpleStatusType *status_type;
-	PurpleValue *value;
+	GValue *value;
 	const char *attr;
 	int error, v;
 
@@ -1516,30 +1516,30 @@ int tcl_cmd_status(ClientData unused, Tc
 					 Tcl_NewStringObj("no such attribute", -1));
 			return TCL_ERROR;
 		}
-		switch (purple_value_get_type(value)) {
-		case PURPLE_TYPE_BOOLEAN:
+		switch (G_VALUE_TYPE(value)) {
+		case G_TYPE_BOOLEAN:
 			if (objc == 4) {
 				Tcl_SetObjResult(interp,
-						 Tcl_NewBooleanObj(purple_value_get_boolean(value)));
+						 Tcl_NewBooleanObj(g_value_get_boolean(value)));
 			} else {
 				if ((error = Tcl_GetBooleanFromObj(interp, objv[4], &v)) != TCL_OK)
 					return error;
 				purple_status_set_attr_boolean(status, attr, v);
 			}
 			break;
-		case PURPLE_TYPE_INT:
+		case G_TYPE_INT:
 			if (objc == 4) {
-				Tcl_SetObjResult(interp, Tcl_NewIntObj(purple_value_get_int(value)));
+				Tcl_SetObjResult(interp, Tcl_NewIntObj(g_value_get_int(value)));
 			} else {
 				if ((error = Tcl_GetIntFromObj(interp, objv[4], &v)) != TCL_OK)
 					return error;
 				purple_status_set_attr_int(status, attr, v );
 			}
 			break;
-		case PURPLE_TYPE_STRING:
+		case G_TYPE_STRING:
 			if (objc == 4)
 				Tcl_SetObjResult(interp,
-						 Tcl_NewStringObj(purple_value_get_string(value), -1));
+						 Tcl_NewStringObj(g_value_get_string(value), -1));
 			else
 				purple_status_set_attr_string(status, attr, Tcl_GetString(objv[4]));
 			break;
============================================================
--- libpurple/protocols/bonjour/bonjour.c	1bf52e55826af1f381a369418dee75f02c267444
+++ libpurple/protocols/bonjour/bonjour.c	c1495760fde922aad9c0a997994ad3b0bc80c35b
@@ -279,14 +279,15 @@ bonjour_status_types(PurpleAccount *acco
 										   BONJOUR_STATUS_ID_AVAILABLE,
 										   NULL, TRUE, TRUE, FALSE,
 										   "message", _("Message"),
-										   purple_value_new(PURPLE_TYPE_STRING), NULL);
+										   purple_g_value_slice_new(G_TYPE_STRING),
+										   NULL);
 	status_types = g_list_append(status_types, type);
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
 										   BONJOUR_STATUS_ID_AWAY,
 										   NULL, TRUE, TRUE, FALSE,
 										   "message", _("Message"),
-										   purple_value_new(PURPLE_TYPE_STRING), NULL);
+										   purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	status_types = g_list_append(status_types, type);
 
 	type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
============================================================
--- libpurple/protocols/gg/gg.c	382cc6f3088d55b420f63710cb33da1b97636fd0
+++ libpurple/protocols/gg/gg.c	cd3ff5f8ca7849f7f20cc7cd2c2885746a7714b7
@@ -1603,7 +1603,7 @@ static GList *ggp_status_types(PurpleAcc
 
 	type = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, type);
 
@@ -1613,13 +1613,13 @@ static GList *ggp_status_types(PurpleAcc
 	 */
 	type = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_INVISIBLE, NULL, NULL, TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, type);
 
 	type = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, type);
 
@@ -1628,12 +1628,12 @@ static GList *ggp_status_types(PurpleAcc
 	 */
 	type = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_INVISIBLE, "blocked", _("Blocked"), TRUE, FALSE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL);
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	types = g_list_append(types, type);
 
 	type = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, type);
 
============================================================
--- libpurple/protocols/irc/irc.c	af1d7c58e5fe45146dcab7ea33a5fac1526e68a8
+++ libpurple/protocols/irc/irc.c	b9b59544b7118eecbcb5b556193edaffe3a65b1a
@@ -242,7 +242,7 @@ static GList *irc_status_types(PurpleAcc
 
 	type = purple_status_type_new_with_attrs(
 		PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
-		"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+		"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 		NULL);
 	types = g_list_append(types, type);
 
============================================================
--- libpurple/protocols/jabber/jabber.c	e1883229fa6f25b9edc67309382c36faf657a627
+++ libpurple/protocols/jabber/jabber.c	44eba9c7b1c3554e4246c865a2c9144003983977
@@ -1610,75 +1610,75 @@ GList *jabber_status_types(PurpleAccount
 {
 	PurpleStatusType *type;
 	GList *types = NULL;
-	PurpleValue *priority_value;
+	GValue *priority_value;
 
-	priority_value = purple_value_new(PURPLE_TYPE_INT);
-	purple_value_set_int(priority_value, 1);
+	priority_value = purple_g_value_slice_new(G_TYPE_INT);
+	g_value_set_int(priority_value, 1);
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
 			jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_ONLINE),
 			NULL, TRUE, TRUE, FALSE,
 			"priority", _("Priority"), priority_value,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
-			"mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
-			"moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
-			"nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
-			"buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
+			"mood", _("Mood"), purple_g_value_slice_new(G_TYPE_STRING),
+			"moodtext", _("Mood Text"), purple_g_value_slice_new(G_TYPE_STRING),
+			"nick", _("Nickname"), purple_g_value_slice_new(G_TYPE_STRING),
+			"buzz", _("Allow Buzz"), purple_g_value_slice_new(G_TYPE_BOOLEAN),
 			NULL);
 	types = g_list_append(types, type);
 
-	priority_value = purple_value_new(PURPLE_TYPE_INT);
-	purple_value_set_int(priority_value, 1);
+	priority_value = purple_g_value_slice_new(G_TYPE_INT);
+	g_value_set_int(priority_value, 1);
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
 			jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_CHAT),
 			_("Chatty"), TRUE, TRUE, FALSE,
 			"priority", _("Priority"), priority_value,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
-			"mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
-			"moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
-			"nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
-			"buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
+			"mood", _("Mood"), purple_g_value_slice_new(G_TYPE_STRING),
+			"moodtext", _("Mood Text"), purple_g_value_slice_new(G_TYPE_STRING),
+			"nick", _("Nickname"), purple_g_value_slice_new(G_TYPE_STRING),
+			"buzz", _("Allow Buzz"), purple_g_value_slice_new(G_TYPE_BOOLEAN),
 			NULL);
 	types = g_list_append(types, type);
 
-	priority_value = purple_value_new(PURPLE_TYPE_INT);
-	purple_value_set_int(priority_value, 0);
+	priority_value = purple_g_value_slice_new(G_TYPE_INT);
+	g_value_set_int(priority_value, 0);
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
 			jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_AWAY),
 			NULL, TRUE, TRUE, FALSE,
 			"priority", _("Priority"), priority_value,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
-			"mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
-			"moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
-			"nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
-			"buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
+			"mood", _("Mood"), purple_g_value_slice_new(G_TYPE_STRING),
+			"moodtext", _("Mood Text"), purple_g_value_slice_new(G_TYPE_STRING),
+			"nick", _("Nickname"), purple_g_value_slice_new(G_TYPE_STRING),
+			"buzz", _("Allow Buzz"), purple_g_value_slice_new(G_TYPE_BOOLEAN),
 			NULL);
 	types = g_list_append(types, type);
 
-	priority_value = purple_value_new(PURPLE_TYPE_INT);
-	purple_value_set_int(priority_value, 0);
+	priority_value = purple_g_value_slice_new(G_TYPE_INT);
+	g_value_set_int(priority_value, 0);
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_EXTENDED_AWAY,
 			jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_XA),
 			NULL, TRUE, TRUE, FALSE,
 			"priority", _("Priority"), priority_value,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
-			"mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
-			"moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
-			"nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
-			"buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
+			"mood", _("Mood"), purple_g_value_slice_new(G_TYPE_STRING),
+			"moodtext", _("Mood Text"), purple_g_value_slice_new(G_TYPE_STRING),
+			"nick", _("Nickname"), purple_g_value_slice_new(G_TYPE_STRING),
+			"buzz", _("Allow Buzz"), purple_g_value_slice_new(G_TYPE_BOOLEAN),
 			NULL);
 	types = g_list_append(types, type);
 
-	priority_value = purple_value_new(PURPLE_TYPE_INT);
-	purple_value_set_int(priority_value, 0);
+	priority_value = purple_g_value_slice_new(G_TYPE_INT);
+	g_value_set_int(priority_value, 0);
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
 			jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_DND),
 			_("Do Not Disturb"), TRUE, TRUE, FALSE,
 			"priority", _("Priority"), priority_value,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
-			"mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
-			"moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
-			"nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
-			"buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
+			"mood", _("Mood"), purple_g_value_slice_new(G_TYPE_STRING),
+			"moodtext", _("Mood Text"), purple_g_value_slice_new(G_TYPE_STRING),
+			"nick", _("Nickname"), purple_g_value_slice_new(G_TYPE_STRING),
+			"buzz", _("Allow Buzz"), purple_g_value_slice_new(G_TYPE_BOOLEAN),
 			NULL);
 	types = g_list_append(types, type);
 
@@ -1690,21 +1690,21 @@ GList *jabber_status_types(PurpleAccount
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE,
 			jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_UNAVAILABLE),
 			NULL, FALSE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, type);
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_TUNE,
 			"tune", NULL, TRUE, TRUE, TRUE,
-			PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_TITLE, _("Tune Title"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_ALBUM, _("Tune Album"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_GENRE, _("Tune Genre"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_COMMENT, _("Tune Comment"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_TRACK, _("Tune Track"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_TIME, _("Tune Time"), purple_value_new(PURPLE_TYPE_INT),
-			PURPLE_TUNE_YEAR, _("Tune Year"), purple_value_new(PURPLE_TYPE_INT),
-			PURPLE_TUNE_URL, _("Tune URL"), purple_value_new(PURPLE_TYPE_STRING),
+			PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_TITLE, _("Tune Title"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_ALBUM, _("Tune Album"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_GENRE, _("Tune Genre"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_COMMENT, _("Tune Comment"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_TRACK, _("Tune Track"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_TIME, _("Tune Time"), purple_g_value_slice_new(G_TYPE_INT),
+			PURPLE_TUNE_YEAR, _("Tune Year"), purple_g_value_slice_new(G_TYPE_INT),
+			PURPLE_TUNE_URL, _("Tune URL"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, type);
 
============================================================
--- libpurple/protocols/msn/msn.c	86de6fd3f2f8346c1089cc554442626a9fce9b49
+++ libpurple/protocols/msn/msn.c	04b17f487f28e02aec2170d8184f0246545407ad
@@ -715,35 +715,35 @@ msn_status_types(PurpleAccount *account)
 
 	status = purple_status_type_new_with_attrs(
 				PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
-				"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+				"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 				NULL);
 	types = g_list_append(types, status);
 
 	status = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, status);
 
 	status = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_AWAY, "brb", _("Be Right Back"), TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, status);
 
 	status = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_UNAVAILABLE, "busy", _("Busy"), TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, status);
 	status = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_UNAVAILABLE, "phone", _("On the Phone"), TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, status);
 	status = purple_status_type_new_with_attrs(
 			PURPLE_STATUS_AWAY, "lunch", _("Out to Lunch"), TRUE, TRUE, FALSE,
-			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, status);
 
@@ -761,9 +761,9 @@ msn_status_types(PurpleAccount *account)
 
 	status = purple_status_type_new_with_attrs(PURPLE_STATUS_TUNE,
 			"tune", NULL, TRUE, TRUE, TRUE,
-			PURPLE_TUNE_ARTIST, _("Artist"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_ALBUM, _("Album"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_TITLE, _("Title"), purple_value_new(PURPLE_TYPE_STRING),
+			PURPLE_TUNE_ARTIST, _("Artist"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_ALBUM, _("Album"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_TITLE, _("Title"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 	types = g_list_append(types, status);
 
============================================================
--- libpurple/protocols/myspace/myspace.c	8c1d6bb12deae61195fd8188566883f40d68079c
+++ libpurple/protocols/myspace/myspace.c	dae161c62b3fd62f6db2cff0bc067055533e1fad
@@ -136,7 +136,7 @@ msim_status_types(PurpleAccount *acct)
 	/* Attributes - each status can have a message. */          \
 	"message",                                                  \
 	_("Message"),                                               \
-	purple_value_new(PURPLE_TYPE_STRING),                       \
+	purple_g_value_slice_new(G_TYPE_STRING),                    \
 	NULL);                                                      \
 	                                                            \
 	                                                            \
@@ -157,8 +157,8 @@ msim_status_types(PurpleAccount *acct)
 			TRUE,                   /* should be user_settable some day */
 			TRUE,                   /* independent */
 
-			PURPLE_TUNE_ARTIST, _("Artist"), purple_value_new(PURPLE_TYPE_STRING),
-			PURPLE_TUNE_TITLE, _("Title"), purple_value_new(PURPLE_TYPE_STRING),
+			PURPLE_TUNE_ARTIST, _("Artist"), purple_g_value_slice_new(G_TYPE_STRING),
+			PURPLE_TUNE_TITLE, _("Title"), purple_g_value_slice_new(G_TYPE_STRING),
 			NULL);
 
 	types = g_list_append(types, status);
============================================================
--- libpurple/protocols/novell/novell.c	1e06846abc22e2052b327090eae74ee58d9db014
+++ libpurple/protocols/novell/novell.c	50d87ea671ef2b5b050e0cd13942d34d5fbbb7ad
@@ -2956,19 +2956,19 @@ novell_status_types(PurpleAccount *accou
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, NOVELL_STATUS_TYPE_AVAILABLE,
 										   NULL, TRUE, TRUE, FALSE,
-										   "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+										   "message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 										   NULL);
 	status_types = g_list_append(status_types, type);
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, NOVELL_STATUS_TYPE_AWAY,
 										   NULL, TRUE, TRUE, FALSE,
-										   "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+										   "message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 										   NULL);
 	status_types = g_list_append(status_types, type);
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, NOVELL_STATUS_TYPE_BUSY,
 										   _("Busy"), TRUE, TRUE, FALSE,
-										   "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+										   "message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 										   NULL);
 	status_types = g_list_append(status_types, type);
 
============================================================
--- libpurple/protocols/null/nullprpl.c	5141dc739fdce1546019ccaad896ec6a828dfc4d
+++ libpurple/protocols/null/nullprpl.c	46eb6f947ab7899e588769b4e9d053435ff99d77
@@ -303,19 +303,19 @@ static GList *nullprpl_status_types(Purp
   type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, NULL_STATUS_ONLINE,
                                 NULL_STATUS_ONLINE, TRUE);
   purple_status_type_add_attr(type, "message", _("Online"),
-                              purple_value_new(PURPLE_TYPE_STRING));
+                              purple_g_value_slice_new(G_TYPE_STRING));
   types = g_list_append(types, type);
 
   type = purple_status_type_new(PURPLE_STATUS_AWAY, NULL_STATUS_AWAY,
                                 NULL_STATUS_AWAY, TRUE);
   purple_status_type_add_attr(type, "message", _("Away"),
-                              purple_value_new(PURPLE_TYPE_STRING));
+                              purple_g_value_slice_new(G_TYPE_STRING));
   types = g_list_append(types, type);
   
   type = purple_status_type_new(PURPLE_STATUS_OFFLINE, NULL_STATUS_OFFLINE,
                                 NULL_STATUS_OFFLINE, TRUE);
   purple_status_type_add_attr(type, "message", _("Offline"),
-                              purple_value_new(PURPLE_TYPE_STRING));
+                              purple_g_value_slice_new(G_TYPE_STRING));
   types = g_list_append(types, type);
 
   return types;
============================================================
--- libpurple/protocols/oscar/oscar.c	038f8996d84d5eb966f8c1495631c52feeb0f69c
+++ libpurple/protocols/oscar/oscar.c	d50efc98009bd4194e449dfe125f2dcc50e79d94
@@ -5918,9 +5918,9 @@ oscar_status_types(PurpleAccount *accoun
 										   OSCAR_STATUS_ID_AVAILABLE,
 										   NULL, TRUE, TRUE, FALSE,
 										   "message", _("Message"),
-										   purple_value_new(PURPLE_TYPE_STRING),
+										   purple_g_value_slice_new(G_TYPE_STRING),
 										   "itmsurl", _("iTunes Music Store Link"),
-										   purple_value_new(PURPLE_TYPE_STRING), NULL);
+										   purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	status_types = g_list_prepend(status_types, type);
 
 	type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE,
@@ -5932,7 +5932,7 @@ oscar_status_types(PurpleAccount *accoun
 										   OSCAR_STATUS_ID_AWAY,
 										   NULL, TRUE, TRUE, FALSE,
 										   "message", _("Message"),
-										   purple_value_new(PURPLE_TYPE_STRING), NULL);
+										   purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	status_types = g_list_prepend(status_types, type);
 
 	type = purple_status_type_new_full(PURPLE_STATUS_INVISIBLE,
@@ -5948,21 +5948,21 @@ oscar_status_types(PurpleAccount *accoun
 				OSCAR_STATUS_ID_OCCUPIED,
 				_("Occupied"), TRUE, is_icq, FALSE,
 				"message", _("Message"),
-				purple_value_new(PURPLE_TYPE_STRING), NULL);
+				purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	status_types = g_list_prepend(status_types, type);
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
 				OSCAR_STATUS_ID_DND,
 				_("Do Not Disturb"), TRUE, is_icq, FALSE,
 				"message", _("Message"),
-				purple_value_new(PURPLE_TYPE_STRING), NULL);
+				purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	status_types = g_list_prepend(status_types, type);
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_EXTENDED_AWAY,
 				OSCAR_STATUS_ID_NA,
 				_("Not Available"), TRUE, is_icq, FALSE,
 				"message", _("Message"),
-				purple_value_new(PURPLE_TYPE_STRING), NULL);
+				purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	status_types = g_list_prepend(status_types, type);
 
 	type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
============================================================
--- libpurple/protocols/sametime/sametime.c	0d98facb1fde03b0ba22d56a30658477844e483c
+++ libpurple/protocols/sametime/sametime.c	d461b582ed780787cfc08512429b3dd2e54f1ab1
@@ -3337,19 +3337,19 @@ static GList *mw_prpl_status_types(Purpl
   type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, MW_STATE_ACTIVE,
 			      NULL, TRUE);
   purple_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"),
-			    purple_value_new(PURPLE_TYPE_STRING));
+			    purple_g_value_slice_new(G_TYPE_STRING));
   types = g_list_append(types, type);
 
   type = purple_status_type_new(PURPLE_STATUS_AWAY, MW_STATE_AWAY,
 			      NULL, TRUE);
   purple_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"),
-			    purple_value_new(PURPLE_TYPE_STRING));
+			    purple_g_value_slice_new(G_TYPE_STRING));
   types = g_list_append(types, type);
   
   type = purple_status_type_new(PURPLE_STATUS_UNAVAILABLE, MW_STATE_BUSY,
 			      _("Do Not Disturb"), TRUE);
   purple_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"),
-			    purple_value_new(PURPLE_TYPE_STRING));
+			    purple_g_value_slice_new(G_TYPE_STRING));
   types = g_list_append(types, type);
   
   type = purple_status_type_new(PURPLE_STATUS_OFFLINE, MW_STATE_OFFLINE,
============================================================
--- libpurple/protocols/simple/simple.c	6a1e71849171b3ac8f622ec3bd0115f36a037aea
+++ libpurple/protocols/simple/simple.c	8cac2aa44820a720e5a96efbeebbb3d9178f17bc
@@ -244,7 +244,7 @@ static GList *simple_status_types(Purple
 
 	type = purple_status_type_new_with_attrs(
 		PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
-		"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+		"message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 		NULL);
 	types = g_list_append(types, type);
 
============================================================
--- libpurple/protocols/yahoo/yahoo.c	762739910de1f26321a0a24ba59128d33bec0b05
+++ libpurple/protocols/yahoo/yahoo.c	8198918e61bd0edc1de344cb50ddb721e8543d8a
@@ -3817,13 +3817,13 @@ static GList *yahoo_status_types(PurpleA
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, YAHOO_STATUS_TYPE_AVAILABLE,
 	                                       NULL, TRUE, TRUE, FALSE,
 	                                       "message", _("Message"),
-	                                       purple_value_new(PURPLE_TYPE_STRING), NULL);
+	                                       purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	types = g_list_append(types, type);
 
 	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_AWAY,
 	                                       NULL, TRUE, TRUE, FALSE,
 	                                       "message", _("Message"),
-	                                       purple_value_new(PURPLE_TYPE_STRING), NULL);
+	                                       purple_g_value_slice_new(G_TYPE_STRING), NULL);
 	types = g_list_append(types, type);
 
 	type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_BRB, _("Be Right Back"), TRUE);
============================================================
--- libpurple/protocols/zephyr/zephyr.c	f28466125358a04f101cc64aec706cc2dfb638e3
+++ libpurple/protocols/zephyr/zephyr.c	4acb7658265d6995a6c6568d45f234b219a83232
@@ -2353,7 +2353,7 @@ static GList *zephyr_status_types(Purple
 
 	type = purple_status_type_new_with_attrs(
 					       PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
-					       "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+					       "message", _("Message"), purple_g_value_slice_new(G_TYPE_STRING),
 					       NULL);
 	types = g_list_append(types, type);
 
============================================================
--- libpurple/status.c	d2c9bedc601a55519e58f67aa09aaf8d80b6ff45
+++ libpurple/status.c	a8fbebdec00cdbdce3899eb7bd4b619858c495c5
@@ -58,7 +58,7 @@ struct _PurpleStatusAttr
 {
 	char *id;
 	char *name;
-	PurpleValue *value_type;
+	GValue *value_type;
 };
 
 /**
@@ -113,7 +113,7 @@ struct _PurpleStatus
 	 * The current values of the attributes for this status.  The
 	 * key is a string containing the name of the attribute.  It is
 	 * a borrowed reference from the list of attrs in the
-	 * PurpleStatusType.  The value is a PurpleValue.
+	 * PurpleStatusType.  The value is a GValue.
 	 */
 	GHashTable *attr_values;
 };
@@ -259,7 +259,7 @@ purple_status_type_new_with_attrs(Purple
 		const char *id, const char *name,
 		gboolean saveable, gboolean user_settable,
 		gboolean independent, const char *attr_id,
-		const char *attr_name, PurpleValue *attr_value,
+		const char *attr_name, GValue *attr_value,
 		...)
 {
 	PurpleStatusType *status_type;
@@ -310,7 +310,7 @@ purple_status_type_add_attr(PurpleStatus
 
 void
 purple_status_type_add_attr(PurpleStatusType *status_type, const char *id,
-		const char *name, PurpleValue *value)
+		const char *name, GValue *value)
 {
 	PurpleStatusAttr *attr;
 
@@ -328,7 +328,7 @@ purple_status_type_add_attrs_vargs(Purpl
 purple_status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
 {
 	const char *id, *name;
-	PurpleValue *value;
+	GValue *value;
 
 	g_return_if_fail(status_type != NULL);
 
@@ -337,7 +337,7 @@ purple_status_type_add_attrs_vargs(Purpl
 		name = va_arg(args, const char *);
 		g_return_if_fail(name != NULL);
 
-		value = va_arg(args, PurpleValue *);
+		value = va_arg(args, GValue *);
 		g_return_if_fail(value != NULL);
 
 		purple_status_type_add_attr(status_type, id, name, value);
@@ -346,7 +346,7 @@ purple_status_type_add_attrs(PurpleStatu
 
 void
 purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
-		const char *name, PurpleValue *value, ...)
+		const char *name, GValue *value, ...)
 {
 	va_list args;
 
@@ -491,7 +491,7 @@ PurpleStatusAttr *
 * PurpleStatusAttr API
 **************************************************************************/
 PurpleStatusAttr *
-purple_status_attr_new(const char *id, const char *name, PurpleValue *value_type)
+purple_status_attr_new(const char *id, const char *name, GValue *value_type)
 {
 	PurpleStatusAttr *attr;
 
@@ -517,7 +517,7 @@ purple_status_attr_destroy(PurpleStatusA
 	g_free(attr->id);
 	g_free(attr->name);
 
-	purple_value_destroy(attr->value_type);
+	purple_g_value_slice_free(attr->value_type);
 
 	PURPLE_DBUS_UNREGISTER_POINTER(attr);
 	g_free(attr);
@@ -539,7 +539,7 @@ purple_status_attr_get_name(const Purple
 	return attr->name;
 }
 
-PurpleValue *
+GValue *
 purple_status_attr_get_value(const PurpleStatusAttr *attr)
 {
 	g_return_val_if_fail(attr != NULL, NULL);
@@ -551,6 +551,12 @@ purple_status_attr_get_value(const Purpl
 /**************************************************************************
 * PurpleStatus API
 **************************************************************************/
+
+/* Prototypes */
+static void purple_status_set_attr_value(PurpleStatus *status, const char *id,
+	const GValue *value);
+
+
 PurpleStatus *
 purple_status_new(PurpleStatusType *status_type, PurplePresence *presence)
 {
@@ -568,13 +574,13 @@ purple_status_new(PurpleStatusType *stat
 
 	status->attr_values =
 		g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
-		(GDestroyNotify)purple_value_destroy);
+		(GDestroyNotify)purple_g_value_slice_free);
 
 	for (l = purple_status_type_get_attrs(status_type); l != NULL; l = l->next)
 	{
 		PurpleStatusAttr *attr = (PurpleStatusAttr *)l->data;
-		PurpleValue *value = purple_status_attr_get_value(attr);
-		PurpleValue *new_value = purple_value_dup(value);
+		const GValue *value = purple_status_attr_get_value(attr);
+		GValue *new_value = purple_g_value_slice_dup(value);
 
 		g_hash_table_insert(status->attr_values,
 							(char *)purple_status_attr_get_id(attr),
@@ -759,7 +765,7 @@ purple_status_set_active_with_attrs_list
 	while (l != NULL)
 	{
 		const gchar *id;
-		PurpleValue *value;
+		GValue *value;
 
 		id = l->data;
 		l = l->next;
@@ -775,42 +781,42 @@ purple_status_set_active_with_attrs_list
 
 		specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
 
-		if (value->type == PURPLE_TYPE_STRING)
-		{
-			const gchar *string_data = l->data;
-			l = l->next;
-			if (((string_data == NULL) && (value->data.string_data == NULL)) ||
-				((string_data != NULL) && (value->data.string_data != NULL) &&
-				!strcmp(string_data, value->data.string_data)))
-			{
-				continue;
+		switch (G_VALUE_TYPE(value)) {
+			case G_TYPE_STRING: {
+				const gchar *string_data = l->data;
+				const gchar *current = g_value_get_string(value);
+				if (!purple_util_strings_equal(string_data, current)) {
+					purple_status_set_attr_string(status, id, string_data);
+					changed = TRUE;
+				}
+				break;
 			}
-			purple_status_set_attr_string(status, id, string_data);
-			changed = TRUE;
+			case G_TYPE_INT: {
+				gint int_data = GPOINTER_TO_INT(l->data);
+				gint current = g_value_get_int(value);
+				if (int_data != current) {
+					purple_status_set_attr_int(status, id, int_data);
+					changed = TRUE;
+				}
+				break;
+			}
+			case G_TYPE_BOOLEAN: {
+				gboolean boolean_data = GPOINTER_TO_INT(l->data);
+				gboolean current = g_value_get_boolean(value);
+				if (boolean_data != current) {
+					purple_status_set_attr_boolean(status, id, boolean_data);
+					changed = TRUE;
+				}
+				break;
+			}
+			default: {
+				/* We don't know what the data is--skip over it */
+				purple_debug_warning("status",
+					"Skipping attribute with unhandled data type %s",
+					G_VALUE_TYPE_NAME(value));
+			}
 		}
-		else if (value->type == PURPLE_TYPE_INT)
-		{
-			int int_data = GPOINTER_TO_INT(l->data);
-			l = l->next;
-			if (int_data == value->data.int_data)
-				continue;
-			purple_status_set_attr_int(status, id, int_data);
-			changed = TRUE;
-		}
-		else if (value->type == PURPLE_TYPE_BOOLEAN)
-		{
-			gboolean boolean_data = GPOINTER_TO_INT(l->data);
-			l = l->next;
-			if (boolean_data == value->data.boolean_data)
-				continue;
-			purple_status_set_attr_boolean(status, id, boolean_data);
-			changed = TRUE;
-		}
-		else
-		{
-			/* We don't know what the data is--skip over it */
-			l = l->next;
-		}
+		l = l->next;
 	}
 
 	/* Reset any unspecified attributes to their default value */
@@ -823,17 +829,8 @@ purple_status_set_active_with_attrs_list
 		attr = l->data;
 		if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp))
 		{
-			PurpleValue *default_value;
-			default_value = purple_status_attr_get_value(attr);
-			if (default_value->type == PURPLE_TYPE_STRING)
-				purple_status_set_attr_string(status, attr->id,
-						purple_value_get_string(default_value));
-			else if (default_value->type == PURPLE_TYPE_INT)
-				purple_status_set_attr_int(status, attr->id,
-						purple_value_get_int(default_value));
-			else if (default_value->type == PURPLE_TYPE_BOOLEAN)
-				purple_status_set_attr_boolean(status, attr->id,
-						purple_value_get_boolean(default_value));
+			const GValue *default_value = purple_status_attr_get_value(attr);
+			purple_status_set_attr_value(status, attr->id, default_value);
 			changed = TRUE;
 		}
 
@@ -846,66 +843,84 @@ purple_status_set_active_with_attrs_list
 	status_has_changed(status);
 }
 
-void
-purple_status_set_attr_boolean(PurpleStatus *status, const char *id,
-		gboolean value)
+static void
+purple_status_set_attr_value(PurpleStatus *status,
+                             const char *id,
+                             const GValue *value)
 {
-	PurpleValue *attr_value;
+	GValue *attr_value;
+	const char *name;
 
 	g_return_if_fail(status != NULL);
 	g_return_if_fail(id     != NULL);
+	g_return_if_fail(value  != NULL);
 
-	/* Make sure this attribute exists and is the correct type. */
+	name = purple_status_type_get_name(purple_status_get_type(status));
 	attr_value = purple_status_get_attr_value(status, id);
-	g_return_if_fail(attr_value != NULL);
-	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN);
 
-	purple_value_set_boolean(attr_value, value);
+	if (attr_value == NULL) {
+		gchar *value_contents = g_strdup_value_contents(value);
+		purple_debug_error("status",
+			"Attempted to set nonexistant status attribute '%s' on "
+			"status '%s' to '%s'.  Fix this!\n",
+			id, name, value_contents);
+		g_free(value_contents);
+		return;
+	}
+	if (G_VALUE_TYPE(attr_value) != G_VALUE_TYPE(value)) {
+		purple_debug_error("status",
+			"Attempted to set status attribute '%s' on status '%s' "
+			"to a value of type '%s', rather than the correct type "
+			"'%s'.  Fix this!\n",
+			id, name, G_VALUE_TYPE_NAME(value),
+			G_VALUE_TYPE_NAME(attr_value));
+		return;
+	}
+
+	/* XXX: Check if the value has actually changed. If it has, and the
+	 * status is active, should this trigger 'status_has_changed'? */
+	g_value_copy(value, attr_value);
 }
 
+/* The standard idiom seems to be
+ *   GValue v = { 0, }
+ * which is good enough for all the g_value_* functions to consider it to be
+ * uninitialized, but triggers -Wmissing-field-initializers, which is included
+ * in -Wextra.  Other projects pass -Wno-missing-field-initializers; we could
+ * do that and lose this macro.
+ */
+#define UNINITIALIZED_GVALUE { 0, { { 0 }, { 0 } } }
+
 void
-purple_status_set_attr_int(PurpleStatus *status, const char *id, int value)
+purple_status_set_attr_boolean(PurpleStatus *status,
+                               const char *id,
+                               gboolean value)
 {
-	PurpleValue *attr_value;
+	GValue val = UNINITIALIZED_GVALUE;
+	g_value_init(&val, G_TYPE_BOOLEAN);
+	g_value_set_boolean(&val, value);
+	purple_status_set_attr_value(status, id, &val);
+}
 
-	g_return_if_fail(status != NULL);
-	g_return_if_fail(id     != NULL);
-
-	/* Make sure this attribute exists and is the correct type. */
-	attr_value = purple_status_get_attr_value(status, id);
-	g_return_if_fail(attr_value != NULL);
-	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT);
-
-	purple_value_set_int(attr_value, value);
+void
+purple_status_set_attr_int(PurpleStatus *status,
+                           const char *id,
+                           int value)
+{
+	GValue val = UNINITIALIZED_GVALUE;
+	g_value_init(&val, G_TYPE_INT);
+	g_value_set_int(&val, value);
+	purple_status_set_attr_value(status, id, &val);
 }
 
 void
 purple_status_set_attr_string(PurpleStatus *status, const char *id,
 		const char *value)
 {
-	PurpleValue *attr_value;
-
-	g_return_if_fail(status != NULL);
-	g_return_if_fail(id     != NULL);
-
-	/* Make sure this attribute exists and is the correct type. */
-	attr_value = purple_status_get_attr_value(status, id);
-	/* This used to be g_return_if_fail, but it's failing a LOT, so
-	 * let's generate a log error for now. */
-	/* g_return_if_fail(attr_value != NULL); */
-	if (attr_value == NULL) {
-		purple_debug_error("status",
-				 "Attempted to set status attribute '%s' for "
-				 "status '%s', which is not legal.  Fix "
-                                 "this!\n", id,
-				 purple_status_type_get_name(purple_status_get_type(status)));
-		return;
-	}
-	g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_STRING);
-
-	/* XXX: Check if the value has actually changed. If it has, and the status
-	 * is active, should this trigger 'status_has_changed'? */
-	purple_value_set_string(attr_value, value);
+	GValue val = UNINITIALIZED_GVALUE;
+	g_value_init(&val, G_TYPE_STRING);
+	g_value_set_string(&val, value);
+	purple_status_set_attr_value(status, id, &val);
 }
 
 PurpleStatusType *
@@ -985,19 +1000,19 @@ purple_status_is_online(const PurpleStat
 			primitive != PURPLE_STATUS_OFFLINE);
 }
 
-PurpleValue *
+GValue *
 purple_status_get_attr_value(const PurpleStatus *status, const char *id)
 {
 	g_return_val_if_fail(status != NULL, NULL);
 	g_return_val_if_fail(id     != NULL, NULL);
 
-	return (PurpleValue *)g_hash_table_lookup(status->attr_values, id);
+	return (GValue *)g_hash_table_lookup(status->attr_values, id);
 }
 
 gboolean
 purple_status_get_attr_boolean(const PurpleStatus *status, const char *id)
 {
-	const PurpleValue *value;
+	const GValue *value;
 
 	g_return_val_if_fail(status != NULL, FALSE);
 	g_return_val_if_fail(id     != NULL, FALSE);
@@ -1005,15 +1020,15 @@ purple_status_get_attr_boolean(const Pur
 	if ((value = purple_status_get_attr_value(status, id)) == NULL)
 		return FALSE;
 
-	g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN, FALSE);
+	g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(value), FALSE);
 
-	return purple_value_get_boolean(value);
+	return g_value_get_boolean(value);
 }
 
 int
 purple_status_get_attr_int(const PurpleStatus *status, const char *id)
 {
-	const PurpleValue *value;
+	const GValue *value;
 
 	g_return_val_if_fail(status != NULL, 0);
 	g_return_val_if_fail(id     != NULL, 0);
@@ -1021,15 +1036,15 @@ purple_status_get_attr_int(const PurpleS
 	if ((value = purple_status_get_attr_value(status, id)) == NULL)
 		return 0;
 
-	g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_INT, 0);
+	g_return_val_if_fail(G_VALUE_HOLDS_INT(value), 0);
 
-	return purple_value_get_int(value);
+	return g_value_get_int(value);
 }
 
 const char *
 purple_status_get_attr_string(const PurpleStatus *status, const char *id)
 {
-	const PurpleValue *value;
+	const GValue *value;
 
 	g_return_val_if_fail(status != NULL, NULL);
 	g_return_val_if_fail(id     != NULL, NULL);
@@ -1037,9 +1052,9 @@ purple_status_get_attr_string(const Purp
 	if ((value = purple_status_get_attr_value(status, id)) == NULL)
 		return NULL;
 
-	g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_STRING, NULL);
+	g_return_val_if_fail(G_VALUE_HOLDS_STRING(value), NULL);
 
-	return purple_value_get_string(value);
+	return g_value_get_string(value);
 }
 
 gint
============================================================
--- libpurple/status.h	c58271a5bf73d2787cc7245b7884c3cf967e1e0b
+++ libpurple/status.h	c6c852c5c542c98dafc01a3c84558cde8200033c
@@ -230,20 +230,20 @@ PurpleStatusType *purple_status_type_new
  *                      status type.
  * @param attr_id       The ID of the first attribute.
  * @param attr_name     The name of the first attribute.
- * @param attr_value    The value type of the first attribute attribute.
- * @param ...           Additional attribute information.
+ * @param attr_value    The value type of the first attribute attribute,
+ *                      allocated with purple_g_value_slice_new(); it will be
+ *                      owned by and ultimately freed with the returned status
+ *                      attribute.
+ * @param ...           Additional attribute information, in (id, name, value)
+ *                      triples, terminated with @c NULL.
  *
  * @return A new status type.
  */
 PurpleStatusType *purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive,
-												const char *id,
-												const char *name,
-												gboolean saveable,
-												gboolean user_settable,
-												gboolean independent,
-												const char *attr_id,
-												const char *attr_name,
-												PurpleValue *attr_value, ...) G_GNUC_NULL_TERMINATED;
+	const char *id, const char *name, gboolean saveable, gboolean
+	user_settable, gboolean independent,
+	const char *attr_id, const char *attr_name, GValue *attr_value,
+	...) G_GNUC_NULL_TERMINATED;
 
 /**
  * Destroys a status type.
@@ -271,10 +271,12 @@ void purple_status_type_set_primary_attr
  * @param status_type The status type to add the attribute to.
  * @param id          The ID of the attribute.
  * @param name        The name presented to the user.
- * @param value       The value type of this attribute.
+ * @param value       The value type of this attribute, allocated
+ *                    with purple_g_value_slice_new(), which @a status_type
+ *                    will take ownership of and ultimately free.
  */
-void purple_status_type_add_attr(PurpleStatusType *status_type, const char *id,
-							   const char *name, PurpleValue *value);
+void purple_status_type_add_attr(PurpleStatusType *status_type,
+	const char *id, const char *name, GValue *value);
 
 /**
  * Adds multiple attributes to a status type.
@@ -282,11 +284,14 @@ void purple_status_type_add_attr(PurpleS
  * @param status_type The status type to add the attribute to.
  * @param id          The ID of the first attribute.
  * @param name        The description of the first attribute.
- * @param value       The value type of the first attribute attribute.
- * @param ...         Additional attribute information.
+ * @param value       The value type of the first attribute attribute, allocated
+ *                    with purple_g_value_slice_new(), which @a status_type
+ *                    will take ownership of and ultimately free.
+ * @param ...         Additional attribute information, terminated with @c NULL.
  */
-void purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
-								const char *name, PurpleValue *value, ...) G_GNUC_NULL_TERMINATED;
+void purple_status_type_add_attrs(PurpleStatusType *status_type,
+	const char *id, const char *name, GValue *value,
+	...) G_GNUC_NULL_TERMINATED;
 
 /**
  * Adds multiple attributes to a status type using a va_list.
@@ -295,7 +300,7 @@ void purple_status_type_add_attrs_vargs(
  * @param args        The va_list of attributes.
  */
 void purple_status_type_add_attrs_vargs(PurpleStatusType *status_type,
-									  va_list args);
+	va_list args);
 
 /**
  * Returns the primitive type of a status type.
@@ -431,12 +436,14 @@ const PurpleStatusType *purple_status_ty
  *
  * @param id         The ID of the attribute.
  * @param name       The name presented to the user.
- * @param value_type The type of data contained in the attribute.
+ * @param value_type The type of data contained in the attribute, allocated
+ *                   with purple_g_value_slice_new(); it will become owned by
+ *                   and ultimately freed with the returned status attribute.
  *
  * @return A new status attribute.
  */
 PurpleStatusAttr *purple_status_attr_new(const char *id, const char *name,
-									 PurpleValue *value_type);
+	GValue *value_type);
 
 /**
  * Destroys a status attribute.
@@ -470,7 +477,7 @@ const char *purple_status_attr_get_name(
  *
  * @return The status attribute's value.
  */
-PurpleValue *purple_status_attr_get_value(const PurpleStatusAttr *attr);
+GValue *purple_status_attr_get_value(const PurpleStatusAttr *attr);
 
 /*@}*/
 
@@ -671,10 +678,11 @@ gboolean purple_status_is_online(const P
  * @param status The status.
  * @param id     The attribute ID.
  *
- * @return The value of the attribute.
+ * @return The value of the attribute, or @c NULL if @a status has no such
+ *         attribute.
  */
-PurpleValue *purple_status_get_attr_value(const PurpleStatus *status,
-									  const char *id);
+GValue *purple_status_get_attr_value(const PurpleStatus *status,
+	const char *id);
 
 /**
  * Returns the boolean value of an attribute in a status with the specified ID.


More information about the Commits mailing list