From 80fb40616494b06471cacd3594d1c559206a604d Mon Sep 17 00:00:00 2001 From: Jakub Adam Date: Tue, 9 Jun 2015 09:30:22 +0200 Subject: [PATCH] purple: build against GPlugin-based 3.x API Pidgin 3.x changed the plugin API substantially. Instead of filling PurplePluginProtocolInfo structure with function pointers, plugin developer is now supposed to inherit PurpleProtocol GObject class and implement its various interfaces. A file which implements the new API, purple-plugin3.c, was added to Sipe Purple backend, whereas the legacy code for libpurple 2.x.x remained in purple-plugin.c. Depending on libpurple version for which Sipe build was configured, the corresponding file is picked. --- configure.ac | 1 + src/purple/Makefile.am | 7 +- src/purple/purple-plugin.c | 31 +----- src/purple/purple-plugin3.c | 260 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 271 insertions(+), 28 deletions(-) create mode 100644 src/purple/purple-plugin3.c diff --git a/configure.ac b/configure.ac index 3ccf4725..32718727 100644 --- a/configure.ac +++ b/configure.ac @@ -408,6 +408,7 @@ AS_IF([test "x$enable_purple" != xno], CFLAGS=$ac_save_CFLAGS LIBS=$ac_save_LIBS])]) AM_CONDITIONAL(SIPE_INCLUDE_PURPLE, [test "x$enable_purple" != xno]) +AM_CONDITIONAL(SIPE_PURPLE3, [test "x$purple_pkgconfig" = xpurple-3]) dnl build option: telepathy backend AC_ARG_ENABLE([telepathy], diff --git a/src/purple/Makefile.am b/src/purple/Makefile.am index b6d0c6a0..ae81a3d6 100644 --- a/src/purple/Makefile.am +++ b/src/purple/Makefile.am @@ -28,9 +28,14 @@ libsipe_backend_la_SOURCES = \ purple-user.c libsipe_la_SOURCES = \ - purple-plugin.c \ purple-plugin-common.c +if SIPE_PURPLE3 +libsipe_la_SOURCES += purple-plugin3.c +else +libsipe_la_SOURCES += purple-plugin.c +endif + AM_CFLAGS = $(st) libsipe_backend_la_CFLAGS = \ diff --git a/src/purple/purple-plugin.c b/src/purple/purple-plugin.c index 60ae97fc..5d6f83ab 100644 --- a/src/purple/purple-plugin.c +++ b/src/purple/purple-plugin.c @@ -42,22 +42,12 @@ #include "accountopt.h" #include "prpl.h" -#include "version.h" #include "sipe-core.h" #define _PurpleMessageFlags PurpleMessageFlags #include "purple-private.h" -#if PURPLE_VERSION_CHECK(3,0,0) -static int sipe_purple_send_im(PurpleConnection *gc, PurpleMessage *msg) -{ - sipe_core_im_send(PURPLE_GC_TO_SIPE_CORE_PUBLIC, - purple_message_get_recipient(msg), - purple_message_get_contents(msg)); - return 1; -} -#else static int sipe_purple_send_im(PurpleConnection *gc, const char *who, const char *what, @@ -66,7 +56,6 @@ static int sipe_purple_send_im(PurpleConnection *gc, sipe_core_im_send(PURPLE_GC_TO_SIPE_CORE_PUBLIC, who, what); return 1; } -#endif /* * Simplistic source upward compatibility path for newer libpurple APIs @@ -89,9 +78,6 @@ static int sipe_purple_send_im(PurpleConnection *gc, #endif static PurplePluginProtocolInfo sipe_prpl_info = { -#if PURPLE_VERSION_CHECK(3,0,0) - sizeof(PurplePluginProtocolInfo), /* struct_size */ -#endif SIPE_PURPLE_PROTOCOL_OPTIONS, NULL, /* user_splits */ NULL, /* protocol_options */ @@ -127,16 +113,12 @@ static PurplePluginProtocolInfo sipe_prpl_info = NULL, /* get_chat_name */ sipe_purple_chat_invite, /* chat_invite */ sipe_purple_chat_leave, /* chat_leave */ -#if !PURPLE_VERSION_CHECK(3,0,0) NULL, /* chat_whisper */ -#endif sipe_purple_chat_send, /* chat_send */ NULL, /* keepalive */ NULL, /* register_user */ NULL, /* get_cb_info */ // deprecated -#if !PURPLE_VERSION_CHECK(3,0,0) NULL, /* get_cb_away */ // deprecated -#endif sipe_purple_alias_buddy, /* alias_buddy */ sipe_purple_group_buddy, /* group_buddy */ sipe_purple_group_rename, /* rename_group */ @@ -161,16 +143,14 @@ static PurplePluginProtocolInfo sipe_prpl_info = NULL, /* unregister_user */ NULL, /* send_attention */ NULL, /* get_attention_types */ -#if !PURPLE_VERSION_CHECK(2,5,0) && !PURPLE_VERSION_CHECK(3,0,0) +#if !PURPLE_VERSION_CHECK(2,5,0) /* Backward compatibility when compiling against 2.4.x API */ (void (*)(void)) /* _purple_reserved4 */ #endif -#if !PURPLE_VERSION_CHECK(3,0,0) sizeof(PurplePluginProtocolInfo), /* struct_size */ -#endif -#if PURPLE_VERSION_CHECK(2,5,0) || PURPLE_VERSION_CHECK(3,0,0) +#if PURPLE_VERSION_CHECK(2,5,0) sipe_purple_get_account_text_table, /* get_account_text_table */ -#if PURPLE_VERSION_CHECK(2,6,0) || PURPLE_VERSION_CHECK(3,0,0) +#if PURPLE_VERSION_CHECK(2,6,0) #ifdef HAVE_VV sipe_purple_initiate_media, /* initiate_media */ sipe_purple_get_media_caps, /* get_media_caps */ @@ -178,16 +158,13 @@ static PurplePluginProtocolInfo sipe_prpl_info = NULL, /* initiate_media */ NULL, /* get_media_caps */ #endif -#if PURPLE_VERSION_CHECK(2,7,0) || PURPLE_VERSION_CHECK(3,0,0) +#if PURPLE_VERSION_CHECK(2,7,0) NULL, /* get_moods */ NULL, /* set_public_alias */ NULL, /* get_public_alias */ #if PURPLE_VERSION_CHECK(2,8,0) NULL, /* add_buddy_with_invite */ NULL, /* add_buddies_with_invite */ -#elif PURPLE_VERSION_CHECK(3,0,0) - NULL, /* get_max_message_size */ - NULL, /* media_send_dtmf */ #endif #endif #endif diff --git a/src/purple/purple-plugin3.c b/src/purple/purple-plugin3.c new file mode 100644 index 00000000..1e66b0d7 --- /dev/null +++ b/src/purple/purple-plugin3.c @@ -0,0 +1,260 @@ +/** + * @file purple-plugin3.c + * + * pidgin-sipe + * + * Copyright (C) 2015 SIPE Project + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +/* Flag needed for correct version of PURPLE_INIT_PLUGIN() */ +#ifndef PURPLE_PLUGINS +#define PURPLE_PLUGINS +#endif + +#include "protocol.h" + +#include "purple-private.h" +#include "sipe-common.h" +#include "sipe-core.h" + +#define SIPE_TYPE_PROTOCOL (sipe_protocol_get_type()) + +typedef struct _SipeProtocol { + PurpleProtocol parent; +} SipeProtocol; + +typedef struct _NullProtocolClass { + PurpleProtocolClass parent_class; +} SipeProtocolClass; + +G_MODULE_EXPORT GType sipe_protocol_get_type(void); + +static void +sipe_protocol_class_init(PurpleProtocolClass *klass) +{ + klass->login = sipe_purple_login; + klass->close = sipe_purple_close; + klass->status_types = sipe_purple_status_types; + klass->list_icon = sipe_purple_list_icon; +} + +static void +sipe_protocol_init(PurpleProtocol *protocol) +{ + sipe_core_init(LOCALEDIR); + + protocol->id = SIPE_PURPLE_PLUGIN_ID; + protocol->name = SIPE_PURPLE_PLUGIN_NAME; + protocol->options = SIPE_PURPLE_PROTOCOL_OPTIONS; + protocol->user_splits = g_list_append(NULL, sipe_purple_user_split()); + protocol->account_options = sipe_purple_account_options(); +} + +static GList * +get_actions(SIPE_UNUSED_PARAMETER PurpleConnection *gc) +{ + return sipe_purple_actions(); +} + +static void +sipe_protocol_client_iface_init(PurpleProtocolClientIface *client_iface) +{ + client_iface->get_actions = get_actions; + client_iface->status_text = sipe_purple_status_text; + client_iface->tooltip_text = sipe_purple_tooltip_text; + client_iface->blist_node_menu = sipe_purple_blist_node_menu; + client_iface->convo_closed = sipe_purple_convo_closed; + client_iface->normalize = purple_normalize_nocase; + client_iface->get_account_text_table = sipe_purple_get_account_text_table; +} + +static void +sipe_protocol_server_iface_init(PurpleProtocolServerIface *server_iface) +{ + server_iface->get_info = sipe_purple_get_info; + server_iface->set_status = sipe_purple_set_status; + server_iface->set_idle = sipe_purple_set_idle; + server_iface->add_buddy = sipe_purple_add_buddy; + server_iface->remove_buddy = sipe_purple_remove_buddy; + server_iface->alias_buddy = sipe_purple_alias_buddy; + server_iface->group_buddy = sipe_purple_group_buddy; + server_iface->rename_group = sipe_purple_group_rename; + server_iface->remove_group = sipe_purple_group_remove; +} + +static int +send_im(PurpleConnection *gc, PurpleMessage *msg) +{ + sipe_core_im_send(PURPLE_GC_TO_SIPE_CORE_PUBLIC, + purple_message_get_recipient(msg), + purple_message_get_contents(msg)); + return 1; +} + +static void +sipe_protocol_im_iface_init(PurpleProtocolIMIface *im_iface) +{ + im_iface->send = send_im; + im_iface->send_typing = sipe_purple_send_typing; +} + +static void +sipe_protocol_chat_iface_init(PurpleProtocolChatIface *chat_iface) +{ + chat_iface->info = sipe_purple_chat_info; + chat_iface->info_defaults = sipe_purple_chat_info_defaults; + chat_iface->join = sipe_purple_chat_join; + chat_iface->invite = sipe_purple_chat_invite; + chat_iface->leave = sipe_purple_chat_leave; + chat_iface->send = sipe_purple_chat_send; +} + +static void +sipe_protocol_privacy_iface_init(PurpleProtocolPrivacyIface *privacy_iface) +{ + privacy_iface->add_permit = sipe_purple_add_permit; + privacy_iface->add_deny = sipe_purple_add_deny; + privacy_iface->rem_permit = sipe_purple_add_deny; + privacy_iface->rem_deny = sipe_purple_add_permit; +} + +static void +sipe_protocol_xfer_iface_init(PurpleProtocolXferIface *xfer_iface) +{ + xfer_iface->send = sipe_purple_ft_send_file; + xfer_iface->new_xfer = sipe_purple_ft_new_xfer; +} + +static void +sipe_protocol_roomlist_iface_init(PurpleProtocolRoomlistIface *roomlist_iface) +{ + roomlist_iface->get_list = sipe_purple_roomlist_get_list; + roomlist_iface->cancel = sipe_purple_roomlist_cancel; +} + +static void +sipe_protocol_media_iface_init(PurpleProtocolMediaIface *media_iface) +{ + media_iface->initiate_session = sipe_purple_initiate_media; + media_iface->get_caps = sipe_purple_get_media_caps; +} + +#ifdef __GNUC__ +#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ >= 5) +#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ >= 5) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif +#endif +PURPLE_DEFINE_TYPE_EXTENDED( + SipeProtocol, sipe_protocol, PURPLE_TYPE_PROTOCOL, 0, + + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CLIENT_IFACE, + sipe_protocol_client_iface_init) + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_SERVER_IFACE, + sipe_protocol_server_iface_init) + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_IM_IFACE, + sipe_protocol_im_iface_init) + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CHAT_IFACE, + sipe_protocol_chat_iface_init) + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_PRIVACY_IFACE, + sipe_protocol_privacy_iface_init) + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER_IFACE, + sipe_protocol_xfer_iface_init) + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_ROOMLIST_IFACE, + sipe_protocol_roomlist_iface_init) + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_MEDIA_IFACE, + sipe_protocol_media_iface_init) +) + +#ifdef __GNUC__ +#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ >= 5) +#pragma GCC diagnostic pop +#endif +#endif + +static PurplePluginInfo * +plugin_query(SIPE_UNUSED_PARAMETER GError **error) +{ + gchar ** authors = g_strsplit(SIPE_PURPLE_PLUGIN_AUTHORS, ", ", -1); + PurplePluginInfo *info = purple_plugin_info_new( + "id", SIPE_PURPLE_PLUGIN_ID, + "name", SIPE_PURPLE_PLUGIN_NAME, + "version", PACKAGE_VERSION, + "category", "Protocol", + "summary", SIPE_PURPLE_PLUGIN_SUMMARY, + "description", SIPE_PURPLE_PLUGIN_DESCRIPTION, + "authors", authors, + "website", PACKAGE_URL, + "abi-version", PURPLE_ABI_VERSION, + "flags", PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD, + NULL); + + g_strfreev(authors); + + return info; +} + +static PurpleProtocol *sipe_protocol = NULL; + +static gboolean +plugin_load(PurplePlugin *plugin, GError **error) +{ + sipe_protocol_register_type(plugin); + + sipe_protocol = purple_protocols_add(SIPE_TYPE_PROTOCOL, error); + if (!sipe_protocol) { + return FALSE; + } + + if (!sipe_purple_plugin_load(plugin)) { + return FALSE; + } + + return TRUE; +} + +static gboolean +plugin_unload(PurplePlugin *plugin, GError **error) +{ + sipe_purple_plugin_unload(plugin); + + if (!purple_protocols_remove(sipe_protocol, error)) { + return FALSE; + } + + return TRUE; +} + +PURPLE_PLUGIN_INIT(sipe, plugin_query, plugin_load, plugin_unload); + +/* + Local Variables: + mode: c + c-file-style: "bsd" + indent-tabs-mode: t + tab-width: 8 + End: +*/ -- 2.11.4.GIT