# HG changeset patch
# Node ID 2039d9d293f36b97d2983b909fe7b4bc8bd9b0c4
# Parent  1e762ac785a26462da28bd874d55693b4027fb21
diff --git a/libpurple/purplemessage.c b/libpurple/purplemessage.c
--- a/libpurple/purplemessage.c
+++ b/libpurple/purplemessage.c
@@ -26,14 +26,15 @@
 #include "purpleenums.h"
 #include "purplemessage.h"
 #include "purpleprivate.h"
+#include "util.h"
 
 struct _PurpleMessage {
 	GObject parent;
 
 	char *id;
-	char *author_name;
+	PurpleContactInfo *author;
+
 	char *author_name_color;
-	char *author_alias;
 
 	char *contents;
 
@@ -82,12 +83,13 @@
  * Helpers
  *****************************************************************************/
 static void
-purple_message_set_author_name(PurpleMessage *message, const char *author) {
-	if(g_set_str(&message->author_name, author)) {
+purple_message_set_author(PurpleMessage *message, PurpleContactInfo *author) {
+	if(g_set_object(&message->author, author)) {
 		GObject *obj = G_OBJECT(message);
 
 		g_object_freeze_notify(obj);
 		g_object_notify_by_pspec(obj, properties[PROP_AUTHOR]);
+		g_object_notify_by_pspec(obj, properties[PROP_AUTHOR_ALIAS]);
 		g_object_notify_by_pspec(obj, properties[PROP_AUTHOR_NAME]);
 		g_object_thaw_notify(obj);
 	}
@@ -107,11 +109,17 @@
 		g_value_set_boolean(value, purple_message_get_action(message));
 		break;
 	case PROP_AUTHOR:
+		g_value_set_object(value, purple_message_get_author(message));
+		break;
 	case PROP_AUTHOR_NAME:
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		g_value_set_string(value, purple_message_get_author_name(message));
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		break;
 	case PROP_AUTHOR_ALIAS:
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		g_value_set_string(value, purple_message_get_author_alias(message));
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		break;
 	case PROP_AUTHOR_NAME_COLOR:
 		g_value_set_string(value,
@@ -170,11 +178,7 @@
 		purple_message_set_action(message, g_value_get_boolean(value));
 		break;
 	case PROP_AUTHOR:
-	case PROP_AUTHOR_NAME:
-		purple_message_set_author_name(message, g_value_get_string(value));
-		break;
-	case PROP_AUTHOR_ALIAS:
-		purple_message_set_author_alias(message, g_value_get_string(value));
+		purple_message_set_author(message, g_value_get_object(value));
 		break;
 	case PROP_AUTHOR_NAME_COLOR:
 		purple_message_set_author_name_color(message,
@@ -227,9 +231,8 @@
 	PurpleMessage *message = PURPLE_MESSAGE(obj);
 
 	g_free(message->id);
-	g_free(message->author_name);
+	g_clear_object(&message->author);
 	g_free(message->author_name_color);
-	g_free(message->author_alias);
 	g_free(message->contents);
 
 	g_clear_error(&message->error);
@@ -279,12 +282,12 @@
 	 *
 	 * The author of the message.
 	 *
-	 * Deprecated: 3.0: This going to be repurposed once all uses are removed.
+	 * Since: 3.0
 	 */
-	properties[PROP_AUTHOR] = g_param_spec_string(
+	properties[PROP_AUTHOR] = g_param_spec_object(
 		"author", NULL, NULL,
-		NULL,
-		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED);
+		PURPLE_TYPE_CONTACT_INFO,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * PurpleMessage:author-alias:
@@ -296,7 +299,7 @@
 	properties[PROP_AUTHOR_ALIAS] = g_param_spec_string(
 		"author-alias", NULL, NULL,
 		NULL,
-		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+		G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED);
 
 	/**
 	 * PurpleMessage:author-name:
@@ -307,11 +310,13 @@
 	 * [property@Message:author]'s type can be changed in the near future.
 	 *
 	 * Since: 3.0
+	 *
+	 * Deprecated: 3.0: Use [property@Message:author] instead.
 	 */
 	properties[PROP_AUTHOR_NAME] = g_param_spec_string(
 		"author-name", NULL, NULL,
 		NULL,
-		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+		G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED);
 
 	/**
 	 * PurpleMessage:author-name-color:
@@ -496,19 +501,12 @@
  *****************************************************************************/
 PurpleMessage *
 purple_message_new(PurpleContactInfo *author, const char *contents) {
-	const char *author_name = NULL;
-
 	g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(author), NULL);
 	g_return_val_if_fail(contents != NULL, NULL);
 
-	author_name = purple_contact_info_get_username(author);
-	if(author_name == NULL) {
-		author_name = purple_contact_info_get_id(author);
-	}
-
 	return g_object_new(
 		PURPLE_TYPE_MESSAGE,
-		"author-name", author_name,
+		"author", author,
 		"contents", contents,
 		NULL);
 }
@@ -531,18 +529,25 @@
 	}
 }
 
-const char *
+PurpleContactInfo *
 purple_message_get_author(PurpleMessage *message) {
 	g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL);
 
-	return purple_message_get_author_name(message);
+	return message->author;
 }
 
 const char *
 purple_message_get_author_name(PurpleMessage *message) {
+	const char *name = NULL;
+
 	g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL);
 
-	return message->author_name;
+	name = purple_contact_info_get_username(message->author);
+	if(purple_strempty(name)) {
+		name = purple_contact_info_get_id(message->author);
+	}
+
+	return name;
 }
 
 void
@@ -564,27 +569,11 @@
 	return message->author_name_color;
 }
 
-void
-purple_message_set_author_alias(PurpleMessage *message,
-                                const char *author_alias)
-{
-	g_return_if_fail(PURPLE_IS_MESSAGE(message));
-
-	if(g_set_str(&message->author_alias, author_alias)) {
-		g_object_notify_by_pspec(G_OBJECT(message),
-		                         properties[PROP_AUTHOR_ALIAS]);
-	}
-}
-
 const char *
 purple_message_get_author_alias(PurpleMessage *message) {
 	g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL);
 
-	if(message->author_alias != NULL) {
-		return message->author_alias;
-	}
-
-	return message->author_name;
+	return purple_contact_info_get_alias(message->author);
 }
 
 void
diff --git a/libpurple/purplemessage.h b/libpurple/purplemessage.h
--- a/libpurple/purplemessage.h
+++ b/libpurple/purplemessage.h
@@ -143,8 +143,8 @@
  *
  * Deprecated: 3.0: this is being repurposed in the future.
  */
-PURPLE_DEPRECATED_FOR(purple_message_get_author_name)
-const char *purple_message_get_author(PurpleMessage *message);
+PURPLE_AVAILABLE_IN_3_0
+PurpleContactInfo *purple_message_get_author(PurpleMessage *message);
 
 /**
  * purple_message_get_author_name:
@@ -156,7 +156,7 @@
  *
  * Since: 3.0
  */
-PURPLE_AVAILABLE_IN_3_0
+PURPLE_DEPRECATED_FOR(purple_message_get_author)
 const char *purple_message_get_author_name(PurpleMessage *message);
 
 /**
@@ -196,23 +196,14 @@
  * Returns: the @message author's alias.
  *
  * Since: 3.0
+ *
+ * Deprecated: 3.0: Use [property@ContactInfo:alias] on
+ *             [property@Message:author] instead.
  */
-PURPLE_AVAILABLE_IN_3_0
+PURPLE_DEPRECATED
 const char *purple_message_get_author_alias(PurpleMessage *message);
 
 /**
- * purple_message_set_author_alias:
- * @message: The message.
- * @alias: The alias.
- *
- * Sets the alias of @message's author. You don't normally need to call this.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-void purple_message_set_author_alias(PurpleMessage *message, const char *alias);
-
-/**
  * purple_message_get_contents:
  * @message: The message.
  *
diff --git a/libpurple/tests/test_conversation.c b/libpurple/tests/test_conversation.c
--- a/libpurple/tests/test_conversation.c
+++ b/libpurple/tests/test_conversation.c
@@ -410,6 +410,7 @@
 static void
 test_purple_conversation_message_write_one(void) {
 	PurpleAccount *account = NULL;
+	PurpleContactInfo *info = NULL;
 	PurpleConversation *conversation = NULL;
 	PurpleMessage *message = NULL;
 	GListModel *messages = NULL;
@@ -424,11 +425,8 @@
 	g_assert_nonnull(messages);
 	g_assert_cmpuint(g_list_model_get_n_items(messages), ==, 0);
 
-	message = g_object_new(
-		PURPLE_TYPE_MESSAGE,
-		"contents", "hello world!",
-		NULL);
-
+	info = purple_account_get_contact_info(account);
+	message = purple_message_new(info, "hello world!");
 	purple_conversation_write_message(conversation, message);
 	g_assert_cmpuint(g_list_model_get_n_items(messages), ==, 1);
 
diff --git a/libpurple/tests/test_message.c b/libpurple/tests/test_message.c
--- a/libpurple/tests/test_message.c
+++ b/libpurple/tests/test_message.c
@@ -38,6 +38,8 @@
  *****************************************************************************/
 static void
 test_purple_message_properties(void) {
+	PurpleContactInfo *author = NULL;
+	PurpleContactInfo *author1 = NULL;
 	PurpleMessage *message = NULL;
 	PurpleMessageFlags flags = 0;
 	GDateTime *timestamp = NULL;
@@ -47,8 +49,6 @@
 	GError *error = NULL;
 	GError *error1 = NULL;
 	char *id = NULL;
-	char *author = NULL;
-	char *author_alias = NULL;
 	char *author_name_color = NULL;
 	char *contents = NULL;
 	gboolean action = FALSE;
@@ -62,6 +62,9 @@
 	error = g_error_new(g_quark_from_static_string("test-message"), 0,
 	                    "delivery failed");
 
+	author = purple_contact_info_new(NULL);
+	purple_contact_info_set_username(author, "author");
+
 	/* We don't set delivered-at here because delivered will set it for us so
 	 * it's impossible to check that here, which is why we have separate tests
 	 * to do that check. We do verify that delivered-at was set though.
@@ -69,8 +72,7 @@
 	message = g_object_new(
 		PURPLE_TYPE_MESSAGE,
 		"action", TRUE,
-		"author-alias", "alias",
-		"author-name", "author",
+		"author", author,
 		"author-name-color", "purple",
 		"contents", "Now that is a big door",
 		"delivered", TRUE,
@@ -87,8 +89,7 @@
 	g_object_get(
 		message,
 		"action", &action,
-		"author-alias", &author_alias,
-		"author-name", &author,
+		"author", &author1,
 		"author-name-color", &author_name_color,
 		"contents", &contents,
 		"delivered", &delivered,
@@ -106,11 +107,8 @@
 
 	g_assert_true(action);
 
-	g_assert_cmpstr(author, ==, "author");
-	g_clear_pointer(&author, g_free);
-
-	g_assert_cmpstr(author_alias, ==, "alias");
-	g_clear_pointer(&author_alias, g_free);
+	g_assert_true(author1 == author);
+	g_clear_object(&author1);
 
 	g_assert_cmpstr(author_name_color, ==, "purple");
 	g_clear_pointer(&author_name_color, g_free);
@@ -146,6 +144,7 @@
 	g_clear_pointer(&timestamp1, g_date_time_unref);
 
 	g_assert_finalize_object(message);
+	g_assert_finalize_object(author);
 }
 
 static void
