pidgin/pidgin

Parents b5f355f90ab0
Children f1b7c03f6cc7
rename conversation.[ch] to purpleconversation.[ch] and split PurpleConversationUiOps out to its own file to avoid circular include issues.

Testing Done:
Compiled and ran locally including docs and pot file. The pot file fails as I need to rebase on [596](https://reviews.imfreedom.org/r/596/)

Reviewed at https://reviews.imfreedom.org/r/597/
--- a/doc/reference/libpurple/libpurple-docs.xml Tue Apr 06 03:35:20 2021 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml Mon Apr 12 20:27:47 2021 -0500
@@ -46,7 +46,6 @@
<xi:include href="xml/circularbuffer.xml" />
<xi:include href="xml/contact.xml" />
<xi:include href="xml/connection.xml" />
- <xi:include href="xml/conversation.xml" />
<xi:include href="xml/conversations.xml" />
<xi:include href="xml/countingnode.xml" />
<xi:include href="xml/debug.xml" />
@@ -73,6 +72,8 @@
<xi:include href="xml/purplebuddypresence.xml" />
<xi:include href="xml/purplechatconversation.xml" />
<xi:include href="xml/purplechatuser.xml" />
+ <xi:include href="xml/purpleconversation.xml" />
+ <xi:include href="xml/purpleconversationuiops.xml" />
<xi:include href="xml/purplecredentialmanager.xml" />
<xi:include href="xml/purplecredentialprovider.xml" />
<xi:include href="xml/purpleimconversation.xml" />
--- a/libpurple/buddyicon.c Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/buddyicon.c Mon Apr 12 20:27:47 2021 -0500
@@ -21,9 +21,9 @@
#include "internal.h"
#include "buddyicon.h"
-#include "conversation.h"
#include "debug.h"
#include "image.h"
+#include "purpleconversation.h"
#include "purpleprivate.h"
#include "purpleprotocolserver.h"
#include "util.h"
--- a/libpurple/buddylist.c Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/buddylist.c Mon Apr 12 20:27:47 2021 -0500
@@ -25,7 +25,6 @@
#include "internal.h"
#include "buddylist.h"
-#include "conversation.h"
#include "debug.h"
#include "notify.h"
#include "prefs.h"
@@ -33,6 +32,7 @@
#include "purpleprivate.h"
#include "purpleprotocolchat.h"
#include "purpleprotocolclient.h"
+#include "purpleconversation.h"
#include "server.h"
#include "signals.h"
#include "util.h"
--- a/libpurple/cmds.h Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/cmds.h Mon Apr 12 20:27:47 2021 -0500
@@ -31,7 +31,7 @@
* @see_also: <link linkend="chapter-signals-cmd">Command signals</link>
*/
-#include "conversation.h"
+#include <purpleconversation.h>
/******************************************************************************
* Structures
--- a/libpurple/conversation.c Tue Apr 06 03:35:20 2021 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1030 +0,0 @@
-/*
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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>
-
-#include "internal.h"
-
-#include "buddylist.h"
-#include "cmds.h"
-#include "conversation.h"
-#include "debug.h"
-#include "enums.h"
-#include "notify.h"
-#include "prefs.h"
-#include "protocol.h"
-#include "purplemarkup.h"
-#include "purpleprivate.h"
-#include "purpleprotocolclient.h"
-#include "request.h"
-#include "signals.h"
-#include "smiley-list.h"
-
-typedef struct _PurpleConversationPrivate PurpleConversationPrivate;
-
-/* General private data for a conversation */
-struct _PurpleConversationPrivate
-{
- PurpleAccount *account; /* The user using this conversation. */
-
- char *name; /* The name of the conversation. */
- char *title; /* The window title. */
-
- gboolean logging; /* The status of logging. */
-
- GList *logs; /* This conversation's logs */
-
- PurpleConversationUiOps *ui_ops; /* UI-specific operations. */
-
- PurpleConnectionFlags features; /* The supported features */
- GList *message_history; /* Message history, as a GList of PurpleMessages */
-
- /* The list of remote smileys. This should be per-buddy (PurpleBuddy),
- * but we don't have any class for people not on our buddy
- * list (PurpleDude?). So, if we have one, we should switch to it. */
- PurpleSmileyList *remote_smileys;
-};
-
-/* GObject Property enums */
-enum
-{
- PROP_0,
- PROP_ACCOUNT,
- PROP_NAME,
- PROP_TITLE,
- PROP_LOGGING,
- PROP_FEATURES,
- PROP_LAST
-};
-
-static GParamSpec *properties[PROP_LAST];
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleConversation, purple_conversation,
- G_TYPE_OBJECT);
-
-static void
-common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags msgflags)
-{
- PurpleAccount *account;
- PurpleConnection *gc;
- PurpleConversationPrivate *priv =
- purple_conversation_get_instance_private(conv);
- char *displayed = NULL;
- const char *sent, *me;
- int err = 0;
-
- if (*message == '\0')
- return;
-
- account = purple_conversation_get_account(conv);
- g_return_if_fail(PURPLE_IS_ACCOUNT(account));
-
- 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)) {
- if(msgflags & PURPLE_MESSAGE_NO_LINKIFY)
- displayed = g_strdup(message);
- else
- displayed = purple_markup_linkify(message);
- }
-
- if (displayed && (priv->features & PURPLE_CONNECTION_FLAG_HTML) &&
- !(msgflags & PURPLE_MESSAGE_RAW)) {
- sent = displayed;
- } else
- sent = message;
-
- msgflags |= PURPLE_MESSAGE_SEND;
-
- if (PURPLE_IS_IM_CONVERSATION(conv)) {
- PurpleMessage *msg = purple_message_new_outgoing(me,
- purple_conversation_get_name(conv), sent, msgflags);
-
- purple_signal_emit(purple_conversations_get_handle(), "sending-im-msg",
- account, msg);
-
- if (!purple_message_is_empty(msg)) {
-
- err = purple_serv_send_im(gc, msg);
-
- if ((err > 0) && (displayed != NULL)) {
- /* revert the contents in case sending-im-msg changed it */
- purple_message_set_contents(msg, displayed);
- purple_conversation_write_message(conv, msg);
- }
-
- 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)) {
- PurpleMessage *msg;
- int id = purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv));
-
- msg = purple_message_new_outgoing(me, NULL, sent, msgflags);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "sending-chat-msg", account, msg, id);
-
- if (!purple_message_is_empty(msg)) {
- err = purple_serv_chat_send(gc, id, msg);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "sent-chat-msg", account, msg, id);
- }
-
- g_object_unref(G_OBJECT(msg));
- }
-
- if (err < 0) {
- const char *who;
- const char *msg;
-
- who = purple_conversation_get_name(conv);
-
- if (err == -E2BIG) {
- msg = _("Unable to send message: The message is too large.");
-
- if (!purple_conversation_present_error(who, account, msg)) {
- char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who);
- purple_notify_error(gc, NULL, msg2,
- _("The message is too large."),
- purple_request_cpar_from_connection(gc));
- g_free(msg2);
- }
- }
- else if (err == -ENOTCONN) {
- purple_debug_error("conversation", "Not yet connected.");
- }
- else {
- msg = _("Unable to send message.");
-
- if (!purple_conversation_present_error(who, account, msg)) {
- char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who);
- purple_notify_error(gc, NULL, msg2, NULL,
- purple_request_cpar_from_connection(gc));
- g_free(msg2);
- }
- }
- }
-
- g_free(displayed);
-}
-
-/**************************************************************************
- * Conversation API
- **************************************************************************/
-void
-purple_conversation_present(PurpleConversation *conv) {
- PurpleConversationUiOps *ops;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
-
- ops = purple_conversation_get_ui_ops(conv);
- if(ops && ops->present)
- ops->present(conv);
-}
-
-void
-purple_conversation_set_features(PurpleConversation *conv, PurpleConnectionFlags features)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
-
- priv = purple_conversation_get_instance_private(conv);
- priv->features = features;
-
- g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_FEATURES]);
-
- purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_FEATURES);
-}
-
-PurpleConnectionFlags
-purple_conversation_get_features(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), 0);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->features;
-}
-
-static PurpleConversationUiOps *
-purple_conversation_ui_ops_copy(PurpleConversationUiOps *ops)
-{
- PurpleConversationUiOps *ops_new;
-
- g_return_val_if_fail(ops != NULL, NULL);
-
- ops_new = g_new(PurpleConversationUiOps, 1);
- *ops_new = *ops;
-
- return ops_new;
-}
-
-GType
-purple_conversation_ui_ops_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- type = g_boxed_type_register_static("PurpleConversationUiOps",
- (GBoxedCopyFunc)purple_conversation_ui_ops_copy,
- (GBoxedFreeFunc)g_free);
- }
-
- return type;
-}
-
-void
-purple_conversation_set_ui_ops(PurpleConversation *conv,
- PurpleConversationUiOps *ops)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- priv = purple_conversation_get_instance_private(conv);
-
- if (priv->ui_ops == ops)
- return;
-
- if (priv->ui_ops != NULL && priv->ui_ops->destroy_conversation != NULL)
- priv->ui_ops->destroy_conversation(conv);
-
- priv->ui_ops = ops;
-}
-
-PurpleConversationUiOps *
-purple_conversation_get_ui_ops(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->ui_ops;
-}
-
-void
-purple_conversation_set_account(PurpleConversation *conv, PurpleAccount *account)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- priv = purple_conversation_get_instance_private(conv);
-
- if (account == purple_conversation_get_account(conv))
- return;
-
- _purple_conversations_update_cache(conv, NULL, account);
- priv->account = account;
-
- g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_ACCOUNT]);
-
- purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_ACCOUNT);
-}
-
-PurpleAccount *
-purple_conversation_get_account(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->account;
-}
-
-PurpleConnection *
-purple_conversation_get_connection(PurpleConversation *conv)
-{
- PurpleAccount *account;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- account = purple_conversation_get_account(conv);
-
- if (account == NULL)
- return NULL;
-
- return purple_account_get_connection(account);
-}
-
-void
-purple_conversation_set_title(PurpleConversation *conv, const char *title)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- g_return_if_fail(title != NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- g_free(priv->title);
- priv->title = g_strdup(title);
-
- if (!g_object_get_data(G_OBJECT(conv), "is-finalizing"))
- g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_TITLE]);
-
- purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_TITLE);
-}
-
-const char *
-purple_conversation_get_title(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->title;
-}
-
-void
-purple_conversation_autoset_title(PurpleConversation *conv)
-{
- PurpleAccount *account;
- PurpleBuddy *b;
- PurpleChat *chat;
- const char *text = NULL, *name;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
-
- account = purple_conversation_get_account(conv);
- name = purple_conversation_get_name(conv);
-
- if (PURPLE_IS_IM_CONVERSATION(conv)) {
- if (account && ((b = purple_blist_find_buddy(account, name)) != NULL))
- text = purple_buddy_get_contact_alias(b);
- } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
- if (account && ((chat = purple_blist_find_chat(account, name)) != NULL))
- text = purple_chat_get_name(chat);
- }
-
- if(text == NULL)
- text = name;
-
- purple_conversation_set_title(conv, text);
-}
-
-void
-purple_conversation_set_name(PurpleConversation *conv, const char *name)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- priv = purple_conversation_get_instance_private(conv);
-
- _purple_conversations_update_cache(conv, name, NULL);
-
- g_free(priv->name);
- priv->name = g_strdup(name);
-
- g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_NAME]);
-
- purple_conversation_autoset_title(conv);
- purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_NAME);
-}
-
-const char *
-purple_conversation_get_name(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->name;
-}
-
-void
-purple_conversation_set_logging(PurpleConversation *conv, gboolean log)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- priv = purple_conversation_get_instance_private(conv);
-
- if (priv->logging != log)
- {
- priv->logging = log;
- if (log && priv->logs == NULL) {
- GDateTime *dt;
- PurpleLog *log;
-
- dt = g_date_time_new_now_local();
- log = purple_log_new(PURPLE_IS_CHAT_CONVERSATION(conv)
- ? PURPLE_LOG_CHAT
- : PURPLE_LOG_IM,
- priv->name, priv->account, conv,
- dt);
- g_date_time_unref(dt);
-
- priv->logs = g_list_append(NULL, log);
- }
-
- g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_LOGGING]);
-
- purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_LOGGING);
- }
-}
-
-gboolean
-purple_conversation_is_logging(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), FALSE);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->logging;
-}
-
-void
-purple_conversation_close_logs(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
-
- priv = purple_conversation_get_instance_private(conv);
- g_list_free_full(priv->logs, (GDestroyNotify)purple_log_free);
- priv->logs = NULL;
-}
-
-void
-_purple_conversation_write_common(PurpleConversation *conv, PurpleMessage *pmsg)
-{
- PurpleConversationPrivate *priv = NULL;
- PurpleProtocol *protocol = NULL;
- PurpleConnection *gc = NULL;
- PurpleAccount *account;
- PurpleConversationUiOps *ops;
- PurpleBuddy *b;
- int plugin_return;
- /* int logging_font_options = 0; */
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- g_return_if_fail(pmsg != NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- ops = purple_conversation_get_ui_ops(conv);
-
- account = purple_conversation_get_account(conv);
-
- if (account != NULL)
- gc = purple_account_get_connection(account);
-
- if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
- (gc != NULL && !g_slist_find(purple_connection_get_active_chats(gc), conv)))
- return;
-
- if (PURPLE_IS_IM_CONVERSATION(conv) &&
- !g_list_find(purple_conversations_get_all(), conv))
- return;
-
- plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
- purple_conversations_get_handle(),
- (PURPLE_IS_IM_CONVERSATION(conv) ? "writing-im-msg" : "writing-chat-msg"),
- conv, pmsg));
-
- if (purple_message_is_empty(pmsg))
- return;
-
- if (plugin_return)
- return;
-
- if (account != NULL) {
- protocol = purple_account_get_protocol(account);
-
- if (PURPLE_IS_IM_CONVERSATION(conv) ||
- !(purple_protocol_get_options(protocol) & OPT_PROTO_UNIQUE_CHATNAME)) {
-
- if (purple_message_get_flags(pmsg) & PURPLE_MESSAGE_SEND) {
- const gchar *alias;
-
- b = purple_blist_find_buddy(account,
- purple_account_get_username(account));
-
- if (purple_account_get_private_alias(account) != NULL)
- alias = purple_account_get_private_alias(account);
- else if (b != NULL && !purple_strequal(purple_buddy_get_name(b),
- purple_buddy_get_contact_alias(b)))
- {
- alias = purple_buddy_get_contact_alias(b);
- } else if (purple_connection_get_display_name(gc) != NULL)
- alias = purple_connection_get_display_name(gc);
- else
- alias = purple_account_get_username(account);
-
- purple_message_set_author_alias(pmsg, alias);
- }
- else if (purple_message_get_flags(pmsg) & PURPLE_MESSAGE_RECV)
- {
- /* TODO: PurpleDude - folks not on the buddy list */
- b = purple_blist_find_buddy(account,
- purple_message_get_author(pmsg));
-
- if (b != NULL) {
- purple_message_set_author_alias(pmsg,
- purple_buddy_get_contact_alias(b));
- }
- }
- }
- }
-
- if (!(purple_message_get_flags(pmsg) & PURPLE_MESSAGE_NO_LOG) && purple_conversation_is_logging(conv)) {
- GList *log;
- GDateTime *dt;
-
- dt = g_date_time_ref(purple_message_get_timestamp(pmsg));
- log = priv->logs;
- while (log != NULL) {
- purple_log_write((PurpleLog *)log->data,
- purple_message_get_flags(pmsg),
- purple_message_get_author_alias(pmsg),
- dt,
- purple_message_get_contents(pmsg));
- log = log->next;
- }
- g_date_time_unref(dt);
- }
-
- if (ops) {
- if (PURPLE_IS_CHAT_CONVERSATION(conv) && ops->write_chat)
- ops->write_chat(PURPLE_CHAT_CONVERSATION(conv), pmsg);
- else if (PURPLE_IS_IM_CONVERSATION(conv) && ops->write_im)
- ops->write_im(PURPLE_IM_CONVERSATION(conv), pmsg);
- else if (ops->write_conv)
- ops->write_conv(conv, pmsg);
- }
-
- g_object_ref(pmsg);
- priv->message_history = g_list_prepend(priv->message_history, pmsg);
-
- purple_signal_emit(purple_conversations_get_handle(),
- (PURPLE_IS_IM_CONVERSATION(conv) ? "wrote-im-msg" : "wrote-chat-msg"),
- conv, pmsg);
-}
-
-void
-purple_conversation_write_message(PurpleConversation *conv, PurpleMessage *msg)
-{
- PurpleConversationClass *klass = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
-
- klass = PURPLE_CONVERSATION_GET_CLASS(conv);
-
- if (klass && klass->write_message)
- klass->write_message(conv, msg);
-}
-
-void purple_conversation_write_system_message(PurpleConversation *conv,
- const gchar *message, PurpleMessageFlags flags)
-{
- _purple_conversation_write_common(conv,
- purple_message_new_system(message, flags));
-}
-
-void
-purple_conversation_send(PurpleConversation *conv, const char *message)
-{
- purple_conversation_send_with_flags(conv, message, 0);
-}
-
-void
-purple_conversation_send_with_flags(PurpleConversation *conv, const char *message,
- PurpleMessageFlags flags)
-{
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- g_return_if_fail(message != NULL);
-
- common_send(conv, message, flags);
-}
-
-gboolean
-purple_conversation_has_focus(PurpleConversation *conv)
-{
- gboolean ret = FALSE;
- PurpleConversationUiOps *ops;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), FALSE);
-
- ops = purple_conversation_get_ui_ops(conv);
-
- if (ops != NULL && ops->has_focus != NULL)
- ret = ops->has_focus(conv);
-
- return ret;
-}
-
-/*
- * TODO: Need to make sure calls to this function happen in the core
- * instead of the UI. That way UIs have less work to do, and the
- * core/UI split is cleaner. Also need to make sure this is called
- * when chats are added/removed from the blist.
- */
-void
-purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdateType type)
-{
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
-
- purple_signal_emit(purple_conversations_get_handle(),
- "conversation-updated", conv, type);
-}
-
-gboolean purple_conversation_present_error(const char *who, PurpleAccount *account, const char *what)
-{
- PurpleConversation *conv;
-
- g_return_val_if_fail(who != NULL, FALSE);
- g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE);
- g_return_val_if_fail(what != NULL, FALSE);
-
- conv = purple_conversations_find_with_account(who, account);
- if (conv != NULL)
- purple_conversation_write_system_message(conv, what, PURPLE_MESSAGE_ERROR);
- else
- return FALSE;
-
- return TRUE;
-}
-
-static void
-purple_conversation_send_confirm_cb(gpointer *data)
-{
- PurpleConversation *conv = data[0];
- char *message = data[1];
-
- g_free(data);
-
- if (!PURPLE_IS_CONVERSATION(conv)) {
- /* Maybe it was closed before this callback was called. */
- return;
- }
-
- common_send(conv, message, 0);
-}
-
-void
-purple_conversation_send_confirm(PurpleConversation *conv, const char *message)
-{
- PurpleConversationPrivate *priv = NULL;
- char *text;
- gpointer *data;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- g_return_if_fail(message != NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- if (priv->ui_ops != NULL && priv->ui_ops->send_confirm != NULL)
- {
- priv->ui_ops->send_confirm(conv, message);
- return;
- }
-
- text = g_strdup_printf("You are about to send the following message:\n%s", message);
- data = g_new0(gpointer, 2);
- data[0] = conv;
- data[1] = (gpointer)message;
-
- purple_request_action(conv, NULL, _("Send Message"), text, 0,
- purple_request_cpar_from_account(
- purple_conversation_get_account(conv)),
- data, 2, _("_Send Message"),
- G_CALLBACK(purple_conversation_send_confirm_cb), _("Cancel"), NULL);
-}
-
-GList *
-purple_conversation_get_extended_menu(PurpleConversation *conv)
-{
- GList *menu = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "conversation-extended-menu", conv, &menu);
- return menu;
-}
-
-void purple_conversation_clear_message_history(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
- GList *list;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
-
- priv = purple_conversation_get_instance_private(conv);
- list = priv->message_history;
- g_list_free_full(list, g_object_unref);
- priv->message_history = NULL;
-
- purple_signal_emit(purple_conversations_get_handle(),
- "cleared-message-history", conv);
-}
-
-GList *purple_conversation_get_message_history(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->message_history;
-}
-
-gboolean
-purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline,
- const gchar *markup, gchar **error)
-{
- char *mark = (markup && *markup) ? NULL : g_markup_escape_text(cmdline, -1), *err = NULL;
- PurpleCmdStatus status = purple_cmd_do_command(conv, cmdline, mark ? mark : markup, error ? error : &err);
- g_free(mark);
- g_free(err);
- return (status == PURPLE_CMD_STATUS_OK);
-}
-
-gssize
-purple_conversation_get_max_message_size(PurpleConversation *conv)
-{
- PurpleProtocol *protocol;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), 0);
-
- protocol = purple_connection_get_protocol(
- purple_conversation_get_connection(conv));
-
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), 0);
-
- return purple_protocol_client_get_max_message_size(PURPLE_PROTOCOL_CLIENT(protocol), conv);
-}
-
-void
-purple_conversation_add_smiley(PurpleConversation *conv, PurpleSmiley *smiley) {
- PurpleConversationPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- g_return_if_fail(smiley);
-
- priv = purple_conversation_get_instance_private(conv);
-
- if (priv->remote_smileys == NULL) {
- priv->remote_smileys = purple_smiley_list_new();
- g_object_set(priv->remote_smileys,
- "drop-failed-remotes", TRUE, NULL);
- }
-
- if(purple_smiley_list_get_by_shortcut(
- priv->remote_smileys,
- purple_smiley_get_shortcut(smiley)))
- {
- /* smiley was already added */
- return;
- }
-
- if (!purple_smiley_list_add(priv->remote_smileys, smiley)) {
- purple_debug_error("conversation", "failed adding remote "
- "smiley to the list");
- }
-}
-
-PurpleSmiley *
-purple_conversation_get_smiley(PurpleConversation *conv, const gchar *shortcut) {
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
- g_return_val_if_fail(shortcut, NULL);
-
- priv = purple_conversation_get_instance_private(conv);
-
- if (priv->remote_smileys == NULL)
- return NULL;
-
- return purple_smiley_list_get_by_shortcut(priv->remote_smileys, shortcut);
-}
-
-PurpleSmileyList *
-purple_conversation_get_remote_smileys(PurpleConversation *conv)
-{
- PurpleConversationPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
-
- priv = purple_conversation_get_instance_private(conv);
- return priv->remote_smileys;
-}
-
-
-/**************************************************************************
- * GObject code
- **************************************************************************/
-
-/* Set method for GObject properties */
-static void
-purple_conversation_set_property(GObject *obj, guint param_id, const GValue *value,
- GParamSpec *pspec)
-{
- PurpleConversation *conv = PURPLE_CONVERSATION(obj);
- PurpleConversationPrivate *priv =
- purple_conversation_get_instance_private(conv);
-
- switch (param_id) {
- case PROP_ACCOUNT:
- priv->account = g_value_get_object(value);
- break;
- case PROP_NAME:
- g_free(priv->name);
- priv->name = g_value_dup_string(value);
- break;
- case PROP_TITLE:
- g_free(priv->title);
- priv->title = g_value_dup_string(value);
- break;
- case PROP_LOGGING:
- purple_conversation_set_logging(conv, g_value_get_boolean(value));
- break;
- case PROP_FEATURES:
- purple_conversation_set_features(conv, g_value_get_flags(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
- }
-}
-
-/* Get method for GObject properties */
-static void
-purple_conversation_get_property(GObject *obj, guint param_id, GValue *value,
- GParamSpec *pspec)
-{
- PurpleConversation *conv = PURPLE_CONVERSATION(obj);
-
- switch (param_id) {
- case PROP_ACCOUNT:
- g_value_set_object(value, purple_conversation_get_account(conv));
- break;
- case PROP_NAME:
- g_value_set_string(value, purple_conversation_get_name(conv));
- break;
- case PROP_TITLE:
- g_value_set_string(value, purple_conversation_get_title(conv));
- break;
- case PROP_LOGGING:
- g_value_set_boolean(value, purple_conversation_is_logging(conv));
- break;
- case PROP_FEATURES:
- g_value_set_flags(value, purple_conversation_get_features(conv));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
- }
-}
-
-static void
-purple_conversation_init(PurpleConversation *conv)
-{
-}
-
-/* Called when done constructing */
-static void
-purple_conversation_constructed(GObject *object)
-{
- PurpleConversation *conv = PURPLE_CONVERSATION(object);
- PurpleAccount *account;
- PurpleConnection *gc;
- PurpleConversationUiOps *ops;
-
- G_OBJECT_CLASS(purple_conversation_parent_class)->constructed(object);
-
- g_object_get(object, "account", &account, NULL);
- gc = purple_account_get_connection(account);
-
- /* copy features from the connection. */
- purple_conversation_set_features(conv, purple_connection_get_flags(gc));
-
- /* add the conversation to the appropriate lists */
- purple_conversations_add(conv);
-
- /* Auto-set the title. */
- purple_conversation_autoset_title(conv);
-
- /* Don't move this.. it needs to be one of the last things done otherwise
- * it causes mysterious crashes on my system.
- * -- Gary
- */
- ops = purple_conversations_get_ui_ops();
- purple_conversation_set_ui_ops(conv, ops);
- if (ops != NULL && ops->create_conversation != NULL)
- ops->create_conversation(conv);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "conversation-created", conv);
-
- g_object_unref(account);
-}
-
-static void
-purple_conversation_dispose(GObject *object)
-{
- g_object_set_data(object, "is-finalizing", GINT_TO_POINTER(TRUE));
-}
-
-/* GObject finalize function */
-static void
-purple_conversation_finalize(GObject *object)
-{
- PurpleConversation *conv = PURPLE_CONVERSATION(object);
- PurpleConversationPrivate *priv =
- purple_conversation_get_instance_private(conv);
- PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(conv);
-
- purple_request_close_with_handle(conv);
-
- /* remove from conversations and im/chats lists prior to emit */
- purple_conversations_remove(conv);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "deleting-conversation", conv);
-
- purple_conversation_close_logs(conv);
- purple_conversation_clear_message_history(conv);
-
- if (ops != NULL && ops->destroy_conversation != NULL)
- ops->destroy_conversation(conv);
-
- g_free(priv->name);
- g_free(priv->title);
-
- priv->name = NULL;
- priv->title = NULL;
-
- G_OBJECT_CLASS(purple_conversation_parent_class)->finalize(object);
-}
-
-/* Class initializer function */
-static void
-purple_conversation_class_init(PurpleConversationClass *klass)
-{
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
- obj_class->dispose = purple_conversation_dispose;
- obj_class->finalize = purple_conversation_finalize;
- obj_class->constructed = purple_conversation_constructed;
-
- /* Setup properties */
- obj_class->get_property = purple_conversation_get_property;
- obj_class->set_property = purple_conversation_set_property;
-
- properties[PROP_ACCOUNT] = g_param_spec_object("account", "Account",
- "The account for the conversation.", PURPLE_TYPE_ACCOUNT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
- properties[PROP_NAME] = g_param_spec_string("name", "Name",
- "The name of the conversation.", NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
- properties[PROP_TITLE] = g_param_spec_string("title", "Title",
- "The title of the conversation.", NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
- properties[PROP_LOGGING] = g_param_spec_boolean("logging", "Logging status",
- "Whether logging is enabled or not.", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- properties[PROP_FEATURES] = g_param_spec_flags("features",
- "Connection features",
- "The connection features of the conversation.",
- PURPLE_TYPE_CONNECTION_FLAGS, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties(obj_class, PROP_LAST, properties);
-}
--- a/libpurple/conversation.h Tue Apr 06 03:35:20 2021 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,621 +0,0 @@
-/* purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_CONVERSATION_H
-#define PURPLE_CONVERSATION_H
-/**
- * SECTION:conversation
- * @section_id: libpurple-conversation
- * @short_description: Conversation base class <filename>conversation.h</filename>
- * @title: Conversation Base Class
- *
- * This is the base class for the conversation abstraction on Libpurple.
- *
- * The present API manages the common functionallity for both kinds of conversations
- * @PurpleIMConversation and @PurpleChatConversation.
- */
-
-#define PURPLE_TYPE_CONVERSATION (purple_conversation_get_type())
-#define PURPLE_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CONVERSATION, PurpleConversation))
-#define PURPLE_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CONVERSATION, PurpleConversationClass))
-#define PURPLE_IS_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CONVERSATION))
-#define PURPLE_IS_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CONVERSATION))
-#define PURPLE_CONVERSATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CONVERSATION, PurpleConversationClass))
-
-/**
- * PURPLE_TYPE_CONVERSATION_UI_OPS:
- *
- * The standard _get_type macro for #PurpleConversationUiOps.
- */
-#define PURPLE_TYPE_CONVERSATION_UI_OPS (purple_conversation_ui_ops_get_type())
-
-/**************************************************************************/
-/* Data Structures */
-/**************************************************************************/
-
-typedef struct _PurpleConversation PurpleConversation;
-typedef struct _PurpleConversationClass PurpleConversationClass;
-
-typedef struct _PurpleConversationUiOps PurpleConversationUiOps;
-
-/**
- * PurpleConversationUpdateType:
- * @PURPLE_CONVERSATION_UPDATE_ADD: The buddy associated with the
- * conversation was added.
- * @PURPLE_CONVERSATION_UPDATE_REMOVE: The buddy associated with the
- * conversation was removed.
- * @PURPLE_CONVERSATION_UPDATE_ACCOUNT: The purple_account was changed.
- * @PURPLE_CONVERSATION_UPDATE_TYPING: The typing state was updated.
- * @PURPLE_CONVERSATION_UPDATE_UNSEEN: The unseen state was updated.
- * @PURPLE_CONVERSATION_UPDATE_LOGGING: Logging for this conversation was
- * enabled or disabled.
- * @PURPLE_CONVERSATION_UPDATE_TOPIC: The topic for a chat was updated.
- * @PURPLE_CONVERSATION_ACCOUNT_ONLINE: One of the user's accounts went online.
- * @PURPLE_CONVERSATION_ACCOUNT_OFFLINE: One of the user's accounts went
- * offline.
- * @PURPLE_CONVERSATION_UPDATE_AWAY: The other user went away.
- * @PURPLE_CONVERSATION_UPDATE_ICON: The other user's buddy icon changed.
- * @PURPLE_CONVERSATION_UPDATE_NAME: The name of the conversation was changed.
- * @PURPLE_CONVERSATION_UPDATE_TITLE: The title of the conversation was updated.
- * @PURPLE_CONVERSATION_UPDATE_CHATLEFT: The user left a chat.
- * @PURPLE_CONVERSATION_UPDATE_FEATURES: The features for a chat have changed.
- *
- * Conversation update type.
- */
-typedef enum
-{
- PURPLE_CONVERSATION_UPDATE_ADD = 0,
- PURPLE_CONVERSATION_UPDATE_REMOVE,
- PURPLE_CONVERSATION_UPDATE_ACCOUNT,
- PURPLE_CONVERSATION_UPDATE_TYPING,
- PURPLE_CONVERSATION_UPDATE_UNSEEN,
- PURPLE_CONVERSATION_UPDATE_LOGGING,
- PURPLE_CONVERSATION_UPDATE_TOPIC,
-
- /*
- * XXX These need to go when we implement a more generic core/UI event
- * system.
- */
- PURPLE_CONVERSATION_ACCOUNT_ONLINE,
- PURPLE_CONVERSATION_ACCOUNT_OFFLINE,
- PURPLE_CONVERSATION_UPDATE_AWAY,
- PURPLE_CONVERSATION_UPDATE_ICON,
- PURPLE_CONVERSATION_UPDATE_NAME,
- PURPLE_CONVERSATION_UPDATE_TITLE,
- PURPLE_CONVERSATION_UPDATE_CHATLEFT,
-
- PURPLE_CONVERSATION_UPDATE_FEATURES
-
-} PurpleConversationUpdateType;
-
-#include <glib.h>
-#include <glib-object.h>
-#include "purplemessage.h"
-
-/**************************************************************************/
-/* PurpleConversation */
-/**************************************************************************/
-/**
- * PurpleConversation:
- *
- * A core representation of a conversation between two or more people.
- *
- * The conversation can be an IM or a chat.
- *
- * Note: When a conversation is destroyed with the last g_object_unref(), the
- * specified conversation is removed from the parent window. If this
- * conversation is the only one contained in the parent window, that
- * window is also destroyed.
- */
-struct _PurpleConversation
-{
- GObject gparent;
-};
-
-/**
- * PurpleConversationClass:
- * @write_message: Writes a message to a chat or IM conversation. See
- * purple_conversation_write_message().
- *
- * Base class for all #PurpleConversation's
- */
-struct _PurpleConversationClass {
- GObjectClass parent_class;
-
- void (*write_message)(PurpleConversation *conv, PurpleMessage *msg);
-
- /*< private >*/
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
-};
-
-#include "account.h"
-#include "buddyicon.h"
-#include "log.h"
-#include "smiley-list.h"
-
-/**************************************************************************/
-/* PurpleConversationUiOps */
-/**************************************************************************/
-/**
- * PurpleConversationUiOps:
- * @create_conversation: Called when @conv is created (but before the
- * <link linkend="conversations-conversation-created"><literal>"conversation-created"</literal></link>
- * signal is emitted).
- * @destroy_conversation: Called just before @conv is freed.
- * @write_chat: Write a message to a chat. If this field is %NULL, libpurple
- * will fall back to using @write_conv.
- * See purple_conversation_write_message().
- * @write_im: Write a message to an IM conversation. If this field is %NULL,
- * libpurple will fall back to using @write_conv.
- * See purple_conversation_write_message().
- * @write_conv: Write a message to a conversation. This is used rather than the
- * chat- or im-specific ops for errors, system messages (such as "x
- * is now know as y"), and as the fallback if @write_im and
- * @write_chat are not implemented. It should be implemented, or
- * the UI will miss conversation error messages and your users will
- * hate you. See purple_conversation_write_message().
- * @chat_add_users: Add @cbuddies to a chat.
- * <sbr/>@cbuddies: A GList of #PurpleChatUser structs.
- * <sbr/>@new_arrivals: Whether join notices should be shown.
- * (Join notices are actually written to
- * the conversation by
- * purple_chat_conversation_add_users())
- * @chat_rename_user: Rename the user in this chat named @old_name to @new_name.
- * (The rename message is written to the conversation by
- * libpurple.) See purple_chat_conversation_rename_user().
- * <sbr/>@new_alias: @new_name's new alias, if they have one.
- * @chat_remove_users: Remove @users from a chat @chat.
- * See purple_chat_conversation_remove_users().
- * @chat_update_user: Called when a user's flags are changed.
- * See purple_chat_user_set_flags().
- * @present: Present this conversation to the user; for example, by displaying
- * the IM dialog.
- * @has_focus: If this UI has a concept of focus (as in a windowing system) and
- * this conversation has the focus, return %TRUE; otherwise, return
- * %FALSE.
- * @send_confirm: Prompt the user for confirmation to send @message. This
- * function should arrange for the message to be sent if the user
- * accepts. If this field is %NULL, libpurple will fall back to
- * using purple_request_action().
- *
- * Conversation operations and events.
- *
- * Any UI representing a conversation must assign a filled-out
- * #PurpleConversationUiOps structure to the #PurpleConversation.
- */
-struct _PurpleConversationUiOps
-{
- void (*create_conversation)(PurpleConversation *conv);
- void (*destroy_conversation)(PurpleConversation *conv);
-
- void (*write_chat)(PurpleChatConversation *chat, PurpleMessage *msg);
- void (*write_im)(PurpleIMConversation *im, PurpleMessage *msg);
- void (*write_conv)(PurpleConversation *conv, PurpleMessage *msg);
-
- void (*chat_add_users)(PurpleChatConversation *chat,
- GList *cbuddies,
- gboolean new_arrivals);
-
- void (*chat_rename_user)(PurpleChatConversation *chat, const char *old_name,
- const char *new_name, const char *new_alias);
-
- void (*chat_remove_users)(PurpleChatConversation *chat, GList *users);
-
- void (*chat_update_user)(PurpleChatUser *cb);
-
- void (*present)(PurpleConversation *conv);
- gboolean (*has_focus)(PurpleConversation *conv);
-
- void (*send_confirm)(PurpleConversation *conv, const char *message);
-
- /*< private >*/
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
-};
-
-G_BEGIN_DECLS
-
-/**************************************************************************/
-/* Conversation API */
-/**************************************************************************/
-
-/**
- * purple_conversation_get_type:
- *
- * Returns: The #GType for the Conversation object.
- */
-GType purple_conversation_get_type(void);
-
-/**
- * purple_conversation_ui_ops_get_type:
- *
- * Returns: The #GType for the #PurpleConversationUiOps boxed structure.
- */
-GType purple_conversation_ui_ops_get_type(void);
-
-/**
- * purple_conversation_present:
- * @conv: The conversation to present
- *
- * Present a conversation to the user. This allows core code to initiate a
- * conversation by displaying the IM dialog.
- */
-void purple_conversation_present(PurpleConversation *conv);
-
-/**
- * purple_conversation_set_ui_ops:
- * @conv: The conversation.
- * @ops: The UI conversation operations structure.
- *
- * Sets the specified conversation's UI operations structure.
- */
-void purple_conversation_set_ui_ops(PurpleConversation *conv,
- PurpleConversationUiOps *ops);
-
-/**
- * purple_conversation_get_ui_ops:
- * @conv: The conversation.
- *
- * Returns the specified conversation's UI operations structure.
- *
- * Returns: The operations structure.
- */
-PurpleConversationUiOps *purple_conversation_get_ui_ops(PurpleConversation *conv);
-
-/**
- * purple_conversation_set_account:
- * @conv: The conversation.
- * @account: The purple_account.
- *
- * Sets the specified conversation's purple_account.
- *
- * This purple_account represents the user using purple, not the person the user
- * is having a conversation/chat/flame with.
- */
-void purple_conversation_set_account(PurpleConversation *conv,
- PurpleAccount *account);
-
-/**
- * purple_conversation_get_account:
- * @conv: The conversation.
- *
- * Returns the specified conversation's purple_account.
- *
- * This purple_account represents the user using purple, not the person the user
- * is having a conversation/chat/flame with.
- *
- * Returns: (transfer none): The conversation's purple_account.
- */
-PurpleAccount *purple_conversation_get_account(PurpleConversation *conv);
-
-/**
- * purple_conversation_get_connection:
- * @conv: The conversation.
- *
- * Returns the specified conversation's purple_connection.
- *
- * Returns: (transfer none): The conversation's purple_connection.
- */
-PurpleConnection *purple_conversation_get_connection(PurpleConversation *conv);
-
-/**
- * purple_conversation_set_title:
- * @conv: The conversation.
- * @title: The title.
- *
- * Sets the specified conversation's title.
- */
-void purple_conversation_set_title(PurpleConversation *conv, const char *title);
-
-/**
- * purple_conversation_get_title:
- * @conv: The conversation.
- *
- * Returns the specified conversation's title.
- *
- * Returns: The title.
- */
-const char *purple_conversation_get_title(PurpleConversation *conv);
-
-/**
- * purple_conversation_autoset_title:
- * @conv: The conversation.
- *
- * Automatically sets the specified conversation's title.
- *
- * This function takes OPT_IM_ALIAS_TAB into account, as well as the
- * user's alias.
- */
-void purple_conversation_autoset_title(PurpleConversation *conv);
-
-/**
- * purple_conversation_set_name:
- * @conv: The conversation.
- * @name: The conversation's name.
- *
- * Sets the specified conversation's name.
- */
-void purple_conversation_set_name(PurpleConversation *conv, const char *name);
-
-/**
- * purple_conversation_get_name:
- * @conv: The conversation.
- *
- * Returns the specified conversation's name.
- *
- * Returns: The conversation's name. If the conversation is an IM with a
- * PurpleBuddy, then it's the name of the PurpleBuddy.
- */
-const char *purple_conversation_get_name(PurpleConversation *conv);
-
-/**
- * purple_conversation_set_logging:
- * @conv: The conversation.
- * @log: %TRUE if logging should be enabled, or %FALSE otherwise.
- *
- * Enables or disables logging for this conversation.
- */
-void purple_conversation_set_logging(PurpleConversation *conv, gboolean log);
-
-/**
- * purple_conversation_is_logging:
- * @conv: The conversation.
- *
- * Returns whether or not logging is enabled for this conversation.
- *
- * Returns: %TRUE if logging is enabled, or %FALSE otherwise.
- */
-gboolean purple_conversation_is_logging(PurpleConversation *conv);
-
-/**
- * purple_conversation_close_logs:
- * @conv: The conversation.
- *
- * Closes any open logs for this conversation.
- *
- * Note that new logs will be opened as necessary (e.g. upon receipt of a
- * message, if the conversation has logging enabled. To disable logging for
- * the remainder of the conversation, use purple_conversation_set_logging().
- */
-void purple_conversation_close_logs(PurpleConversation *conv);
-
-/**
- * purple_conversation_write_message:
- * @conv: The conversation.
- * @msg: The message to write.
- *
- * Writes to a chat or an IM.
- */
-void purple_conversation_write_message(PurpleConversation *conv,
- PurpleMessage *msg);
-
-/**
- * purple_conversation_write_system_message:
- * @conv: The conversation.
- * @message: The message to write.
- * @flags: The message flags (you don't need to set %PURPLE_MESSAGE_SYSTEM.
- *
- * Wites a system message to a chat or an IM.
- */
-void purple_conversation_write_system_message(PurpleConversation *conv,
- const gchar *message, PurpleMessageFlags flags);
-
-/**
- * purple_conversation_send:
- * @conv: The conversation.
- * @message: The message to send.
- *
- * Sends a message to this conversation. This function calls
- * purple_conversation_send_with_flags() with no additional flags.
- */
-void purple_conversation_send(PurpleConversation *conv, const char *message);
-
-/**
- * purple_conversation_send_with_flags:
- * @conv: The conversation.
- * @message: The message to send.
- * @flags: The PurpleMessageFlags flags to use in addition to
- * PURPLE_MESSAGE_SEND.
- *
- * Sends a message to this conversation with specified flags.
- */
-void purple_conversation_send_with_flags(PurpleConversation *conv, const char *message,
- PurpleMessageFlags flags);
-
-/**
- * purple_conversation_set_features:
- * @conv: The conversation
- * @features: Bitset defining supported features
- *
- * Set the features as supported for the given conversation.
- */
-void purple_conversation_set_features(PurpleConversation *conv,
- PurpleConnectionFlags features);
-
-
-/**
- * purple_conversation_get_features:
- * @conv: The conversation
- *
- * Get the features supported by the given conversation.
- */
-PurpleConnectionFlags purple_conversation_get_features(PurpleConversation *conv);
-
-/**
- * purple_conversation_has_focus:
- * @conv: The conversation.
- *
- * Determines if a conversation has focus
- *
- * Returns: %TRUE if the conversation has focus, %FALSE if
- * it does not or the UI does not have a concept of conversation focus
- */
-gboolean purple_conversation_has_focus(PurpleConversation *conv);
-
-/**
- * purple_conversation_update:
- * @conv: The conversation.
- * @type: The update type.
- *
- * Updates the visual status and UI of a conversation.
- */
-void purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdateType type);
-
-/**
- * purple_conversation_get_message_history:
- * @conv: The conversation
- *
- * Retrieve the message history of a conversation.
- *
- * Returns: (element-type PurpleMessage) (transfer none):
- * A GList of PurpleMessage's. You must not modify the
- * list or the data within. The list contains the newest message at
- * the beginning, and the oldest message at the end.
- */
-GList *purple_conversation_get_message_history(PurpleConversation *conv);
-
-/**
- * purple_conversation_clear_message_history:
- * @conv: The conversation
- *
- * Clear the message history of a conversation.
- */
-void purple_conversation_clear_message_history(PurpleConversation *conv);
-
-/**
- * purple_conversation_send_confirm:
- * @conv: The conversation.
- * @message: The message to send.
- *
- * Sends a message to a conversation after confirming with
- * the user.
- *
- * This function is intended for use in cases where the user
- * hasn't explicitly and knowingly caused a message to be sent.
- * The confirmation ensures that the user isn't sending a
- * message by mistake.
- */
-void purple_conversation_send_confirm(PurpleConversation *conv, const char *message);
-
-/**
- * purple_conversation_get_extended_menu:
- * @conv: The conversation.
- *
- * Retrieves the extended menu items for the conversation.
- *
- * Returns: (element-type PurpleActionMenu) (transfer full): The extended menu
- * items for a conversation, as harvested by the chat-extended-menu
- * signal.
- */
-GList * purple_conversation_get_extended_menu(PurpleConversation *conv);
-
-/**
- * purple_conversation_do_command:
- * @conv: The conversation.
- * @cmdline: The entire command including the arguments.
- * @markup: %NULL, or the formatted command line.
- * @error: If the command failed errormsg is filled in with the appropriate error
- * message, if not %NULL. It must be freed by the caller with g_free().
- *
- * Perform a command in a conversation. Similar to purple_cmd_do_command().
- *
- * Returns: %TRUE if the command was executed successfully, %FALSE otherwise.
- */
-gboolean purple_conversation_do_command(PurpleConversation *conv,
- const gchar *cmdline, const gchar *markup, gchar **error);
-
-/**
- * purple_conversation_get_max_message_size:
- * @conv: The conversation to query.
- *
- * Gets the maximum message size in bytes for the conversation.
- *
- * See #PurpleProtocolClientInterface's <literal>get_max_message_size</literal>.
- *
- * Returns: Maximum message size, 0 if unspecified, -1 for infinite.
- */
-gssize
-purple_conversation_get_max_message_size(PurpleConversation *conv);
-
-/**
- * purple_conversation_add_smiley:
- * @conv: The conversation that receives new smiley.
- * @smiley: The smiley.
- *
- * Adds a smiley to the list of smileys that belong to this conversation.
- */
-void purple_conversation_add_smiley(PurpleConversation *conv, PurpleSmiley *smiley);
-
-/**
- * purple_conversation_get_smiley:
- * @conv: The conversation.
- * @shortcut: The shortcut.
- *
- * Lookups for the smiley previously added to this conversation.
- *
- * Returns: (transfer none): The smiley, or %NULL if it doesn't exists.
- */
-PurpleSmiley *purple_conversation_get_smiley(PurpleConversation *conv, const gchar *shortcut);
-
-/**
- * purple_conversation_get_remote_smileys:
- * @conv: The conversation.
- *
- * Get all remote smileys previously added to this conversation.
- *
- * Returns: (transfer none): The list of remote smileys.
- */
-PurpleSmileyList *
-purple_conversation_get_remote_smileys(PurpleConversation *conv);
-
-/**************************************************************************/
-/* Conversation Helper API */
-/**************************************************************************/
-
-/**
- * purple_conversation_present_error:
- * @who: The user this error is about
- * @account: The account this error is on
- * @what: The error
- *
- * Presents an IM-error to the user
- *
- * This is a helper function to find a conversation, write an error to it, and
- * raise the window. If a conversation with this user doesn't already exist,
- * the function will return FALSE and the calling function can attempt to present
- * the error another way (purple_notify_error, most likely)
- *
- * Returns: TRUE if the error was presented, else FALSE
- */
-gboolean purple_conversation_present_error(const char *who, PurpleAccount *account, const char *what);
-
-G_END_DECLS
-
-#endif /* PURPLE_CONVERSATION_H */
--- a/libpurple/core.c Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/core.c Mon Apr 12 20:27:47 2021 -0500
@@ -24,7 +24,6 @@
#include "internal.h"
#include "cmds.h"
#include "connection.h"
-#include "conversation.h"
#include "core.h"
#include "debug.h"
#include "xfer.h"
@@ -36,6 +35,7 @@
#include "plugins.h"
#include "prefs.h"
#include "proxy.h"
+#include "purpleconversation.h"
#include "purplecredentialmanager.h"
#include "purplemessage.h"
#include "purpleprivate.h"
--- a/libpurple/meson.build Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/meson.build Mon Apr 12 20:27:47 2021 -0500
@@ -11,7 +11,6 @@
'cmds.c',
'connection.c',
'contact.c',
- 'conversation.c',
'conversations.c',
'core.c',
'countingnode.c',
@@ -50,6 +49,8 @@
'purplebuddypresence.c',
'purplechatconversation.c',
'purplechatuser.c',
+ 'purpleconversation.c',
+ 'purpleconversationuiops.c',
'purplecredentialmanager.c',
'purplecredentialprovider.c',
'purpleimconversation.c',
@@ -109,7 +110,6 @@
'cmds.h',
'connection.h',
'contact.h',
- 'conversation.h',
'conversations.h',
'core.h',
'countingnode.h',
@@ -141,6 +141,8 @@
'purplebuddypresence.h',
'purplechatconversation.h',
'purplechatuser.h',
+ 'purpleconversation.h',
+ 'purpleconversationuiops.h',
'purplecredentialmanager.h',
'purplecredentialprovider.h',
'purpleimconversation.h',
@@ -224,7 +226,6 @@
'account.h',
'buddyicon.h',
'connection.h',
- 'conversation.h',
'debug.h',
'eventloop.h',
'notify.h',
@@ -232,6 +233,7 @@
'protocol.h',
'protocols.h',
'purplechatuser.h',
+ 'purpleconversation.h',
'purpleimconversation.h',
'purplemessage.h',
'roomlist.h',
--- a/libpurple/protocols.c Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/protocols.c Mon Apr 12 20:27:47 2021 -0500
@@ -24,12 +24,12 @@
#include <glib/gi18n-lib.h>
#include "internal.h"
-#include "conversation.h"
#include "debug.h"
#include "network.h"
#include "notify.h"
#include "protocol.h"
#include "purpleaccountoption.h"
+#include "purpleconversation.h"
#include "purplecredentialmanager.h"
#include "purpleprotocolattention.h"
#include "purpleprotocolmanager.h"
--- a/libpurple/purplechatconversation.h Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/purplechatconversation.h Mon Apr 12 20:27:47 2021 -0500
@@ -45,8 +45,8 @@
typedef struct _PurpleChatConversationClass PurpleChatConversationClass;
#include "purplechatuser.h"
+#include "purpleconversation.h"
#include "purpleimconversation.h"
-#include "conversation.h"
G_BEGIN_DECLS
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleconversation.c Mon Apr 12 20:27:47 2021 -0500
@@ -0,0 +1,1003 @@
+/*
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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>
+
+#include "internal.h"
+
+#include "buddylist.h"
+#include "cmds.h"
+#include "debug.h"
+#include "enums.h"
+#include "notify.h"
+#include "prefs.h"
+#include "protocol.h"
+#include "purpleconversation.h"
+#include "purplemarkup.h"
+#include "purpleprivate.h"
+#include "purpleprotocolclient.h"
+#include "request.h"
+#include "signals.h"
+#include "smiley-list.h"
+
+typedef struct _PurpleConversationPrivate PurpleConversationPrivate;
+
+/* General private data for a conversation */
+struct _PurpleConversationPrivate
+{
+ PurpleAccount *account; /* The user using this conversation. */
+
+ char *name; /* The name of the conversation. */
+ char *title; /* The window title. */
+
+ gboolean logging; /* The status of logging. */
+
+ GList *logs; /* This conversation's logs */
+
+ PurpleConversationUiOps *ui_ops; /* UI-specific operations. */
+
+ PurpleConnectionFlags features; /* The supported features */
+ GList *message_history; /* Message history, as a GList of PurpleMessages */
+
+ /* The list of remote smileys. This should be per-buddy (PurpleBuddy),
+ * but we don't have any class for people not on our buddy
+ * list (PurpleDude?). So, if we have one, we should switch to it. */
+ PurpleSmileyList *remote_smileys;
+};
+
+/* GObject Property enums */
+enum
+{
+ PROP_0,
+ PROP_ACCOUNT,
+ PROP_NAME,
+ PROP_TITLE,
+ PROP_LOGGING,
+ PROP_FEATURES,
+ PROP_LAST
+};
+
+static GParamSpec *properties[PROP_LAST];
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleConversation, purple_conversation,
+ G_TYPE_OBJECT);
+
+static void
+common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags msgflags)
+{
+ PurpleAccount *account;
+ PurpleConnection *gc;
+ PurpleConversationPrivate *priv =
+ purple_conversation_get_instance_private(conv);
+ char *displayed = NULL;
+ const char *sent, *me;
+ int err = 0;
+
+ if (*message == '\0')
+ return;
+
+ account = purple_conversation_get_account(conv);
+ g_return_if_fail(PURPLE_IS_ACCOUNT(account));
+
+ 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)) {
+ if(msgflags & PURPLE_MESSAGE_NO_LINKIFY)
+ displayed = g_strdup(message);
+ else
+ displayed = purple_markup_linkify(message);
+ }
+
+ if (displayed && (priv->features & PURPLE_CONNECTION_FLAG_HTML) &&
+ !(msgflags & PURPLE_MESSAGE_RAW)) {
+ sent = displayed;
+ } else
+ sent = message;
+
+ msgflags |= PURPLE_MESSAGE_SEND;
+
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ PurpleMessage *msg = purple_message_new_outgoing(me,
+ purple_conversation_get_name(conv), sent, msgflags);
+
+ purple_signal_emit(purple_conversations_get_handle(), "sending-im-msg",
+ account, msg);
+
+ if (!purple_message_is_empty(msg)) {
+
+ err = purple_serv_send_im(gc, msg);
+
+ if ((err > 0) && (displayed != NULL)) {
+ /* revert the contents in case sending-im-msg changed it */
+ purple_message_set_contents(msg, displayed);
+ purple_conversation_write_message(conv, msg);
+ }
+
+ 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)) {
+ PurpleMessage *msg;
+ int id = purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv));
+
+ msg = purple_message_new_outgoing(me, NULL, sent, msgflags);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "sending-chat-msg", account, msg, id);
+
+ if (!purple_message_is_empty(msg)) {
+ err = purple_serv_chat_send(gc, id, msg);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "sent-chat-msg", account, msg, id);
+ }
+
+ g_object_unref(G_OBJECT(msg));
+ }
+
+ if (err < 0) {
+ const char *who;
+ const char *msg;
+
+ who = purple_conversation_get_name(conv);
+
+ if (err == -E2BIG) {
+ msg = _("Unable to send message: The message is too large.");
+
+ if (!purple_conversation_present_error(who, account, msg)) {
+ char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who);
+ purple_notify_error(gc, NULL, msg2,
+ _("The message is too large."),
+ purple_request_cpar_from_connection(gc));
+ g_free(msg2);
+ }
+ }
+ else if (err == -ENOTCONN) {
+ purple_debug_error("conversation", "Not yet connected.");
+ }
+ else {
+ msg = _("Unable to send message.");
+
+ if (!purple_conversation_present_error(who, account, msg)) {
+ char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who);
+ purple_notify_error(gc, NULL, msg2, NULL,
+ purple_request_cpar_from_connection(gc));
+ g_free(msg2);
+ }
+ }
+ }
+
+ g_free(displayed);
+}
+
+/**************************************************************************
+ * Conversation API
+ **************************************************************************/
+void
+purple_conversation_present(PurpleConversation *conv) {
+ PurpleConversationUiOps *ops;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ ops = purple_conversation_get_ui_ops(conv);
+ if(ops && ops->present)
+ ops->present(conv);
+}
+
+void
+purple_conversation_set_features(PurpleConversation *conv, PurpleConnectionFlags features)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ priv = purple_conversation_get_instance_private(conv);
+ priv->features = features;
+
+ g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_FEATURES]);
+
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_FEATURES);
+}
+
+PurpleConnectionFlags
+purple_conversation_get_features(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), 0);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->features;
+}
+
+void
+purple_conversation_set_ui_ops(PurpleConversation *conv,
+ PurpleConversationUiOps *ops)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ priv = purple_conversation_get_instance_private(conv);
+
+ if (priv->ui_ops == ops)
+ return;
+
+ if (priv->ui_ops != NULL && priv->ui_ops->destroy_conversation != NULL)
+ priv->ui_ops->destroy_conversation(conv);
+
+ priv->ui_ops = ops;
+}
+
+PurpleConversationUiOps *
+purple_conversation_get_ui_ops(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->ui_ops;
+}
+
+void
+purple_conversation_set_account(PurpleConversation *conv, PurpleAccount *account)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ priv = purple_conversation_get_instance_private(conv);
+
+ if (account == purple_conversation_get_account(conv))
+ return;
+
+ _purple_conversations_update_cache(conv, NULL, account);
+ priv->account = account;
+
+ g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_ACCOUNT]);
+
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_ACCOUNT);
+}
+
+PurpleAccount *
+purple_conversation_get_account(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->account;
+}
+
+PurpleConnection *
+purple_conversation_get_connection(PurpleConversation *conv)
+{
+ PurpleAccount *account;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ account = purple_conversation_get_account(conv);
+
+ if (account == NULL)
+ return NULL;
+
+ return purple_account_get_connection(account);
+}
+
+void
+purple_conversation_set_title(PurpleConversation *conv, const char *title)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ g_return_if_fail(title != NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ g_free(priv->title);
+ priv->title = g_strdup(title);
+
+ if (!g_object_get_data(G_OBJECT(conv), "is-finalizing"))
+ g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_TITLE]);
+
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_TITLE);
+}
+
+const char *
+purple_conversation_get_title(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->title;
+}
+
+void
+purple_conversation_autoset_title(PurpleConversation *conv)
+{
+ PurpleAccount *account;
+ PurpleBuddy *b;
+ PurpleChat *chat;
+ const char *text = NULL, *name;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ account = purple_conversation_get_account(conv);
+ name = purple_conversation_get_name(conv);
+
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ if (account && ((b = purple_blist_find_buddy(account, name)) != NULL))
+ text = purple_buddy_get_contact_alias(b);
+ } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
+ if (account && ((chat = purple_blist_find_chat(account, name)) != NULL))
+ text = purple_chat_get_name(chat);
+ }
+
+ if(text == NULL)
+ text = name;
+
+ purple_conversation_set_title(conv, text);
+}
+
+void
+purple_conversation_set_name(PurpleConversation *conv, const char *name)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ priv = purple_conversation_get_instance_private(conv);
+
+ _purple_conversations_update_cache(conv, name, NULL);
+
+ g_free(priv->name);
+ priv->name = g_strdup(name);
+
+ g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_NAME]);
+
+ purple_conversation_autoset_title(conv);
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_NAME);
+}
+
+const char *
+purple_conversation_get_name(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->name;
+}
+
+void
+purple_conversation_set_logging(PurpleConversation *conv, gboolean log)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ priv = purple_conversation_get_instance_private(conv);
+
+ if (priv->logging != log)
+ {
+ priv->logging = log;
+ if (log && priv->logs == NULL) {
+ GDateTime *dt;
+ PurpleLog *log;
+
+ dt = g_date_time_new_now_local();
+ log = purple_log_new(PURPLE_IS_CHAT_CONVERSATION(conv)
+ ? PURPLE_LOG_CHAT
+ : PURPLE_LOG_IM,
+ priv->name, priv->account, conv,
+ dt);
+ g_date_time_unref(dt);
+
+ priv->logs = g_list_append(NULL, log);
+ }
+
+ g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_LOGGING]);
+
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_LOGGING);
+ }
+}
+
+gboolean
+purple_conversation_is_logging(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), FALSE);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->logging;
+}
+
+void
+purple_conversation_close_logs(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ priv = purple_conversation_get_instance_private(conv);
+ g_list_free_full(priv->logs, (GDestroyNotify)purple_log_free);
+ priv->logs = NULL;
+}
+
+void
+_purple_conversation_write_common(PurpleConversation *conv, PurpleMessage *pmsg)
+{
+ PurpleConversationPrivate *priv = NULL;
+ PurpleProtocol *protocol = NULL;
+ PurpleConnection *gc = NULL;
+ PurpleAccount *account;
+ PurpleConversationUiOps *ops;
+ PurpleBuddy *b;
+ int plugin_return;
+ /* int logging_font_options = 0; */
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ g_return_if_fail(pmsg != NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ ops = purple_conversation_get_ui_ops(conv);
+
+ account = purple_conversation_get_account(conv);
+
+ if (account != NULL)
+ gc = purple_account_get_connection(account);
+
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
+ (gc != NULL && !g_slist_find(purple_connection_get_active_chats(gc), conv)))
+ return;
+
+ if (PURPLE_IS_IM_CONVERSATION(conv) &&
+ !g_list_find(purple_conversations_get_all(), conv))
+ return;
+
+ plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
+ purple_conversations_get_handle(),
+ (PURPLE_IS_IM_CONVERSATION(conv) ? "writing-im-msg" : "writing-chat-msg"),
+ conv, pmsg));
+
+ if (purple_message_is_empty(pmsg))
+ return;
+
+ if (plugin_return)
+ return;
+
+ if (account != NULL) {
+ protocol = purple_account_get_protocol(account);
+
+ if (PURPLE_IS_IM_CONVERSATION(conv) ||
+ !(purple_protocol_get_options(protocol) & OPT_PROTO_UNIQUE_CHATNAME)) {
+
+ if (purple_message_get_flags(pmsg) & PURPLE_MESSAGE_SEND) {
+ const gchar *alias;
+
+ b = purple_blist_find_buddy(account,
+ purple_account_get_username(account));
+
+ if (purple_account_get_private_alias(account) != NULL)
+ alias = purple_account_get_private_alias(account);
+ else if (b != NULL && !purple_strequal(purple_buddy_get_name(b),
+ purple_buddy_get_contact_alias(b)))
+ {
+ alias = purple_buddy_get_contact_alias(b);
+ } else if (purple_connection_get_display_name(gc) != NULL)
+ alias = purple_connection_get_display_name(gc);
+ else
+ alias = purple_account_get_username(account);
+
+ purple_message_set_author_alias(pmsg, alias);
+ }
+ else if (purple_message_get_flags(pmsg) & PURPLE_MESSAGE_RECV)
+ {
+ /* TODO: PurpleDude - folks not on the buddy list */
+ b = purple_blist_find_buddy(account,
+ purple_message_get_author(pmsg));
+
+ if (b != NULL) {
+ purple_message_set_author_alias(pmsg,
+ purple_buddy_get_contact_alias(b));
+ }
+ }
+ }
+ }
+
+ if (!(purple_message_get_flags(pmsg) & PURPLE_MESSAGE_NO_LOG) && purple_conversation_is_logging(conv)) {
+ GList *log;
+ GDateTime *dt;
+
+ dt = g_date_time_ref(purple_message_get_timestamp(pmsg));
+ log = priv->logs;
+ while (log != NULL) {
+ purple_log_write((PurpleLog *)log->data,
+ purple_message_get_flags(pmsg),
+ purple_message_get_author_alias(pmsg),
+ dt,
+ purple_message_get_contents(pmsg));
+ log = log->next;
+ }
+ g_date_time_unref(dt);
+ }
+
+ if (ops) {
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) && ops->write_chat)
+ ops->write_chat(PURPLE_CHAT_CONVERSATION(conv), pmsg);
+ else if (PURPLE_IS_IM_CONVERSATION(conv) && ops->write_im)
+ ops->write_im(PURPLE_IM_CONVERSATION(conv), pmsg);
+ else if (ops->write_conv)
+ ops->write_conv(conv, pmsg);
+ }
+
+ g_object_ref(pmsg);
+ priv->message_history = g_list_prepend(priv->message_history, pmsg);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ (PURPLE_IS_IM_CONVERSATION(conv) ? "wrote-im-msg" : "wrote-chat-msg"),
+ conv, pmsg);
+}
+
+void
+purple_conversation_write_message(PurpleConversation *conv, PurpleMessage *msg)
+{
+ PurpleConversationClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ klass = PURPLE_CONVERSATION_GET_CLASS(conv);
+
+ if (klass && klass->write_message)
+ klass->write_message(conv, msg);
+}
+
+void purple_conversation_write_system_message(PurpleConversation *conv,
+ const gchar *message, PurpleMessageFlags flags)
+{
+ _purple_conversation_write_common(conv,
+ purple_message_new_system(message, flags));
+}
+
+void
+purple_conversation_send(PurpleConversation *conv, const char *message)
+{
+ purple_conversation_send_with_flags(conv, message, 0);
+}
+
+void
+purple_conversation_send_with_flags(PurpleConversation *conv, const char *message,
+ PurpleMessageFlags flags)
+{
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ g_return_if_fail(message != NULL);
+
+ common_send(conv, message, flags);
+}
+
+gboolean
+purple_conversation_has_focus(PurpleConversation *conv)
+{
+ gboolean ret = FALSE;
+ PurpleConversationUiOps *ops;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), FALSE);
+
+ ops = purple_conversation_get_ui_ops(conv);
+
+ if (ops != NULL && ops->has_focus != NULL)
+ ret = ops->has_focus(conv);
+
+ return ret;
+}
+
+/*
+ * TODO: Need to make sure calls to this function happen in the core
+ * instead of the UI. That way UIs have less work to do, and the
+ * core/UI split is cleaner. Also need to make sure this is called
+ * when chats are added/removed from the blist.
+ */
+void
+purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdateType type)
+{
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "conversation-updated", conv, type);
+}
+
+gboolean purple_conversation_present_error(const char *who, PurpleAccount *account, const char *what)
+{
+ PurpleConversation *conv;
+
+ g_return_val_if_fail(who != NULL, FALSE);
+ g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE);
+ g_return_val_if_fail(what != NULL, FALSE);
+
+ conv = purple_conversations_find_with_account(who, account);
+ if (conv != NULL)
+ purple_conversation_write_system_message(conv, what, PURPLE_MESSAGE_ERROR);
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+purple_conversation_send_confirm_cb(gpointer *data)
+{
+ PurpleConversation *conv = data[0];
+ char *message = data[1];
+
+ g_free(data);
+
+ if (!PURPLE_IS_CONVERSATION(conv)) {
+ /* Maybe it was closed before this callback was called. */
+ return;
+ }
+
+ common_send(conv, message, 0);
+}
+
+void
+purple_conversation_send_confirm(PurpleConversation *conv, const char *message)
+{
+ PurpleConversationPrivate *priv = NULL;
+ char *text;
+ gpointer *data;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ g_return_if_fail(message != NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ if (priv->ui_ops != NULL && priv->ui_ops->send_confirm != NULL)
+ {
+ priv->ui_ops->send_confirm(conv, message);
+ return;
+ }
+
+ text = g_strdup_printf("You are about to send the following message:\n%s", message);
+ data = g_new0(gpointer, 2);
+ data[0] = conv;
+ data[1] = (gpointer)message;
+
+ purple_request_action(conv, NULL, _("Send Message"), text, 0,
+ purple_request_cpar_from_account(
+ purple_conversation_get_account(conv)),
+ data, 2, _("_Send Message"),
+ G_CALLBACK(purple_conversation_send_confirm_cb), _("Cancel"), NULL);
+}
+
+GList *
+purple_conversation_get_extended_menu(PurpleConversation *conv)
+{
+ GList *menu = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "conversation-extended-menu", conv, &menu);
+ return menu;
+}
+
+void purple_conversation_clear_message_history(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+ GList *list;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ priv = purple_conversation_get_instance_private(conv);
+ list = priv->message_history;
+ g_list_free_full(list, g_object_unref);
+ priv->message_history = NULL;
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "cleared-message-history", conv);
+}
+
+GList *purple_conversation_get_message_history(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->message_history;
+}
+
+gboolean
+purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline,
+ const gchar *markup, gchar **error)
+{
+ char *mark = (markup && *markup) ? NULL : g_markup_escape_text(cmdline, -1), *err = NULL;
+ PurpleCmdStatus status = purple_cmd_do_command(conv, cmdline, mark ? mark : markup, error ? error : &err);
+ g_free(mark);
+ g_free(err);
+ return (status == PURPLE_CMD_STATUS_OK);
+}
+
+gssize
+purple_conversation_get_max_message_size(PurpleConversation *conv)
+{
+ PurpleProtocol *protocol;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), 0);
+
+ protocol = purple_connection_get_protocol(
+ purple_conversation_get_connection(conv));
+
+ g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), 0);
+
+ return purple_protocol_client_get_max_message_size(PURPLE_PROTOCOL_CLIENT(protocol), conv);
+}
+
+void
+purple_conversation_add_smiley(PurpleConversation *conv, PurpleSmiley *smiley) {
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+ g_return_if_fail(smiley);
+
+ priv = purple_conversation_get_instance_private(conv);
+
+ if (priv->remote_smileys == NULL) {
+ priv->remote_smileys = purple_smiley_list_new();
+ g_object_set(priv->remote_smileys,
+ "drop-failed-remotes", TRUE, NULL);
+ }
+
+ if(purple_smiley_list_get_by_shortcut(
+ priv->remote_smileys,
+ purple_smiley_get_shortcut(smiley)))
+ {
+ /* smiley was already added */
+ return;
+ }
+
+ if (!purple_smiley_list_add(priv->remote_smileys, smiley)) {
+ purple_debug_error("conversation", "failed adding remote "
+ "smiley to the list");
+ }
+}
+
+PurpleSmiley *
+purple_conversation_get_smiley(PurpleConversation *conv, const gchar *shortcut) {
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+ g_return_val_if_fail(shortcut, NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+
+ if (priv->remote_smileys == NULL)
+ return NULL;
+
+ return purple_smiley_list_get_by_shortcut(priv->remote_smileys, shortcut);
+}
+
+PurpleSmileyList *
+purple_conversation_get_remote_smileys(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
+
+ priv = purple_conversation_get_instance_private(conv);
+ return priv->remote_smileys;
+}
+
+
+/**************************************************************************
+ * GObject code
+ **************************************************************************/
+
+/* Set method for GObject properties */
+static void
+purple_conversation_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleConversation *conv = PURPLE_CONVERSATION(obj);
+ PurpleConversationPrivate *priv =
+ purple_conversation_get_instance_private(conv);
+
+ switch (param_id) {
+ case PROP_ACCOUNT:
+ priv->account = g_value_get_object(value);
+ break;
+ case PROP_NAME:
+ g_free(priv->name);
+ priv->name = g_value_dup_string(value);
+ break;
+ case PROP_TITLE:
+ g_free(priv->title);
+ priv->title = g_value_dup_string(value);
+ break;
+ case PROP_LOGGING:
+ purple_conversation_set_logging(conv, g_value_get_boolean(value));
+ break;
+ case PROP_FEATURES:
+ purple_conversation_set_features(conv, g_value_get_flags(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_conversation_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleConversation *conv = PURPLE_CONVERSATION(obj);
+
+ switch (param_id) {
+ case PROP_ACCOUNT:
+ g_value_set_object(value, purple_conversation_get_account(conv));
+ break;
+ case PROP_NAME:
+ g_value_set_string(value, purple_conversation_get_name(conv));
+ break;
+ case PROP_TITLE:
+ g_value_set_string(value, purple_conversation_get_title(conv));
+ break;
+ case PROP_LOGGING:
+ g_value_set_boolean(value, purple_conversation_is_logging(conv));
+ break;
+ case PROP_FEATURES:
+ g_value_set_flags(value, purple_conversation_get_features(conv));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_conversation_init(PurpleConversation *conv)
+{
+}
+
+/* Called when done constructing */
+static void
+purple_conversation_constructed(GObject *object)
+{
+ PurpleConversation *conv = PURPLE_CONVERSATION(object);
+ PurpleAccount *account;
+ PurpleConnection *gc;
+ PurpleConversationUiOps *ops;
+
+ G_OBJECT_CLASS(purple_conversation_parent_class)->constructed(object);
+
+ g_object_get(object, "account", &account, NULL);
+ gc = purple_account_get_connection(account);
+
+ /* copy features from the connection. */
+ purple_conversation_set_features(conv, purple_connection_get_flags(gc));
+
+ /* add the conversation to the appropriate lists */
+ purple_conversations_add(conv);
+
+ /* Auto-set the title. */
+ purple_conversation_autoset_title(conv);
+
+ /* Don't move this.. it needs to be one of the last things done otherwise
+ * it causes mysterious crashes on my system.
+ * -- Gary
+ */
+ ops = purple_conversations_get_ui_ops();
+ purple_conversation_set_ui_ops(conv, ops);
+ if (ops != NULL && ops->create_conversation != NULL)
+ ops->create_conversation(conv);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "conversation-created", conv);
+
+ g_object_unref(account);
+}
+
+static void
+purple_conversation_dispose(GObject *object)
+{
+ g_object_set_data(object, "is-finalizing", GINT_TO_POINTER(TRUE));
+}
+
+/* GObject finalize function */
+static void
+purple_conversation_finalize(GObject *object)
+{
+ PurpleConversation *conv = PURPLE_CONVERSATION(object);
+ PurpleConversationPrivate *priv =
+ purple_conversation_get_instance_private(conv);
+ PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(conv);
+
+ purple_request_close_with_handle(conv);
+
+ /* remove from conversations and im/chats lists prior to emit */
+ purple_conversations_remove(conv);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "deleting-conversation", conv);
+
+ purple_conversation_close_logs(conv);
+ purple_conversation_clear_message_history(conv);
+
+ if (ops != NULL && ops->destroy_conversation != NULL)
+ ops->destroy_conversation(conv);
+
+ g_free(priv->name);
+ g_free(priv->title);
+
+ priv->name = NULL;
+ priv->title = NULL;
+
+ G_OBJECT_CLASS(purple_conversation_parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void
+purple_conversation_class_init(PurpleConversationClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->dispose = purple_conversation_dispose;
+ obj_class->finalize = purple_conversation_finalize;
+ obj_class->constructed = purple_conversation_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_conversation_get_property;
+ obj_class->set_property = purple_conversation_set_property;
+
+ properties[PROP_ACCOUNT] = g_param_spec_object("account", "Account",
+ "The account for the conversation.", PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_NAME] = g_param_spec_string("name", "Name",
+ "The name of the conversation.", NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_TITLE] = g_param_spec_string("title", "Title",
+ "The title of the conversation.", NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_LOGGING] = g_param_spec_boolean("logging", "Logging status",
+ "Whether logging is enabled or not.", FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_FEATURES] = g_param_spec_flags("features",
+ "Connection features",
+ "The connection features of the conversation.",
+ PURPLE_TYPE_CONNECTION_FLAGS, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, PROP_LAST, properties);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleconversation.h Mon Apr 12 20:27:47 2021 -0500
@@ -0,0 +1,525 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_CONVERSATION_H
+#define PURPLE_CONVERSATION_H
+/**
+ * SECTION:purpleconversation
+ * @section_id: libpurple-purpleconversation
+ * @short_description: Conversation base class
+ * @title: Conversation Base Class
+ *
+ * This is the base class for the conversation abstraction on Libpurple.
+ *
+ * The present API manages the common functionallity for both kinds of conversations
+ * @PurpleIMConversation and @PurpleChatConversation.
+ */
+
+#define PURPLE_TYPE_CONVERSATION (purple_conversation_get_type())
+#define PURPLE_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CONVERSATION, PurpleConversation))
+#define PURPLE_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CONVERSATION, PurpleConversationClass))
+#define PURPLE_IS_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CONVERSATION))
+#define PURPLE_IS_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CONVERSATION))
+#define PURPLE_CONVERSATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CONVERSATION, PurpleConversationClass))
+
+/**************************************************************************/
+/* Data Structures */
+/**************************************************************************/
+
+typedef struct _PurpleConversation PurpleConversation;
+typedef struct _PurpleConversationClass PurpleConversationClass;
+
+/**
+ * PurpleConversationUpdateType:
+ * @PURPLE_CONVERSATION_UPDATE_ADD: The buddy associated with the
+ * conversation was added.
+ * @PURPLE_CONVERSATION_UPDATE_REMOVE: The buddy associated with the
+ * conversation was removed.
+ * @PURPLE_CONVERSATION_UPDATE_ACCOUNT: The purple_account was changed.
+ * @PURPLE_CONVERSATION_UPDATE_TYPING: The typing state was updated.
+ * @PURPLE_CONVERSATION_UPDATE_UNSEEN: The unseen state was updated.
+ * @PURPLE_CONVERSATION_UPDATE_LOGGING: Logging for this conversation was
+ * enabled or disabled.
+ * @PURPLE_CONVERSATION_UPDATE_TOPIC: The topic for a chat was updated.
+ * @PURPLE_CONVERSATION_ACCOUNT_ONLINE: One of the user's accounts went online.
+ * @PURPLE_CONVERSATION_ACCOUNT_OFFLINE: One of the user's accounts went
+ * offline.
+ * @PURPLE_CONVERSATION_UPDATE_AWAY: The other user went away.
+ * @PURPLE_CONVERSATION_UPDATE_ICON: The other user's buddy icon changed.
+ * @PURPLE_CONVERSATION_UPDATE_NAME: The name of the conversation was changed.
+ * @PURPLE_CONVERSATION_UPDATE_TITLE: The title of the conversation was updated.
+ * @PURPLE_CONVERSATION_UPDATE_CHATLEFT: The user left a chat.
+ * @PURPLE_CONVERSATION_UPDATE_FEATURES: The features for a chat have changed.
+ *
+ * Conversation update type.
+ */
+typedef enum
+{
+ PURPLE_CONVERSATION_UPDATE_ADD = 0,
+ PURPLE_CONVERSATION_UPDATE_REMOVE,
+ PURPLE_CONVERSATION_UPDATE_ACCOUNT,
+ PURPLE_CONVERSATION_UPDATE_TYPING,
+ PURPLE_CONVERSATION_UPDATE_UNSEEN,
+ PURPLE_CONVERSATION_UPDATE_LOGGING,
+ PURPLE_CONVERSATION_UPDATE_TOPIC,
+
+ /*
+ * XXX These need to go when we implement a more generic core/UI event
+ * system.
+ */
+ PURPLE_CONVERSATION_ACCOUNT_ONLINE,
+ PURPLE_CONVERSATION_ACCOUNT_OFFLINE,
+ PURPLE_CONVERSATION_UPDATE_AWAY,
+ PURPLE_CONVERSATION_UPDATE_ICON,
+ PURPLE_CONVERSATION_UPDATE_NAME,
+ PURPLE_CONVERSATION_UPDATE_TITLE,
+ PURPLE_CONVERSATION_UPDATE_CHATLEFT,
+
+ PURPLE_CONVERSATION_UPDATE_FEATURES
+
+} PurpleConversationUpdateType;
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <purplemessage.h>
+
+/**************************************************************************/
+/* PurpleConversation */
+/**************************************************************************/
+/**
+ * PurpleConversation:
+ *
+ * A core representation of a conversation between two or more people.
+ *
+ * The conversation can be an IM or a chat.
+ *
+ * Note: When a conversation is destroyed with the last g_object_unref(), the
+ * specified conversation is removed from the parent window. If this
+ * conversation is the only one contained in the parent window, that
+ * window is also destroyed.
+ */
+struct _PurpleConversation
+{
+ GObject gparent;
+};
+
+/**
+ * PurpleConversationClass:
+ * @write_message: Writes a message to a chat or IM conversation. See
+ * purple_conversation_write_message().
+ *
+ * Base class for all #PurpleConversation's
+ */
+struct _PurpleConversationClass {
+ GObjectClass parent_class;
+
+ void (*write_message)(PurpleConversation *conv, PurpleMessage *msg);
+
+ /*< private >*/
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+#include <purpleconversationuiops.h>
+#include "account.h"
+#include "buddyicon.h"
+#include "log.h"
+#include "smiley-list.h"
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/* Conversation API */
+/**************************************************************************/
+
+/**
+ * purple_conversation_get_type:
+ *
+ * Returns: The #GType for the Conversation object.
+ */
+GType purple_conversation_get_type(void);
+
+/**
+ * purple_conversation_present:
+ * @conv: The conversation to present
+ *
+ * Present a conversation to the user. This allows core code to initiate a
+ * conversation by displaying the IM dialog.
+ */
+void purple_conversation_present(PurpleConversation *conv);
+
+/**
+ * purple_conversation_set_ui_ops:
+ * @conv: The conversation.
+ * @ops: The UI conversation operations structure.
+ *
+ * Sets the specified conversation's UI operations structure.
+ */
+void purple_conversation_set_ui_ops(PurpleConversation *conv,
+ PurpleConversationUiOps *ops);
+
+/**
+ * purple_conversation_get_ui_ops:
+ * @conv: The conversation.
+ *
+ * Returns the specified conversation's UI operations structure.
+ *
+ * Returns: The operations structure.
+ */
+PurpleConversationUiOps *purple_conversation_get_ui_ops(PurpleConversation *conv);
+
+/**
+ * purple_conversation_set_account:
+ * @conv: The conversation.
+ * @account: The purple_account.
+ *
+ * Sets the specified conversation's purple_account.
+ *
+ * This purple_account represents the user using purple, not the person the user
+ * is having a conversation/chat/flame with.
+ */
+void purple_conversation_set_account(PurpleConversation *conv,
+ PurpleAccount *account);
+
+/**
+ * purple_conversation_get_account:
+ * @conv: The conversation.
+ *
+ * Returns the specified conversation's purple_account.
+ *
+ * This purple_account represents the user using purple, not the person the user
+ * is having a conversation/chat/flame with.
+ *
+ * Returns: (transfer none): The conversation's purple_account.
+ */
+PurpleAccount *purple_conversation_get_account(PurpleConversation *conv);
+
+/**
+ * purple_conversation_get_connection:
+ * @conv: The conversation.
+ *
+ * Returns the specified conversation's purple_connection.
+ *
+ * Returns: (transfer none): The conversation's purple_connection.
+ */
+PurpleConnection *purple_conversation_get_connection(PurpleConversation *conv);
+
+/**
+ * purple_conversation_set_title:
+ * @conv: The conversation.
+ * @title: The title.
+ *
+ * Sets the specified conversation's title.
+ */
+void purple_conversation_set_title(PurpleConversation *conv, const char *title);
+
+/**
+ * purple_conversation_get_title:
+ * @conv: The conversation.
+ *
+ * Returns the specified conversation's title.
+ *
+ * Returns: The title.
+ */
+const char *purple_conversation_get_title(PurpleConversation *conv);
+
+/**
+ * purple_conversation_autoset_title:
+ * @conv: The conversation.
+ *
+ * Automatically sets the specified conversation's title.
+ *
+ * This function takes OPT_IM_ALIAS_TAB into account, as well as the
+ * user's alias.
+ */
+void purple_conversation_autoset_title(PurpleConversation *conv);
+
+/**
+ * purple_conversation_set_name:
+ * @conv: The conversation.
+ * @name: The conversation's name.
+ *
+ * Sets the specified conversation's name.
+ */
+void purple_conversation_set_name(PurpleConversation *conv, const char *name);
+
+/**
+ * purple_conversation_get_name:
+ * @conv: The conversation.
+ *
+ * Returns the specified conversation's name.
+ *
+ * Returns: The conversation's name. If the conversation is an IM with a
+ * PurpleBuddy, then it's the name of the PurpleBuddy.
+ */
+const char *purple_conversation_get_name(PurpleConversation *conv);
+
+/**
+ * purple_conversation_set_logging:
+ * @conv: The conversation.
+ * @log: %TRUE if logging should be enabled, or %FALSE otherwise.
+ *
+ * Enables or disables logging for this conversation.
+ */
+void purple_conversation_set_logging(PurpleConversation *conv, gboolean log);
+
+/**
+ * purple_conversation_is_logging:
+ * @conv: The conversation.
+ *
+ * Returns whether or not logging is enabled for this conversation.
+ *
+ * Returns: %TRUE if logging is enabled, or %FALSE otherwise.
+ */
+gboolean purple_conversation_is_logging(PurpleConversation *conv);
+
+/**
+ * purple_conversation_close_logs:
+ * @conv: The conversation.
+ *
+ * Closes any open logs for this conversation.
+ *
+ * Note that new logs will be opened as necessary (e.g. upon receipt of a
+ * message, if the conversation has logging enabled. To disable logging for
+ * the remainder of the conversation, use purple_conversation_set_logging().
+ */
+void purple_conversation_close_logs(PurpleConversation *conv);
+
+/**
+ * purple_conversation_write_message:
+ * @conv: The conversation.
+ * @msg: The message to write.
+ *
+ * Writes to a chat or an IM.
+ */
+void purple_conversation_write_message(PurpleConversation *conv,
+ PurpleMessage *msg);
+
+/**
+ * purple_conversation_write_system_message:
+ * @conv: The conversation.
+ * @message: The message to write.
+ * @flags: The message flags (you don't need to set %PURPLE_MESSAGE_SYSTEM.
+ *
+ * Wites a system message to a chat or an IM.
+ */
+void purple_conversation_write_system_message(PurpleConversation *conv,
+ const gchar *message, PurpleMessageFlags flags);
+
+/**
+ * purple_conversation_send:
+ * @conv: The conversation.
+ * @message: The message to send.
+ *
+ * Sends a message to this conversation. This function calls
+ * purple_conversation_send_with_flags() with no additional flags.
+ */
+void purple_conversation_send(PurpleConversation *conv, const char *message);
+
+/**
+ * purple_conversation_send_with_flags:
+ * @conv: The conversation.
+ * @message: The message to send.
+ * @flags: The PurpleMessageFlags flags to use in addition to
+ * PURPLE_MESSAGE_SEND.
+ *
+ * Sends a message to this conversation with specified flags.
+ */
+void purple_conversation_send_with_flags(PurpleConversation *conv, const char *message,
+ PurpleMessageFlags flags);
+
+/**
+ * purple_conversation_set_features:
+ * @conv: The conversation
+ * @features: Bitset defining supported features
+ *
+ * Set the features as supported for the given conversation.
+ */
+void purple_conversation_set_features(PurpleConversation *conv,
+ PurpleConnectionFlags features);
+
+
+/**
+ * purple_conversation_get_features:
+ * @conv: The conversation
+ *
+ * Get the features supported by the given conversation.
+ */
+PurpleConnectionFlags purple_conversation_get_features(PurpleConversation *conv);
+
+/**
+ * purple_conversation_has_focus:
+ * @conv: The conversation.
+ *
+ * Determines if a conversation has focus
+ *
+ * Returns: %TRUE if the conversation has focus, %FALSE if
+ * it does not or the UI does not have a concept of conversation focus
+ */
+gboolean purple_conversation_has_focus(PurpleConversation *conv);
+
+/**
+ * purple_conversation_update:
+ * @conv: The conversation.
+ * @type: The update type.
+ *
+ * Updates the visual status and UI of a conversation.
+ */
+void purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdateType type);
+
+/**
+ * purple_conversation_get_message_history:
+ * @conv: The conversation
+ *
+ * Retrieve the message history of a conversation.
+ *
+ * Returns: (element-type PurpleMessage) (transfer none):
+ * A GList of PurpleMessage's. You must not modify the
+ * list or the data within. The list contains the newest message at
+ * the beginning, and the oldest message at the end.
+ */
+GList *purple_conversation_get_message_history(PurpleConversation *conv);
+
+/**
+ * purple_conversation_clear_message_history:
+ * @conv: The conversation
+ *
+ * Clear the message history of a conversation.
+ */
+void purple_conversation_clear_message_history(PurpleConversation *conv);
+
+/**
+ * purple_conversation_send_confirm:
+ * @conv: The conversation.
+ * @message: The message to send.
+ *
+ * Sends a message to a conversation after confirming with
+ * the user.
+ *
+ * This function is intended for use in cases where the user
+ * hasn't explicitly and knowingly caused a message to be sent.
+ * The confirmation ensures that the user isn't sending a
+ * message by mistake.
+ */
+void purple_conversation_send_confirm(PurpleConversation *conv, const char *message);
+
+/**
+ * purple_conversation_get_extended_menu:
+ * @conv: The conversation.
+ *
+ * Retrieves the extended menu items for the conversation.
+ *
+ * Returns: (element-type PurpleActionMenu) (transfer full): The extended menu
+ * items for a conversation, as harvested by the chat-extended-menu
+ * signal.
+ */
+GList * purple_conversation_get_extended_menu(PurpleConversation *conv);
+
+/**
+ * purple_conversation_do_command:
+ * @conv: The conversation.
+ * @cmdline: The entire command including the arguments.
+ * @markup: %NULL, or the formatted command line.
+ * @error: If the command failed errormsg is filled in with the appropriate error
+ * message, if not %NULL. It must be freed by the caller with g_free().
+ *
+ * Perform a command in a conversation. Similar to purple_cmd_do_command().
+ *
+ * Returns: %TRUE if the command was executed successfully, %FALSE otherwise.
+ */
+gboolean purple_conversation_do_command(PurpleConversation *conv,
+ const gchar *cmdline, const gchar *markup, gchar **error);
+
+/**
+ * purple_conversation_get_max_message_size:
+ * @conv: The conversation to query.
+ *
+ * Gets the maximum message size in bytes for the conversation.
+ *
+ * See #PurpleProtocolClientInterface's <literal>get_max_message_size</literal>.
+ *
+ * Returns: Maximum message size, 0 if unspecified, -1 for infinite.
+ */
+gssize
+purple_conversation_get_max_message_size(PurpleConversation *conv);
+
+/**
+ * purple_conversation_add_smiley:
+ * @conv: The conversation that receives new smiley.
+ * @smiley: The smiley.
+ *
+ * Adds a smiley to the list of smileys that belong to this conversation.
+ */
+void purple_conversation_add_smiley(PurpleConversation *conv, PurpleSmiley *smiley);
+
+/**
+ * purple_conversation_get_smiley:
+ * @conv: The conversation.
+ * @shortcut: The shortcut.
+ *
+ * Lookups for the smiley previously added to this conversation.
+ *
+ * Returns: (transfer none): The smiley, or %NULL if it doesn't exists.
+ */
+PurpleSmiley *purple_conversation_get_smiley(PurpleConversation *conv, const gchar *shortcut);
+
+/**
+ * purple_conversation_get_remote_smileys:
+ * @conv: The conversation.
+ *
+ * Get all remote smileys previously added to this conversation.
+ *
+ * Returns: (transfer none): The list of remote smileys.
+ */
+PurpleSmileyList *
+purple_conversation_get_remote_smileys(PurpleConversation *conv);
+
+/**************************************************************************/
+/* Conversation Helper API */
+/**************************************************************************/
+
+/**
+ * purple_conversation_present_error:
+ * @who: The user this error is about
+ * @account: The account this error is on
+ * @what: The error
+ *
+ * Presents an IM-error to the user
+ *
+ * This is a helper function to find a conversation, write an error to it, and
+ * raise the window. If a conversation with this user doesn't already exist,
+ * the function will return FALSE and the calling function can attempt to present
+ * the error another way (purple_notify_error, most likely)
+ *
+ * Returns: TRUE if the error was presented, else FALSE
+ */
+gboolean purple_conversation_present_error(const char *who, PurpleAccount *account, const char *what);
+
+G_END_DECLS
+
+#endif /* PURPLE_CONVERSATION_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleconversationuiops.c Mon Apr 12 20:27:47 2021 -0500
@@ -0,0 +1,58 @@
+/*
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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>
+
+#include <purpleconversationuiops.h>
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static PurpleConversationUiOps *
+purple_conversation_ui_ops_copy(PurpleConversationUiOps *ops)
+{
+ PurpleConversationUiOps *ops_new;
+
+ g_return_val_if_fail(ops != NULL, NULL);
+
+ ops_new = g_new(PurpleConversationUiOps, 1);
+ *ops_new = *ops;
+
+ return ops_new;
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+GType
+purple_conversation_ui_ops_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleConversationUiOps",
+ (GBoxedCopyFunc)purple_conversation_ui_ops_copy,
+ (GBoxedFreeFunc)g_free);
+ }
+
+ return type;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleconversationuiops.h Mon Apr 12 20:27:47 2021 -0500
@@ -0,0 +1,145 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_CONVERSATION_UI_OPS_H
+#define PURPLE_CONVERSATION_UI_OPS_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+/**
+ * SECTION:purpleconversationuiops
+ * @section_id: libpurple-purpleconversationuiops
+ * @short_description: Ui Operations for Conversations
+ * @title: Ui Operations for Conversations
+ *
+ * libpurple needs to tell the user interface when certain things happen in a
+ * conversation and it uses this structure to do so.
+ */
+
+/**
+ * PURPLE_TYPE_CONVERSATION_UI_OPS:
+ *
+ * The standard _get_type macro for #PurpleConversationUiOps.
+ */
+#define PURPLE_TYPE_CONVERSATION_UI_OPS (purple_conversation_ui_ops_get_type())
+typedef struct _PurpleConversationUiOps PurpleConversationUiOps;
+
+#include <purpleconversation.h>
+#include <purplechatconversation.h>
+#include <purpleimconversation.h>
+#include <purplemessage.h>
+
+/**
+ * PurpleConversationUiOps:
+ * @create_conversation: Called when @conv is created (but before the
+ * <link linkend="conversations-conversation-created"><literal>"conversation-created"</literal></link>
+ * signal is emitted).
+ * @destroy_conversation: Called just before @conv is freed.
+ * @write_chat: Write a message to a chat. If this field is %NULL, libpurple
+ * will fall back to using @write_conv.
+ * See purple_conversation_write_message().
+ * @write_im: Write a message to an IM conversation. If this field is %NULL,
+ * libpurple will fall back to using @write_conv.
+ * See purple_conversation_write_message().
+ * @write_conv: Write a message to a conversation. This is used rather than the
+ * chat- or im-specific ops for errors, system messages (such as "x
+ * is now know as y"), and as the fallback if @write_im and
+ * @write_chat are not implemented. It should be implemented, or
+ * the UI will miss conversation error messages and your users will
+ * hate you. See purple_conversation_write_message().
+ * @chat_add_users: Add @cbuddies to a chat.
+ * <sbr/>@cbuddies: A GList of #PurpleChatUser structs.
+ * <sbr/>@new_arrivals: Whether join notices should be shown.
+ * (Join notices are actually written to
+ * the conversation by
+ * purple_chat_conversation_add_users())
+ * @chat_rename_user: Rename the user in this chat named @old_name to @new_name.
+ * (The rename message is written to the conversation by
+ * libpurple.) See purple_chat_conversation_rename_user().
+ * <sbr/>@new_alias: @new_name's new alias, if they have one.
+ * @chat_remove_users: Remove @users from a chat @chat.
+ * See purple_chat_conversation_remove_users().
+ * @chat_update_user: Called when a user's flags are changed.
+ * See purple_chat_user_set_flags().
+ * @present: Present this conversation to the user; for example, by displaying
+ * the IM dialog.
+ * @has_focus: If this UI has a concept of focus (as in a windowing system) and
+ * this conversation has the focus, return %TRUE; otherwise, return
+ * %FALSE.
+ * @send_confirm: Prompt the user for confirmation to send @message. This
+ * function should arrange for the message to be sent if the user
+ * accepts. If this field is %NULL, libpurple will fall back to
+ * using purple_request_action().
+ *
+ * Conversation operations and events.
+ *
+ * Any UI representing a conversation must assign a filled-out
+ * #PurpleConversationUiOps structure to the #PurpleConversation.
+ */
+struct _PurpleConversationUiOps
+{
+ void (*create_conversation)(PurpleConversation *conv);
+ void (*destroy_conversation)(PurpleConversation *conv);
+
+ void (*write_chat)(PurpleChatConversation *chat, PurpleMessage *msg);
+ void (*write_im)(PurpleIMConversation *im, PurpleMessage *msg);
+ void (*write_conv)(PurpleConversation *conv, PurpleMessage *msg);
+
+ void (*chat_add_users)(PurpleChatConversation *chat,
+ GList *cbuddies,
+ gboolean new_arrivals);
+
+ void (*chat_rename_user)(PurpleChatConversation *chat, const char *old_name,
+ const char *new_name, const char *new_alias);
+
+ void (*chat_remove_users)(PurpleChatConversation *chat, GList *users);
+
+ void (*chat_update_user)(PurpleChatUser *cb);
+
+ void (*present)(PurpleConversation *conv);
+ gboolean (*has_focus)(PurpleConversation *conv);
+
+ void (*send_confirm)(PurpleConversation *conv, const char *message);
+
+ /*< private >*/
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**
+ * purple_conversation_ui_ops_get_type:
+ *
+ * Returns: The #GType for the #PurpleConversationUiOps boxed structure.
+ */
+GType purple_conversation_ui_ops_get_type(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_CONVERSATION_UI_OPS_H */
--- a/libpurple/purpleimconversation.h Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/purpleimconversation.h Mon Apr 12 20:27:47 2021 -0500
@@ -61,7 +61,8 @@
typedef struct _PurpleIMConversation PurpleIMConversation;
typedef struct _PurpleIMConversationClass PurpleIMConversationClass;
-#include <conversation.h>
+#include "buddyicon.h"
+#include <purpleconversation.h>
/**
* PurpleIMConversation:
--- a/libpurple/request.h Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/request.h Mon Apr 12 20:27:47 2021 -0500
@@ -41,7 +41,7 @@
#include <glib.h>
#include <glib-object.h>
-#include "conversation.h"
+#include "purpleconversation.h"
#include "request-datasheet.h"
#define PURPLE_TYPE_REQUEST_UI_OPS (purple_request_ui_ops_get_type())
--- a/libpurple/server.c Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/server.c Mon Apr 12 20:27:47 2021 -0500
@@ -27,12 +27,12 @@
#include "internal.h"
#include "buddylist.h"
-#include "conversation.h"
#include "debug.h"
#include "log.h"
#include "notify.h"
#include "prefs.h"
#include "protocol.h"
+#include "purpleconversation.h"
#include "purpleprivate.h"
#include "purpleprotocolattention.h"
#include "purpleprotocolchat.h"
--- a/libpurple/smiley-parser.h Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/smiley-parser.h Mon Apr 12 20:27:47 2021 -0500
@@ -41,7 +41,7 @@
#include <glib.h>
-#include "conversation.h"
+#include <purpleconversation.h>
#include "smiley.h"
#include "smiley-list.h"
--- a/libpurple/util.c Tue Apr 06 03:35:20 2021 -0500
+++ b/libpurple/util.c Mon Apr 12 20:27:47 2021 -0500
@@ -22,12 +22,12 @@
#include "internal.h"
#include "purpleprivate.h"
-#include "conversation.h"
#include "core.h"
#include "debug.h"
#include "notify.h"
#include "protocol.h"
#include "prefs.h"
+#include "purpleconversation.h"
#include "purpleprotocolclient.h"
#include "util.h"
--- a/po/POTFILES.in Tue Apr 06 03:35:20 2021 -0500
+++ b/po/POTFILES.in Mon Apr 12 20:27:47 2021 -0500
@@ -35,7 +35,6 @@
libpurple/cmds.c
libpurple/connection.c
libpurple/contact.c
-libpurple/conversation.c
libpurple/conversations.c
libpurple/core.c
libpurple/countingnode.c
@@ -245,6 +244,7 @@
libpurple/purplebuddypresence.c
libpurple/purplechatconversation.c
libpurple/purplechatuser.c
+libpurple/purpleconversation.c
libpurple/purplecredentialmanager.c
libpurple/purplecredentialprovider.c
libpurple/purple-gio.c