Fri, 29 Dec 2017 03:57:44 +0000
Merged in rw_grim/pidgin (pull request #297)
Moved PurpleProtocolXfer to xfer.[ch], started a testing ui
Approved-by: Eion Robb <eionrobb@gmail.com>
| finch/gntblist.c | file | annotate | diff | comparison | revisions |
--- 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,