Split PurpleProtocolChat to its own file and clean up the API.
Testing Done:
* Compiled and tested bonjour (not affected) and irc locally.
* Built and verified the docs.
* verified `ninja pidgin-pot` was successful.
Bugs closed: 17457
Reviewed at https://reviews.imfreedom.org/r/406/
--- a/doc/reference/libpurple/libpurple-docs.xml Mon Jan 11 01:08:47 2021 -0600
+++ b/doc/reference/libpurple/libpurple-docs.xml Mon Jan 11 01:51:14 2021 -0600
@@ -74,6 +74,7 @@
<xi:include href="xml/purplemarkup.xml" />
<xi:include href="xml/purplepresence.xml" />
<xi:include href="xml/purpleprotocolattention.xml" />
+ <xi:include href="xml/purpleprotocolchat.xml" /> <xi:include href="xml/purpleprotocolclient.xml" />
<xi:include href="xml/purpleprotocolfactory.xml" />
<xi:include href="xml/purpleprotocolim.xml" />
--- a/finch/gntblist.c Mon Jan 11 01:08:47 2021 -0600
+++ b/finch/gntblist.c Mon Jan 11 01:51:14 2021 -0600
@@ -644,7 +644,7 @@
gc = purple_account_get_connection(account);
protocol = purple_connection_get_protocol(gc);
- hash = purple_protocol_chat_iface_info_defaults(protocol, gc, name);
+ hash = purple_protocol_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), gc, name); chat = purple_chat_new(account, name, hash);
@@ -985,13 +985,15 @@
PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
PurpleRequestField *field;
+ PurpleProtocol *protocol; PurpleProtocolChatEntry *pce;
purple_request_fields_add_group(fields, group);
gc = purple_account_get_connection(purple_chat_get_account(chat));
- parts = purple_protocol_chat_iface_info(purple_connection_get_protocol(gc), gc);
+ protocol = purple_connection_get_protocol(gc); + parts = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol), gc); for (iter = parts; iter; iter = iter->next) {
@@ -1275,7 +1277,7 @@
account = purple_chat_get_account(c);
protocol = purple_protocols_find(purple_account_get_protocol_id(account));
- name = purple_protocol_chat_iface_get_name(protocol, purple_chat_get_components(c));
+ name = purple_protocol_chat_get_name(PURPLE_PROTOCOL_CHAT(protocol), purple_chat_get_components(c)); } else if (PURPLE_IS_CONTACT(node)) {
finch_log_show_contact((PurpleContact *)node);
@@ -2669,7 +2671,7 @@
chat = purple_blist_find_chat(account, name);
PurpleProtocol *protocol = purple_connection_get_protocol(gc);
- hash = purple_protocol_chat_iface_info_defaults(protocol, gc, name);
+ hash = purple_protocol_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), gc, name); hash = purple_chat_get_components(chat);
--- a/finch/gntconv.c Mon Jan 11 01:08:47 2021 -0600
+++ b/finch/gntconv.c Mon Jan 11 01:51:14 2021 -0600
@@ -306,7 +306,7 @@
chat = find_chat_for_conversation(conv);
PurpleProtocol *protocol = purple_connection_get_protocol(gc);
- comps = purple_protocol_chat_iface_info_defaults(protocol, gc,
+ comps = purple_protocol_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_conversation_get_name(conv));
comps = purple_chat_get_components(chat);
@@ -658,7 +658,7 @@
protocol = purple_connection_get_protocol(gc);
- realname = purple_protocol_chat_iface_get_user_real_name(protocol, gc,
+ realname = purple_protocol_chat_get_user_real_name(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_chat_conversation_get_id(
PURPLE_CHAT_CONVERSATION(fc->active_conv)), name);
--- a/libpurple/buddylist.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/buddylist.c Mon Jan 11 01:51:14 2021 -0600
@@ -31,6 +31,7 @@
#include "purpleprivate.h"
+#include "purpleprotocolchat.h" #include "purpleprotocolclient.h"
@@ -1779,7 +1780,7 @@
if (account != purple_chat_get_account(chat))
- parts = purple_protocol_chat_iface_info(protocol,
+ parts = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol), purple_account_get_connection(purple_chat_get_account(chat)));
--- a/libpurple/chat.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/chat.c Mon Jan 11 01:51:14 2021 -0600
@@ -22,6 +22,7 @@
+#include "purpleprotocolchat.h" typedef struct _PurpleChatPrivate PurpleChatPrivate;
@@ -86,7 +87,8 @@
if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info)) {
PurpleProtocolChatEntry *pce;
- GList *parts = purple_protocol_chat_iface_info(protocol, purple_account_get_connection(priv->account));
+ GList *parts = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol), + purple_account_get_connection(priv->account)); ret = g_hash_table_lookup(priv->components, pce->identifier);
g_list_free_full(parts, g_free);
--- a/libpurple/meson.build Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/meson.build Mon Jan 11 01:51:14 2021 -0600
@@ -59,6 +59,7 @@
'purpleprotocolattention.c',
+ 'purpleprotocolchat.c', 'purpleprotocolclient.c',
'purpleprotocolfactory.c',
@@ -147,6 +148,7 @@
'purpleprotocolattention.h',
+ 'purpleprotocolchat.h', 'purpleprotocolclient.h',
'purpleprotocolfactory.h',
--- a/libpurple/protocol.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocol.c Mon Jan 11 01:51:14 2021 -0600
@@ -402,110 +402,3 @@
#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
#undef DEFINE_PROTOCOL_FUNC
-/**************************************************************************
- * Protocol Chat Interface API
- **************************************************************************/
-#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
- PurpleProtocolChatInterface *chat_iface = \
- PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol); \
- if (chat_iface && chat_iface->funcname) \
- chat_iface->funcname(__VA_ARGS__);
-#define DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol,defaultreturn,funcname,...) \
- PurpleProtocolChatInterface *chat_iface = \
- PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol); \
- if (chat_iface && chat_iface->funcname) \
- return chat_iface->funcname(__VA_ARGS__); \
-purple_protocol_chat_iface_get_type(void)
- if (G_UNLIKELY(type == 0)) {
- static const GTypeInfo info = {
- .class_size = sizeof(PurpleProtocolChatInterface),
- type = g_type_register_static(G_TYPE_INTERFACE,
- "PurpleProtocolChatInterface", &info, 0);
-purple_protocol_chat_iface_info(PurpleProtocol *protocol, PurpleConnection *gc)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, info, gc);
-purple_protocol_chat_iface_info_defaults(PurpleProtocol *protocol,
- PurpleConnection *gc, const char *chat_name)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, info_defaults, gc,
-purple_protocol_chat_iface_join(PurpleProtocol *protocol, PurpleConnection *gc,
- GHashTable *components)
- DEFINE_PROTOCOL_FUNC(protocol, join, gc, components);
-purple_protocol_chat_iface_reject(PurpleProtocol *protocol,
- PurpleConnection *gc, GHashTable *components)
- DEFINE_PROTOCOL_FUNC(protocol, reject, gc, components);
-purple_protocol_chat_iface_get_name(PurpleProtocol *protocol,
- GHashTable *components)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, get_name, components);
-purple_protocol_chat_iface_invite(PurpleProtocol *protocol,
- PurpleConnection *gc, int id, const char *message, const char *who)
- DEFINE_PROTOCOL_FUNC(protocol, invite, gc, id, message, who);
-purple_protocol_chat_iface_leave(PurpleProtocol *protocol, PurpleConnection *gc,
- DEFINE_PROTOCOL_FUNC(protocol, leave, gc, id);
-purple_protocol_chat_iface_send(PurpleProtocol *protocol, PurpleConnection *gc,
- int id, PurpleMessage *msg)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, 0, send, gc, id, msg);
-purple_protocol_chat_iface_get_user_real_name(PurpleProtocol *protocol,
- PurpleConnection *gc, int id, const char *who)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, get_user_real_name, gc, id,
-purple_protocol_chat_iface_set_topic(PurpleProtocol *protocol,
- PurpleConnection *gc, int id, const char *topic)
- DEFINE_PROTOCOL_FUNC(protocol, set_topic, gc, id, topic);
-#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
-#undef DEFINE_PROTOCOL_FUNC
--- a/libpurple/protocol.h Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocol.h Mon Jan 11 01:51:14 2021 -0600
@@ -276,105 +276,6 @@
#define PURPLE_PROTOCOL_SERVER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_SERVER, \
PurpleProtocolServerInterface))
-#define PURPLE_TYPE_PROTOCOL_CHAT (purple_protocol_chat_iface_get_type())
-typedef struct _PurpleProtocolChatInterface PurpleProtocolChatInterface;
- * PurpleProtocolChatInterface:
- * @info: Returns a list of #PurpleProtocolChatEntry structs, which represent
- * information required by the protocol to join a chat. libpurple will
- * call join_chat along with the information filled by the user.
- * <sbr/>Returns: A list of #PurpleProtocolChatEntry's
- * @info_defaults: Returns a hashtable which maps #PurpleProtocolChatEntry
- * struct identifiers to default options as strings based on
- * @chat_name. The resulting hashtable should be created with
- * #g_hash_table_new_full(#g_str_hash, #g_str_equal, %NULL,
- * #g_free). Use @get_name if you instead need to extract a chat
- * name from a hashtable.
- * <sbr/>@chat_name: The chat name to be turned into components
- * <sbr/>Returns: Hashtable containing the information extracted
- * @join: Called when the user requests joining a chat. Should arrange for
- * purple_serv_got_joined_chat() to be called.
- * <sbr/>@components: A hashtable containing information required to join
- * the chat as described by the entries returned by
- * @info. It may also be called when accepting an
- * invitation, in which case this matches the data
- * parameter passed to purple_serv_got_chat_invite().
- * @reject: Called when the user refuses a chat invitation.
- * <sbr/>@components: A hashtable containing information required to
- * join the chat as passed to purple_serv_got_chat_invite().
- * @get_name: Returns a chat name based on the information in components. Use
- * @info_defaults if you instead need to generate a hashtable from a
- * <sbr/>@components: A hashtable containing information about the
- * @invite: Invite a user to join a chat.
- * <sbr/>@id: The id of the chat to invite the user to.
- * <sbr/>@message: A message displayed to the user when the invitation
- * <sbr/>@who: The name of the user to send the invation to.
- * @leave: Called when the user requests leaving a chat.
- * <sbr/>@id: The id of the chat to leave
- * @send: Send a message to a chat.
- * <sbr/>This protocol function should return a positive value on
- * success. If the message is too big to be sent, return
- * <literal>-E2BIG</literal>. If the account is not connected,
- * return <literal>-ENOTCONN</literal>. If the protocol is unable
- * to send the message for another reason, return some other
- * negative value. You can use one of the valid #errno values, or
- * <sbr/>@id: The id of the chat to send the message to.
- * <sbr/>@msg: The message to send to the chat.
- * <sbr/>Returns: A positive number or 0 in case of success, a
- * negative error number in case of failure.
- * @get_user_real_name: Gets the real name of a participant in a chat. For
- * example, on XMPP this turns a chat room nick
- * <literal>foo</literal> into
- * <literal>room\@server/foo</literal>.
- * <sbr/>@gc: the connection on which the room is.
- * <sbr/>@id: the ID of the chat room.
- * <sbr/>@who: the nickname of the chat participant.
- * <sbr/>Returns: the real name of the participant. This
- * string must be freed by the caller.
- * The protocol chat interface.
- * This interface provides callbacks needed by protocols that implement chats.
-struct _PurpleProtocolChatInterface
- GTypeInterface parent_iface;
- GList *(*info)(PurpleConnection *connection);
- GHashTable *(*info_defaults)(PurpleConnection *connection, const char *chat_name);
- void (*join)(PurpleConnection *connection, GHashTable *components);
- void (*reject)(PurpleConnection *connection, GHashTable *components);
- char *(*get_name)(GHashTable *components);
- void (*invite)(PurpleConnection *connection, int id,
- const char *message, const char *who);
- void (*leave)(PurpleConnection *connection, int id);
- int (*send)(PurpleConnection *connection, int id, PurpleMessage *msg);
- char *(*get_user_real_name)(PurpleConnection *gc, int id, const char *who);
- void (*set_topic)(PurpleConnection *gc, int id, const char *topic);
-#define PURPLE_IS_PROTOCOL_CHAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL_CHAT))
-#define PURPLE_PROTOCOL_CHAT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_CHAT, \
- PurpleProtocolChatInterface))
* PURPLE_PROTOCOL_IMPLEMENTS:
* @protocol: The protocol in which to check
@@ -585,166 +486,6 @@
/* Protocol Chat Interface API */
/**************************************************************************/
- * purple_protocol_chat_iface_get_type:
- * Returns: The #GType for the protocol chat interface.
-GType purple_protocol_chat_iface_get_type(void);
- * purple_protocol_chat_iface_info:
- * @protocol: The #PurpleProtocol instance.
- * @connection: The #PurpleConnection instance.
- * Gets the list of #PurpleProtocolChatEntry's that are required to join a
- * Returns: (transfer full) (element-type PurpleProtocolChatEntry): The list
- * of #PurpleProtocolChatEntry's that are used to join a chat.
-GList *purple_protocol_chat_iface_info(PurpleProtocol *protocol,
- PurpleConnection *connection);
- * purple_protocol_chat_iface_info_defaults:
- * @protocol: The #PurpleProtocol instance
- * @connection: The #PurpleConnection instance
- * @chat_name: The name of the chat
- * Returns a #GHashTable of the default protocol dependent components that will
- * be passed to #purple_protocol_chat_iface_join.
- * Returns: (transfer full) (element-type utf8 utf8): The values that will be
- * used to join the chat.
-GHashTable *purple_protocol_chat_iface_info_defaults(PurpleProtocol *protocol,
- PurpleConnection *connection, const char *chat_name);
- * purple_protocol_chat_iface_join:
- * @protocol: The #PurpleProtocol instance
- * @connection: The #PurpleConnection instance
- * @components: (element-type utf8 utf8): The protocol dependent join
- * Joins the chat described in @components.
-void purple_protocol_chat_iface_join(PurpleProtocol *protocol, PurpleConnection *connection,
- GHashTable *components);
- * purple_protocol_chat_iface_reject:
- * @protocol: The #PurpleProtocol instance
- * @connection: The #PurpleConnection instance
- * @components: (element-type utf8 utf8): The protocol dependent join
- * Not quite sure exactly what this does or where it's used. Please fill in
- * the details if you know.
-void purple_protocol_chat_iface_reject(PurpleProtocol *protocol,
- PurpleConnection *connection, GHashTable *components);
- * purple_protocol_chat_iface_get_name:
- * @protocol: The #PurpleProtocol instance
- * @components: (element-type utf8 utf8): The protocol dependent join
- * Gets the name from @components.
- * Returns: (transfer full): The chat name from @components.
-char *purple_protocol_chat_iface_get_name(PurpleProtocol *protocol,
- GHashTable *components);
- * purple_protocol_chat_iface_invite:
- * @protocol: The #PurpleProtocol instance
- * @connection: The #PurpleConnection instance
- * @id: The id of the chat
- * @message: The invite message
- * @who: The target of the invite
- * Sends an invite to @who with @message.
-void purple_protocol_chat_iface_invite(PurpleProtocol *protocol,
- PurpleConnection *connection, int id, const char *message, const char *who);
- * purple_protocol_chat_iface_leave:
- * @protocol: The #PurpleProtocol instance
- * @connection: The #PurpleConnection instance
- * @id: The id of the chat
- * Leaves the chat identified by @id.
-void purple_protocol_chat_iface_leave(PurpleProtocol *protocol, PurpleConnection *connection,
- * purple_protocol_chat_iface_send:
- * @protocol: The #PurpleProtocol instance
- * @connection: The #PurpleConnection instance
- * @id: The id of the chat
- * @msg: The message to send
- * Sends @msg to the chat identified by @id.
- * Returns: 0 on success, non-zero on failure.
-int purple_protocol_chat_iface_send(PurpleProtocol *protocol, PurpleConnection *connection,
- int id, PurpleMessage *msg);
- * purple_protocol_chat_iface_get_user_real_name:
- * @protocol: The #PurpleProtocol instance
- * @gc: The #PurpleConnection instance
- * @id: The id of the chat
- * Gets the real name of @who.
- * Returns: (transfer full): The realname of @who.
-char *purple_protocol_chat_iface_get_user_real_name(PurpleProtocol *protocol,
- PurpleConnection *gc, int id, const char *who);
- * purple_protocol_chat_iface_set_topic:
- * @protocol: The #PurpleProtocol instance
- * @gc: The #PurpleConnection instance
- * @id: The id of the chat
- * @topic: The new topic
- * Sets the topic for the chat with id @id to @topic.
-void purple_protocol_chat_iface_set_topic(PurpleProtocol *protocol,
- PurpleConnection *gc, int id, const char *topic);
#endif /* PURPLE_PROTOCOL_H */
--- a/libpurple/protocols/facebook/facebook.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/facebook/facebook.c Mon Jan 11 01:51:14 2021 -0600
@@ -1231,7 +1231,7 @@
+fb_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection *connection) PurpleProtocolChatEntry *pce;
@@ -1246,7 +1246,8 @@
-fb_chat_info_defaults(PurpleConnection *gc, const gchar *name)
+fb_chat_info_defaults(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, @@ -1257,7 +1258,8 @@
-fb_chat_join(PurpleConnection *gc, GHashTable *data)
+fb_chat_join(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, @@ -1295,7 +1297,7 @@
-fb_chat_get_name(GHashTable *data)
+fb_chat_get_name(PurpleProtocolChat *protocol_chat, GHashTable *data) @@ -1306,8 +1308,8 @@
-fb_chat_invite(PurpleConnection *gc, gint id, const gchar *msg,
+fb_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, const gchar *msg, const gchar *who) @@ -1339,7 +1341,8 @@
-fb_chat_send(PurpleConnection *gc, gint id, PurpleMessage *msg)
+fb_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, gint id, @@ -1372,7 +1375,8 @@
-fb_chat_set_topic(PurpleConnection *gc, gint id, const gchar *topic)
+fb_chat_set_topic(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, const gchar *topic) --- a/libpurple/protocols/gg/chat.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/gg/chat.c Mon Jan 11 01:51:14 2021 -0600
@@ -293,8 +293,8 @@
purple_chat_conversation_remove_user(chat->conv, ggp_uin_to_str(uin), NULL);
-GList * ggp_chat_info(PurpleConnection *gc)
+ggp_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection *gc) { PurpleProtocolChatEntry *pce;
@@ -307,7 +307,9 @@
-GHashTable * ggp_chat_info_defaults(PurpleConnection *gc, const char *chat_name)
+ggp_chat_info_defaults(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + const gchar *chat_name) @@ -319,8 +321,8 @@
-char * ggp_chat_get_name(GHashTable *components)
+ggp_chat_get_name(PurpleProtocolChat *protocol_chat, GHashTable *components) { return g_strdup((gchar*)g_hash_table_lookup(components, "id"));
@@ -347,7 +349,9 @@
-void ggp_chat_join(PurpleConnection *gc, GHashTable *components)
+ggp_chat_join(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + GHashTable *components) ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc);
GGPInfo *info = purple_connection_get_protocol_data(gc);
@@ -394,6 +398,8 @@
static void ggp_chat_join_id(PurpleConnection *gc, uint64_t id)
+ PurpleProtocol *protocol = purple_connection_get_protocol(gc); ggp_chat_local_info *chat = ggp_chat_get(gc, id);
if (chat && !chat->left) {
@@ -416,12 +422,15 @@
- components = ggp_chat_info_defaults(gc, ggp_chat_get_name_from_id(id));
+ components = ggp_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), gc, + ggp_chat_get_name_from_id(id)); purple_serv_got_join_chat_failed(gc, components);
g_hash_table_destroy(components);
-void ggp_chat_leave(PurpleConnection *gc, int local_id)
+ggp_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, GGPInfo *info = purple_connection_get_protocol_data(gc);
ggp_chat_local_info *chat;
@@ -448,8 +457,9 @@
-void ggp_chat_invite(PurpleConnection *gc, int local_id, const char *message,
+ggp_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint local_id, const gchar *message, const gchar *who) GGPInfo *info = purple_connection_get_protocol_data(gc);
ggp_chat_local_info *chat;
@@ -470,7 +480,9 @@
-int ggp_chat_send(PurpleConnection *gc, int local_id, PurpleMessage *msg)
+ggp_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint local_id, PurpleMessage *msg) GGPInfo *info = purple_connection_get_protocol_data(gc);
--- a/libpurple/protocols/gg/chat.h Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/gg/chat.h Mon Jan 11 01:51:14 2021 -0600
@@ -41,15 +41,15 @@
void ggp_chat_got_event(PurpleConnection *gc, const struct gg_event *ev);
-GList * ggp_chat_info(PurpleConnection *gc);
-GHashTable * ggp_chat_info_defaults(PurpleConnection *gc,
+GList * ggp_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection *gc); +GHashTable * ggp_chat_info_defaults(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, -char * ggp_chat_get_name(GHashTable *components);
-void ggp_chat_join(PurpleConnection *gc, GHashTable *components);
-void ggp_chat_leave(PurpleConnection *gc, int local_id);
-void ggp_chat_invite(PurpleConnection *gc, int local_id, const char *message,
+char * ggp_chat_get_name(PurpleProtocolChat *protocol_chat, GHashTable *components); +void ggp_chat_join(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, GHashTable *components); +void ggp_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int local_id); +void ggp_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int local_id, const char *message, -int ggp_chat_send(PurpleConnection *gc, int local_id, PurpleMessage *msg);
+int ggp_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int local_id, PurpleMessage *msg); void ggp_chat_got_message(PurpleConnection *gc, uint64_t chat_id,
const char *message, time_t time, uin_t who);
--- a/libpurple/protocols/irc/irc.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/irc/irc.c Mon Jan 11 01:51:14 2021 -0600
@@ -41,8 +41,8 @@
static void irc_login_cb(GObject *source, GAsyncResult *res, gpointer user_data);
static void irc_close(PurpleConnection *gc);
static int irc_im_send(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg);
-static int irc_chat_send(PurpleConnection *gc, int id, PurpleMessage *msg);
-static void irc_chat_join (PurpleConnection *gc, GHashTable *data);
+static int irc_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int id, PurpleMessage *msg); +static void irc_chat_join(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, GHashTable *data); static void irc_read_input_cb(GObject *source, GAsyncResult *res, gpointer data);
static guint irc_nick_hash(const char *nick);
@@ -386,8 +386,8 @@
-static GList *irc_chat_join_info(PurpleConnection *gc)
+irc_chat_join_info(PurpleProtocolChat *protocol_chat, PurpleConnection *gc) { PurpleProtocolChatEntry *pce;
@@ -406,7 +406,9 @@
-static GHashTable *irc_chat_info_defaults(PurpleConnection *gc, const char *chat_name)
+irc_chat_info_defaults(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + const gchar *chat_name) @@ -761,7 +763,9 @@
-static void irc_chat_join (PurpleConnection *gc, GHashTable *data)
+irc_chat_join(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, struct irc_conn *irc = purple_connection_get_protocol_data(gc);
@@ -771,11 +775,14 @@
irc_cmd_join(irc, "join", NULL, args);
-static char *irc_get_chat_name(GHashTable *data) {
+irc_get_chat_name(PurpleProtocolChat *protocol_chat, GHashTable *data) { return g_strdup(g_hash_table_lookup(data, "channel"));
-static void irc_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name)
+irc_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, const gchar *message, const gchar *name) struct irc_conn *irc = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, id));
@@ -791,7 +798,9 @@
-static void irc_chat_leave (PurpleConnection *gc, int id)
+irc_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, struct irc_conn *irc = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, id));
@@ -806,7 +815,9 @@
purple_serv_got_chat_left(gc, id);
-static int irc_chat_send(PurpleConnection *gc, int id, PurpleMessage *msg)
+irc_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, gint id, struct irc_conn *irc = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, id));
@@ -854,7 +865,9 @@
-static void irc_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
+irc_chat_set_topic(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, const gchar *topic) --- a/libpurple/protocols/jabber/chat.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/jabber/chat.c Mon Jan 11 01:51:14 2021 -0600
@@ -31,7 +31,9 @@
-GList *jabber_chat_info(PurpleConnection *gc)
+jabber_chat_info(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection) PurpleProtocolChatEntry *pce;
@@ -203,7 +205,8 @@
void jabber_chat_member_free(JabberChatMember *jcm);
-char *jabber_get_chat_name(GHashTable *data) {
+jabber_get_chat_name(PurpleProtocolChat *protocol_chat, GHashTable *data) { char *room, *server, *chat_name = NULL;
room = g_hash_table_lookup(data, "room");
@@ -414,7 +417,9 @@
-void jabber_chat_leave(PurpleConnection *gc, int id)
+jabber_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, JabberStream *js = purple_connection_get_protocol_data(gc);
JabberChat *chat = jabber_chat_find_by_id(js, id);
@@ -454,7 +459,9 @@
return purple_chat_conversation_has_user(conv, name);
-char *jabber_chat_user_real_name(PurpleConnection *gc, int id, const char *who)
+jabber_chat_user_real_name(PurpleProtocolChat *protocol_chat, + PurpleConnection *gc, gint id, const gchar *who) JabberStream *js = purple_connection_get_protocol_data(gc);
@@ -736,7 +743,9 @@
-void jabber_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
+jabber_chat_set_topic(PurpleProtocolChat *protocol_chat, + PurpleConnection *gc, gint id, const gchar *topic) JabberStream *js = purple_connection_get_protocol_data(gc);
JabberChat *chat = jabber_chat_find_by_id(js, id);
--- a/libpurple/protocols/jabber/chat.h Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/jabber/chat.h Mon Jan 11 01:51:14 2021 -0600
@@ -52,9 +52,9 @@
-GList *jabber_chat_info(PurpleConnection *gc);
+GList *jabber_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection *connection); GHashTable *jabber_chat_info_defaults(PurpleConnection *gc, const char *chat_name);
-char *jabber_get_chat_name(GHashTable *data);
+char *jabber_get_chat_name(PurpleProtocolChat *protocol_chat, GHashTable *data); * in-protocol function for joining a chat room. Doesn't require sticking goop
@@ -80,13 +80,13 @@
gboolean jabber_chat_find_buddy(PurpleChatConversation *conv, const char *name);
void jabber_chat_invite(PurpleConnection *gc, int id, const char *message,
-void jabber_chat_leave(PurpleConnection *gc, int id);
-char *jabber_chat_user_real_name(PurpleConnection *gc, int id, const char *who);
+void jabber_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int id); +char *jabber_chat_user_real_name(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int id, const char *who); void jabber_chat_request_room_configure(JabberChat *chat);
void jabber_chat_create_instant_room(JabberChat *chat);
void jabber_chat_register(JabberChat *chat);
void jabber_chat_change_topic(JabberChat *chat, const char *topic);
-void jabber_chat_set_topic(PurpleConnection *gc, int id, const char *topic);
+void jabber_chat_set_topic(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int id, const char *topic); gboolean jabber_chat_change_nick(JabberChat *chat, const char *nick);
void jabber_chat_part(JabberChat *chat, const char *msg);
void jabber_chat_track_handle(JabberChat *chat, const char *handle,
--- a/libpurple/protocols/jabber/jabber.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/jabber/jabber.c Mon Jan 11 01:51:14 2021 -0600
@@ -4193,14 +4193,37 @@
im_iface->send_typing = jabber_send_typing;
+jabber_protocol_chat_info_defaults(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, + return jabber_chat_info_defaults(connection, name); +jabber_protocol_chat_join(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, GHashTable *components) + jabber_chat_join(connection, components); +jabber_protocol_chat_invite(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, gint id, + const gchar *message, const gchar *who) + jabber_chat_invite(connection, id, message, who); jabber_protocol_chat_iface_init(PurpleProtocolChatInterface *chat_iface)
chat_iface->info = jabber_chat_info;
- chat_iface->info_defaults = jabber_chat_info_defaults;
- chat_iface->join = jabber_chat_join;
+ chat_iface->info_defaults = jabber_protocol_chat_info_defaults; + chat_iface->join = jabber_protocol_chat_join; chat_iface->get_name = jabber_get_chat_name;
- chat_iface->invite = jabber_chat_invite;
+ chat_iface->invite = jabber_protocol_chat_invite; chat_iface->leave = jabber_chat_leave;
chat_iface->send = jabber_message_send_chat;
chat_iface->get_user_real_name = jabber_chat_user_real_name;
--- a/libpurple/protocols/jabber/message.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/jabber/message.c Mon Jan 11 01:51:14 2021 -0600
@@ -1226,7 +1226,9 @@
-int jabber_message_send_chat(PurpleConnection *gc, int id, PurpleMessage *msg)
+jabber_message_send_chat(PurpleProtocolChat *protocol_chat, + PurpleConnection *gc, gint id, PurpleMessage *msg) --- a/libpurple/protocols/jabber/message.h Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/jabber/message.h Mon Jan 11 01:51:14 2021 -0600
@@ -71,7 +71,7 @@
void jabber_message_parse(JabberStream *js, PurpleXmlNode *packet);
int jabber_message_send_im(PurpleProtocolIM *pim, PurpleConnection *gc, PurpleMessage *msg);
-int jabber_message_send_chat(PurpleConnection *gc, int id, PurpleMessage *msg);
+int jabber_message_send_chat(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, int id, PurpleMessage *msg); unsigned int jabber_send_typing(PurpleProtocolIM *pim, PurpleConnection *gc, const char *who, PurpleIMTypingState state);
--- a/libpurple/protocols/novell/novell.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/novell/novell.c Mon Jan 11 01:51:14 2021 -0600
@@ -2405,7 +2405,8 @@
-novell_chat_leave(PurpleConnection * gc, int id)
+novell_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, NMConference *conference;
@@ -2435,8 +2436,8 @@
-novell_chat_invite(PurpleConnection *gc, int id,
- const char *message, const char *who)
+novell_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, const gchar *message, const gchar *who) NMConference *conference;
@@ -2472,8 +2473,9 @@
-novell_chat_send(PurpleConnection * gc, int id, PurpleMessage *msg)
+novell_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, PurpleMessage *msg) NMConference *conference;
PurpleChatConversation *chat;
--- a/libpurple/protocols/null/nullprpl.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/null/nullprpl.c Mon Jan 11 01:51:14 2021 -0600
@@ -324,7 +324,8 @@
-static GList *null_chat_info(PurpleConnection *gc) {
+null_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection *gc) { PurpleProtocolChatEntry *pce; /* defined in protocols.h */
purple_debug_info("nullprpl", "returning chat setting 'room'\n");
@@ -337,8 +338,10 @@
return g_list_append(NULL, pce);
-static GHashTable *null_chat_info_defaults(PurpleConnection *gc,
+null_chat_info_defaults(PurpleProtocolChat *protocol_chat, + PurpleConnection *gc, const gchar *room) purple_debug_info("nullprpl", "returning chat default setting "
@@ -676,7 +679,10 @@
-static void null_join_chat(PurpleConnection *gc, GHashTable *components) {
+null_join_chat(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + GHashTable *components) const char *username = purple_account_get_username(purple_connection_get_account(gc));
const char *room = g_hash_table_lookup(components, "room");
int chat_id = g_str_hash(room);
@@ -699,7 +705,10 @@
-static void null_reject_chat(PurpleConnection *gc, GHashTable *components) {
+null_reject_chat(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + GHashTable *components) const char *invited_by = g_hash_table_lookup(components, "invited_by");
const char *room = g_hash_table_lookup(components, "room");
const char *username = purple_account_get_username(purple_connection_get_account(gc));
@@ -722,14 +731,17 @@
-static char *null_get_chat_name(GHashTable *components) {
+null_get_chat_name(PurpleProtocolChat *protocol_chat, GHashTable *components) { const char *room = g_hash_table_lookup(components, "room");
purple_debug_info("nullprpl", "reporting chat room name '%s'\n", room);
-static void null_chat_invite(PurpleConnection *gc, int id,
- const char *message, const char *who) {
+null_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, const gchar *message, const gchar *who) const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
const char *room = purple_conversation_get_name(PURPLE_CONVERSATION(chat));
@@ -771,7 +783,10 @@
-static void null_chat_leave(PurpleConnection *gc, int id) {
+null_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
purple_debug_info("nullprpl", "%s is leaving chat room %s\n",
purple_account_get_username(purple_connection_get_account(gc)),
@@ -793,7 +808,10 @@
-static int null_chat_send(PurpleConnection *gc, int id, PurpleMessage *msg) {
+null_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, PurpleMessage *msg) const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
const gchar *message = purple_message_get_contents(msg);
@@ -890,8 +908,10 @@
-static void null_set_chat_topic(PurpleConnection *gc, int id,
+null_set_chat_topic(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + gint id, const gchar *topic) PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
--- a/libpurple/protocols/sametime/sametime.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/sametime/sametime.c Mon Jan 11 01:51:14 2021 -0600
@@ -3491,7 +3491,10 @@
-static GList *mw_protocol_chat_info(PurpleConnection *gc) {
+mw_protocol_chat_info(PurpleProtocolChat *protocol_chat, PurpleProtocolChatEntry *pce;
@@ -3504,8 +3507,11 @@
-static GHashTable *mw_protocol_chat_info_defaults(PurpleConnection *gc,
+mw_protocol_chat_info_defaults(PurpleProtocolChat *protocol_chat, g_return_val_if_fail(gc != NULL, NULL);
@@ -4362,8 +4368,10 @@
-static void mw_protocol_join_chat(PurpleConnection *gc,
- GHashTable *components) {
+mw_protocol_join_chat(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + GHashTable *components) struct mwPurpleProtocolData *pd;
@@ -4403,9 +4411,11 @@
-static void mw_protocol_reject_chat(PurpleConnection *gc,
- GHashTable *components) {
+mw_protocol_reject_chat(PurpleProtocolChat *protocol_chat, + GHashTable *components) struct mwPurpleProtocolData *pd;
struct mwServiceConference *srvc;
@@ -4427,16 +4437,18 @@
-static char *mw_protocol_get_chat_name(GHashTable *components) {
+mw_protocol_get_chat_name(PurpleProtocolChat *protocol_chat, + GHashTable *components) return g_hash_table_lookup(components, CHAT_KEY_NAME);
-static void mw_protocol_chat_invite(PurpleConnection *gc,
- const char *invitation,
+mw_protocol_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + int id, const char *invitation, const char *who) struct mwPurpleProtocolData *pd;
struct mwConference *conf;
@@ -4460,9 +4472,10 @@
-static void mw_protocol_chat_leave(PurpleConnection *gc,
+mw_protocol_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, struct mwPurpleProtocolData *pd;
struct mwConference *conf;
@@ -4483,7 +4496,9 @@
-static int mw_protocol_chat_send(PurpleConnection *gc, int id, PurpleMessage *pmsg)
+mw_protocol_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + int id, PurpleMessage *pmsg) struct mwPurpleProtocolData *pd;
struct mwConference *conf;
--- a/libpurple/protocols/zephyr/zephyr.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/protocols/zephyr/zephyr.c Mon Jan 11 01:51:14 2021 -0600
@@ -1623,7 +1623,9 @@
-static int zephyr_chat_send(PurpleConnection * gc, int id, PurpleMessage *msg)
+zephyr_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *gc, + int id, PurpleMessage *msg) @@ -1931,8 +1933,8 @@
-static GList *zephyr_chat_info(PurpleConnection * gc)
+zephyr_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection * gc) { PurpleProtocolChatEntry *pce;
@@ -1966,7 +1968,8 @@
g_free(subscribe_failed);
-static char *zephyr_get_chat_name(GHashTable *data) {
+zephyr_get_chat_name(PurpleProtocolChat *protocol_chat, GHashTable *data) { gchar* zclass = g_hash_table_lookup(data,"class");
gchar* inst = g_hash_table_lookup(data,"instance");
gchar* recipient = g_hash_table_lookup(data, "recipient");
@@ -2048,7 +2051,16 @@
zephyr_chat_set_topic(gc,zt1->id,instname);
-static void zephyr_chat_leave(PurpleConnection * gc, int id)
+zephyr_protocol_chat_join(PurpleProtocolChat *protocol_chat, + PurpleConnection *gc, GHashTable * data) + zephyr_join_chat(gc, data); +zephyr_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection * gc, zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
@@ -2163,6 +2175,13 @@
+zephyr_protocol_chat_set_topic(PurpleProtocolChat *protocol_chat, + PurpleConnection *gc, int id, const char *topic) + zephyr_chat_set_topic(gc, id, topic); static PurpleCmdRet zephyr_purple_cmd_msg(PurpleConversation *conv,
@@ -2549,11 +2568,11 @@
zephyr_protocol_chat_iface_init(PurpleProtocolChatInterface *chat_iface)
chat_iface->info = zephyr_chat_info;
- chat_iface->join = zephyr_join_chat;
+ chat_iface->join = zephyr_protocol_chat_join; chat_iface->get_name = zephyr_get_chat_name;
chat_iface->leave = zephyr_chat_leave;
chat_iface->send = zephyr_chat_send;
- chat_iface->set_topic = zephyr_chat_set_topic;
+ chat_iface->set_topic = zephyr_protocol_chat_set_topic; chat_iface->get_user_real_name = NULL; /* XXX */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleprotocolchat.c Mon Jan 11 01:51:14 2021 -0600
@@ -0,0 +1,207 @@
+ * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * 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, see <https://www.gnu.org/licenses/>. +#include "purpleprotocolchat.h" +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_INTERFACE(PurpleProtocolChat, purple_protocol_chat, G_TYPE_INVALID) +purple_protocol_chat_default_init(PurpleProtocolChatInterface *iface) { +/****************************************************************************** + *****************************************************************************/ +purple_protocol_chat_info(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection) + PurpleProtocolChatInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat), NULL); + g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), NULL); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->info != NULL) { + return iface->info(protocol_chat, connection); +purple_protocol_chat_info_defaults(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, + const gchar *chat_name) + PurpleProtocolChatInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat), NULL); + g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), NULL); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->info_defaults != NULL) { + return iface->info_defaults(protocol_chat, connection, chat_name); +purple_protocol_chat_join(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, + GHashTable *components) + PurpleProtocolChatInterface *iface = NULL; + g_return_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat)); + g_return_if_fail(PURPLE_IS_CONNECTION(connection)); + g_return_if_fail(components != NULL); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->join != NULL) { + iface->join(protocol_chat, connection, components); +purple_protocol_chat_reject(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, + GHashTable *components) + PurpleProtocolChatInterface *iface = NULL; + g_return_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat)); + g_return_if_fail(PURPLE_IS_CONNECTION(connection)); + g_return_if_fail(components != NULL); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->reject != NULL) { + iface->reject(protocol_chat, connection, components); +purple_protocol_chat_get_name(PurpleProtocolChat *protocol_chat, + GHashTable *components) + PurpleProtocolChatInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat), NULL); + g_return_val_if_fail(components != NULL, NULL); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->get_name != NULL) { + return iface->get_name(protocol_chat, components); +purple_protocol_chat_invite(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, gint id, + const gchar *message, const gchar *who) + PurpleProtocolChatInterface *iface = NULL; + g_return_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat)); + g_return_if_fail(PURPLE_IS_CONNECTION(connection)); + g_return_if_fail(who != NULL); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->invite != NULL) { + iface->invite(protocol_chat, connection, id, message, who); +purple_protocol_chat_leave(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, gint id) + PurpleProtocolChatInterface *iface = NULL; + g_return_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat)); + g_return_if_fail(PURPLE_IS_CONNECTION(connection)); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->leave != NULL) { + iface->leave(protocol_chat, connection, id); +purple_protocol_chat_send(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, gint id, + PurpleMessage *message) + PurpleProtocolChatInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat), -1); + g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), -1); + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), -1); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->send != NULL) { + return iface->send(protocol_chat, connection, id, message); +purple_protocol_chat_get_user_real_name(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, gint id, + PurpleProtocolChatInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat), NULL); + g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), NULL); + g_return_val_if_fail(who != NULL, NULL); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->get_user_real_name != NULL) { + return iface->get_user_real_name(protocol_chat, connection, id, who); +purple_protocol_chat_set_topic(PurpleProtocolChat *protocol_chat, + PurpleConnection *connection, gint id, + PurpleProtocolChatInterface *iface = NULL; + g_return_if_fail(PURPLE_IS_PROTOCOL_CHAT(protocol_chat)); + g_return_if_fail(PURPLE_IS_CONNECTION(connection)); + iface = PURPLE_PROTOCOL_CHAT_GET_IFACE(protocol_chat); + if(iface != NULL && iface->set_topic != NULL) { + iface->set_topic(protocol_chat, connection, id, topic); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleprotocolchat.h Mon Jan 11 01:51:14 2021 -0600
@@ -0,0 +1,262 @@
+ * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * 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, see <https://www.gnu.org/licenses/>. +#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) +# error "only <purple.h> may be included directly" +#ifndef PURPLE_PROTOCOL_CHAT_H +#define PURPLE_PROTOCOL_CHAT_H + * SECTION:purpleprotocolchat + * @section_id: libpurple-purpleprotocolchat + * @short_description: Protocol Chat Interface + * @title: ProtocolChat Interface + * #PurpleProtocolChat describes the API that protocols need to implement for + * handling multiple user conversations. +#include <glib-object.h> +#include <libpurple/connection.h> +#include <libpurple/purplemessage.h> +#define PURPLE_TYPE_PROTOCOL_CHAT (purple_protocol_chat_get_type()) +G_DECLARE_INTERFACE(PurpleProtocolChat, purple_protocol_chat, PURPLE, PROTOCOL_CHAT, + * PURPLE_TYPE_PROTOCOL_CHAT: + * The standard _get_type method for #PurpleProtocolChat. + * PurpleProtocolChatInterface: + * @info: Returns a list of #PurpleProtocolChatEntry structs, which represent + * information required by the protocol to join a chat. libpurple will + * call join_chat along with the information filled by the user. + * @info_defaults: Returns a hashtable which maps #PurpleProtocolChatEntry + * struct identifiers to default options as strings based on + * @chat_name. The resulting hashtable should be created with + * #g_hash_table_new_full(#g_str_hash, #g_str_equal, %NULL, + * #g_free). Use @get_name if you instead need to extract a chat + * name from a hashtable. + * @join: Called when the user requests joining a chat. Should arrange for + * purple_serv_got_joined_chat() to be called. + * @reject: Called when the user refuses a chat invitation. + * @get_name: Returns a chat name based on the information in components. Use + * @info_defaults if you instead need to generate a hashtable from a + * @invite: Invite a user to join a chat. + * @leave: Called when the user requests leaving a chat. + * @send: Send a message to a chat. + * @get_user_real_name: Gets the real name of a participant in a chat. For + * example, on XMPP this turns a chat room nick + * <literal>foo</literal> into + * <literal>room\@server/foo</literal>. + * @set_topic: Called to set the topic for the given chat. + * The protocol chat interface. + * This interface provides callbacks needed by protocols that implement chats. +struct _PurpleProtocolChatInterface { + GList *(*info)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection); + GHashTable *(*info_defaults)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, const gchar *chat_name); + void (*join)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, GHashTable *components); + void (*reject)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, GHashTable *components); + gchar *(*get_name)(PurpleProtocolChat *protocol_chat, GHashTable *components); + void (*invite)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, const gchar *message, const gchar *who); + void (*leave)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id); + gint (*send)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, PurpleMessage *message); + gchar *(*get_user_real_name)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, const gchar *who); + void (*set_topic)(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, const gchar *topic); + * purple_protocol_chat_info: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * Gets the list of #PurpleProtocolChatEntry's that are required to join a + * Returns: (transfer full) (element-type PurpleProtocolChatEntry): The list + * of #PurpleProtocolChatEntry's that are used to join a chat. +GList *purple_protocol_chat_info(PurpleProtocolChat *protocol_chat, PurpleConnection *connection); + * purple_protocol_chat_info_defaults: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @chat_name: The name of the chat. + * Returns a #GHashTable of the default protocol dependent components that will + * be passed to purple_protocol_chat_join(). + * Returns: (transfer full) (element-type utf8 utf8): The values that will be + * used to join the chat. +GHashTable *purple_protocol_chat_info_defaults(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, const gchar *chat_name); + * purple_protocol_chat_join: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @components: (element-type utf8 utf8) (transfer none): The protocol + * dependent join components. + * Joins the chat described in @components. +void purple_protocol_chat_join(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, GHashTable *components); + * purple_protocol_chat_reject: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @components: (element-type utf8 utf8) (transfer none): The protocol + * dependent join components. + * Used to reject a chat invite. +void purple_protocol_chat_reject(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, GHashTable *components); + * purple_protocol_chat_get_name: + * @protocol_chat: The #PurpleProtocolChat instance. + * @components: (element-type utf8 utf8) (transfer none): The protocol + * dependent join components. + * Gets the name from @components. + * Returns: (transfer full): The chat name from @components. +gchar *purple_protocol_chat_get_name(PurpleProtocolChat *protocol_chat, GHashTable *components); + * purple_protocol_chat_invite: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @id: The id of the chat. + * @message: The invite message. + * @who: The target of the invite. + * Sends an invite to @who with @message. +void purple_protocol_chat_invite(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, const gchar *message, const gchar *who); + * purple_protocol_chat_leave: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @id: The id of the chat. + * Leaves the chat identified by @id. +void purple_protocol_chat_leave(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id); + * purple_protocol_chat_send: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @id: The id of the chat. + * @message: The message to send. + * Sends @message to the chat identified by @id. + * Returns: 0 on success, non-zero on failure. +gint purple_protocol_chat_send(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, PurpleMessage *message); + * purple_protocol_chat_get_user_real_name: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @id: The id of the chat. + * Gets the real name of @who. + * Returns: (transfer full): The realname of @who. +gchar *purple_protocol_chat_get_user_real_name(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, const gchar *who); + * purple_protocol_chat_set_topic: + * @protocol_chat: The #PurpleProtocolChat instance. + * @connection: The #PurpleConnection instance. + * @id: The id of the chat. + * @topic: The new topic. + * Sets the topic for the chat with id @id to @topic. +void purple_protocol_chat_set_topic(PurpleProtocolChat *protocol_chat, PurpleConnection *connection, gint id, const gchar *topic); +#endif /* PURPLE_PROTOCOL_CHAT_H */ --- a/libpurple/server.c Mon Jan 11 01:08:47 2021 -0600
+++ b/libpurple/server.c Mon Jan 11 01:51:14 2021 -0600
@@ -35,6 +35,7 @@
#include "purpleprivate.h"
#include "purpleprotocolattention.h"
+#include "purpleprotocolchat.h" #include "purpleprotocolim.h"
#include "purpleprotocolprivacy.h"
@@ -412,7 +413,7 @@
protocol = purple_connection_get_protocol(gc);
- purple_protocol_chat_iface_join(protocol, gc, data);
+ purple_protocol_chat_join(PURPLE_PROTOCOL_CHAT(protocol), gc, data); @@ -423,7 +424,7 @@
protocol = purple_connection_get_protocol(gc);
- purple_protocol_chat_iface_reject(protocol, gc, data);
+ purple_protocol_chat_reject(PURPLE_PROTOCOL_CHAT(protocol), gc, data); @@ -445,8 +446,10 @@
purple_signal_emit(purple_conversations_get_handle(), "chat-inviting-user",
- purple_protocol_chat_iface_invite(protocol, gc, id, buffy, name);
+ purple_protocol_chat_invite(PURPLE_PROTOCOL_CHAT(protocol), gc, id, purple_signal_emit(purple_conversations_get_handle(), "chat-invited-user",
@@ -464,7 +467,7 @@
PurpleProtocol *protocol;
protocol = purple_connection_get_protocol(gc);
- purple_protocol_chat_iface_leave(protocol, gc, id);
+ purple_protocol_chat_leave(PURPLE_PROTOCOL_CHAT(protocol), gc, id); int purple_serv_chat_send(PurpleConnection *gc, int id, PurpleMessage *msg)
@@ -474,8 +477,10 @@
g_return_val_if_fail(msg != NULL, -EINVAL);
- if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, send))
- return purple_protocol_chat_iface_send(protocol, gc, id, msg);
+ if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, send)) { + return purple_protocol_chat_send(PURPLE_PROTOCOL_CHAT(protocol), gc, --- a/pidgin/gtkblist.c Mon Jan 11 01:08:47 2021 -0600
+++ b/pidgin/gtkblist.c Mon Jan 11 01:51:14 2021 -0600
@@ -380,8 +380,10 @@
components = purple_chat_get_components(chat);
- chat_name = purple_protocol_chat_iface_get_name(protocol, components);
+ chat_name = purple_protocol_chat_get_name(PURPLE_PROTOCOL_CHAT(protocol), @@ -651,13 +653,15 @@
PurpleRequestField *field;
PurpleProtocolChatEntry *pce;
+ PurpleProtocol *protocol; PurpleChat *chat = (PurpleChat*)node;
purple_request_fields_add_group(fields, group);
gc = purple_account_get_connection(purple_chat_get_account(chat));
- parts = purple_protocol_chat_iface_info(purple_connection_get_protocol(gc), gc);
+ protocol = purple_connection_get_protocol(gc); + parts = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol), gc); for (iter = parts; iter; iter = iter->next) {
@@ -732,7 +736,8 @@
account = purple_chat_get_account(c);
protocol = purple_protocols_find(purple_account_get_protocol_id(account));
- name = purple_protocol_chat_iface_get_name(protocol, purple_chat_get_components(c));
+ name = purple_protocol_chat_get_name(PURPLE_PROTOCOL_CHAT(protocol), + purple_chat_get_components(c)); } else if (PURPLE_IS_CONTACT(node)) {
pidgin_log_show_contact(PURPLE_CONTACT(node));
@@ -1056,8 +1061,9 @@
g_list_free(data->entries);
- list = purple_protocol_chat_iface_info(protocol, gc);
- defaults = purple_protocol_chat_iface_info_defaults(protocol, gc, default_chat_name);
+ list = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol), gc); + defaults = purple_protocol_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), + gc, default_chat_name); for (tmp = list; tmp; tmp = tmp->next)
@@ -3289,10 +3295,12 @@
conv = PURPLE_CHAT_CONVERSATION(bnode->conv.conv);
- if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, get_name))
- chat_name = purple_protocol_chat_iface_get_name(protocol, purple_chat_get_components(chat));
+ if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, get_name)) { + chat_name = purple_protocol_chat_get_name(PURPLE_PROTOCOL_CHAT(protocol), + purple_chat_get_components(chat)); chat_name = g_strdup(purple_chat_get_name(chat));
conv = purple_conversations_find_chat_with_account(chat_name,
purple_chat_get_account(chat));
@@ -3311,8 +3319,10 @@
- cur = purple_protocol_chat_iface_info(protocol, purple_account_get_connection(purple_chat_get_account(chat)));
+ cur = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol), + purple_account_get_connection(purple_chat_get_account(chat))); --- a/pidgin/gtkconv.c Mon Jan 11 01:08:47 2021 -0600
+++ b/pidgin/gtkconv.c Mon Jan 11 01:51:14 2021 -0600
@@ -1114,9 +1114,10 @@
protocol = purple_connection_get_protocol(gc);
- real_who = purple_protocol_chat_iface_get_user_real_name(protocol, gc,
+ real_who = purple_protocol_chat_get_user_real_name(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)), who);
@@ -1168,9 +1169,10 @@
protocol = purple_connection_get_protocol(gc);
- real_who = purple_protocol_chat_iface_get_user_real_name(protocol, gc,
+ real_who = purple_protocol_chat_get_user_real_name(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)), who);
purple_serv_send_file(gc, real_who ? real_who : who, NULL);
@@ -1256,7 +1258,7 @@
can_receive_file = FALSE;
- real_who = purple_protocol_chat_iface_get_user_real_name(protocol, gc,
+ real_who = purple_protocol_chat_get_user_real_name(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_chat_conversation_get_id(chat), who);
if (!purple_protocol_xfer_can_receive(
@@ -2477,7 +2479,7 @@
purple_protocols_find(purple_account_get_protocol_id(account));
if (purple_account_get_connection(account) != NULL &&
PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info_defaults)) {
- components = purple_protocol_chat_iface_info_defaults(protocol, purple_account_get_connection(account),
+ components = purple_protocol_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), purple_account_get_connection(account), purple_conversation_get_name(conv));
components = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -3298,7 +3300,6 @@
PurpleConversation *conv;
- PurpleProtocol *protocol;
@@ -3417,7 +3418,7 @@
gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), "");
- purple_protocol_chat_iface_set_topic(protocol, gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)),
+ purple_protocol_chat_set_topic(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)), @@ -5730,7 +5731,7 @@
PurpleChat *chat = purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
PurpleProtocol *protocol = purple_connection_get_protocol(gc);
- comps = purple_protocol_chat_iface_info_defaults(protocol, gc, purple_conversation_get_name(conv));
+ comps = purple_protocol_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_conversation_get_name(conv)); comps = purple_chat_get_components(chat);
--- a/pidgin/gtkutils.c Mon Jan 11 01:08:47 2021 -0600
+++ b/pidgin/gtkutils.c Mon Jan 11 01:51:14 2021 -0600
@@ -421,7 +421,7 @@
protocol = purple_connection_get_protocol(conn);
- who = purple_protocol_chat_iface_get_user_real_name(protocol, conn, chat, name);
+ who = purple_protocol_chat_get_user_real_name(PURPLE_PROTOCOL_CHAT(protocol), conn, chat, name); pidgin_retrieve_user_info(conn, who ? who : name);
--- a/po/POTFILES.in Mon Jan 11 01:08:47 2021 -0600
+++ b/po/POTFILES.in Mon Jan 11 01:51:14 2021 -0600
@@ -257,6 +257,7 @@
libpurple/purplemessage.c
libpurple/purplepresence.c
libpurple/purpleprotocolattention.c
+libpurple/purpleprotocolchat.c libpurple/purpleprotocolclient.c
libpurple/purpleprotocolim.c
libpurple/purpleprotocolmedia.c