--- a/finch/gntconv.c Sun Sep 27 21:13:04 2020 -0500
+++ b/finch/gntconv.c Sat Oct 03 05:58:21 2020 -0500
@@ -902,11 +902,14 @@
/* Unnecessary to print the timestamp for delayed message */
if (purple_prefs_get_bool("/finch/conversations/timestamps")) {
- time_t mtime = purple_message_get_time(msg);
+ gchar *timestamp = NULL; + timestamp = purple_message_format_timestamp(msg, "(%H:%M:%S)"); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv),
- purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)), gnt_color_pair(color_timestamp));
+ gnt_color_pair(color_timestamp)); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), " ", GNT_TEXT_FLAG_NORMAL);
--- a/finch/gntpounce.c Sun Sep 27 21:13:04 2020 -0500
+++ b/finch/gntpounce.c Sat Oct 03 05:58:21 2020 -0500
@@ -843,15 +843,18 @@
+ const gchar *me = purple_account_get_name_for_display(account); im = purple_conversations_find_im_with_account(pouncee, account);
im = purple_im_conversation_new(account, pouncee);
- pmsg = purple_message_new_outgoing(pouncee, message, 0);
+ pmsg = purple_message_new_outgoing(me, pouncee, message, 0); purple_serv_send_im(purple_account_get_connection(account), pmsg);
purple_conversation_write_message(PURPLE_CONVERSATION(im), pmsg);
+ g_object_unref(G_OBJECT(pmsg)); --- a/libpurple/conversation.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/conversation.c Sat Oct 03 05:58:21 2020 -0500
@@ -87,9 +87,8 @@
PurpleConversationPrivate *priv =
purple_conversation_get_instance_private(conv);
@@ -101,6 +100,8 @@
gc = purple_account_get_connection(account);
g_return_if_fail(PURPLE_IS_CONNECTION(gc));
+ me = purple_account_get_name_for_display(account); /* Always linkfy the text for display, unless we're
* explicitly asked to do otheriwse*/
if (!(msgflags & PURPLE_MESSAGE_INVISIBLE)) {
@@ -119,7 +120,7 @@
msgflags |= PURPLE_MESSAGE_SEND;
if (PURPLE_IS_IM_CONVERSATION(conv)) {
- msg = purple_message_new_outgoing(
+ PurpleMessage *msg = purple_message_new_outgoing(me, purple_conversation_get_name(conv), sent, msgflags);
purple_signal_emit(purple_conversations_get_handle(), "sending-im-msg",
@@ -138,11 +139,14 @@
purple_signal_emit(purple_conversations_get_handle(),
"sent-im-msg", account, msg);
+ g_object_unref(G_OBJECT(msg)); else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
int id = purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv));
- msg = purple_message_new_outgoing(NULL, sent, msgflags);
+ msg = purple_message_new_outgoing(me, NULL, sent, msgflags); purple_signal_emit(purple_conversations_get_handle(),
"sending-chat-msg", account, msg, id);
@@ -153,6 +157,8 @@
purple_signal_emit(purple_conversations_get_handle(),
"sent-chat-msg", account, msg, id);
+ g_object_unref(G_OBJECT(msg)); @@ -558,7 +564,7 @@
- dt = g_date_time_new_from_unix_local(purple_message_get_time(pmsg));
+ dt = g_date_time_ref(purple_message_get_timestamp(pmsg)); purple_log_write((PurpleLog *)log->data,
--- a/libpurple/core.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/core.c Sat Oct 03 05:58:21 2020 -0500
@@ -171,7 +171,6 @@
purple_savedstatuses_init();
- _purple_message_init();
purple_conversations_init();
@@ -251,7 +250,6 @@
- _purple_message_uninit();
/* Everything after util_uninit cannot try to write things to the
--- a/libpurple/example/nullclient.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/example/nullclient.c Sat Oct 03 05:58:21 2020 -0500
@@ -40,13 +40,15 @@
null_write_conv(PurpleConversation *conv, PurpleMessage *msg)
- time_t mtime = purple_message_get_time(msg);
+ gchar *timestamp = purple_message_format_timestamp(msg, "(%H:%M:%S)"); printf("(%s) %s %s: %s\n",
purple_conversation_get_name(conv),
- purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
purple_message_get_author_alias(msg),
purple_message_get_contents(msg));
static PurpleConversationUiOps null_conv_uiops =
--- a/libpurple/message.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/message.c Sat Oct 03 05:58:21 2020 -0500
@@ -33,259 +33,513 @@
* A message data container.
+ PurpleMessageContentType content_type; PurpleMessageFlags flags;
+static GParamSpec *properties[N_PROPERTIES]; +G_DEFINE_TYPE(PurpleMessage, purple_message, G_TYPE_OBJECT) -static GParamSpec *properties[PROP_LAST];
+/****************************************************************************** + *****************************************************************************/ +purple_message_set_id(PurpleMessage *message, guint id) { -static GHashTable *messages = NULL;
+ g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ID]); -G_DEFINE_TYPE_WITH_PRIVATE(PurpleMessage, purple_message, G_TYPE_OBJECT)
+purple_message_set_author(PurpleMessage *message, const gchar *author) { + g_free(message->author); + message->author = g_strdup(author); + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_AUTHOR]); /******************************************************************************
- ******************************************************************************/
+ * GObject Implementation + *****************************************************************************/ +purple_message_get_property(GObject *object, guint param_id, GValue *value, + PurpleMessage *message = PURPLE_MESSAGE(object); + g_value_set_uint(value, purple_message_get_id(message)); + g_value_set_string(value, purple_message_get_author(message)); + case PROP_AUTHOR_ALIAS: + g_value_set_string(value, purple_message_get_author_alias(message)); + g_value_set_string(value, purple_message_get_recipient(message)); + g_value_set_string(value, purple_message_get_contents(message)); + case PROP_CONTENT_TYPE: + g_value_set_enum(value, purple_message_get_content_type(message)); + g_value_set_boxed(value, purple_message_get_timestamp(message)); + g_value_set_flags(value, purple_message_get_flags(message)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); +purple_message_set_property(GObject *object, guint param_id, + const GValue *value, GParamSpec *pspec) + PurpleMessage *message = PURPLE_MESSAGE(object); + purple_message_set_id(message, g_value_get_uint(value)); + purple_message_set_author(message, g_value_get_string(value)); + case PROP_AUTHOR_ALIAS: + purple_message_set_author_alias(message, g_value_get_string(value)); + purple_message_set_recipient(message, g_value_get_string(value)); + purple_message_set_contents(message, g_value_get_string(value)); + case PROP_CONTENT_TYPE: + purple_message_set_content_type(message, g_value_get_enum(value)); + purple_message_set_timestamp(message, g_value_get_boxed(value)); + purple_message_set_flags(message, g_value_get_flags(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); +purple_message_finalize(GObject *obj) { + PurpleMessage *message = PURPLE_MESSAGE(obj); + g_free(message->author); + g_free(message->author_alias); + g_free(message->recipient); + g_free(message->contents); + if(message->timestamp != NULL) { + g_date_time_unref(message->timestamp); + g_hash_table_destroy(message->attachments); + G_OBJECT_CLASS(purple_message_parent_class)->finalize(obj); +purple_message_init(PurpleMessage *message) { + message->attachments = g_hash_table_new_full(g_int64_hash, g_int64_equal, +purple_message_class_init(PurpleMessageClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->get_property = purple_message_get_property; + obj_class->set_property = purple_message_set_property; + obj_class->finalize = purple_message_finalize; + * The account specific identifier of the message. + properties[PROP_ID] = g_param_spec_uint( + "The session-unique message id", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + * PurpleMessage::author: + * The author of the message. + properties[PROP_AUTHOR] = g_param_spec_string( + "The username of the person, who sent the message.", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurpleMessage::author-alias: + * The alias of the author. + properties[PROP_AUTHOR_ALIAS] = g_param_spec_string( + "author-alias", "Author's alias", + "The alias of the sender", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurpleMessage::recipient: + * The recipient of the message. + properties[PROP_RECIPIENT] = g_param_spec_string( + "recipient", "Recipient", + "The username of the recipient.", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurpleMessage::content: + * The contents of the message. + properties[PROP_CONTENTS] = g_param_spec_string( + "contents", "Contents", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurpleMessage::content-type: + * The content-type of the message. + properties[PROP_CONTENT_TYPE] = g_param_spec_enum( + "content-type", "content-type", + "The content-type of the message.", + PURPLE_TYPE_MESSAGE_CONTENT_TYPE, PURPLE_MESSAGE_CONTENT_TYPE_PLAIN, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurpleMessage::timestamp: + * The timestamp of the message. + properties[PROP_TIMESTAMP] = g_param_spec_boxed( + "timestamp", "timestamp", + "The timestamp of the message", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurpleMessage::flags: + * The #PurpleMessageFlags for the message. + properties[PROP_FLAGS] = g_param_spec_flags( + "Bitwise set of #PurpleMessageFlags flags", + PURPLE_TYPE_MESSAGE_FLAGS, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); +/****************************************************************************** + *****************************************************************************/ -purple_message_new_outgoing(const gchar *who, const gchar *contents,
- PurpleMessageFlags flags)
+purple_message_new_outgoing(const gchar *author, const gchar *recipient, + const gchar *contents, PurpleMessageFlags flags) + PurpleMessage *message = NULL; g_warn_if_fail(!(flags & PURPLE_MESSAGE_RECV));
g_warn_if_fail(!(flags & PURPLE_MESSAGE_SYSTEM));
flags |= PURPLE_MESSAGE_SEND;
+ dt = g_date_time_new_now_local(); /* who may be NULL for outgoing MUC messages */
- return g_object_new(PURPLE_TYPE_MESSAGE,
- "author-alias", _("Me"),
+ message = PURPLE_MESSAGE(g_object_new(PURPLE_TYPE_MESSAGE, + "recipient", recipient, - "time", (guint64)time(NULL),
purple_message_new_incoming(const gchar *who, const gchar *contents,
- PurpleMessageFlags flags, guint64 timestamp)
+ PurpleMessageFlags flags, guint64 timestamp) + PurpleMessage *message = NULL; g_warn_if_fail(!(flags & PURPLE_MESSAGE_SEND));
g_warn_if_fail(!(flags & PURPLE_MESSAGE_SYSTEM));
flags |= PURPLE_MESSAGE_RECV;
- timestamp = time(NULL);
+ dt = g_date_time_new_now_local(); + dt = g_date_time_new_from_unix_local((gint64)timestamp); - return g_object_new(PURPLE_TYPE_MESSAGE,
+ message = PURPLE_MESSAGE(g_object_new(PURPLE_TYPE_MESSAGE,
-purple_message_new_system(const gchar *contents, PurpleMessageFlags flags)
+purple_message_new_system(const gchar *contents, PurpleMessageFlags flags) { + PurpleMessage *message = NULL; g_warn_if_fail(!(flags & PURPLE_MESSAGE_SEND));
g_warn_if_fail(!(flags & PURPLE_MESSAGE_RECV));
flags |= PURPLE_MESSAGE_SYSTEM;
+ dt = g_date_time_new_now_local(); - return g_object_new(PURPLE_TYPE_MESSAGE,
+ message = PURPLE_MESSAGE(g_object_new(PURPLE_TYPE_MESSAGE, - "time", (guint64)time(NULL),
-purple_message_get_id(PurpleMessage *msg)
- PurpleMessagePrivate *priv = NULL;
+purple_message_get_id(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); - g_return_val_if_fail(PURPLE_IS_MESSAGE(msg), 0);
- priv = purple_message_get_instance_private(msg);
-purple_message_find_by_id(guint id)
- g_return_val_if_fail(id > 0, NULL);
+purple_message_get_author(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); + return message->author; - return g_hash_table_lookup(messages, GINT_TO_POINTER(id));
+purple_message_set_recipient(PurpleMessage *message, const gchar *recipient) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + g_free(message->recipient); + message->recipient = g_strdup(recipient); + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_RECIPIENT]); -purple_message_get_author(PurpleMessage *msg)
- PurpleMessagePrivate *priv = NULL;
+purple_message_get_recipient(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); + return message->recipient; - g_return_val_if_fail(PURPLE_IS_MESSAGE(msg), NULL);
+purple_message_set_author_alias(PurpleMessage *message, + const gchar *author_alias) + g_return_if_fail(PURPLE_IS_MESSAGE(message)); - priv = purple_message_get_instance_private(msg);
+ g_free(message->author_alias); + message->author_alias = g_strdup(author_alias); + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_AUTHOR_ALIAS]); -purple_message_get_recipient(PurpleMessage *msg)
- PurpleMessagePrivate *priv = NULL;
+purple_message_get_author_alias(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); - g_return_val_if_fail(PURPLE_IS_MESSAGE(msg), NULL);
+ if (message->author_alias == NULL) + return purple_message_get_author(message); - priv = purple_message_get_instance_private(msg);
- return priv->recipient;
+ return message->author_alias; -purple_message_set_author_alias(PurpleMessage *msg, const gchar *alias)
- g_object_set(msg, "author-alias", alias, NULL);
+purple_message_set_contents(PurpleMessage *message, const gchar *contents) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + g_free(message->contents); + message->contents = g_strdup(contents); + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_CONTENTS]); -purple_message_get_author_alias(PurpleMessage *msg)
- PurpleMessagePrivate *priv = NULL;
+purple_message_get_contents(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); - g_return_val_if_fail(PURPLE_IS_MESSAGE(msg), NULL);
- priv = purple_message_get_instance_private(msg);
- if (priv->author_alias == NULL)
- return purple_message_get_author(msg);
- return priv->author_alias;
+ return message->contents; -purple_message_set_contents(PurpleMessage *msg, const gchar *cont)
+purple_message_set_content_type(PurpleMessage *message, + PurpleMessageContentType content_type) - g_object_set(msg, "contents", cont, NULL);
+ g_return_if_fail(PURPLE_IS_MESSAGE(message)); + message->content_type = content_type; + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_CONTENT_TYPE]);
-purple_message_get_contents(PurpleMessage *msg)
- PurpleMessagePrivate *priv = NULL;
+PurpleMessageContentType +purple_message_get_content_type(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), + PURPLE_MESSAGE_CONTENT_TYPE_PLAIN); - g_return_val_if_fail(PURPLE_IS_MESSAGE(msg), NULL);
- priv = purple_message_get_instance_private(msg);
+ return message->content_type; -purple_message_is_empty(PurpleMessage *msg)
- const gchar *cont = purple_message_get_contents(msg);
- return (cont == NULL || cont[0] == '\0');
+purple_message_is_empty(PurpleMessage *message) { + return (message->contents == NULL || message->contents[0] == '\0'); -purple_message_set_time(PurpleMessage *msg, guint64 msgtime)
- g_object_set(msg, "time", msgtime, NULL);
+purple_message_set_timestamp(PurpleMessage *message, GDateTime *timestamp) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + g_clear_pointer(&message->timestamp, g_date_time_unref); + if(timestamp != NULL) { + message->timestamp = g_date_time_ref(timestamp); + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_TIMESTAMP]);
-purple_message_get_time(PurpleMessage *msg)
- PurpleMessagePrivate *priv = NULL;
+purple_message_get_timestamp(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); + if(message->timestamp == NULL) { + GDateTime *dt = g_date_time_new_now_local(); + purple_message_set_timestamp(message, dt); - g_return_val_if_fail(PURPLE_IS_MESSAGE(msg), 0);
+ return message->timestamp; +purple_message_format_timestamp(PurpleMessage *message, const gchar *format) { - priv = purple_message_get_instance_private(msg);
+ g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); + g_return_val_if_fail(format != NULL, NULL); + dt = purple_message_get_timestamp(message); + return g_date_time_format(dt, format); -purple_message_set_flags(PurpleMessage *msg, PurpleMessageFlags flags)
- g_object_set(msg, "flags", flags, NULL);
+purple_message_set_flags(PurpleMessage *message, PurpleMessageFlags flags) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + message->flags = flags; + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_FLAGS]); -purple_message_get_flags(PurpleMessage *msg)
- PurpleMessagePrivate *priv = NULL;
+purple_message_get_flags(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); - g_return_val_if_fail(PURPLE_IS_MESSAGE(msg), 0);
- priv = purple_message_get_instance_private(msg);
purple_message_add_attachment(PurpleMessage *message,
PurpleAttachment *attachment)
- PurpleMessagePrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE);
g_return_val_if_fail(PURPLE_IS_ATTACHMENT(attachment), FALSE);
- priv = purple_message_get_instance_private(message);
- return g_hash_table_insert(priv->attachments,
+ return g_hash_table_insert(message->attachments, purple_attachment_get_hash_key(attachment),
g_object_ref(G_OBJECT(attachment)));
purple_message_remove_attachment(PurpleMessage *message, guint64 id) {
- PurpleMessagePrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE);
- priv = purple_message_get_instance_private(message);
- return g_hash_table_remove(priv->attachments, &id);
+ return g_hash_table_remove(message->attachments, &id); purple_message_get_attachment(PurpleMessage *message, guint64 id) {
- PurpleMessagePrivate *priv = NULL;
PurpleAttachment *attachment = NULL;
g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL);
- priv = purple_message_get_instance_private(message);
- attachment = g_hash_table_lookup(priv->attachments, &id);
+ attachment = g_hash_table_lookup(message->attachments, &id); if(PURPLE_IS_ATTACHMENT(attachment)) {
return PURPLE_ATTACHMENT(g_object_ref(G_OBJECT(attachment)));
@@ -298,14 +552,13 @@
PurpleAttachmentForeachFunc func,
- PurpleMessagePrivate *priv = NULL;
g_return_if_fail(PURPLE_IS_MESSAGE(message));
g_return_if_fail(func != NULL);
- g_hash_table_iter_init(&iter, priv->attachments);
+ g_hash_table_iter_init(&iter, message->attachments); while(g_hash_table_iter_next(&iter, NULL, &value)) {
func(PURPLE_ATTACHMENT(value), data);
@@ -313,166 +566,7 @@
purple_message_clear_attachments(PurpleMessage *message) {
- PurpleMessagePrivate *priv = NULL;
g_return_if_fail(PURPLE_IS_MESSAGE(message));
- priv = purple_message_get_instance_private(message);
- g_hash_table_remove_all(priv->attachments);
-/******************************************************************************
- ******************************************************************************/
-purple_message_init(PurpleMessage *msg)
- static guint max_id = 0;
- PurpleMessagePrivate *priv = purple_message_get_instance_private(msg);
- priv->attachments = g_hash_table_new_full(g_int64_hash, g_int64_equal,
- g_hash_table_insert(messages, GINT_TO_POINTER(max_id), msg);
-purple_message_finalize(GObject *obj)
- PurpleMessage *message = PURPLE_MESSAGE(obj);
- PurpleMessagePrivate *priv = purple_message_get_instance_private(message);
- g_free(priv->author_alias);
- g_free(priv->recipient);
- g_free(priv->contents);
- g_hash_table_destroy(priv->attachments);
- G_OBJECT_CLASS(purple_message_parent_class)->finalize(obj);
-purple_message_get_property(GObject *object, guint par_id, GValue *value,
- PurpleMessage *message = PURPLE_MESSAGE(object);
- PurpleMessagePrivate *priv = purple_message_get_instance_private(message);
- g_value_set_uint(value, priv->id);
- g_value_set_string(value, priv->author);
- case PROP_AUTHOR_ALIAS:
- g_value_set_string(value, priv->author_alias);
- g_value_set_string(value, priv->recipient);
- g_value_set_string(value, priv->contents);
- g_value_set_uint64(value, priv->msgtime);
- g_value_set_flags(value, priv->flags);
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec);
+ g_hash_table_remove_all(message->attachments);
-purple_message_set_property(GObject *object, guint par_id, const GValue *value,
- PurpleMessage *message = PURPLE_MESSAGE(object);
- PurpleMessagePrivate *priv = purple_message_get_instance_private(message);
- priv->author = g_value_dup_string(value);
- case PROP_AUTHOR_ALIAS:
- g_free(priv->author_alias);
- priv->author_alias = g_value_dup_string(value);
- g_free(priv->recipient);
- priv->recipient = g_value_dup_string(value);
- g_free(priv->contents);
- priv->contents = g_value_dup_string(value);
- priv->msgtime = g_value_get_uint64(value);
- priv->flags = g_value_get_flags(value);
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec);
-purple_message_class_init(PurpleMessageClass *klass)
- GObjectClass *gobj_class = G_OBJECT_CLASS(klass);
- gobj_class->finalize = purple_message_finalize;
- gobj_class->get_property = purple_message_get_property;
- gobj_class->set_property = purple_message_set_property;
- properties[PROP_ID] = g_param_spec_uint("id",
- "ID", "The session-unique message id",
- 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- properties[PROP_AUTHOR] = g_param_spec_string("author",
- "Author", "The username of the person, who sent the message.",
- NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_AUTHOR_ALIAS] = g_param_spec_string("author-alias",
- "Author's alias", "The alias of the person, who sent the "
- "message. For outgoing messages, it's your alias.",
- NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_RECIPIENT] = g_param_spec_string("recipient",
- "Recipient", "The username of the recipient.",
- NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_CONTENTS] = g_param_spec_string("contents",
- "Contents", "The message text",
- NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_TIME] = g_param_spec_uint64("time",
- "Time", "Message timestamp",
- 0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_FLAGS] = g_param_spec_flags("flags",
- "Flags", "Bitwise set of #PurpleMessageFlags flags",
- PURPLE_TYPE_MESSAGE_FLAGS, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties(gobj_class, PROP_LAST, properties);
-_purple_message_init(void)
- messages = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-_purple_message_uninit(void)
- g_hash_table_destroy(messages);
--- a/libpurple/message.h Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/message.h Sat Oct 03 05:58:21 2020 -0500
@@ -48,6 +48,8 @@
* The standard _get_type macro for #PurpleMessage.
#define PURPLE_TYPE_MESSAGE purple_message_get_type()
@@ -96,27 +98,50 @@
+ * PurpleMessageContentType: + * @PURPLE_MESSAGE_CONTENT_TYPE_PLAIN: The message has no formatting. + * @PURPLE_MESSAGE_CONTENT_TYPE_HTML: The message is formatted in HTML. + * @PURPLE_MESSAGE_CONTENT_TYPE_XHTML: The mesage is formatted in XHTML. + * @PURPLE_MESSAGE_CONTENT_TYPE_MARKDOWN: The message is formatted in Markdown. + * The message formatting for the message. +typedef enum /*< prefix=PURPLE_MESSAGE_CONTENT_TYPE,underscore_name=PURPLE_MESSAGE_CONTENT_TYPE >*/ + PURPLE_MESSAGE_CONTENT_TYPE_PLAIN = 0, + PURPLE_MESSAGE_CONTENT_TYPE_HTML, + PURPLE_MESSAGE_CONTENT_TYPE_XHTML, + PURPLE_MESSAGE_CONTENT_TYPE_MARKDOWN, +} PurpleMessageContentType; * purple_message_get_type:
* Returns: the #GType for a message.
G_DECLARE_FINAL_TYPE(PurpleMessage, purple_message, PURPLE, MESSAGE, GObject)
* purple_message_new_outgoing:
- * @who: Message's recipient.
- * @contents: The contents of a message.
- * @flags: The message flags.
+ * @recipient: The recipient. + * @contents: The contents. + * @flags: The #PurpleMessageFlags. - * Creates new outgoing message (the user is the author).
+ * Creates new outgoing message to @recipient. - * You don't need to set the #PURPLE_MESSAGE_SEND flag.
+ * You don't need to set the #PURPLE_MESSAGE_SEND flag. If the message is not + * plain text be sure to call purple_message_set_content_type(). - * Returns: the new #PurpleMessage.
+ * Returns: (transfer full): The new #PurpleMessage instance.
-purple_message_new_outgoing(const gchar *who, const gchar *contents,
- PurpleMessageFlags flags);
+PurpleMessage *purple_message_new_outgoing(const gchar *author, const gchar *recipient, const gchar *contents, PurpleMessageFlags flags); * purple_message_new_incoming:
@@ -130,10 +155,10 @@
* You don't need to set the #PURPLE_MESSAGE_RECV flag.
* Returns: the new #PurpleMessage.
-purple_message_new_incoming(const gchar *who, const gchar *contents,
- PurpleMessageFlags flags, guint64 timestamp);
+PurpleMessage *purple_message_new_incoming(const gchar *who, const gchar *contents, PurpleMessageFlags flags, guint64 timestamp); * purple_message_new_system:
@@ -145,151 +170,198 @@
* You don't need to set the #PURPLE_MESSAGE_SYSTEM flag.
* Returns: the new #PurpleMessage.
-purple_message_new_system(const gchar *contents, PurpleMessageFlags flags);
+PurpleMessage *purple_message_new_system(const gchar *contents, PurpleMessageFlags flags);
+ * @message: The message. * Returns the unique identifier of the message. These identifiers are not
* serialized - it's a per-session id.
- * Returns: the global identifier of @msg.
+ * Returns: the global identifier of @message.
-purple_message_get_id(PurpleMessage *msg);
- * purple_message_find_by_id:
- * @id: The message identifier.
- * Finds the message with a given @id.
- * Returns: (transfer none): The #PurpleMessage, or %NULL if not found.
-purple_message_find_by_id(guint id);
+guint purple_message_get_id(PurpleMessage *message); * purple_message_get_author:
+ * @message: The message. - * Returns the author of the message - his screen name (not a local alias).
+ * Returns the author of the message, not a local alias. + * Returns: the author of @message. - * Returns: the author of @msg.
-purple_message_get_author(PurpleMessage *msg);
+const gchar *purple_message_get_author(PurpleMessage *message); + * purple_message_set_recipient: + * @message: The #PurpleMessage instance. + * @recipient: The name of the recipient. + * Sets the recipient of @message to @recipient. +void purple_message_set_recipient(PurpleMessage *message, const gchar *recipient); * purple_message_get_recipient:
+ * @message: The message. - * Returns the recipient of the message - his screen name (not a local alias).
+ * Returns the recipient of the message, not a local alias. - * Returns: the recipient of @msg.
+ * Returns: the recipient of @message.
-purple_message_get_recipient(PurpleMessage *msg);
+const gchar *purple_message_get_recipient(PurpleMessage *message); * purple_message_set_author_alias:
+ * @message: The message. - * Sets the alias of @msg's author. You don't normally need to call this.
+ * Sets the alias of @message's author. You don't normally need to call this.
-purple_message_set_author_alias(PurpleMessage *msg, const gchar *alias);
+void purple_message_set_author_alias(PurpleMessage *message, const gchar *alias); * purple_message_get_author_alias:
+ * @message: The message. - * Returns the alias of @msg author.
+ * Returns the alias of @message author. - * Returns: the @msg author's alias.
+ * Returns: the @message author's alias.
-purple_message_get_author_alias(PurpleMessage *msg);
+const gchar *purple_message_get_author_alias(PurpleMessage *message); * purple_message_set_contents:
+ * @message: The message. - * Sets the contents of the @msg. It might be HTML.
+ * Sets the contents of the @message. It might be HTML.
-purple_message_set_contents(PurpleMessage *msg, const gchar *cont);
+void purple_message_set_contents(PurpleMessage *message, const gchar *cont); * purple_message_get_contents:
+ * @message: The message. * Returns the contents of the message.
- * Returns: the contents of @msg.
+ * Returns: the contents of @message.
-purple_message_get_contents(PurpleMessage *msg);
+const gchar *purple_message_get_contents(PurpleMessage *message); + * purple_message_set_content_type: + * @message: The #PurpleMessage instance. + * @content_type: The #PurpleMessageContentType value. + * Sets the content-type of @message to @content_type. +void purple_message_set_content_type(PurpleMessage *message, PurpleMessageContentType content_type); + * purple_message_get_content_type: + * @message: The #PurpleMessage instance. + * Gets the content-type of @message. + * Returns: The #PurpleMessageContentType of @message. +PurpleMessageContentType purple_message_get_content_type(PurpleMessage *message); * purple_message_is_empty:
+ * @message: The message. * Checks, if the message's body is empty.
- * Returns: %TRUE, if @msg is empty.
+ * Returns: %TRUE, if @message is empty.
-purple_message_is_empty(PurpleMessage *msg);
+gboolean purple_message_is_empty(PurpleMessage *message); + * purple_message_set_timestamp: + * @message: The #PurpleMessage instance. + * @timestamp: (nullable): The #GDateTime of the message. + * Sets the timestamp of @message. +void purple_message_set_timestamp(PurpleMessage *message, GDateTime *timestamp); - * purple_message_set_time:
- * @msgtime: The timestamp of a message.
+ * purple_message_get_timestamp: + * @message: The message. + * Returns a @message's timestamp. If @message does not currently have a + * timestamp, the current time will be set as the time stamp and returned. - * Sets the @msg's timestamp. It should be a date of posting, but it can be
- * a date of receiving (if the former is not available).
+ * Returns: (transfer none): The #GDateTime timestamp from @message.
-purple_message_set_time(PurpleMessage *msg, guint64 msgtime);
+GDateTime *purple_message_get_timestamp(PurpleMessage *message); - * purple_message_get_time:
- * Returns a @msg's timestamp.
+ * purple_message_format_timestamp: + * @message: The #PurpleMessage instance. + * @format: The format to output the time stamp as. - * Returns: @msg's timestamp.
+ * Formats the timestamp of @message and returns it. + * Returns: The formatted timestamp.
-purple_message_get_time(PurpleMessage *msg);
+gchar *purple_message_format_timestamp(PurpleMessage *message, const gchar *format); * purple_message_set_flags:
+ * @message: The message. * @flags: The message flags.
- * Sets flags for @msg. It shouldn't be in a conflict with a message type,
+ * Sets flags for @message. It shouldn't be in a conflict with a message type,
-purple_message_set_flags(PurpleMessage *msg, PurpleMessageFlags flags);
+void purple_message_set_flags(PurpleMessage *message, PurpleMessageFlags flags); * purple_message_get_flags:
+ * @message: The message. - * Returns the flags of a @msg.
+ * Returns the flags of a @message. - * Returns: the flags of a @msg.
+ * Returns: the flags of a @message.
-purple_message_get_flags(PurpleMessage *msg);
+PurpleMessageFlags purple_message_get_flags(PurpleMessage *message); * purple_message_add_attachment:
@@ -299,6 +371,8 @@
* Adds @attachment to @message.
* Returns %TRUE if an attachment with the same ID did not already exist.
gboolean purple_message_add_attachment(PurpleMessage *message, PurpleAttachment *attachment);
@@ -311,6 +385,8 @@
* Returns: %TRUE if the #PurpleAttachment was found and removed, %FALSE
gboolean purple_message_remove_attachment(PurpleMessage *message, guint64 id);
@@ -323,6 +399,8 @@
* Returns: (transfer full): The #PurpleAttachment if it was found, otherwise
PurpleAttachment *purple_message_get_attachment(PurpleMessage *message, guint64 id);
@@ -333,6 +411,8 @@
* @data: User data to pass to @func.
* Calls @func for each #PurpleAttachment that's attached to @message.
void purple_message_foreach_attachment(PurpleMessage *message, PurpleAttachmentForeachFunc func, gpointer data);
@@ -341,6 +421,8 @@
* @message: The #PurpleMessage instance.
* Removes all attachments from @message.
void purple_message_clear_attachments(PurpleMessage *message);
--- a/libpurple/plugins/offlinemsg.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/plugins/offlinemsg.c Sat Oct 03 05:58:21 2020 -0500
@@ -73,7 +73,11 @@
PurplePounceOption option;
PurpleConversation *conv;
+ PurpleMessage *message; + me = purple_account_get_name_for_display(offline->account); event = PURPLE_POUNCE_SIGNON;
option = PURPLE_POUNCE_OPTION_NONE;
@@ -99,9 +103,9 @@
g_object_set_data(G_OBJECT(conv), "plugin_pack:offlinemsg",
GINT_TO_POINTER(OFFLINE_MSG_YES));
- /* TODO: use a reference to a PurpleMessage */
- purple_conversation_write_message(conv,
- purple_message_new_outgoing(offline->who, offline->message, 0));
+ message = purple_message_new_outgoing(me, offline->who, offline->message, 0); + purple_conversation_write_message(conv, message); + g_object_unref(G_OBJECT(message)); --- a/libpurple/protocols/facebook/util.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/protocols/facebook/util.c Sat Oct 03 05:58:21 2020 -0500
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
#include <glib/gi18n-lib.h>
@@ -432,7 +433,8 @@
fb_util_serv_got_im(PurpleConnection *gc, const gchar *who, const gchar *text,
PurpleMessageFlags flags, guint64 timestamp)
+ const gchar *name, *me; PurpleIMConversation *conv;
@@ -449,21 +451,30 @@
conv = purple_im_conversation_new(acct, who);
+ me = purple_account_get_name_for_display(acct); name = purple_account_get_username(acct);
- msg = purple_message_new_outgoing(name, text, flags);
- purple_message_set_time(msg, timestamp);
+ msg = purple_message_new_outgoing(me, name, text, flags); + dt = g_date_time_new_from_unix_local((gint64)timestamp); + purple_message_set_timestamp(msg, dt); purple_conversation_write_message(PURPLE_CONVERSATION(conv), msg);
+ g_object_unref(G_OBJECT(msg)); fb_util_serv_got_chat_in(PurpleConnection *gc, gint id, const gchar *who,
const gchar *text, PurpleMessageFlags flags,
PurpleChatConversation *conv;
if (!(flags & PURPLE_MESSAGE_SEND)) {
purple_serv_got_chat_in(gc, id, who, flags, text, timestamp);
@@ -473,10 +484,18 @@
acct = purple_connection_get_account(gc);
conv = purple_conversations_find_chat(gc, id);
+ me = purple_account_get_name_for_display(acct); name = purple_account_get_username(acct);
- msg = purple_message_new_outgoing(name, text, flags);
- purple_message_set_time(msg, timestamp);
+ msg = purple_message_new_outgoing(me, name, text, flags); + dt = g_date_time_new_from_unix_local((gint64)timestamp); + purple_message_set_timestamp(msg, dt); purple_conversation_write_message(PURPLE_CONVERSATION(conv), msg);
+ g_object_unref(G_OBJECT(msg)); --- a/libpurple/protocols/gg/chat.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/protocols/gg/chat.c Sat Oct 03 05:58:21 2020 -0500
@@ -25,6 +25,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
#include <glib/gi18n-lib.h>
@@ -471,6 +473,7 @@
int ggp_chat_send(PurpleConnection *gc, int local_id, PurpleMessage *msg)
GGPInfo *info = purple_connection_get_protocol_data(gc);
PurpleChatConversation *conv;
ggp_chat_local_info *chat;
@@ -496,10 +499,11 @@
me = purple_account_get_username(purple_connection_get_account(gc));
+ dt = purple_message_get_timestamp(msg); purple_serv_got_chat_in(gc, chat->local_id, me,
purple_message_get_flags(msg),
purple_message_get_contents(msg),
- purple_message_get_time(msg));
+ (time_t)g_date_time_to_unix(dt)); @@ -507,11 +511,12 @@
void ggp_chat_got_message(PurpleConnection *gc, uint64_t chat_id,
const char *message, time_t time, uin_t who)
+ PurpleAccount *account = NULL; ggp_chat_local_info *chat;
- me = ggp_str_to_uin(purple_account_get_username(
- purple_connection_get_account(gc)));
+ account = purple_connection_get_account(gc); + me = ggp_str_to_uin(purple_account_get_username(account)); chat = ggp_chat_get(gc, chat_id);
@@ -522,11 +527,16 @@
ggp_chat_open_conv(chat);
pmsg = purple_message_new_outgoing(
+ purple_account_get_name_for_display(account), ggp_uin_to_str(who), message, 0);
- purple_message_set_time(pmsg, time);
+ dt = g_date_time_new_from_unix_local((gint64)time); + purple_message_set_timestamp(pmsg, dt); purple_conversation_write_message(
PURPLE_CONVERSATION(chat->conv), pmsg);
--- a/libpurple/protocols/gg/message-prpl.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/protocols/gg/message-prpl.c Sat Oct 03 05:58:21 2020 -0500
@@ -235,16 +235,28 @@
ggp_chat_got_message(gc, msg->chat_id, msg->text, msg->time,
} else if (msg->type == GGP_MESSAGE_GOT_TYPE_MULTILOGON) {
+ PurpleAccount *account = NULL; PurpleIMConversation *im = ggp_message_get_conv(gc, msg->user);
+ const gchar *me = NULL; - pmsg = purple_message_new_outgoing(NULL, msg->text, 0);
- purple_message_set_time(pmsg, msg->time);
+ account = purple_connection_get_account(gc); + me = purple_account_get_name_for_display(account); + pmsg = purple_message_new_outgoing(me, NULL, msg->text, 0); + dt = g_date_time_new_from_unix_local((gint64)msg->time); + purple_message_set_timestamp(pmsg, dt); purple_conversation_write_message(PURPLE_CONVERSATION(im), pmsg);
+ g_object_unref(G_OBJECT(pmsg)); purple_debug_error("gg", "ggp_message_got_display: "
"unexpected message type: %d\n", msg->type);
static gboolean ggp_message_format_from_gg_found_img(const GMatchInfo *info,
--- a/libpurple/protocols/irc/cmds.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/protocols/irc/cmds.c Sat Oct 03 05:58:21 2020 -0500
@@ -88,9 +88,9 @@
int irc_cmd_ctcp_action(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
PurpleConnection *gc = purple_account_get_connection(irc->account);
- char *action, *escaped, *dst, **newargs;
+ gchar *action, *escaped, *dst, **newargs; PurpleConversation *convo;
@@ -98,28 +98,41 @@
convo = purple_conversations_find_with_account(target, irc->account);
+ me = purple_account_get_name_for_display(irc->account); msg = g_strdup_printf("/me %s", args[0]);
/* XXX: we'd prefer to keep this in conversation.c */
if (PURPLE_IS_IM_CONVERSATION(convo)) {
- pmsg = purple_message_new_outgoing(
- purple_conversation_get_name(convo), msg, 0);
+ const gchar *conv_name = purple_conversation_get_name(convo); + pmsg = purple_message_new_outgoing(me, conv_name, msg, 0); purple_signal_emit(purple_conversations_get_handle(),
"sending-im-msg", irc->account, pmsg);
- pmsg = purple_message_new_outgoing(NULL, msg, 0);
+ pmsg = purple_message_new_outgoing(me, NULL, msg, 0); purple_signal_emit(purple_conversations_get_handle(),
"sending-chat-msg", irc->account, pmsg,
purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(convo)));
+ /* We free the original message because it could have been changed by the + * sending-*-msg signals above. - if (purple_message_is_empty(pmsg))
+ /* if the message was eaten by a signal we bail */ + if(purple_message_is_empty(pmsg)) { + g_object_unref(G_OBJECT(pmsg)); - msg = g_strdup(purple_message_get_contents(pmsg)); /* XXX: is it really necessary? */
+ /* create a copy of the updated message, which should not be null because + * we just tested if it was empty in the above conditional. + msg = g_strdup(purple_message_get_contents(pmsg)); if (strncmp(msg, "/me ", 4) != 0) {
newargs = g_new0(char *, 2);
@@ -177,18 +190,23 @@
escaped = g_markup_escape_text(args[0], -1);
action = g_strdup_printf("/me %s", escaped);
- if (action[strlen(action) - 1] == '\n')
+ if (action[strlen(action) - 1] == '\n') { action[strlen(action) - 1] = '\0';
- if (PURPLE_IS_CHAT_CONVERSATION(convo))
+ if (PURPLE_IS_CHAT_CONVERSATION(convo)) { purple_serv_got_chat_in(gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(convo)),
purple_connection_get_display_name(gc),
PURPLE_MESSAGE_SEND, action, time(NULL));
- purple_conversation_write_message(convo, purple_message_new_outgoing(
- purple_connection_get_display_name(gc), action, 0));
+ purple_message_set_recipient(pmsg, + purple_connection_get_display_name(gc)); + purple_conversation_write_message(convo, pmsg); + g_object_unref(G_OBJECT(pmsg)); @@ -512,11 +530,20 @@
purple_conversation_present(PURPLE_CONVERSATION(im));
+ PurpleMessage *message = NULL; + const gchar *me = NULL; + const gchar *recipient = NULL; gc = purple_account_get_connection(irc->account);
irc_cmd_privmsg(irc, cmd, target, args);
- purple_conversation_write_message(PURPLE_CONVERSATION(im),
- purple_message_new_outgoing(
- purple_connection_get_display_name(gc), args[1], 0));
+ me = purple_account_get_name_for_display(irc->account); + recipient = purple_connection_get_display_name(gc); + message = purple_message_new_outgoing(me, recipient, args[1], 0); + purple_conversation_write_message(PURPLE_CONVERSATION(im), message); + g_object_unref(G_OBJECT(message)); --- a/libpurple/protocols/jabber/jabber.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/protocols/jabber/jabber.c Sat Oct 03 05:58:21 2020 -0500
@@ -3059,20 +3059,25 @@
static PurpleCmdRet jabber_cmd_chat_msg(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
+ PurpleAccount *account = NULL; PurpleConnection *pc = NULL;
PurpleProtocol *prpl = NULL;
PurpleMessage *msg = NULL;
JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
+ const gchar *me = NULL; return PURPLE_CMD_RET_FAILED;
+ account = purple_connection_get_account(pc); + me = purple_account_get_name_for_display(account); who = g_strdup_printf("%s@%s/%s", chat->room, chat->server, args[0]);
pc = purple_conversation_get_connection(conv);
prpl = purple_connection_get_protocol(pc);
- msg = purple_message_new_outgoing(who, args[1], 0);
+ msg = purple_message_new_outgoing(me, who, args[1], 0); jabber_message_send_im(PURPLE_PROTOCOL_IM(prpl), pc, msg);
--- a/libpurple/purpleprivate.h Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/purpleprivate.h Sat Oct 03 05:58:21 2020 -0500
@@ -189,22 +189,6 @@
_purple_fstat(int fd, GStatBuf *st);
- * _purple_message_init: (skip)
- * Initializes the #PurpleMessage subsystem.
-_purple_message_init(void);
- * _purple_message_uninit: (skip)
- * Uninitializes the #PurpleMessage subsystem.
-_purple_message_uninit(void);
* _purple_conversation_write_common:
* @conv: The conversation.
--- a/libpurple/server.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/server.c Sat Oct 03 05:58:21 2020 -0500
@@ -556,6 +556,7 @@
pmsg = purple_message_new_incoming(name, message, flags, mtime);
purple_conversation_write_message(PURPLE_CONVERSATION(im), pmsg);
+ g_object_unref(G_OBJECT(pmsg)); @@ -622,12 +623,15 @@
if (!(flags & PURPLE_MESSAGE_AUTO_RESP))
+ const gchar *me = purple_account_get_name_for_display(account); - msg = purple_message_new_outgoing(name,
+ msg = purple_message_new_outgoing(me, name, away_msg, PURPLE_MESSAGE_AUTO_RESP);
purple_serv_send_im(gc, msg);
purple_conversation_write_message(PURPLE_CONVERSATION(im), msg);
+ g_object_unref(G_OBJECT(msg)); @@ -890,16 +894,23 @@
purple_signal_emit(purple_conversations_get_handle(), "received-chat-msg", purple_connection_get_account(g),
who, message, chat, flags);
- if (flags & PURPLE_MESSAGE_RECV)
+ if (flags & PURPLE_MESSAGE_RECV) { pmsg = purple_message_new_incoming(who, message, flags, mtime);
- pmsg = purple_message_new_outgoing(who, message, flags);
- purple_message_set_time(pmsg, mtime);
+ PurpleAccount *account = purple_connection_get_account(g); + GDateTime *dt = g_date_time_new_from_unix_local((gint64)mtime); + const gchar *me = purple_account_get_name_for_display(account); + pmsg = purple_message_new_outgoing(me, who, message, flags); + purple_message_set_timestamp(pmsg, dt); purple_conversation_write_message(PURPLE_CONVERSATION(chat), pmsg);
+ g_object_unref(G_OBJECT(pmsg)); void purple_serv_send_file(PurpleConnection *gc, const char *who, const char *file)
--- a/libpurple/tests/test_ui.c Sun Sep 27 21:13:04 2020 -0500
+++ b/libpurple/tests/test_ui.c Sat Oct 03 05:58:21 2020 -0500
@@ -40,13 +40,15 @@
test_write_conv(PurpleConversation *conv, PurpleMessage *msg)
- time_t mtime = purple_message_get_time(msg);
+ gchar *timestamp = purple_message_format_timestamp(msg, "(%H:%M:%S)"); printf("(%s) %s %s: %s\n",
purple_conversation_get_name(conv),
- purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
purple_message_get_author_alias(msg),
purple_message_get_contents(msg));
static PurpleConversationUiOps test_conv_uiops = {
--- a/pidgin/gtkconv.c Sun Sep 27 21:13:04 2020 -0500
+++ b/pidgin/gtkconv.c Sat Oct 03 05:58:21 2020 -0500
@@ -4640,11 +4640,13 @@
purple_conversation_get_name(conv));
GHashTable *comps = purple_chat_get_components(chat);
time_t now, history_since, prev_history_since = 0;
struct tm *history_since_tm;
const char *history_since_s, *prev_history_since_s;
- history_since = purple_message_get_time(pmsg) + 1;
+ dt = purple_message_get_timestamp(pmsg); + history_since = g_date_time_to_unix(dt) + 1; prev_history_since_s = g_hash_table_lookup(comps,
@@ -6025,8 +6027,10 @@
message_compare(PurpleMessage *m1, PurpleMessage *m2)
- guint64 t1 = purple_message_get_time(m1), t2 = purple_message_get_time(m2);
- return (t1 > t2) - (t1 < t2);
+ GDateTime *dt1 = purple_message_get_timestamp(m1); + GDateTime *dt2 = purple_message_get_timestamp(m2); + return g_date_time_compare(dt1, dt2); /* Adds some message history to the gtkconv. This happens in a idle-callback. */
@@ -6036,13 +6040,14 @@
PidginConversation *gtkconv = data;
int timer = gtkconv->attach_timer;
- time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->editor), "attach-start-time"));
+ GDateTime *when = (GDateTime *)g_object_get_data(G_OBJECT(gtkconv->editor), "attach-start-time"); gboolean im = (PURPLE_IS_IM_CONVERSATION(gtkconv->active_conv));
gtkconv->attach_timer = 0;
while (gtkconv->attach_current && count < ADD_MESSAGE_HISTORY_AT_ONCE) {
PurpleMessage *msg = gtkconv->attach_current->data;
- if (!im && when && (guint64)when < purple_message_get_time(msg)) {
+ GDateTime *dt = purple_message_get_timestamp(msg); + if (!im && when && g_date_time_difference(dt, when) >= 0) { g_object_set_data(G_OBJECT(gtkconv->editor), "attach-start-time", NULL);
/* XXX: should it be gtkconv->active_conv? */
@@ -6069,8 +6074,10 @@
GList *history = purple_conversation_get_message_history(conv);
for (; history; history = history->next) {
PurpleMessage *msg = history->data;
- if (purple_message_get_time(msg) > (guint64)when)
+ GDateTime *dt = purple_message_get_timestamp(msg); + if(g_date_time_difference(dt, when) > 0) { msgs = g_list_prepend(msgs, msg);
msgs = g_list_sort(msgs, (GCompareFunc)message_compare);
@@ -6131,6 +6138,8 @@
list = purple_conversation_get_message_history(conv);
if (PURPLE_IS_IM_CONVERSATION(conv)) {
list = g_list_copy(list);
@@ -6147,8 +6156,9 @@
gtkconv->attach_current = g_list_last(list);
- g_object_set_data(G_OBJECT(gtkconv->editor), "attach-start-time",
- GINT_TO_POINTER(purple_message_get_time(list->data)));
+ dt = purple_message_get_timestamp(PURPLE_MESSAGE(list->data)); + g_object_set_data_full(G_OBJECT(gtkconv->editor), "attach-start-time", + g_date_time_ref(dt), (GDestroyNotify)g_date_time_unref); gtkconv->attach_timer = g_idle_add(add_message_history_to_gtkconv, gtkconv);
purple_signal_emit(pidgin_conversations_get_handle(),
--- a/pidgin/gtkpounce.c Sun Sep 27 21:13:04 2020 -0500
+++ b/pidgin/gtkpounce.c Sat Oct 03 05:58:21 2020 -0500
@@ -1397,15 +1397,18 @@
im = purple_conversations_find_im_with_account(pouncee, account);
+ me = purple_account_get_name_for_display(account); im = purple_im_conversation_new(account, pouncee);
- pmsg = purple_message_new_outgoing(pouncee, message, 0);
+ pmsg = purple_message_new_outgoing(me, pouncee, message, 0); purple_serv_send_im(purple_account_get_connection(account), pmsg);
purple_conversation_write_message(PURPLE_CONVERSATION(im), pmsg);
+ g_object_unref(G_OBJECT(pmsg)); --- a/pidgin/pidginmessage.c Sun Sep 27 21:13:04 2020 -0500
+++ b/pidgin/pidginmessage.c Sat Oct 03 05:58:21 2020 -0500
@@ -27,7 +27,6 @@
@@ -55,13 +54,7 @@
pidgin_message_set_message(PidginMessage *message, PurpleMessage *purple_msg) {
if(g_set_object(&message->message, purple_msg)) {
- g_clear_pointer(&message->timestamp, g_date_time_unref);
- message->timestamp = g_date_time_new_from_unix_local(purple_message_get_time(purple_msg));
- g_object_freeze_notify(G_OBJECT(message));
g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_MESSAGE]);
- g_object_notify(G_OBJECT(message), "timestamp");
- g_object_thaw_notify(G_OBJECT(message));
@@ -199,7 +192,7 @@
g_value_set_string(value, purple_message_get_contents(message->message));
- g_value_set_pointer(value, message->timestamp);
+ g_value_set_boxed(value, purple_message_get_timestamp(message->message)); g_value_set_boolean(value, FALSE);
@@ -241,7 +234,6 @@
PidginMessage *message = PIDGIN_MESSAGE(obj);
g_clear_object(&message->message);
- g_clear_pointer(&message->timestamp, g_date_time_unref);
G_OBJECT_CLASS(pidgin_message_parent_class)->finalize(obj);