pidgin/pidgin

20c80c3c31c5
Merged in rw_grim/pidgin (pull request #297)

Moved PurpleProtocolXfer to xfer.[ch], started a testing ui

Approved-by: Eion Robb
--- a/finch/gntblist.c Tue Dec 26 05:56:57 2017 +0000
+++ b/finch/gntblist.c Fri Dec 29 03:57:44 2017 +0000
@@ -1214,12 +1214,16 @@
add_custom_action(menu, _("Add Buddy Pounce"),
PURPLE_CALLBACK(finch_blist_pounce_node_cb), buddy);
- if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, send))
+ if (PURPLE_IS_PROTOCOL_XFER(protocol))
{
- if (!PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, can_receive) ||
- purple_protocol_xfer_iface_can_receive(protocol, gc, purple_buddy_get_name(buddy)))
+ if (purple_protocol_xfer_can_receive(
+ PURPLE_PROTOCOL_XFER(protocol),
+ gc,
+ purple_buddy_get_name(buddy))
+ ) {
add_custom_action(menu, _("Send File"),
PURPLE_CALLBACK(finch_blist_menu_send_file_cb), buddy);
+ }
}
account = purple_buddy_get_account(buddy);
--- a/finch/gntconv.c Tue Dec 26 05:56:57 2017 +0000
+++ b/finch/gntconv.c Fri Dec 29 03:57:44 2017 +0000
@@ -719,10 +719,13 @@
gnt_menu_add_item(GNT_MENU(sub), item);
gnt_menuitem_set_callback(item, add_pounce_cb, ggc);
- if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, send) &&
- (!PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, can_receive) ||
- purple_protocol_xfer_iface_can_receive(protocol, gc,
- purple_conversation_get_name(ggc->active_conv)))) {
+ if (PURPLE_IS_PROTOCOL_XFER(protocol) &&
+ purple_protocol_xfer_can_receive(
+ PURPLE_PROTOCOL_XFER(protocol),
+ gc,
+ purple_conversation_get_name(ggc->active_conv)
+ )
+ ) {
item = gnt_menuitem_new(_("Send File"));
gnt_menu_add_item(GNT_MENU(sub), item);
gnt_menuitem_set_callback(item, send_file_cb, ggc);
--- a/libpurple/plugins.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/plugins.c Fri Dec 29 03:57:44 2017 +0000
@@ -1137,7 +1137,11 @@
gplugin_manager_add_default_paths();
- purple_plugins_add_search_path(PURPLE_LIBDIR);
+ if(!g_getenv("PURPLE_PLUGINS_SKIP")) {
+ purple_plugins_add_search_path(PURPLE_LIBDIR);
+ } else {
+ purple_debug_info("plugins", "PURPLE_PLUGINS_SKIP environment variable set, skipping normal plugin paths");
+ }
g_signal_connect(gplugin_manager_get_instance(), "loading-plugin",
G_CALLBACK(plugin_loading_cb), NULL);
--- a/libpurple/protocol.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocol.c Fri Dec 29 03:57:44 2017 +0000
@@ -800,63 +800,6 @@
#undef DEFINE_PROTOCOL_FUNC
/**************************************************************************
- * Protocol Xfer Interface API
- **************************************************************************/
-#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
- PurpleProtocolXferIface *xfer_iface = \
- PURPLE_PROTOCOL_GET_XFER_IFACE(protocol); \
- if (xfer_iface && xfer_iface->funcname) \
- xfer_iface->funcname(__VA_ARGS__);
-
-#define DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol,defaultreturn,funcname,...) \
- PurpleProtocolXferIface *xfer_iface = \
- PURPLE_PROTOCOL_GET_XFER_IFACE(protocol); \
- if (xfer_iface && xfer_iface->funcname) \
- return xfer_iface->funcname(__VA_ARGS__); \
- else \
- return defaultreturn;
-
-GType
-purple_protocol_xfer_iface_get_type(void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY(type == 0)) {
- static const GTypeInfo info = {
- .class_size = sizeof(PurpleProtocolXferIface),
- };
-
- type = g_type_register_static(G_TYPE_INTERFACE,
- "PurpleProtocolXferIface", &info, 0);
- }
- return type;
-}
-
-gboolean
-purple_protocol_xfer_iface_can_receive(PurpleProtocol *protocol,
- PurpleConnection *gc, const char *who)
-{
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, FALSE, can_receive, gc, who);
-}
-
-void
-purple_protocol_xfer_iface_send(PurpleProtocol *protocol, PurpleConnection *gc,
- const char *who, const char *filename)
-{
- DEFINE_PROTOCOL_FUNC(protocol, send, gc, who, filename);
-}
-
-PurpleXfer *
-purple_protocol_xfer_iface_new_xfer(PurpleProtocol *protocol,
- PurpleConnection *gc, const char *who)
-{
- DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, new_xfer, gc, who);
-}
-
-#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
-#undef DEFINE_PROTOCOL_FUNC
-
-/**************************************************************************
* Protocol Roomlist Interface API
**************************************************************************/
#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
--- a/libpurple/protocol.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocol.h Fri Dec 29 03:57:44 2017 +0000
@@ -556,35 +556,6 @@
#define PURPLE_PROTOCOL_GET_PRIVACY_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_PRIVACY_IFACE, \
PurpleProtocolPrivacyIface))
-#define PURPLE_TYPE_PROTOCOL_XFER_IFACE (purple_protocol_xfer_iface_get_type())
-
-typedef struct _PurpleProtocolXferIface PurpleProtocolXferIface;
-
-/**
- * PurpleProtocolXferIface:
- *
- * The protocol file transfer interface.
- *
- * This interface provides file transfer callbacks for the protocol.
- */
-struct _PurpleProtocolXferIface
-{
- /*< private >*/
- GTypeInterface parent_iface;
-
- /*< public >*/
- gboolean (*can_receive)(PurpleConnection *connection, const char *who);
-
- void (*send)(PurpleConnection *connection, const char *who,
- const char *filename);
-
- PurpleXfer *(*new_xfer)(PurpleConnection *connection, const char *who);
-};
-
-#define PURPLE_PROTOCOL_HAS_XFER_IFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL_XFER_IFACE))
-#define PURPLE_PROTOCOL_GET_XFER_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_XFER_IFACE, \
- PurpleProtocolXferIface))
-
#define PURPLE_TYPE_PROTOCOL_ROOMLIST_IFACE (purple_protocol_roomlist_iface_get_type())
typedef struct _PurpleProtocolRoomlistIface PurpleProtocolRoomlistIface;
@@ -1084,26 +1055,6 @@
PurpleConnection *connection);
/**************************************************************************/
-/* Protocol Xfer Interface API */
-/**************************************************************************/
-
-/**
- * purple_protocol_xfer_iface_get_type:
- *
- * Returns: The #GType for the protocol xfer interface.
- */
-GType purple_protocol_xfer_iface_get_type(void);
-
-gboolean purple_protocol_xfer_iface_can_receive(PurpleProtocol *protocol,
- PurpleConnection *connection, const char *who);
-
-void purple_protocol_xfer_iface_send(PurpleProtocol *protocol, PurpleConnection *connection,
- const char *who, const char *filename);
-
-PurpleXfer *purple_protocol_xfer_iface_new_xfer(PurpleProtocol *protocol,
- PurpleConnection *connection, const char *who);
-
-/**************************************************************************/
/* Protocol Roomlist Interface API */
/**************************************************************************/
--- a/libpurple/protocols/bonjour/bonjour.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/bonjour/bonjour.c Fri Dec 29 03:57:44 2017 +0000
@@ -466,7 +466,7 @@
}
static gboolean
-bonjour_can_receive_file(PurpleConnection *connection, const char *who)
+bonjour_can_receive_file(PurpleProtocolXfer *prplxfer, PurpleConnection *connection, const char *who)
{
PurpleBuddy *buddy = purple_blist_find_buddy(purple_connection_get_account(connection), who);
@@ -699,7 +699,7 @@
}
static void
-bonjour_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface)
+bonjour_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
{
xfer_iface->can_receive = bonjour_can_receive_file;
xfer_iface->send = bonjour_send_file;
@@ -718,7 +718,7 @@
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_IM_IFACE,
bonjour_protocol_im_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER_IFACE,
+ PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER,
bonjour_protocol_xfer_iface_init)
);
--- a/libpurple/protocols/bonjour/bonjour_ft.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.c Fri Dec 29 03:57:44 2017 +0000
@@ -339,7 +339,7 @@
}
PurpleXfer *
-bonjour_new_xfer(PurpleConnection *gc, const char *who)
+bonjour_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who)
{
PurpleXfer *xfer;
XepXfer *xep_xfer;
@@ -376,7 +376,7 @@
}
void
-bonjour_send_file(PurpleConnection *gc, const char *who, const char *file)
+bonjour_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file)
{
PurpleXfer *xfer;
@@ -385,7 +385,7 @@
purple_debug_info("bonjour", "Bonjour-send-file to=%s.\n", who);
- xfer = bonjour_new_xfer(gc, who);
+ xfer = bonjour_new_xfer(prplxfer, gc, who);
if (file)
purple_xfer_request_accepted(xfer, file);
--- a/libpurple/protocols/bonjour/bonjour_ft.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.h Fri Dec 29 03:57:44 2017 +0000
@@ -60,7 +60,7 @@
* @param gc The PurpleConnection handle.
* @param who Who will we be sending it to?
*/
-PurpleXfer *bonjour_new_xfer(PurpleConnection *gc, const char *who);
+PurpleXfer *bonjour_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
/**
* Send a file.
@@ -69,7 +69,7 @@
* @param who Who are we sending it to?
* @param file What file? If NULL, user will choose after this call.
*/
-void bonjour_send_file(PurpleConnection *gc, const char *who, const char *file);
+void bonjour_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file);
void xep_si_parse(PurpleConnection *pc, PurpleXmlNode *packet, PurpleBuddy *pb);
void
--- a/libpurple/protocols/gg/edisc.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/gg/edisc.c Fri Dec 29 03:57:44 2017 +0000
@@ -383,7 +383,7 @@
static void ggp_edisc_xfer_send_done(PurpleHttpConnection *hc,
PurpleHttpResponse *response, gpointer _xfer);
-gboolean ggp_edisc_xfer_can_receive_file(PurpleConnection *gc,
+gboolean ggp_edisc_xfer_can_receive_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc,
const char *who)
{
PurpleBuddy *buddy;
@@ -664,7 +664,7 @@
ggp_edisc_xfer_error(xfer, _("Error while sending a file"));
}
-PurpleXfer * ggp_edisc_xfer_send_new(PurpleConnection *gc, const char *who)
+PurpleXfer * ggp_edisc_xfer_send_new(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who)
{
PurpleXfer *xfer;
ggp_edisc_xfer *edisc_xfer;
@@ -686,7 +686,7 @@
return xfer;
}
-void ggp_edisc_xfer_send_file(PurpleConnection *gc, const char *who,
+void ggp_edisc_xfer_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who,
const char *filename)
{
PurpleXfer *xfer;
@@ -697,7 +697,7 @@
/* Nothing interesting here, this code is common among protocols.
* See ggp_edisc_xfer_send_new. */
- xfer = ggp_edisc_xfer_send_new(gc, who);
+ xfer = ggp_edisc_xfer_send_new(prplxfer, gc, who);
if (filename)
purple_xfer_request_accepted(xfer, filename);
else
--- a/libpurple/protocols/gg/edisc.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/gg/edisc.h Fri Dec 29 03:57:44 2017 +0000
@@ -41,9 +41,9 @@
const char *data);
/* Sending a file. */
-gboolean ggp_edisc_xfer_can_receive_file(PurpleConnection *gc, const char *who);
-void ggp_edisc_xfer_send_file(PurpleConnection *gc, const char *who,
+gboolean ggp_edisc_xfer_can_receive_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
+void ggp_edisc_xfer_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who,
const char *filename);
-PurpleXfer * ggp_edisc_xfer_send_new(PurpleConnection *gc, const char *who);
+PurpleXfer * ggp_edisc_xfer_send_new(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
#endif /* _GGP_EDISC_H */
--- a/libpurple/protocols/gg/gg.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/gg/gg.c Fri Dec 29 03:57:44 2017 +0000
@@ -1071,7 +1071,7 @@
}
static void
-ggp_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface)
+ggp_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
{
xfer_iface->can_receive = ggp_edisc_xfer_can_receive_file;
xfer_iface->send = ggp_edisc_xfer_send_file;
@@ -1099,7 +1099,7 @@
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_PRIVACY_IFACE,
ggp_protocol_privacy_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER_IFACE,
+ PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER,
ggp_protocol_xfer_iface_init)
);
--- a/libpurple/protocols/irc/dcc_send.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/irc/dcc_send.c Fri Dec 29 03:57:44 2017 +0000
@@ -359,7 +359,7 @@
}
-PurpleXfer *irc_dccsend_new_xfer(PurpleConnection *gc, const char *who) {
+PurpleXfer *irc_dccsend_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who) {
PurpleXfer *xfer;
struct irc_xfer_send_data *xd;
@@ -387,8 +387,8 @@
* buddy menu
* It sets up the PurpleXfer struct and tells Purple to go ahead
*/
-void irc_dccsend_send_file(PurpleConnection *gc, const char *who, const char *file) {
- PurpleXfer *xfer = irc_dccsend_new_xfer(gc, who);
+void irc_dccsend_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file) {
+ PurpleXfer *xfer = irc_dccsend_new_xfer(prplxfer, gc, who);
/* Perform the request */
if (file)
--- a/libpurple/protocols/irc/irc.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/irc/irc.c Fri Dec 29 03:57:44 2017 +0000
@@ -916,7 +916,7 @@
}
static void
-irc_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface)
+irc_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
{
xfer_iface->send = irc_dccsend_send_file;
xfer_iface->new_xfer = irc_dccsend_new_xfer;
@@ -940,7 +940,7 @@
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_ROOMLIST_IFACE,
irc_protocol_roomlist_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER_IFACE,
+ PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER,
irc_protocol_xfer_iface_init)
);
--- a/libpurple/protocols/irc/irc.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/irc/irc.h Fri Dec 29 03:57:44 2017 +0000
@@ -237,7 +237,7 @@
int irc_cmd_whois(struct irc_conn *irc, const char *cmd, const char *target, const char **args);
int irc_cmd_whowas(struct irc_conn *irc, const char *cmd, const char *target, const char **args);
-PurpleXfer *irc_dccsend_new_xfer(PurpleConnection *gc, const char *who);
-void irc_dccsend_send_file(PurpleConnection *gc, const char *who, const char *file);
+PurpleXfer *irc_dccsend_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
+void irc_dccsend_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file);
void irc_dccsend_recv(struct irc_conn *irc, const char *from, const char *msg);
#endif /* _PURPLE_IRC_H */
--- a/libpurple/protocols/jabber/jabber.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/jabber/jabber.c Fri Dec 29 03:57:44 2017 +0000
@@ -3540,7 +3540,7 @@
#endif
}
-gboolean jabber_can_receive_file(PurpleConnection *gc, const char *who)
+gboolean jabber_can_receive_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who)
{
JabberStream *js = purple_connection_get_protocol_data(gc);
@@ -4263,7 +4263,7 @@
}
static void
-jabber_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface)
+jabber_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
{
xfer_iface->can_receive = jabber_can_receive_file;
xfer_iface->send = jabber_si_xfer_send;
@@ -4297,7 +4297,7 @@
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_MEDIA_IFACE,
jabber_protocol_media_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER_IFACE,
+ PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER,
jabber_protocol_xfer_iface_init)
);
--- a/libpurple/protocols/jabber/jabber.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/jabber/jabber.h Fri Dec 29 03:57:44 2017 +0000
@@ -431,6 +431,6 @@
gboolean jabber_initiate_media(PurpleAccount *account, const char *who,
PurpleMediaSessionType type);
PurpleMediaCaps jabber_get_media_caps(PurpleAccount *account, const char *who);
-gboolean jabber_can_receive_file(PurpleConnection *gc, const gchar *who);
+gboolean jabber_can_receive_file(PurpleProtocolXfer *xfer, PurpleConnection *gc, const gchar *who);
#endif /* PURPLE_JABBER_H_ */
--- a/libpurple/protocols/jabber/si.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/jabber/si.c Fri Dec 29 03:57:44 2017 +0000
@@ -1618,7 +1618,7 @@
}
}
-PurpleXfer *jabber_si_new_xfer(PurpleConnection *gc, const char *who)
+PurpleXfer *jabber_si_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who)
{
JabberStream *js;
@@ -1647,11 +1647,11 @@
return xfer;
}
-void jabber_si_xfer_send(PurpleConnection *gc, const char *who, const char *file)
+void jabber_si_xfer_send(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file)
{
PurpleXfer *xfer;
- xfer = jabber_si_new_xfer(gc, who);
+ xfer = jabber_si_new_xfer(prplxfer, gc, who);
if (file)
purple_xfer_request_accepted(xfer, file);
--- a/libpurple/protocols/jabber/si.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/jabber/si.h Fri Dec 29 03:57:44 2017 +0000
@@ -32,8 +32,8 @@
JabberIqType type, const char *id, PurpleXmlNode *query);
void jabber_si_parse(JabberStream *js, const char *from, JabberIqType type,
const char *id, PurpleXmlNode *si);
-PurpleXfer *jabber_si_new_xfer(PurpleConnection *gc, const char *who);
-void jabber_si_xfer_send(PurpleConnection *gc, const char *who, const char *file);
+PurpleXfer *jabber_si_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
+void jabber_si_xfer_send(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file);
void jabber_si_init(void);
void jabber_si_uninit(void);
--- a/libpurple/protocols/oscar/oscar.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/oscar/oscar.c Fri Dec 29 03:57:44 2017 +0000
@@ -5257,7 +5257,7 @@
* allowed to send a file to this user.
*/
gboolean
-oscar_can_receive_file(PurpleConnection *gc, const char *who)
+oscar_can_receive_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who)
{
OscarData *od;
PurpleAccount *account;
@@ -5286,7 +5286,7 @@
}
PurpleXfer *
-oscar_new_xfer(PurpleConnection *gc, const char *who)
+oscar_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who)
{
PurpleXfer *xfer;
OscarData *od;
@@ -5320,11 +5320,11 @@
* file is to be sent to a special someone.
*/
void
-oscar_send_file(PurpleConnection *gc, const char *who, const char *file)
+oscar_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file)
{
PurpleXfer *xfer;
- xfer = oscar_new_xfer(gc, who);
+ xfer = oscar_new_xfer(prplxfer, gc, who);
if (file != NULL)
purple_xfer_request_accepted(xfer, file);
@@ -5760,7 +5760,7 @@
}
static void
-oscar_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface)
+oscar_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
{
xfer_iface->can_receive = oscar_can_receive_file;
xfer_iface->send = oscar_send_file;
@@ -5785,7 +5785,7 @@
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_PRIVACY_IFACE,
oscar_protocol_privacy_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER_IFACE,
+ PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER,
oscar_protocol_xfer_iface_init)
);
--- a/libpurple/protocols/oscar/oscarcommon.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/oscar/oscarcommon.h Fri Dec 29 03:57:44 2017 +0000
@@ -116,9 +116,9 @@
const char *oscar_normalize(const PurpleAccount *account, const char *str);
void oscar_set_icon(PurpleConnection *gc, PurpleImage *img);
void oscar_remove_group(PurpleConnection *gc, PurpleGroup *group);
-gboolean oscar_can_receive_file(PurpleConnection *gc, const char *who);
-void oscar_send_file(PurpleConnection *gc, const char *who, const char *file);
-PurpleXfer *oscar_new_xfer(PurpleConnection *gc, const char *who);
+gboolean oscar_can_receive_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
+void oscar_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who, const char *file);
+PurpleXfer *oscar_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who);
gboolean oscar_offline_message(const PurpleBuddy *buddy);
gssize oscar_get_max_message_size(PurpleConversation *conv);
GList *oscar_get_actions(PurpleConnection *gc);
--- a/libpurple/protocols/sametime/sametime.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/sametime/sametime.c Fri Dec 29 03:57:44 2017 +0000
@@ -4941,7 +4941,8 @@
}
-static gboolean mw_protocol_can_receive_file(PurpleConnection *gc,
+static gboolean mw_protocol_can_receive_file(PurpleProtocolXfer *prplxfer,
+ PurpleConnection *gc,
const char *who) {
struct mwPurpleProtocolData *pd;
struct mwServiceAware *srvc;
@@ -5030,7 +5031,7 @@
}
-static PurpleXfer *mw_protocol_new_xfer(PurpleConnection *gc, const char *who) {
+static PurpleXfer *mw_protocol_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who) {
PurpleAccount *acct;
PurpleXfer *xfer;
@@ -5046,10 +5047,11 @@
return xfer;
}
-static void mw_protocol_send_file(PurpleConnection *gc,
+static void mw_protocol_send_file(PurpleProtocolXfer *prplxfer,
+ PurpleConnection *gc,
const char *who, const char *file) {
- PurpleXfer *xfer = mw_protocol_new_xfer(gc, who);
+ PurpleXfer *xfer = mw_protocol_new_xfer(prplxfer, gc, who);
if(file) {
DEBUG_INFO("file != NULL\n");
@@ -5701,7 +5703,7 @@
static void
-mw_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface)
+mw_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
{
xfer_iface->can_receive = mw_protocol_can_receive_file;
xfer_iface->send = mw_protocol_send_file;
@@ -5727,7 +5729,7 @@
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_PRIVACY_IFACE,
mw_protocol_privacy_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER_IFACE,
+ PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER,
mw_protocol_xfer_iface_init)
);
--- a/libpurple/protocols/silc/ft.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/silc/ft.c Fri Dec 29 03:57:44 2017 +0000
@@ -441,7 +441,7 @@
g_free(context);
}
-PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name)
+PurpleXfer *silcpurple_ftp_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *name)
{
SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
@@ -482,7 +482,7 @@
return xfer->xfer;
}
-void silcpurple_ftp_send_file(PurpleConnection *gc, const char *name, const char *file)
+void silcpurple_ftp_send_file(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *name, const char *file)
{
PurpleXfer *xfer = silcpurple_ftp_new_xfer(gc, name);
--- a/libpurple/protocols/silc/silc.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/protocols/silc/silc.c Fri Dec 29 03:57:44 2017 +0000
@@ -2283,7 +2283,7 @@
}
static void
-silcpurple_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface)
+silcpurple_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
{
xfer_iface->send = silcpurple_ftp_send_file;
xfer_iface->new_xfer = silcpurple_ftp_new_xfer;
--- a/libpurple/server.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/server.c Fri Dec 29 03:57:44 2017 +0000
@@ -894,9 +894,12 @@
if (gc) {
protocol = purple_connection_get_protocol(gc);
- if (!PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, can_receive) ||
- purple_protocol_xfer_iface_can_receive(protocol, gc, who))
+ if(PURPLE_IS_PROTOCOL_XFER(protocol)) {
+ PurpleProtocolXfer *xfer = PURPLE_PROTOCOL_XFER(protocol);
- purple_protocol_xfer_iface_send(protocol, gc, who, file);
+ if(purple_protocol_xfer_can_receive(xfer, gc, who)) {
+ purple_protocol_xfer_send(xfer, gc, who, file);
+ }
+ }
}
}
--- a/libpurple/tests/meson.build Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/tests/meson.build Fri Dec 29 03:57:44 2017 +0000
@@ -1,16 +1,30 @@
PROGS = [
'image',
+ 'protocol_xfer',
'smiley',
'smiley_list',
'trie',
'util',
'xmlnode'
]
+
+test_ui = static_library(
+ 'test-ui',
+ 'test_ui.c',
+ 'test_ui.h',
+ c_args: [
+ '-DTEST_DATA_DIR="@0@/data"'.format(meson.current_source_dir())
+ ],
+ dependencies: [libpurple_dep, glib, dbus, dbus_glib]
+)
+
foreach prog : PROGS
- e = executable('test_' + prog, 'test_@0@.c'.format(prog),
- c_args : [
- '-DTEST_DATA_DIR="@0@/data"'.format(meson.current_source_dir())
- ],
- dependencies : [libpurple_dep, glib])
- test(prog, e)
+ e = executable('test_' + prog, 'test_@0@.c'.format(prog),
+ c_args : [
+ '-DTEST_DATA_DIR="@0@/data"'.format(meson.current_source_dir())
+ ],
+ dependencies : [libpurple_dep, glib, dbus, dbus_glib],
+ link_with: test_ui,
+ )
+ test(prog, e)
endforeach
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_protocol_xfer.c Fri Dec 29 03:57:44 2017 +0000
@@ -0,0 +1,185 @@
+/*
+ * Purple
+ *
+ * Purple is the legal property of its developers, whose names are too
+ * numerous to list here. Please refer to the COPYRIGHT file distributed
+ * with this source distribution
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include <purple.h>
+
+#include "dbus-server.h"
+
+#include "test_ui.h"
+
+/******************************************************************************
+ * PurpleProtcolXfer Implementations
+ *****************************************************************************/
+static GType test_purple_protocol_xfer_get_type(void);
+
+typedef struct {
+ PurpleProtocol parent;
+
+ gboolean can_send;
+ gboolean new_xfer_called;
+ gboolean send_called;
+} TestPurpleProtocolXfer;
+
+typedef struct {
+ PurpleProtocolClass parent;
+} TestPurpleProtocolXferClass;
+
+
+static gboolean
+test_purple_protocol_xfer_can_receive(PurpleProtocolXfer *prplxfer, PurpleConnection *c, const gchar *who) {
+ TestPurpleProtocolXfer *test_xfer = (TestPurpleProtocolXfer *)prplxfer;
+
+ return test_xfer->can_send;
+}
+
+static void
+test_purple_protocol_xfer_send(PurpleProtocolXfer *prplxfer, PurpleConnection *c, const gchar *who, const gchar *filename) {
+ TestPurpleProtocolXfer *test_xfer = (TestPurpleProtocolXfer *)prplxfer;
+
+ test_xfer->send_called = TRUE;
+}
+
+static PurpleXfer *
+test_purple_protocol_xfer_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *c, const gchar *who) {
+ TestPurpleProtocolXfer *test_xfer = (TestPurpleProtocolXfer *)prplxfer;
+ PurpleAccount *a = purple_connection_get_account(c);
+
+ test_xfer->new_xfer_called = TRUE;
+
+ return purple_xfer_new(a, PURPLE_XFER_TYPE_SEND, who);
+}
+
+static void
+test_purple_protocol_xfer_iface_init(PurpleProtocolXferInterface *iface) {
+ iface->can_receive = test_purple_protocol_xfer_can_receive;
+ iface->send = test_purple_protocol_xfer_send;
+ iface->new_xfer = test_purple_protocol_xfer_new_xfer;
+}
+
+G_DEFINE_TYPE_WITH_CODE(
+ TestPurpleProtocolXfer,
+ test_purple_protocol_xfer,
+ PURPLE_TYPE_PROTOCOL,
+ G_IMPLEMENT_INTERFACE(
+ PURPLE_TYPE_PROTOCOL_XFER,
+ test_purple_protocol_xfer_iface_init
+ )
+);
+
+static void
+test_purple_protocol_xfer_init(TestPurpleProtocolXfer *prplxfer) {
+ PurpleProtocol *prpl = PURPLE_PROTOCOL(prplxfer);
+
+ prpl->id = "prpl-xfer";
+}
+
+static void
+test_purple_protocol_xfer_class_init(TestPurpleProtocolXferClass *klass) {
+}
+
+/******************************************************************************
+ * Tests
+ *****************************************************************************/
+static void
+test_purple_protocol_xfer_can_receive_func(void) {
+ TestPurpleProtocolXfer *xfer = g_object_new(test_purple_protocol_xfer_get_type(), NULL);
+ PurpleAccount *a = purple_account_new("prpl-xfer-can-receive", "prpl-xfer");
+ PurpleConnection *c = g_object_new(PURPLE_TYPE_CONNECTION, "account", a, NULL);
+ gboolean actual = FALSE;
+
+ g_assert_true(PURPLE_IS_PROTOCOL_XFER(xfer));
+
+ xfer->can_send = FALSE;
+ actual = purple_protocol_xfer_can_receive(
+ PURPLE_PROTOCOL_XFER(xfer),
+ c,
+ "foo"
+ );
+ g_assert_false(actual);
+
+ xfer->can_send = TRUE;
+ actual = purple_protocol_xfer_can_receive(
+ PURPLE_PROTOCOL_XFER(xfer),
+ c,
+ "foo"
+ );
+ g_assert_true(actual);
+}
+
+static void
+test_purple_protocol_xfer_send_func(void) {
+ TestPurpleProtocolXfer *prplxfer = g_object_new(test_purple_protocol_xfer_get_type(), NULL);
+ PurpleAccount *a = purple_account_new("prpl-xfer-send", "prpl-xfer");
+ PurpleConnection *c = g_object_new(PURPLE_TYPE_CONNECTION, "account", a, NULL);
+
+ purple_protocol_xfer_send(PURPLE_PROTOCOL_XFER(prplxfer), c, "foo", "somefile");
+ g_assert_true(prplxfer->send_called);
+}
+
+static void
+test_purple_protocol_xfer_new_func(void) {
+ TestPurpleProtocolXfer *prplxfer = g_object_new(test_purple_protocol_xfer_get_type(), NULL);
+ PurpleAccount *a = purple_account_new("prpl-xfer-new-xfer", "prpl-xfer");
+ PurpleConnection *c = g_object_new(PURPLE_TYPE_CONNECTION, "account", a, NULL);
+ PurpleXfer *xfer = NULL;
+
+ xfer = purple_protocol_xfer_new_xfer(PURPLE_PROTOCOL_XFER(prplxfer), c, "foo");
+ g_assert_true(PURPLE_IS_XFER(xfer));
+ g_assert_cmpstr("foo", ==, purple_xfer_get_remote_user(xfer));
+ g_assert_true(prplxfer->new_xfer_called);
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+gint
+main(gint argc, gchar **argv) {
+ gint res = 0;
+
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_set_nonfatal_assertions();
+
+ test_ui_purple_init();
+
+ g_test_add_func(
+ "/protocol-xfer/can-receive",
+ test_purple_protocol_xfer_can_receive_func
+ );
+
+ g_test_add_func(
+ "/protocol-xfer/send",
+ test_purple_protocol_xfer_send_func
+ );
+
+ g_test_add_func(
+ "/protocol-xfer/new",
+ test_purple_protocol_xfer_new_func
+ );
+
+ res = g_test_run();
+
+ return res;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_ui.c Fri Dec 29 03:57:44 2017 +0000
@@ -0,0 +1,117 @@
+/*
+ * pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ *
+ */
+
+#include "purple.h"
+
+#include <glib.h>
+#include <glib/gprintf.h>
+
+#include <signal.h>
+#include <string.h>
+#ifdef _WIN32
+# include <conio.h>
+#else
+# include <unistd.h>
+#endif
+
+#include "test_ui.h"
+
+/*** Conversation uiops ***/
+static void
+test_write_conv(PurpleConversation *conv, PurpleMessage *msg)
+{
+ time_t mtime = purple_message_get_time(msg);
+
+ printf("(%s) %s %s: %s\n",
+ purple_conversation_get_name(conv),
+ purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
+ purple_message_get_author_alias(msg),
+ purple_message_get_contents(msg));
+}
+
+static PurpleConversationUiOps test_conv_uiops = {
+ .write_conv = test_write_conv
+};
+
+static void
+test_ui_init(void)
+{
+ purple_conversations_set_ui_ops(&test_conv_uiops);
+}
+
+static PurpleCoreUiOps test_core_uiops = {
+ .ui_init = test_ui_init
+};
+
+void
+test_ui_purple_init(void) {
+#ifndef _WIN32
+ /* libpurple's built-in DNS resolution forks processes to perform
+ * blocking lookups without blocking the main process. It does not
+ * handle SIGCHLD itself, so if the UI does not you quickly get an army
+ * of zombie subprocesses marching around.
+ */
+ signal(SIGCHLD, SIG_IGN);
+#endif
+
+ /* set the magic PURPLE_PLUGINS_SKIP environment variable */
+ g_setenv("PURPLE_PLUGINS_SKIP", "1", TRUE);
+
+ /* Set a custom user directory (optional) */
+ purple_util_set_user_dir(TEST_DATA_DIR);
+
+ /* We do not want any debugging for now to keep the noise to a minimum. */
+ purple_debug_set_enabled(FALSE);
+
+ /* Set the core-uiops, which is used to
+ * - initialize the ui specific preferences.
+ * - initialize the debug ui.
+ * - initialize the ui components for all the modules.
+ * - uninitialize the ui components for all the modules when the core terminates.
+ */
+ purple_core_set_ui_ops(&test_core_uiops);
+
+ /* Now that all the essential stuff has been set, let's try to init the core. It's
+ * necessary to provide a non-NULL name for the current ui to the core. This name
+ * is used by stuff that depends on this ui, for example the ui-specific plugins. */
+ if (!purple_core_init("test-ui")) {
+ /* Initializing the core failed. Terminate. */
+ fprintf(stderr,
+ "libpurple initialization failed. Dumping core.\n"
+ "Please report this!\n");
+ abort();
+ }
+
+ /* Set path to search for plugins. The core (libpurple) takes care of loading the
+ * core-plugins, which includes the in-tree protocols. So it is not essential to add
+ * any path here, but it might be desired, especially for ui-specific plugins. */
+ purple_plugins_add_search_path(TEST_DATA_DIR);
+ purple_plugins_refresh();
+
+ /* Load the preferences. */
+ purple_prefs_load();
+
+ /* Load the desired plugins. The client should save the list of loaded plugins in
+ * the preferences using purple_plugins_save_loaded(PLUGIN_SAVE_PREF) */
+ purple_plugins_load_saved(TEST_DATA_DIR);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_ui.h Fri Dec 29 03:57:44 2017 +0000
@@ -0,0 +1,33 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef PURPLE_TEST_UI_H
+#define PURPLE_TEST_UI_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void test_ui_purple_init(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_TEST_UI_H */
--- a/libpurple/xfer.c Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/xfer.c Fri Dec 29 03:57:44 2017 +0000
@@ -2360,21 +2360,23 @@
g_return_val_if_fail(who != NULL, NULL);
protocol = purple_protocols_find(purple_account_get_protocol_id(account));
-
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
-
- if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, FACTORY_IFACE, xfer_new))
- xfer = purple_protocol_factory_iface_xfer_new(protocol, account, type,
- who);
- else
+ if (PURPLE_IS_PROTOCOL_XFER(protocol)) {
+ PurpleConnection *connection = purple_account_get_connection(account);
+
+ xfer = purple_protocol_xfer_new_xfer(
+ PURPLE_PROTOCOL_XFER(protocol),
+ connection,
+ /* TODO: this should support the type */
+ who
+ );
+ } else {
xfer = g_object_new(PURPLE_TYPE_XFER,
"account", account,
"type", type,
"remote-user", who,
NULL
);
-
- g_return_val_if_fail(xfer != NULL, NULL);
+ }
return xfer;
}
@@ -2477,3 +2479,66 @@
return type;
}
+
+/**************************************************************************
+ * PurpleXferProtocolInterface
+ **************************************************************************/
+G_DEFINE_INTERFACE(PurpleProtocolXfer, purple_protocol_xfer, G_TYPE_INVALID);
+
+static void
+purple_protocol_xfer_default_init(PurpleProtocolXferInterface *face) {
+}
+
+gboolean
+purple_protocol_xfer_can_receive(PurpleProtocolXfer *prplxfer,
+ PurpleConnection *connection,
+ const gchar *who
+) {
+ PurpleProtocolXferInterface *iface = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_PROTOCOL_XFER(prplxfer), FALSE);
+ g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), FALSE);
+ g_return_val_if_fail(who, FALSE);
+
+ iface = PURPLE_PROTOCOL_XFER_GET_IFACE(prplxfer);
+ if(iface && iface->can_receive)
+ return iface->can_receive(prplxfer, connection, who);
+
+ return FALSE;
+}
+
+void
+purple_protocol_xfer_send(PurpleProtocolXfer *prplxfer,
+ PurpleConnection *connection,
+ const gchar *who,
+ const gchar *filename
+) {
+ PurpleProtocolXferInterface *iface = NULL;
+
+ g_return_if_fail(PURPLE_IS_PROTOCOL_XFER(prplxfer));
+ g_return_if_fail(PURPLE_IS_CONNECTION(connection));
+ g_return_if_fail(who);
+ g_return_if_fail(filename);
+
+ iface = PURPLE_PROTOCOL_XFER_GET_IFACE(prplxfer);
+ if(iface && iface->send)
+ iface->send(prplxfer, connection, who, filename);
+}
+
+PurpleXfer *
+purple_protocol_xfer_new_xfer(PurpleProtocolXfer *prplxfer,
+ PurpleConnection *connection,
+ const gchar *who
+) {
+ PurpleProtocolXferInterface *iface = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_PROTOCOL_XFER(prplxfer), FALSE);
+ g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), FALSE);
+ g_return_val_if_fail(who, FALSE);
+
+ iface = PURPLE_PROTOCOL_XFER_GET_IFACE(prplxfer);
+ if(iface && iface->new_xfer)
+ return iface->new_xfer(prplxfer, connection, who);
+
+ return NULL;
+}
--- a/libpurple/xfer.h Tue Dec 26 05:56:57 2017 +0000
+++ b/libpurple/xfer.h Fri Dec 29 03:57:44 2017 +0000
@@ -38,6 +38,11 @@
#define PURPLE_TYPE_XFER_UI_OPS (purple_xfer_ui_ops_get_type())
+#define PURPLE_TYPE_PROTOCOL_XFER (purple_protocol_xfer_get_type())
+#define PURPLE_PROTOCOL_XFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_PROTOCOL_XFER, PurpleProtocolXfer))
+#define PURPLE_IS_PROTOCOL_XFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL_XFER))
+#define PURPLE_PROTOCOL_XFER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_XFER, PurpleProtocolXferInterface))
+
/**************************************************************************/
/** Data Structures */
/**************************************************************************/
@@ -46,10 +51,14 @@
typedef struct _PurpleXferUiOps PurpleXferUiOps;
+typedef struct _PurpleProtocolXfer PurpleProtocolXfer;
+typedef struct _PurpleProtocolXferInterface PurpleProtocolXferInterface;
+
#include <glib.h>
#include <stdio.h>
#include "account.h"
+#include "connection.h"
/**
* PurpleXferType:
@@ -182,6 +191,26 @@
void (*_purple_reserved4)(void);
};
+/**
+ * PurpleProtocolXferInterface:
+ *
+ * The protocol file transfer interface.
+ *
+ * This interface provides file transfer callbacks for the protocol.
+ */
+struct _PurpleProtocolXferInterface
+{
+ /*< private >*/
+ GTypeInterface parent_iface;
+
+ /*< public >*/
+ gboolean (*can_receive)(PurpleProtocolXfer *prplxfer, PurpleConnection *c, const gchar *who);
+
+ void (*send)(PurpleProtocolXfer *prplxfer, PurpleConnection *c, const gchar *who, const gchar *filename);
+
+ PurpleXfer *(*new_xfer)(PurpleProtocolXfer *prplxfer, PurpleConnection *c, const gchar *who);
+};
+
G_BEGIN_DECLS
/**************************************************************************/
@@ -946,6 +975,52 @@
*/
PurpleXferUiOps *purple_xfers_get_ui_ops(void);
+/******************************************************************************
+ * Protocol Interface
+ *****************************************************************************/
+
+/**
+ * purple_protocol_xfer_get_type:
+ *
+ * Returns: The #GType for the protocol xfer interface.
+ */
+GType purple_protocol_xfer_get_type(void);
+
+/**
+ * purple_protocol_xfer_can_receive:
+ * @prplxfer: The #PurpleProtocolXfer implementer instance
+ * @connection: The #PurpleConnection that we're checking
+ * @who: The user that we want to send a file transfer to.
+ *
+ * Checks whether or not we can transfer a file to @who.
+ *
+ * Returns: TRUE on success, FALSE otherwise.
+ */
+gboolean purple_protocol_xfer_can_receive(PurpleProtocolXfer *prplxfer, PurpleConnection *connection, const gchar *who);
+
+/**
+ * purple_protocol_xfer_send:
+ * @prplxfer: The #PurpleProtocolXfer implementer instance
+ * @connection: The #PurpleConnection that we're checking
+ * @who: The user that we want to set a file transfer to.
+ * @filename: The name of the file to send.
+ *
+ * Sends @filename to @who.
+ */
+void purple_protocol_xfer_send(PurpleProtocolXfer *prplxfer, PurpleConnection *connection, const gchar *who, const gchar *filename);
+
+/**
+ * purple_protocol_xfer_send:
+ * @prplxfer: The #PurpleProtocolXfer implementer instance
+ * @connection: The #PurpleConnection that we're checking
+ * @who: The user that we want to send a file transfer to.
+ *
+ * Creates a new #PurpleXfer to @who.
+ *
+ * Returns: A new #PurpleXfer instance.
+ */
+PurpleXfer *purple_protocol_xfer_new_xfer(PurpleProtocolXfer *prplxfer, PurpleConnection *connection, const gchar *who);
+
G_END_DECLS
#endif /* _PURPLE_XFER_H_ */
--- a/pidgin/gtkblist.c Tue Dec 26 05:56:57 2017 +0000
+++ b/pidgin/gtkblist.c Fri Dec 29 03:57:44 2017 +0000
@@ -1525,11 +1525,11 @@
#endif
- if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, send)) {
- if (!PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, can_receive) ||
- purple_protocol_xfer_iface_can_receive(protocol,
- purple_account_get_connection(purple_buddy_get_account(buddy)), purple_buddy_get_name(buddy)))
- {
+ if (protocol && PURPLE_IS_PROTOCOL_XFER(protocol)) {
+ if (purple_protocol_xfer_can_receive(
+ PURPLE_PROTOCOL_XFER(protocol),
+ purple_account_get_connection(purple_buddy_get_account(buddy)), purple_buddy_get_name(buddy)
+ )) {
pidgin_new_menu_item(menu, _("_Send File..."),
PIDGIN_STOCK_TOOLBAR_SEND_FILE,
G_CALLBACK(gtk_blist_menu_send_file_cb),
--- a/pidgin/gtkconv.c Tue Dec 26 05:56:57 2017 +0000
+++ b/pidgin/gtkconv.c Fri Dec 29 03:57:44 2017 +0000
@@ -1680,7 +1680,7 @@
g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
- if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, send))
+ if (protocol && PURPLE_IS_PROTOCOL_XFER(protocol))
{
gboolean can_receive_file = TRUE;
@@ -1694,9 +1694,11 @@
gchar *real_who = NULL;
real_who = purple_protocol_chat_iface_get_user_real_name(protocol, gc,
purple_chat_conversation_get_id(chat), who);
- if (!(!PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, can_receive) ||
- purple_protocol_xfer_iface_can_receive(protocol, gc, real_who ? real_who : who)))
+
+ if (!purple_protocol_xfer_can_receive(protocol, gc, real_who ? real_who : who)) {
can_receive_file = FALSE;
+ }
+
g_free(real_who);
}
@@ -7418,12 +7420,18 @@
if (PURPLE_IS_IM_CONVERSATION(conv))
{
+ gboolean can_send_file = FALSE;
+ const gchar *name = purple_conversation_get_name(conv);
+
+ if (PURPLE_IS_PROTOCOL_XFER(protocol) &&
+ purple_protocol_xfer_can_receive(PURPLE_PROTOCOL_XFER(protocol), gc, name)
+ ) {
+ can_send_file = TRUE;
+ }
+
gtk_action_set_sensitive(win->menu->add, (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER_IFACE, add_buddy)));
gtk_action_set_sensitive(win->menu->remove, (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER_IFACE, remove_buddy)));
- gtk_action_set_sensitive(win->menu->send_file,
- (PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, send) &&
- (!PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, can_receive) ||
- purple_protocol_xfer_iface_can_receive(protocol, gc, purple_conversation_get_name(conv)))));
+ gtk_action_set_sensitive(win->menu->send_file, can_send_file);
gtk_action_set_sensitive(win->menu->get_attention, (PURPLE_PROTOCOL_IMPLEMENTS(protocol, ATTENTION_IFACE, send)));
gtk_action_set_sensitive(win->menu->alias,
(account != NULL) &&
--- a/pidgin/gtkutils.c Tue Dec 26 05:56:57 2017 +0000
+++ b/pidgin/gtkutils.c Fri Dec 29 03:57:44 2017 +0000
@@ -1469,10 +1469,15 @@
if (!(purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_NO_IMAGES))
im = TRUE;
- if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, can_receive))
- ft = purple_protocol_xfer_iface_can_receive(protocol, gc, who);
- else if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, XFER_IFACE, send))
- ft = TRUE;
+ if (protocol && PURPLE_IS_PROTOCOL_XFER(protocol)) {
+ PurpleProtocolXferInterface *iface = PURPLE_PROTOCOL_XFER(protocol);
+
+ if(iface->can_receive) {
+ ft = purple_protocol_xfer_can_receive(protocol, gc, who);
+ } else {
+ ft = (iface->send) ? TRUE : FALSE;
+ }
+ }
if (im && ft) {
purple_request_choice(NULL, NULL,