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 "conversation.h"
+#include "purpleconversation.h" #include "purpleprivate.h"
#include "purpleprotocolserver.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 "conversation.h"
@@ -33,6 +32,7 @@
#include "purpleprivate.h"
#include "purpleprotocolchat.h"
#include "purpleprotocolclient.h"
+#include "purpleconversation.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> /******************************************************************************
--- 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 is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * 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 "conversation.h"
-#include "purplemarkup.h"
-#include "purpleprivate.h"
-#include "purpleprotocolclient.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 */
-static GParamSpec *properties[PROP_LAST];
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleConversation, purple_conversation,
-common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags msgflags)
- PurpleAccount *account;
- PurpleConversationPrivate *priv =
- purple_conversation_get_instance_private(conv);
- char *displayed = NULL;
- 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);
- displayed = purple_markup_linkify(message);
- if (displayed && (priv->features & PURPLE_CONNECTION_FLAG_HTML) &&
- !(msgflags & PURPLE_MESSAGE_RAW)) {
- 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",
- 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)) {
- 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));
- who = purple_conversation_get_name(conv);
- 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));
- else if (err == -ENOTCONN) {
- purple_debug_error("conversation", "Not yet connected.");
- 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));
-/**************************************************************************
- **************************************************************************/
-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)
-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);
-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);
-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);
-purple_conversation_ui_ops_get_type(void)
- type = g_boxed_type_register_static("PurpleConversationUiOps",
- (GBoxedCopyFunc)purple_conversation_ui_ops_copy,
- (GBoxedFreeFunc)g_free);
-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)
- if (priv->ui_ops != NULL && priv->ui_ops->destroy_conversation != NULL)
- priv->ui_ops->destroy_conversation(conv);
-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);
-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))
- _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);
-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);
-purple_conversation_get_connection(PurpleConversation *conv)
- PurpleAccount *account;
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
- account = purple_conversation_get_account(conv);
- return purple_account_get_connection(account);
-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);
- 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);
-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);
-purple_conversation_autoset_title(PurpleConversation *conv)
- PurpleAccount *account;
- 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);
- purple_conversation_set_title(conv, text);
-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);
- 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);
-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);
-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)
- if (log && priv->logs == NULL) {
- dt = g_date_time_new_now_local();
- log = purple_log_new(PURPLE_IS_CHAT_CONVERSATION(conv)
- priv->name, priv->account, conv,
- 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);
-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);
-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);
-_purple_conversation_write_common(PurpleConversation *conv, PurpleMessage *pmsg)
- PurpleConversationPrivate *priv = NULL;
- PurpleProtocol *protocol = NULL;
- PurpleConnection *gc = NULL;
- PurpleAccount *account;
- PurpleConversationUiOps *ops;
- /* 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);
- gc = purple_account_get_connection(account);
- if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
- (gc != NULL && !g_slist_find(purple_connection_get_active_chats(gc), conv)))
- if (PURPLE_IS_IM_CONVERSATION(conv) &&
- !g_list_find(purple_conversations_get_all(), conv))
- 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"),
- if (purple_message_is_empty(pmsg))
- 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) {
- 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);
- 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));
- 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)) {
- dt = g_date_time_ref(purple_message_get_timestamp(pmsg));
- purple_log_write((PurpleLog *)log->data,
- purple_message_get_flags(pmsg),
- purple_message_get_author_alias(pmsg),
- purple_message_get_contents(pmsg));
- 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);
- 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"),
-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));
-purple_conversation_send(PurpleConversation *conv, const char *message)
- purple_conversation_send_with_flags(conv, message, 0);
-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);
-purple_conversation_has_focus(PurpleConversation *conv)
- 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);
- * 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.
-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);
- purple_conversation_write_system_message(conv, what, PURPLE_MESSAGE_ERROR);
-purple_conversation_send_confirm_cb(gpointer *data)
- PurpleConversation *conv = data[0];
- char *message = data[1];
- if (!PURPLE_IS_CONVERSATION(conv)) {
- /* Maybe it was closed before this callback was called. */
- common_send(conv, message, 0);
-purple_conversation_send_confirm(PurpleConversation *conv, const char *message)
- PurpleConversationPrivate *priv = NULL;
- 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);
- text = g_strdup_printf("You are about to send the following message:\n%s", message);
- data = g_new0(gpointer, 2);
- 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);
-purple_conversation_get_extended_menu(PurpleConversation *conv)
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL);
- purple_signal_emit(purple_conversations_get_handle(),
- "conversation-extended-menu", conv, &menu);
-void purple_conversation_clear_message_history(PurpleConversation *conv)
- PurpleConversationPrivate *priv = NULL;
- 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;
-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);
- return (status == PURPLE_CMD_STATUS_OK);
-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);
-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(
- purple_smiley_get_shortcut(smiley)))
- /* smiley was already added */
- if (!purple_smiley_list_add(priv->remote_smileys, smiley)) {
- purple_debug_error("conversation", "failed adding remote "
-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 purple_smiley_list_get_by_shortcut(priv->remote_smileys, shortcut);
-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;
-/**************************************************************************
- **************************************************************************/
-/* Set method for GObject properties */
-purple_conversation_set_property(GObject *obj, guint param_id, const GValue *value,
- PurpleConversation *conv = PURPLE_CONVERSATION(obj);
- PurpleConversationPrivate *priv =
- purple_conversation_get_instance_private(conv);
- priv->account = g_value_get_object(value);
- priv->name = g_value_dup_string(value);
- priv->title = g_value_dup_string(value);
- purple_conversation_set_logging(conv, g_value_get_boolean(value));
- purple_conversation_set_features(conv, g_value_get_flags(value));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-/* Get method for GObject properties */
-purple_conversation_get_property(GObject *obj, guint param_id, GValue *value,
- PurpleConversation *conv = PURPLE_CONVERSATION(obj);
- g_value_set_object(value, purple_conversation_get_account(conv));
- g_value_set_string(value, purple_conversation_get_name(conv));
- g_value_set_string(value, purple_conversation_get_title(conv));
- g_value_set_boolean(value, purple_conversation_is_logging(conv));
- g_value_set_flags(value, purple_conversation_get_features(conv));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-purple_conversation_init(PurpleConversation *conv)
-/* Called when done constructing */
-purple_conversation_constructed(GObject *object)
- PurpleConversation *conv = PURPLE_CONVERSATION(object);
- PurpleAccount *account;
- 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.
- 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);
-purple_conversation_dispose(GObject *object)
- g_object_set_data(object, "is-finalizing", GINT_TO_POINTER(TRUE));
-/* GObject finalize function */
-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_OBJECT_CLASS(purple_conversation_parent_class)->finalize(object);
-/* Class initializer function */
-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;
- 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",
- "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 is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * 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"
-#ifndef PURPLE_CONVERSATION_H
-#define PURPLE_CONVERSATION_H
- * @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())
-/**************************************************************************/
-/**************************************************************************/
-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
- * @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
- * @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.
- 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
- 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-object.h>
-#include "purplemessage.h"
-/**************************************************************************/
-/* 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
- * 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);
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
-#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>
- * @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
- * 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
- * @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
- * @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,
- 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);
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
-/**************************************************************************/
-/**************************************************************************/
- * 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.
- * 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.
-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
-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,
- * 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
- * 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
- * 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
-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
-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.
-purple_conversation_get_max_message_size(PurpleConversation *conv);
- * purple_conversation_add_smiley:
- * @conv: The conversation that receives new 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.
-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
- * 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);
-#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 "conversation.h"
@@ -36,6 +35,7 @@
+#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 @@
@@ -50,6 +49,8 @@
'purplechatconversation.c',
+ 'purpleconversation.c', + 'purpleconversationuiops.c', 'purplecredentialmanager.c',
'purplecredentialprovider.c',
'purpleimconversation.c',
@@ -109,7 +110,6 @@
@@ -141,6 +141,8 @@
'purplechatconversation.h',
+ 'purpleconversation.h', + 'purpleconversationuiops.h', 'purplecredentialmanager.h',
'purplecredentialprovider.h',
'purpleimconversation.h',
@@ -224,7 +226,6 @@
@@ -232,6 +233,7 @@
+ 'purpleconversation.h', 'purpleimconversation.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 "conversation.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"
--- /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 is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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 "purpleconversation.h" +#include "purplemarkup.h" +#include "purpleprivate.h" +#include "purpleprotocolclient.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 */ +static GParamSpec *properties[PROP_LAST]; +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleConversation, purple_conversation, +common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags msgflags) + PurpleAccount *account; + PurpleConversationPrivate *priv = + purple_conversation_get_instance_private(conv); + char *displayed = NULL; + 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); + displayed = purple_markup_linkify(message); + if (displayed && (priv->features & PURPLE_CONNECTION_FLAG_HTML) && + !(msgflags & PURPLE_MESSAGE_RAW)) { + 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", + 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)) { + 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)); + who = purple_conversation_get_name(conv); + 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)); + else if (err == -ENOTCONN) { + purple_debug_error("conversation", "Not yet connected."); + 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)); +/************************************************************************** + **************************************************************************/ +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) +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); +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); +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) + if (priv->ui_ops != NULL && priv->ui_ops->destroy_conversation != NULL) + priv->ui_ops->destroy_conversation(conv); +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); +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)) + _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); +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); +purple_conversation_get_connection(PurpleConversation *conv) + PurpleAccount *account; + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL); + account = purple_conversation_get_account(conv); + return purple_account_get_connection(account); +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); + 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); +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); +purple_conversation_autoset_title(PurpleConversation *conv) + PurpleAccount *account; + 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); + purple_conversation_set_title(conv, text); +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); + 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); +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); +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) + if (log && priv->logs == NULL) { + dt = g_date_time_new_now_local(); + log = purple_log_new(PURPLE_IS_CHAT_CONVERSATION(conv) + priv->name, priv->account, conv, + 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); +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); +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); +_purple_conversation_write_common(PurpleConversation *conv, PurpleMessage *pmsg) + PurpleConversationPrivate *priv = NULL; + PurpleProtocol *protocol = NULL; + PurpleConnection *gc = NULL; + PurpleAccount *account; + PurpleConversationUiOps *ops; + /* 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); + gc = purple_account_get_connection(account); + if (PURPLE_IS_CHAT_CONVERSATION(conv) && + (gc != NULL && !g_slist_find(purple_connection_get_active_chats(gc), conv))) + if (PURPLE_IS_IM_CONVERSATION(conv) && + !g_list_find(purple_conversations_get_all(), conv)) + 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"), + if (purple_message_is_empty(pmsg)) + 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) { + 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); + 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)); + 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)) { + dt = g_date_time_ref(purple_message_get_timestamp(pmsg)); + purple_log_write((PurpleLog *)log->data, + purple_message_get_flags(pmsg), + purple_message_get_author_alias(pmsg), + purple_message_get_contents(pmsg)); + 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); + 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"), +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)); +purple_conversation_send(PurpleConversation *conv, const char *message) + purple_conversation_send_with_flags(conv, message, 0); +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); +purple_conversation_has_focus(PurpleConversation *conv) + 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); + * 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. +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); + purple_conversation_write_system_message(conv, what, PURPLE_MESSAGE_ERROR); +purple_conversation_send_confirm_cb(gpointer *data) + PurpleConversation *conv = data[0]; + char *message = data[1]; + if (!PURPLE_IS_CONVERSATION(conv)) { + /* Maybe it was closed before this callback was called. */ + common_send(conv, message, 0); +purple_conversation_send_confirm(PurpleConversation *conv, const char *message) + PurpleConversationPrivate *priv = NULL; + 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); + text = g_strdup_printf("You are about to send the following message:\n%s", message); + data = g_new0(gpointer, 2); + 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); +purple_conversation_get_extended_menu(PurpleConversation *conv) + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL); + purple_signal_emit(purple_conversations_get_handle(), + "conversation-extended-menu", conv, &menu); +void purple_conversation_clear_message_history(PurpleConversation *conv) + PurpleConversationPrivate *priv = NULL; + 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; +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); + return (status == PURPLE_CMD_STATUS_OK); +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); +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( + purple_smiley_get_shortcut(smiley))) + /* smiley was already added */ + if (!purple_smiley_list_add(priv->remote_smileys, smiley)) { + purple_debug_error("conversation", "failed adding remote " +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 purple_smiley_list_get_by_shortcut(priv->remote_smileys, shortcut); +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; +/************************************************************************** + **************************************************************************/ +/* Set method for GObject properties */ +purple_conversation_set_property(GObject *obj, guint param_id, const GValue *value, + PurpleConversation *conv = PURPLE_CONVERSATION(obj); + PurpleConversationPrivate *priv = + purple_conversation_get_instance_private(conv); + priv->account = g_value_get_object(value); + priv->name = g_value_dup_string(value); + priv->title = g_value_dup_string(value); + purple_conversation_set_logging(conv, g_value_get_boolean(value)); + purple_conversation_set_features(conv, g_value_get_flags(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +/* Get method for GObject properties */ +purple_conversation_get_property(GObject *obj, guint param_id, GValue *value, + PurpleConversation *conv = PURPLE_CONVERSATION(obj); + g_value_set_object(value, purple_conversation_get_account(conv)); + g_value_set_string(value, purple_conversation_get_name(conv)); + g_value_set_string(value, purple_conversation_get_title(conv)); + g_value_set_boolean(value, purple_conversation_is_logging(conv)); + g_value_set_flags(value, purple_conversation_get_features(conv)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_conversation_init(PurpleConversation *conv) +/* Called when done constructing */ +purple_conversation_constructed(GObject *object) + PurpleConversation *conv = PURPLE_CONVERSATION(object); + PurpleAccount *account; + 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. + 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); +purple_conversation_dispose(GObject *object) + g_object_set_data(object, "is-finalizing", GINT_TO_POINTER(TRUE)); +/* GObject finalize function */ +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_OBJECT_CLASS(purple_conversation_parent_class)->finalize(object); +/* Class initializer function */ +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; + 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", + "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 is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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" +#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)) +/**************************************************************************/ +/**************************************************************************/ +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 + * @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 + * @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. + 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 + 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-object.h> +#include <purplemessage.h> +/**************************************************************************/ +/* 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 + * 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); + void (*_purple_reserved1)(void); + void (*_purple_reserved2)(void); + void (*_purple_reserved3)(void); + void (*_purple_reserved4)(void); +#include <purpleconversationuiops.h> +#include "smiley-list.h" +/**************************************************************************/ +/**************************************************************************/ + * 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. + * 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. +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 +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, + * 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 + * 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 + * 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 +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 +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. +purple_conversation_get_max_message_size(PurpleConversation *conv); + * purple_conversation_add_smiley: + * @conv: The conversation that receives new 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. +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 + * 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); +#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 is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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> +/****************************************************************************** + *****************************************************************************/ +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); +/****************************************************************************** + *****************************************************************************/ +purple_conversation_ui_ops_get_type(void) + type = g_boxed_type_register_static("PurpleConversationUiOps", + (GBoxedCopyFunc)purple_conversation_ui_ops_copy, + (GBoxedFreeFunc)g_free); --- /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 is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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" +#ifndef PURPLE_CONVERSATION_UI_OPS_H +#define PURPLE_CONVERSATION_UI_OPS_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> + * @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 + * 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 + * @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 + * @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, + 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); + void (*_purple_reserved1)(void); + void (*_purple_reserved2)(void); + void (*_purple_reserved3)(void); + void (*_purple_reserved4)(void); + * purple_conversation_ui_ops_get_type: + * Returns: The #GType for the #PurpleConversationUiOps boxed structure. +GType purple_conversation_ui_ops_get_type(void); +#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 <purpleconversation.h> --- 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 "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 "conversation.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 "conversation.h"
+#include <purpleconversation.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 "purpleprivate.h"
-#include "conversation.h"
+#include "purpleconversation.h" #include "purpleprotocolclient.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/conversation.c
libpurple/conversations.c
@@ -245,6 +244,7 @@
libpurple/purplebuddypresence.c
libpurple/purplechatconversation.c
libpurple/purplechatuser.c
+libpurple/purpleconversation.c libpurple/purplecredentialmanager.c
libpurple/purplecredentialprovider.c