pidgin/pidgin

77d7bc9e5151
Parents cb26b9c6d4d0
Children 2ebcb8eb5c01
Make PurpleProtocolIM a proper interface

Move PurpleProtocolIM to a proper interface and it's own files

Update the protocols for the PurpleProtocolIM change

Testing Done:
Compiled, verified no new warnings, and tested with a few protocol plugins.

A bunch of the protocols have very weird/mixed syntax. I did what I could to keep it consistent but I'm sure I messed something up there, that said, since their all so inconsistent compared to everything else, I don't consider it a big deal which is why I didn't try to hard to fix it.

Reviewed at https://reviews.imfreedom.org/r/64/
--- a/doc/reference/libpurple/libpurple-docs.xml Thu Aug 13 18:29:17 2020 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml Thu Aug 13 21:07:35 2020 -0500
@@ -68,6 +68,7 @@
<xi:include href="xml/purpleaccountusersplit.xml" />
<xi:include href="xml/purplekeyvaluepair.xml" />
<xi:include href="xml/purpleprotocolfactory.xml" />
+ <xi:include href="xml/purpleprotocolim.xml" />
<xi:include href="xml/purpleuiinfo.xml" />
<xi:include href="xml/queuedoutputstream.xml" />
<xi:include href="xml/signals.xml" />
--- a/libpurple/meson.build Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/meson.build Thu Aug 13 21:07:35 2020 -0500
@@ -52,6 +52,7 @@
'purpleimconversation.c',
'purplekeyvaluepair.c',
'purpleprotocolfactory.c',
+ 'purpleprotocolim.c',
'purpleuiinfo.c',
'queuedoutputstream.c',
'request.c',
@@ -132,6 +133,7 @@
'purpleimconversation.h',
'purplekeyvaluepair.h',
'purpleprotocolfactory.h',
+ 'purpleprotocolim.h',
'purpleuiinfo.h',
'queuedoutputstream.h',
'request.h',
--- a/libpurple/protocol.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocol.c Thu Aug 13 21:07:35 2020 -0500
@@ -533,56 +533,6 @@
#undef DEFINE_PROTOCOL_FUNC
/**************************************************************************
- * Protocol IM Interface API
- **************************************************************************/
-#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
- PurpleProtocolIMInterface *im_iface = \
- PURPLE_PROTOCOL_IM_GET_IFACE(protocol); \
- if (im_iface && im_iface->funcname) \
- im_iface->funcname(__VA_ARGS__);
-
-#define DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol,defaultreturn,funcname,...) \
- PurpleProtocolIMInterface *im_iface = \
- PURPLE_PROTOCOL_IM_GET_IFACE(protocol); \
- if (im_iface && im_iface->funcname) \
- return im_iface->funcname(__VA_ARGS__); \
- else \
- return defaultreturn;
-
-GType
-purple_protocol_im_iface_get_type(void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY(type == 0)) {
- static const GTypeInfo info = {
- .class_size = sizeof(PurpleProtocolIMInterface),
- };
-
- type = g_type_register_static(G_TYPE_INTERFACE,
- "PurpleProtocolIMInterface", &info, 0);
- }
- return type;
-}
-
-int
-purple_protocol_im_iface_send(PurpleProtocol *protocol, PurpleConnection *gc,
- PurpleMessage *msg)
-{
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, 0, send, gc, msg);
-}
-
-unsigned int
-purple_protocol_im_iface_send_typing(PurpleProtocol *protocol,
- PurpleConnection *gc, const char *name, PurpleIMTypingState state)
-{
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, 0, send_typing, gc, name, state);
-}
-
-#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
-#undef DEFINE_PROTOCOL_FUNC
-
-/**************************************************************************
* Protocol Chat Interface API
**************************************************************************/
#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
--- a/libpurple/protocol.h Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocol.h Thu Aug 13 21:07:35 2020 -0500
@@ -375,46 +375,6 @@
#define PURPLE_PROTOCOL_SERVER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_SERVER, \
PurpleProtocolServerInterface))
-#define PURPLE_TYPE_PROTOCOL_IM (purple_protocol_im_iface_get_type())
-
-typedef struct _PurpleProtocolIMInterface PurpleProtocolIMInterface;
-
-/**
- * PurpleProtocolIMInterface:
- * @send: 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
- * just big something. If the message should not be echoed to the
- * conversation window, return 0.
- * @send_typing: If this protocol requires the #PURPLE_IM_TYPING message to be
- * sent repeatedly to signify that the user is still typing, then
- * the protocol should return the number of seconds to wait before
- * sending a subsequent notification. Otherwise the protocol
- * should return 0.
- *
- * The protocol IM interface.
- *
- * This interface provides callbacks needed by protocols that implement IMs.
- */
-struct _PurpleProtocolIMInterface
-{
- /*< private >*/
- GTypeInterface parent_iface;
-
- /*< public >*/
- int (*send)(PurpleConnection *connection, PurpleMessage *msg);
-
- unsigned int (*send_typing)(PurpleConnection *connection, const char *name,
- PurpleIMTypingState state);
-};
-
-#define PURPLE_IS_PROTOCOL_IM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL_IM))
-#define PURPLE_PROTOCOL_IM_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_IM, \
- PurpleProtocolIMInterface))
-
#define PURPLE_TYPE_PROTOCOL_CHAT (purple_protocol_chat_iface_get_type())
typedef struct _PurpleProtocolChatInterface PurpleProtocolChatInterface;
@@ -901,23 +861,6 @@
PurpleGetPublicAliasFailureCallback failure_cb);
/**************************************************************************/
-/* Protocol IM Interface API */
-/**************************************************************************/
-
-/**
- * purple_protocol_im_iface_get_type:
- *
- * Returns: The #GType for the protocol IM interface.
- */
-GType purple_protocol_im_iface_get_type(void);
-
-int purple_protocol_im_iface_send(PurpleProtocol *protocol, PurpleConnection *connection,
- PurpleMessage *msg);
-
-unsigned int purple_protocol_im_iface_send_typing(PurpleProtocol *protocol,
- PurpleConnection *connection, const char *name, PurpleIMTypingState state);
-
-/**************************************************************************/
/* Protocol Chat Interface API */
/**************************************************************************/
--- a/libpurple/protocols/bonjour/bonjour.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/bonjour/bonjour.c Thu Aug 13 21:07:35 2020 -0500
@@ -206,7 +206,7 @@
}
static int
-bonjour_send_im(PurpleConnection *connection, PurpleMessage *msg)
+bonjour_send_im(PurpleProtocolIM *im, PurpleConnection *connection, PurpleMessage *msg)
{
BonjourData *bd = purple_connection_get_protocol_data(connection);
--- a/libpurple/protocols/facebook/facebook.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/facebook/facebook.c Thu Aug 13 21:07:35 2020 -0500
@@ -1192,7 +1192,7 @@
}
static gint
-fb_im_send(PurpleConnection *gc, PurpleMessage *msg)
+fb_im_send(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg)
{
const gchar *name;
const gchar *text;
@@ -1215,8 +1215,8 @@
}
static guint
-fb_im_send_typing(PurpleConnection *gc, const gchar *name,
- PurpleIMTypingState state)
+fb_im_send_typing(PurpleProtocolIM *im, PurpleConnection *gc,
+ const gchar *name, PurpleIMTypingState state)
{
FbApi *api;
FbData *fata;
--- a/libpurple/protocols/gg/gg.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/gg/gg.c Thu Aug 13 21:07:35 2020 -0500
@@ -859,7 +859,7 @@
purple_debug_info("gg", "Connection closed.\n");
}
-static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state)
+static unsigned int ggp_send_typing(PurpleProtocolIM *im, PurpleConnection *gc, const char *name, PurpleIMTypingState state)
{
GGPInfo *info = purple_connection_get_protocol_data(gc);
int dummy_length; /* we don't send real length of typed message */
--- a/libpurple/protocols/gg/message-prpl.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/gg/message-prpl.c Thu Aug 13 21:07:35 2020 -0500
@@ -625,7 +625,8 @@
return text_new;
}
-int ggp_message_send_im(PurpleConnection *gc, PurpleMessage *msg)
+int ggp_message_send_im(PurpleProtocolIM *pim, PurpleConnection *gc,
+ PurpleMessage *msg)
{
GGPInfo *info = purple_connection_get_protocol_data(gc);
PurpleIMConversation *im;
--- a/libpurple/protocols/gg/message-prpl.h Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/gg/message-prpl.h Thu Aug 13 21:07:35 2020 -0500
@@ -43,7 +43,7 @@
void ggp_message_got_multilogon(PurpleConnection *gc,
const struct gg_event_msg *ev);
-int ggp_message_send_im(PurpleConnection *gc, PurpleMessage *msg);
+int ggp_message_send_im(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg);
gchar * ggp_message_format_to_gg(PurpleConversation *conv, const gchar *text);
#endif /* PURPLE_GG_MESSAGE_PRPL_H */
--- a/libpurple/protocols/irc/irc.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/irc/irc.c Thu Aug 13 21:07:35 2020 -0500
@@ -40,7 +40,7 @@
static void irc_login(PurpleAccount *account);
static void irc_login_cb(GObject *source, GAsyncResult *res, gpointer user_data);
static void irc_close(PurpleConnection *gc);
-static int irc_im_send(PurpleConnection *gc, PurpleMessage *msg);
+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 void irc_read_input_cb(GObject *source, GAsyncResult *res, gpointer data);
@@ -630,7 +630,7 @@
g_free(irc);
}
-static int irc_im_send(PurpleConnection *gc, PurpleMessage *msg)
+static int irc_im_send(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg)
{
struct irc_conn *irc = purple_connection_get_protocol_data(gc);
char *plain;
--- a/libpurple/protocols/jabber/jabber.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/jabber/jabber.c Thu Aug 13 21:07:35 2020 -0500
@@ -3057,6 +3057,9 @@
static PurpleCmdRet jabber_cmd_chat_msg(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
+ PurpleConnection *pc = NULL;
+ PurpleProtocol *prpl = NULL;
+ PurpleMessage *msg = NULL;
JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
char *who;
@@ -3064,9 +3067,12 @@
return PURPLE_CMD_RET_FAILED;
who = g_strdup_printf("%s@%s/%s", chat->room, chat->server, args[0]);
-
- jabber_message_send_im(purple_conversation_get_connection(conv),
- purple_message_new_outgoing(who, args[1], 0));
+ pc = purple_conversation_get_connection(conv);
+ prpl = purple_connection_get_protocol(pc);
+
+ msg = purple_message_new_outgoing(who, args[1], 0);
+
+ jabber_message_send_im(PURPLE_PROTOCOL_IM(prpl), pc, msg);
g_free(who);
return PURPLE_CMD_RET_OK;
--- a/libpurple/protocols/jabber/message.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/jabber/message.c Thu Aug 13 21:07:35 2020 -0500
@@ -1134,7 +1134,8 @@
return ret;
}
-int jabber_message_send_im(PurpleConnection *gc, PurpleMessage *msg)
+int jabber_message_send_im(PurpleProtocolIM *pim, PurpleConnection *gc,
+ PurpleMessage *msg)
{
JabberMessage *jm;
JabberBuddy *jb;
@@ -1245,7 +1246,8 @@
return 1;
}
-unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state)
+unsigned int jabber_send_typing(PurpleProtocolIM *pim, PurpleConnection *gc,
+ const char *who, PurpleIMTypingState state)
{
JabberStream *js;
JabberMessage *jm;
--- a/libpurple/protocols/jabber/message.h Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/jabber/message.h Thu Aug 13 21:07:35 2020 -0500
@@ -70,10 +70,10 @@
void jabber_message_send(JabberMessage *jm);
void jabber_message_parse(JabberStream *js, PurpleXmlNode *packet);
-int jabber_message_send_im(PurpleConnection *gc, PurpleMessage *msg);
+int jabber_message_send_im(PurpleProtocolIM *pim, PurpleConnection *gc, PurpleMessage *msg);
int jabber_message_send_chat(PurpleConnection *gc, int id, PurpleMessage *msg);
-unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state);
+unsigned int jabber_send_typing(PurpleProtocolIM *pim, PurpleConnection *gc, const char *who, PurpleIMTypingState state);
gboolean jabber_buzz_isenabled(JabberStream *js, const gchar *namespace);
--- a/libpurple/protocols/novell/novell.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/novell/novell.c Thu Aug 13 21:07:35 2020 -0500
@@ -2242,7 +2242,7 @@
}
static int
-novell_send_im(PurpleConnection *gc, PurpleMessage *msg)
+novell_send_im(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg)
{
NMUserRecord *user_record = NULL;
NMConference *conf = NULL;
@@ -2333,7 +2333,7 @@
}
static unsigned int
-novell_send_typing(PurpleConnection * gc, const char *name, PurpleIMTypingState state)
+novell_send_typing(PurpleProtocolIM *im, PurpleConnection * gc, const char *name, PurpleIMTypingState state)
{
NMConference *conf = NULL;
NMUser *user;
--- a/libpurple/protocols/null/nullprpl.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/null/nullprpl.c Thu Aug 13 21:07:35 2020 -0500
@@ -399,7 +399,8 @@
foreach_null_gc(report_status_change, gc, NULL);
}
-static int null_send_im(PurpleConnection *gc, PurpleMessage *msg)
+static int null_send_im(PurpleProtocolIM *im, PurpleConnection *gc,
+ PurpleMessage *msg)
{
const char *from_username = purple_account_get_username(purple_connection_get_account(gc));
const gchar *who = purple_message_get_recipient(msg);
@@ -479,8 +480,10 @@
(PurpleIMTypingState)typing);
}
-static unsigned int null_send_typing(PurpleConnection *gc, const char *name,
- PurpleIMTypingState typing) {
+static unsigned int null_send_typing(PurpleProtocolIM *im,
+ PurpleConnection *gc, const char *name,
+ PurpleIMTypingState typing)
+{
purple_debug_info("nullprpl", "%s %s\n", purple_account_get_username(purple_connection_get_account(gc)),
typing_state_to_string(typing));
foreach_null_gc(notify_typing, gc, (gpointer)typing);
--- a/libpurple/protocols/sametime/sametime.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/sametime/sametime.c Thu Aug 13 21:07:35 2020 -0500
@@ -3665,8 +3665,9 @@
}
-static int mw_protocol_send_im(PurpleConnection *gc, PurpleMessage *msg) {
-
+static int mw_protocol_send_im(PurpleProtocolIM *im, PurpleConnection *gc,
+ PurpleMessage *msg)
+{
gchar name[1000];
struct mwPurpleProtocolData *pd;
struct mwIdBlock who = { name, NULL };
@@ -3743,7 +3744,8 @@
}
-static unsigned int mw_protocol_send_typing(PurpleConnection *gc,
+static unsigned int mw_protocol_send_typing(PurpleProtocolIM *im,
+ PurpleConnection *gc,
const char *name,
PurpleIMTypingState state) {
--- a/libpurple/protocols/silc/silc.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/silc/silc.c Thu Aug 13 21:07:35 2020 -0500
@@ -1453,7 +1453,8 @@
}
static int
-silcpurple_send_im(PurpleConnection *gc, PurpleMessage *pmsg)
+silcpurple_send_im(PurpleProtocolIM *pim, PurpleConnection *gc,
+ PurpleMessage *pmsg)
{
SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
--- a/libpurple/protocols/simple/simple.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/simple/simple.c Thu Aug 13 21:07:35 2020 -0500
@@ -1082,7 +1082,7 @@
g_free(fullto);
}
-static int simple_im_send(PurpleConnection *gc, PurpleMessage *msg) {
+static int simple_im_send(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg) {
struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
char *to = g_strdup(purple_message_get_recipient(msg));
char *text = purple_unescape_html(purple_message_get_contents(msg));
@@ -1340,7 +1340,7 @@
send_sip_response(sip->gc, msg, 200, "OK", NULL);
}
-static unsigned int simple_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state) {
+static unsigned int simple_typing(PurpleProtocolIM *im, PurpleConnection *gc, const char *name, PurpleIMTypingState state) {
struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
--- a/libpurple/protocols/zephyr/zephyr.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/protocols/zephyr/zephyr.c Thu Aug 13 21:07:35 2020 -0500
@@ -2057,7 +2057,7 @@
}
-static int zephyr_send_im(PurpleConnection *gc, PurpleMessage *msg)
+static int zephyr_send_im(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg)
{
const char *sig;
zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
@@ -2531,7 +2531,7 @@
return "zephyr";
}
-static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state) {
+static unsigned int zephyr_send_typing(PurpleProtocolIM *im, PurpleConnection *gc, const char *who, PurpleIMTypingState state) {
gchar *recipient;
zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if (use_tzc(zephyr))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleprotocolim.c Thu Aug 13 21:07:35 2020 -0500
@@ -0,0 +1,67 @@
+/*
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "purpleprotocolim.h"
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_INTERFACE(PurpleProtocolIM, purple_protocol_im, G_TYPE_INVALID)
+
+static void
+purple_protocol_im_default_init(PurpleProtocolIMInterface *iface) {
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+gint
+purple_protocol_im_send(PurpleProtocolIM *im, PurpleConnection *gc,
+ PurpleMessage *msg)
+{
+ PurpleProtocolIMInterface *iface = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_PROTOCOL_IM(im), -1);
+
+ iface = PURPLE_PROTOCOL_IM_GET_IFACE(im);
+ if(iface && iface->send) {
+ return iface->send(im, gc, msg);
+ }
+
+ return -1;
+}
+
+guint
+purple_protocol_im_send_typing(PurpleProtocolIM *im, PurpleConnection *gc,
+ const gchar *name, PurpleIMTypingState state)
+{
+ PurpleProtocolIMInterface *iface = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_PROTOCOL_IM(im), 0);
+
+ iface = PURPLE_PROTOCOL_IM_GET_IFACE(im);
+ if(iface && iface->send_typing) {
+ return iface->send_typing(im, gc, name, state);
+ }
+
+ return 0;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleprotocolim.h Thu Aug 13 21:07:35 2020 -0500
@@ -0,0 +1,130 @@
+/*
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_PROTOCOL_IM_H
+#define PURPLE_PROTOCOL_IM_H
+
+/**
+ * SECTION:protocolim
+ * @section_id: libpurple-protocolim
+ * @short_description: Protocol Instant Message Interface
+ * @title: ProtocolIM Interface
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libpurple/connection.h>
+#include <libpurple/conversationtypes.h>
+
+#define PURPLE_TYPE_PROTOCOL_IM (purple_protocol_im_get_type())
+G_DECLARE_INTERFACE(PurpleProtocolIM, purple_protocol_im, PURPLE, PROTOCOL_IM,
+ GObject)
+
+/**
+ * PURPLE_TYPE_PROTOCOL_IM:
+ *
+ * The standard _get_type method for #PurpleProtocolIM.
+ */
+
+/**
+ * PurpleProtocolIMInterface:
+ * @send: 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
+ * just big something. If the message should not be echoed to the
+ * conversation window, return 0.
+ * @send_typing: If this protocol requires the #PURPLE_IM_TYPING message to be
+ * sent repeatedly to signify that the user is still typing, then
+ * the protocol should return the number of seconds to wait before
+ * sending a subsequent notification. Otherwise the protocol
+ * should return 0.
+ *
+ * The protocol IM interface that needs to be implemented to send one to one
+ * messages.
+ */
+struct _PurpleProtocolIMInterface {
+ /*< private >*/
+ GTypeInterface parent;
+
+ /*< public >*/
+ gint (*send)(PurpleProtocolIM *im, PurpleConnection *connection,
+ PurpleMessage *msg);
+
+ guint (*send_typing)(PurpleProtocolIM *im, PurpleConnection *connection,
+ const gchar *name, PurpleIMTypingState state);
+
+ /*< private >*/
+ gpointer reserved[4];
+};
+
+G_BEGIN_DECLS
+
+/**
+ * purple_protocol_im_send:
+ * @im: The #PurpleProtocolIM instance.
+ * @connection: The #PurpleConnection to use.
+ * @msg: The #PurpleMessage to send.
+ *
+ * Sends @msg out over @connection.
+ *
+ * Returns: >= 0 on success, or < 0 on error. If 0 is returned the message
+ * should not be output locally.
+ */
+gint purple_protocol_im_send(PurpleProtocolIM *im,
+ PurpleConnection *connection,
+ PurpleMessage *msg);
+
+/**
+ * purple_protocol_im_send_type:
+ * @im: The #PurpleProtocolIM instance.
+ * @connection: The #PurpleConversation to use.
+ * @name: The name of the user to send a typing notification to.
+ * @state: The #PurpleIMTypingState Value.
+ *
+ * If this protocol requires the #PURPLE_IM_TYPING message to be sent
+ * repeatedly to signify that the user is still typing, then the protocol
+ * should return the number of seconds to wait before sending a subsequent
+ * notification. Otherwise the protocol should return 0.
+ *
+ * Returns: A quiet-period, specified in seconds, where Purple will not send
+ * any additional typing notification messages. Most protocols should
+ * return 0, which means that no additional #PURPLE_IM_TYPING messages
+ * need to be sent. If this is 5, for example, then Purple will wait
+ * five seconds, and if the Purple user is still typing then Purple
+ * will send another #PURPLE_IM_TYPING message.
+ */
+guint purple_protocol_im_send_typing(PurpleProtocolIM *im,
+ PurpleConnection *connection,
+ const gchar *name,
+ PurpleIMTypingState state);
+
+G_END_DECLS
+
+#endif /* PURPLE_PROTOCOL_IM_H */
+
--- a/libpurple/server.c Thu Aug 13 18:29:17 2020 -0500
+++ b/libpurple/server.c Thu Aug 13 21:07:35 2020 -0500
@@ -34,6 +34,7 @@
#include "prefs.h"
#include "protocol.h"
#include "purpleprivate.h"
+#include "purpleprotocolim.h"
#include "request.h"
#include "signals.h"
#include "server.h"
@@ -46,11 +47,11 @@
unsigned int
purple_serv_send_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state)
{
- PurpleProtocol *protocol;
+ if(gc) {
+ PurpleProtocol *protocol = purple_connection_get_protocol(gc);
+ PurpleProtocolIM *im = PURPLE_PROTOCOL_IM(protocol);
- if (gc) {
- protocol = purple_connection_get_protocol(gc);
- return purple_protocol_im_iface_send_typing(protocol, gc, name, state);
+ return purple_protocol_im_send_typing(im, gc, name, state);
}
return 0;
@@ -139,8 +140,15 @@
im = purple_conversations_find_im_with_account(recipient, account);
- if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, IM, send))
- val = purple_protocol_im_iface_send(protocol, gc, msg);
+ /* we probably shouldn't be here if the protocol doesn't know how to send
+ * im's... but there was a similar check here before so I just reproduced
+ * it until we can reevaluate this function.
+ */
+ if(PURPLE_IS_PROTOCOL_IM(protocol)) {
+ PurpleProtocolIM *pim = PURPLE_PROTOCOL_IM(protocol);
+
+ val = purple_protocol_im_send(pim, gc, msg);
+ }
/*
* XXX - If "only auto-reply when away & idle" is set, then shouldn't