--- a/doc/reference/libpurple/libpurple-docs.xml Tue Aug 25 23:18:09 2020 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml Thu Aug 27 03:29:49 2020 -0500
@@ -71,6 +71,7 @@
<xi:include href="xml/purplekeyvaluepair.xml" />
<xi:include href="xml/purpleprotocolfactory.xml" />
<xi:include href="xml/purpleprotocolim.xml" />
+ <xi:include href="xml/purpleprotocolmedia.xml" /> <xi:include href="xml/purpleprotocolprivacy.xml" />
<xi:include href="xml/purpleuiinfo.xml" />
<xi:include href="xml/queuedoutputstream.xml" />
--- a/libpurple/meson.build Tue Aug 25 23:18:09 2020 -0500
+++ b/libpurple/meson.build Thu Aug 27 03:29:49 2020 -0500
@@ -55,6 +55,7 @@
'purpleprotocolfactory.c',
+ 'purpleprotocolmedia.c', 'purpleprotocolprivacy.c',
@@ -135,6 +136,7 @@
'purpleprotocolfactory.h',
+ 'purpleprotocolmedia.h', 'purpleprotocolprivacy.h',
--- a/libpurple/protocol.c Tue Aug 25 23:18:09 2020 -0500
+++ b/libpurple/protocol.c Thu Aug 27 03:29:49 2020 -0500
@@ -638,61 +638,3 @@
#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
#undef DEFINE_PROTOCOL_FUNC
-/**************************************************************************
- * Protocol Media Interface API
- **************************************************************************/
-#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
- PurpleProtocolMediaInterface *media_iface = \
- PURPLE_PROTOCOL_MEDIA_GET_IFACE(protocol); \
- if (media_iface && media_iface->funcname) \
- media_iface->funcname(__VA_ARGS__);
-#define DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol,defaultreturn,funcname,...) \
- PurpleProtocolMediaInterface *media_iface = \
- PURPLE_PROTOCOL_MEDIA_GET_IFACE(protocol); \
- if (media_iface && media_iface->funcname) \
- return media_iface->funcname(__VA_ARGS__); \
-purple_protocol_media_iface_get_type(void)
- if (G_UNLIKELY(type == 0)) {
- static const GTypeInfo info = {
- .class_size = sizeof(PurpleProtocolMediaInterface),
- type = g_type_register_static(G_TYPE_INTERFACE,
- "PurpleProtocolMediaInterface", &info, 0);
-purple_protocol_media_iface_initiate_session(PurpleProtocol *protocol,
- PurpleAccount *account, const char *who, PurpleMediaSessionType type)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, FALSE, initiate_session, account,
-purple_protocol_media_iface_get_caps(PurpleProtocol *protocol,
- PurpleAccount *account, const char *who)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, 0, get_caps, account, who);
-gboolean purple_protocol_media_iface_send_dtmf(PurpleProtocol *protocol,
- PurpleMedia *media, gchar dtmf, guint8 volume, guint8 duration)
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, FALSE, send_dtmf, media,
- dtmf, volume, duration);
-#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
-#undef DEFINE_PROTOCOL_FUNC
--- a/libpurple/protocol.h Tue Aug 25 23:18:09 2020 -0500
+++ b/libpurple/protocol.h Thu Aug 27 03:29:49 2020 -0500
@@ -474,54 +474,6 @@
#define PURPLE_PROTOCOL_CHAT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_CHAT, \
PurpleProtocolChatInterface))
-#define PURPLE_TYPE_PROTOCOL_MEDIA (purple_protocol_media_iface_get_type())
-typedef struct _PurpleProtocolMediaInterface PurpleProtocolMediaInterface;
- * PurpleProtocolMediaInterface:
- * @initiate_session: Initiate a media session with the given contact.
- * <sbr/>@account: The account to initiate the media session
- * <sbr/>@who: The remote user to initiate the session with.
- * <sbr/>@type: The type of media session to initiate.
- * <sbr/>Returns: %TRUE if the call succeeded else %FALSE.
- * (Doesn't imply the media session or stream
- * will be successfully created)
- * @get_caps: Checks to see if the given contact supports the given type of
- * <sbr/>@account: The account the contact is on.
- * <sbr/>@who: The remote user to check for media capability with.
- * <sbr/>Returns: The media caps the contact supports.
- * @send_dtmf: Sends DTMF codes out-of-band in a protocol-specific way if the
- * protocol supports it, or failing that in-band if the media backend
- * can do so. See purple_media_send_dtmf().
- * The protocol media interface.
- * This interface provides callbacks for media sessions on the protocol.
-struct _PurpleProtocolMediaInterface
- GTypeInterface parent_iface;
- gboolean (*initiate_session)(PurpleAccount *account, const char *who,
- PurpleMediaSessionType type);
- PurpleMediaCaps (*get_caps)(PurpleAccount *account,
- gboolean (*send_dtmf)(PurpleMedia *media, gchar dtmf,
- guint8 volume, guint8 duration);
-#define PURPLE_IS_PROTOCOL_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL_MEDIA))
-#define PURPLE_PROTOCOL_MEDIA_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_MEDIA, \
- PurpleProtocolMediaInterface))
* PURPLE_PROTOCOL_IMPLEMENTS:
* @protocol: The protocol in which to check
@@ -988,71 +940,6 @@
void purple_protocol_chat_iface_set_topic(PurpleProtocol *protocol,
PurpleConnection *gc, int id, const char *topic);
-/**************************************************************************/
-/* Protocol Media Interface API */
-/**************************************************************************/
- * purple_protocol_media_iface_get_type:
- * Returns: The #GType for the protocol media interface.
-GType purple_protocol_media_iface_get_type(void);
- * purple_protocol_media_iface_initiate_session:
- * @protocol: The #PurpleProtocol instance.
- * @account: The #PurpleAccount instance.
- * @who: The user to initiate a media session with.
- * @type: The type of media session to create.
- * Initiates a media connection of @type to @who.
- * Returns: TRUE if successful, FALSE otherwise.
-gboolean purple_protocol_media_iface_initiate_session(PurpleProtocol *protocol,
- PurpleAccount *account, const char *who, PurpleMediaSessionType type);
- * purple_protocol_media_iface_get_caps:
- * @protocol: The #PurpleProtocol instance.
- * @account: The #PurpleAccount instance.
- * @who: The user to get the media capabilites for.
- * Gets the #PurpleMediaCaps for @who which determine what types of media are
- * Returns: the media capabilities of @who.
-PurpleMediaCaps purple_protocol_media_iface_get_caps(PurpleProtocol *protocol,
- PurpleAccount *account, const char *who);
- * purple_protocol_media_iface_send_dtmf:
- * @protocol: The #PurpleProtocol instance.
- * @media: The #PurpleMedia instance.
- * @dtmf: A DTMF to send.
- * @volume: The volume to send @dtmf at.
- * @duration: The duration to send @dtmf (in ms?)
- * Sends a DTMF (dual-tone multi-frequency) signal via the established @media
- * for the given @duration at the given @volume.
- * It is up to the specific implementation if DTMF is send in or out of band.
- * Returns: TRUE if successful, FALSE otherwise.
-gboolean purple_protocol_media_iface_send_dtmf(PurpleProtocol *protocol,
- PurpleMedia *media, gchar dtmf, guint8 volume, guint8 duration);
#endif /* PURPLE_PROTOCOL_H */
--- a/libpurple/protocols.c Tue Aug 25 23:18:09 2020 -0500
+++ b/libpurple/protocols.c Thu Aug 27 03:29:49 2020 -0500
@@ -30,6 +30,7 @@
#include "purpleaccountoption.h"
+#include "purpleprotocolmedia.h" @@ -469,17 +470,24 @@
PurpleConnection *gc = NULL;
PurpleProtocol *protocol = NULL;
gc = purple_account_get_connection(account);
protocol = purple_connection_get_protocol(gc);
- /* should check that the protocol supports this media type here? */
- return purple_protocol_media_iface_initiate_session(protocol, account, who, type);
+ if(PURPLE_IS_PROTOCOL_MEDIA(protocol)) { + PurpleProtocolMedia *media = PURPLE_PROTOCOL_MEDIA(protocol); + return purple_protocol_media_initiate_session(media, account, who,
@@ -489,15 +497,22 @@
PurpleConnection *gc = NULL;
PurpleProtocol *protocol = NULL;
gc = purple_account_get_connection(account);
protocol = purple_connection_get_protocol(gc);
- return purple_protocol_media_iface_get_caps(protocol, account, who);
+ if(PURPLE_IS_PROTOCOL_MEDIA(protocol)) { + return purple_protocol_media_get_caps(PURPLE_PROTOCOL_MEDIA(protocol), + return PURPLE_MEDIA_CAPS_NONE; + return PURPLE_MEDIA_CAPS_NONE; - return PURPLE_MEDIA_CAPS_NONE;
--- a/libpurple/protocols/jabber/jabber.c Tue Aug 25 23:18:09 2020 -0500
+++ b/libpurple/protocols/jabber/jabber.c Thu Aug 27 03:29:49 2020 -0500
@@ -3250,6 +3250,7 @@
+ PurpleProtocolMedia *media; PurpleMediaSessionType type;
@@ -3258,7 +3259,7 @@
jabber_media_cancel_cb(JabberMediaRequest *request,
- PurpleRequestFields *fields)
+ PurpleRequestFields *fields) @@ -3271,7 +3272,7 @@
purple_request_fields_get_field(fields, "resource");
const gchar *selected = purple_request_field_choice_get_value(field);
gchar *who = g_strdup_printf("%s/%s", request->who, selected);
- jabber_initiate_media(request->account, who, request->type);
+ jabber_initiate_media(request->media, request->account, who, request->type); @@ -3280,8 +3281,8 @@
-jabber_initiate_media(PurpleAccount *account, const char *who,
- PurpleMediaSessionType type)
+jabber_initiate_media(PurpleProtocolMedia *media, PurpleAccount *account, + const gchar *who, PurpleMediaSessionType type) PurpleConnection *gc = purple_account_get_connection(account);
@@ -3342,7 +3343,7 @@
jbr = jb->resources->data;
name = g_strdup_printf("%s/%s", who, jbr->name);
- result = jabber_initiate_media(account, name, type);
+ result = jabber_initiate_media(media, account, name, type); @@ -3364,7 +3365,7 @@
name = g_strdup_printf("%s/%s", who, ljbr->name);
- caps = jabber_get_media_caps(account, name);
+ caps = jabber_get_media_caps(media, account, name); if ((type & PURPLE_MEDIA_AUDIO) &&
@@ -3399,7 +3400,7 @@
purple_request_field_destroy(field);
name = g_strdup_printf("%s/%s", who, jbr->name);
- result = jabber_initiate_media(account, name, type);
+ result = jabber_initiate_media(media, account, name, type); @@ -3408,6 +3409,7 @@
fields = purple_request_fields_new();
group = purple_request_field_group_new(NULL);
request = g_new0(JabberMediaRequest, 1);
+ request->media = media; request->account = account;
request->who = g_strdup(who);
@@ -3428,7 +3430,9 @@
-PurpleMediaCaps jabber_get_media_caps(PurpleAccount *account, const char *who)
+jabber_get_media_caps(PurpleProtocolMedia *media, PurpleAccount *account, PurpleConnection *gc = purple_account_get_connection(account);
--- a/libpurple/protocols/jabber/jabber.h Tue Aug 25 23:18:09 2020 -0500
+++ b/libpurple/protocols/jabber/jabber.h Thu Aug 27 03:29:49 2020 -0500
@@ -423,9 +423,8 @@
gboolean jabber_audio_enabled(JabberStream *js, const char *unused);
gboolean jabber_video_enabled(JabberStream *js, const char *unused);
-gboolean jabber_initiate_media(PurpleAccount *account, const char *who,
- PurpleMediaSessionType type);
-PurpleMediaCaps jabber_get_media_caps(PurpleAccount *account, const char *who);
+gboolean jabber_initiate_media(PurpleProtocolMedia *media, PurpleAccount *account, const char *who, PurpleMediaSessionType type); +PurpleMediaCaps jabber_get_media_caps(PurpleProtocolMedia *media, PurpleAccount *account, const char *who); gboolean jabber_can_receive_file(PurpleProtocolXfer *xfer, PurpleConnection *gc, const gchar *who);
#endif /* PURPLE_JABBER_JABBER_H */
--- a/libpurple/purpleprotocolim.h Tue Aug 25 23:18:09 2020 -0500
+++ b/libpurple/purpleprotocolim.h Thu Aug 27 03:29:49 2020 -0500
@@ -27,8 +27,8 @@
#define PURPLE_PROTOCOL_IM_H
- * @section_id: libpurple-protocolim
+ * SECTION:purpleprotocolim + * @section_id: libpurple-purpleprotocolim * @short_description: Protocol Instant Message Interface
* @title: ProtocolIM Interface
@@ -47,6 +47,8 @@
* PURPLE_TYPE_PROTOCOL_IM:
* The standard _get_type method for #PurpleProtocolIM.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleprotocolmedia.c Thu Aug 27 03:29:49 2020 -0500
@@ -0,0 +1,85 @@
+ * 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 <http://www.gnu.org/licenses/>. +#include "purpleprotocolmedia.h" +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_INTERFACE(PurpleProtocolMedia, purple_protocol_media, G_TYPE_INVALID) +purple_protocol_media_default_init(PurpleProtocolMediaInterface *iface) { +/****************************************************************************** + *****************************************************************************/ +purple_protocol_media_initiate_session(PurpleProtocolMedia *media, + PurpleAccount *account, + PurpleMediaSessionType type) + PurpleProtocolMediaInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_MEDIA(media), FALSE); + iface = PURPLE_PROTOCOL_MEDIA_GET_IFACE(media); + if(iface && iface->initiate_session) { + return iface->initiate_session(media, account, who, type); +purple_protocol_media_get_caps(PurpleProtocolMedia *media, + PurpleAccount *account, const gchar *who) + PurpleProtocolMediaInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_MEDIA(media), PURPLE_MEDIA_NONE); + iface = PURPLE_PROTOCOL_MEDIA_GET_IFACE(media); + if(iface && iface->get_caps) { + return iface->get_caps(media, account, who); + return PURPLE_MEDIA_NONE; +purple_protocol_media_send_dtmf(PurpleProtocolMedia *protocol_media, + PurpleMedia *media, gchar dtmf, guint8 volume, + PurpleProtocolMediaInterface *iface = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL_MEDIA(protocol_media), FALSE); + iface = PURPLE_PROTOCOL_MEDIA_GET_IFACE(protocol_media); + if(iface && iface->send_dtmf) { + return iface->send_dtmf(protocol_media, media, dtmf, volume, duration); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleprotocolmedia.h Thu Aug 27 03:29:49 2020 -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, see <http://www.gnu.org/licenses/>. +#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) +# error "only <purple.h> may be included directly" +#ifndef PURPLE_PROTOCOL_MEDIA_H +#define PURPLE_PROTOCOL_MEDIA_H + * SECTION:purpleprotocolmedia + * @section_id: libpurple-purpleprotocolmedia + * @short_description: Protocol Media Interface + * @title: ProtocolMedia Interface +#include <glib-object.h> +#include <libpurple/account.h> +#include <libpurple/media.h> +#define PURPLE_TYPE_PROTOCOL_MEDIA (purple_protocol_media_get_type()) +G_DECLARE_INTERFACE(PurpleProtocolMedia, purple_protocol_media, PURPLE, + PROTOCOL_MEDIA, GObject) + * PURPLE_TYPE_PROTOCOL_MEDIA: + * The standard _get_type method for #PurpleProtocolMedia. + * PurpleProtocolMediaInterface: + * @initiate_session: Initiate a media session with the given contact. + * <sbr/>@account: The account to initiate the media session + * <sbr/>@who: The remote user to initiate the session with. + * <sbr/>@type: The type of media session to initiate. + * <sbr/>Returns: %TRUE if the call succeeded else %FALSE. + * (Doesn't imply the media session or stream + * will be successfully created) + * @get_caps: Checks to see if the given contact supports the given type of + * <sbr/>@account: The account the contact is on. + * <sbr/>@who: The remote user to check for media capability with. + * <sbr/>Returns: The media caps the contact supports. + * @send_dtmf: Sends DTMF codes out-of-band in a protocol-specific way if the + * protocol supports it, or failing that in-band if the media backend + * can do so. See purple_media_send_dtmf(). + * The protocol media interface. + * This interface provides callbacks for media sessions on the protocol. +struct _PurpleProtocolMediaInterface { + gboolean (*initiate_session)(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who, PurpleMediaSessionType type); + PurpleMediaCaps (*get_caps)(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who); + gboolean (*send_dtmf)(PurpleProtocolMedia *protocol_media, PurpleMedia *media, gchar dtmf, guint8 volume, guint8 duration); + * purple_protocol_media_initiate_session: + * @media: The #PurpleProtocolMedia instance. + * @account: The #PurpleAccount instance. + * @who: The user to initiate a media session with. + * @type: The type of media session to create. + * Initiates a media connection of @type to @who. + * Returns: %TRUE if successful, %FALSE otherwise. +gboolean purple_protocol_media_initiate_session(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who, PurpleMediaSessionType type); + * purple_protocol_media_get_caps: + * @media: The #PurpleProtocolMedia instance. + * @account: The #PurpleAccount instance. + * @who: The user to get the media capabilites for. + * Gets the #PurpleMediaCaps for @who which determine what types of media are + * Returns: the media capabilities of @who. +PurpleMediaCaps purple_protocol_media_get_caps(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who); + * purple_protocol_media_send_dtmf: + * @protocol_media: The #PurpleProtocolMedia instance. + * @media: The #PurpleMedia instance. + * @dtmf: A DTMF to send. + * @volume: The volume to send @dtmf at. + * @duration: The duration to send @dtmf (in ms?) + * Sends a DTMF (dual-tone multi-frequency) signal via the established @media + * for the given @duration at the given @volume. + * It is up to the specific implementation if DTMF is send in or out of band. + * Returns: %TRUE if successful, %FALSE otherwise. +gboolean purple_protocol_media_send_dtmf(PurpleProtocolMedia *protocol_media, PurpleMedia *media, gchar dtmf, guint8 volume, guint8 duration); +#endif /* PURPLE_PROTOCOL_MEDIA_H */ --- a/po/POTFILES.in Tue Aug 25 23:18:09 2020 -0500
+++ b/po/POTFILES.in Thu Aug 27 03:29:49 2020 -0500
@@ -268,6 +268,8 @@
libpurple/purplechatuser.c
libpurple/purpleimconversation.c
+libpurple/purpleprotocolim.c +libpurple/purpleprotocolmedia.c libpurple/purpleprotocolprivacy.c
libpurple/queuedoutputstream.c