pidgin/pidgin

Merge heads.

2018-02-15, Elliott Sales de Andrade
b149f0a61857
Merge heads.
  • +179 -0
    libpurple/attention.c
  • +254 -0
    libpurple/attention.h
  • +2 -0
    libpurple/meson.build
  • +0 -50
    libpurple/protocol.c
  • +0 -45
    libpurple/protocol.h
  • +2 -145
    libpurple/protocols.c
  • +0 -139
    libpurple/protocols.h
  • +1 -25
    libpurple/protocols/bonjour/jabber.c
  • +0 -18
    libpurple/protocols/gg/account.c
  • +0 -23
    libpurple/protocols/gg/validator.c
  • +0 -6
    libpurple/protocols/gg/validator.h
  • +0 -5
    libpurple/protocols/irc/irc.c
  • +0 -29
    libpurple/protocols/jabber/auth_scram.c
  • +0 -18
    libpurple/protocols/jabber/buddy.c
  • +0 -24
    libpurple/protocols/jabber/chat.c
  • +0 -3
    libpurple/protocols/jabber/gtalk.c
  • +7 -129
    libpurple/protocols/jabber/jabber.c
  • +3 -2
    libpurple/protocols/jabber/jabber.h
  • +0 -12
    libpurple/protocols/jabber/jingle/jingle.c
  • +0 -7
    libpurple/protocols/jabber/jingle/rtp.c
  • +0 -31
    libpurple/protocols/jabber/jutil.c
  • +3 -12
    libpurple/protocols/jabber/parser.c
  • +0 -12
    libpurple/protocols/jabber/presence.c
  • +0 -11
    libpurple/protocols/jabber/roster.c
  • +3 -4
    libpurple/protocols/jabber/tests/test_jabber_scram.c
  • +0 -21
    libpurple/protocols/jabber/useravatar.c
  • +0 -3
    libpurple/protocols/jabber/xmpp.c
  • +0 -14
    libpurple/protocols/novell/novell.c
  • +0 -130
    libpurple/protocols/sametime/sametime.c
  • +0 -36
    libpurple/protocols/silc/chat.c
  • +0 -110
    libpurple/protocols/silc/ops.c
  • +0 -37
    libpurple/protocols/silc/silc.c
  • +0 -8
    libpurple/protocols/simple/ntlm.c
  • +0 -48
    libpurple/protocols/zephyr/ZFmtSmRLst.c
  • +0 -9
    libpurple/protocols/zephyr/ZMkAuth.c
  • +0 -53
    libpurple/protocols/zephyr/ZPeekIfNot.c
  • +0 -16
    libpurple/protocols/zephyr/ZRetSubs.c
  • +0 -46
    libpurple/protocols/zephyr/ZSendRLst.c
  • +0 -35
    libpurple/protocols/zephyr/ZSendRaw.c
  • +0 -4
    libpurple/protocols/zephyr/meson.build
  • +2 -2
    libpurple/server.c
  • +1 -0
    libpurple/server.h
  • +2 -0
    libpurple/tests/meson.build
  • +181 -0
    libpurple/tests/test_attention_type.c
  • +156 -0
    libpurple/tests/test_protocol_attention.c
  • +0 -23
    libpurple/win32/libc_interface.c
  • +0 -24
    libpurple/win32/libc_internal.h
  • +1 -1
    meson.build
  • +4 -3
    pidgin/gtkconv.c
  • +1 -1
    pidgin/gtkwebviewtoolbar.c
  • --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/libpurple/attention.c Thu Feb 15 23:17:27 2018 -0500
    @@ -0,0 +1,179 @@
    +/* 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 "attention.h"
    +
    +/******************************************************************************
    + * PurpleAttentionType API
    + *****************************************************************************/
    +struct _PurpleAttentionType {
    + const gchar *name;
    + const gchar *incoming_description;
    + const gchar *outgoing_description;
    + const gchar *icon_name;
    + const gchar *unlocalized_name;
    +};
    +
    +G_DEFINE_BOXED_TYPE(
    + PurpleAttentionType,
    + purple_attention_type,
    + purple_attention_type_copy,
    + g_free
    +);
    +
    +PurpleAttentionType *
    +purple_attention_type_new(const gchar *unlocalized_name,
    + const gchar *name,
    + const gchar *incoming_description,
    + const gchar *outgoing_description)
    +{
    + PurpleAttentionType *attn = g_new0(PurpleAttentionType, 1);
    +
    + attn->unlocalized_name = unlocalized_name;
    + attn->name = name;
    + attn->incoming_description = incoming_description;
    + attn->outgoing_description = outgoing_description;
    +
    + return attn;
    +}
    +
    +PurpleAttentionType *
    +purple_attention_type_copy(PurpleAttentionType *attn) {
    + PurpleAttentionType *attn_copy = NULL;
    +
    + g_return_val_if_fail(attn != NULL, NULL);
    +
    + attn_copy = g_new(PurpleAttentionType, 1);
    + *attn_copy = *attn;
    +
    + return attn_copy;
    +}
    +
    +const gchar *
    +purple_attention_type_get_name(const PurpleAttentionType *type) {
    + g_return_val_if_fail(type, NULL);
    +
    + return type->name;
    +}
    +
    +void
    +purple_attention_type_set_name(PurpleAttentionType *type, const gchar *name) {
    + g_return_if_fail(type);
    +
    + type->name = name;
    +}
    +
    +const gchar *
    +purple_attention_type_get_incoming_desc(const PurpleAttentionType *type) {
    + g_return_val_if_fail(type, NULL);
    +
    + return type->incoming_description;
    +}
    +
    +void
    +purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const gchar *desc) {
    + g_return_if_fail(type);
    +
    + type->incoming_description = desc;
    +}
    +
    +const gchar *
    +purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type) {
    + g_return_val_if_fail(type, NULL);
    +
    + return type->outgoing_description;
    +}
    +
    +void
    +purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const gchar *desc) {
    + g_return_if_fail(type != NULL);
    +
    + type->outgoing_description = desc;
    +}
    +
    +const gchar *
    +purple_attention_type_get_icon_name(const PurpleAttentionType *type) {
    + g_return_val_if_fail(type, NULL);
    +
    + if(type->icon_name == NULL || *(type->icon_name) == '\0')
    + return NULL;
    +
    + return type->icon_name;
    +}
    +
    +void
    +purple_attention_type_set_icon_name(PurpleAttentionType *type, const gchar *name) {
    + g_return_if_fail(type);
    +
    + type->icon_name = name;
    +}
    +
    +const gchar *
    +purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type) {
    + g_return_val_if_fail(type, NULL);
    +
    + return type->unlocalized_name;
    +}
    +
    +void
    +purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const gchar *ulname) {
    + g_return_if_fail(type);
    +
    + type->unlocalized_name = ulname;
    +}
    +
    +/******************************************************************************
    + * PurpleAttentionType API
    + *****************************************************************************/
    +G_DEFINE_INTERFACE(PurpleProtocolAttention, purple_protocol_attention, G_TYPE_INVALID);
    +
    +static void
    +purple_protocol_attention_default_init(PurpleProtocolAttentionInterface *iface) {
    +}
    +
    +gboolean
    +purple_protocol_attention_send(PurpleProtocolAttention *attn, PurpleConnection *gc, const gchar *username, guint type) {
    + PurpleProtocolAttentionInterface *iface = NULL;
    +
    + g_return_val_if_fail(PURPLE_IS_PROTOCOL_ATTENTION(attn), FALSE);
    +
    + iface = PURPLE_PROTOCOL_ATTENTION_GET_IFACE(attn);
    + if(iface && iface->send) {
    + return iface->send(attn, gc, username, type);
    + }
    +
    + return FALSE;
    +}
    +
    +GList *
    +purple_protocol_attention_get_types(PurpleProtocolAttention *attn, PurpleAccount *account) {
    + PurpleProtocolAttentionInterface *iface = NULL;
    +
    + g_return_val_if_fail(PURPLE_IS_PROTOCOL_ATTENTION(attn), NULL);
    +
    + iface = PURPLE_PROTOCOL_ATTENTION_GET_IFACE(attn);
    + if(iface && iface->get_types) {
    + return iface->get_types(attn, account);
    + }
    +
    + return NULL;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/libpurple/attention.h Thu Feb 15 23:17:27 2018 -0500
    @@ -0,0 +1,254 @@
    +/* 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_ATTENTION_H
    +#define PURPLE_ATTENTION_H
    +
    +#include <glib.h>
    +#include <glib-object.h>
    +
    +/**
    + * SECTION:attention
    + * @section_id: libpurple-attention
    + * @short_description: <filename>attention.h</filename>
    + * @title: Attention Object and Interfaces
    + */
    +
    +#define PURPLE_TYPE_ATTENTION_TYPE (purple_attention_type_get_type())
    +
    +/**
    + * PurpleAttentionType:
    + * @name: The name to show in GUI elements.
    + * @incoming_description: Shown when received.
    + * @outgoing_description: Shown when sent.
    + * @icon_name: Optional name of the icon to display.
    + * @unlocalized_name: An unlocalized name for UIs that would rather use that.
    + *
    + * Represents "nudges" and "buzzes" that you may send to a buddy to attract
    + * their attention (or vice-versa).
    + */
    +typedef struct _PurpleAttentionType PurpleAttentionType;
    +
    +#define PURPLE_TYPE_PROTOCOL_ATTENTION (purple_protocol_attention_get_type())
    +#define PURPLE_PROTOCOL_ATTENTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_PROTOCOL_ATTENTION, PurpleProtocolAttention))
    +#define PURPLE_IS_PROTOCOL_ATTENTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL_ATTENTION))
    +#define PURPLE_PROTOCOL_ATTENTION_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_ATTENTION, PurpleProtocolAttentionInterface))
    +
    +typedef struct _PurpleProtocolAttention PurpleProtocolAttention;
    +typedef struct _PurpleProtocolAttentionInterface PurpleProtocolAttentionInterface;
    +
    +#include "account.h"
    +#include "connection.h"
    +
    +/**
    + * PurpleProtocolAttentionInterface:
    + *
    + * The protocol attention interface.
    + *
    + * This interface provides attention API for sending and receiving
    + * zaps/nudges/buzzes etc.
    + */
    +struct _PurpleProtocolAttentionInterface
    +{
    + /*< private >*/
    + GTypeInterface parent;
    +
    + /*< public >*/
    + gboolean (*send)(PurpleProtocolAttention *attn, PurpleConnection *gc, const gchar *username, guint type);
    +
    + GList *(*get_types)(PurpleProtocolAttention *attn, PurpleAccount *acct);
    +};
    +
    +G_BEGIN_DECLS
    +
    +/******************************************************************************
    + * AttentionType API
    + *****************************************************************************/
    +
    +/**
    + * purple_attention_type_get_type:
    + *
    + * Returns: The #GType for the #PurpleAttentionType boxed structure.
    + */
    +GType purple_attention_type_get_type(void);
    +
    +PurpleAttentionType *purple_attention_type_copy(PurpleAttentionType *attn);
    +
    +/**
    + * purple_attention_type_new:
    + * @unlocalized_name: A non-localized string that can be used by UIs in need of such
    + * non-localized strings. This should be the same as @name,
    + * without localization.
    + * @name: A localized string that the UI may display for the event. This
    + * should be the same string as @unlocalized_name, with localization.
    + * @incoming_description: A localized description shown when the event is received.
    + * @outgoing_description: A localized description shown when the event is sent.
    + *
    + * Creates a new #PurpleAttentionType object and sets its mandatory parameters.
    + *
    + * Returns: A pointer to the new object.
    + */
    +PurpleAttentionType *purple_attention_type_new(const gchar *unlocalized_name, const gchar *name,
    + const gchar *incoming_description, const gchar *outgoing_description);
    +
    +/**
    + * purple_attention_type_get_name:
    + * @type: The attention type.
    + *
    + * Get the attention type's name as displayed by the UI.
    + *
    + * Returns: The name.
    + */
    +const gchar *purple_attention_type_get_name(const PurpleAttentionType *type);
    +
    +/**
    + * purple_attention_type_set_name:
    + * @type: The attention type.
    + * @name: The localized name that will be displayed by UIs. This should be
    + * the same string given as the unlocalized name, but with
    + * localization.
    + *
    + * Sets the displayed name of the attention-demanding event.
    + */
    +void purple_attention_type_set_name(PurpleAttentionType *type, const gchar *name);
    +
    +/**
    + * purple_attention_type_get_incoming_desc:
    + * @type: The attention type.
    + *
    + * Get the attention type's description shown when the event is received.
    + *
    + * Returns: The description.
    + */
    +const gchar *purple_attention_type_get_incoming_desc(const PurpleAttentionType *type);
    +
    +/**
    + * purple_attention_type_set_incoming_desc:
    + * @type: The attention type.
    + * @desc: The localized description for incoming events.
    + *
    + * Sets the description of the attention-demanding event shown in conversations
    + * when the event is received.
    + */
    +void purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const gchar *desc);
    +
    +/**
    + * purple_attention_type_get_outgoing_desc:
    + * @type: The attention type.
    + *
    + * Get the attention type's description shown when the event is sent.
    + *
    + * Returns: The description.
    + */
    +const gchar *purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type);
    +
    +/**
    + * purple_attention_type_set_outgoing_desc:
    + * @type: The attention type.
    + * @desc: The localized description for outgoing events.
    + *
    + * Sets the description of the attention-demanding event shown in conversations
    + * when the event is sent.
    + */
    +void purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const gchar *desc);
    +
    +/**
    + * purple_attention_type_get_icon_name:
    + * @type: The attention type.
    + *
    + * Get the attention type's icon name.
    + *
    + * Note: Icons are optional for attention events.
    + *
    + * Returns: The icon name or %NULL if unset/empty.
    + */
    +const gchar *purple_attention_type_get_icon_name(const PurpleAttentionType *type);
    +
    +/**
    + * purple_attention_type_set_icon_name:
    + * @type: The attention type.
    + * @name: The icon's name.
    + *
    + * Sets the name of the icon to display for the attention event; this is optional.
    + *
    + * Note: Icons are optional for attention events.
    + */
    +void purple_attention_type_set_icon_name(PurpleAttentionType *type, const gchar *name);
    +
    +/**
    + * purple_attention_type_get_unlocalized_name:
    + * @type: The attention type
    + *
    + * Get the attention type's unlocalized name; this is useful for some UIs.
    + *
    + * Returns: The unlocalized name.
    + */
    +const gchar *purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type);
    +
    +/**
    + * purple_attention_type_set_unlocalized_name:
    + * @type: The attention type.
    + * @ulname: The unlocalized name. This should be the same string given as
    + * the localized name, but without localization.
    + *
    + * Sets the unlocalized name of the attention event; some UIs may need this,
    + * thus it is required.
    + */
    +void purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const gchar *ulname);
    +
    +/******************************************************************************
    + * Protocol Interface
    + *****************************************************************************/
    +
    +/**
    + * purple_protocol_attention_get_type:
    + *
    + * Returns: The #GType for the protocol attention interface.
    + */
    +GType purple_protocol_attention_get_type(void);
    +
    +/**
    + * purple_protocol_attention_get_types:
    + * @protocol: The #PurpleProtocol.
    + * @account: The #PurpleAccount whose attention types to get.
    + *
    + * Returns a list of #PurpleAttentionType's for @attn.
    + *
    + * Returns: (transfer container) (element-type PurpleAttentionType): The list of #PurpleAttentionType's.
    + */
    +GList *purple_protocol_attention_get_types(PurpleProtocolAttention *attn, PurpleAccount *acct);
    +
    +/**
    + * purple_protocol_attention_send:
    + * @attn: The #PurpleProtocolAttention instance.
    + * @gc: The #PurpleConnection to send on
    + * @username: The name of the user to send the attention to.
    + * @type: The type of attention to send.
    + *
    + * Sends an attention message of @type to @username.
    + *
    + * Returns: TRUE on success, FALSE otherwise.
    + */
    +gboolean purple_protocol_attention_send(PurpleProtocolAttention *attn, PurpleConnection *gc, const gchar *username, guint type);
    +
    +G_END_DECLS
    +
    +#endif /* PURPLE_ATTENTION_H */
    --- a/libpurple/meson.build Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/meson.build Thu Feb 15 23:17:27 2018 -0500
    @@ -2,6 +2,7 @@
    'account.c',
    'accounts.c',
    'accountopt.c',
    + 'attention.c',
    'blistnode.c',
    'buddy.c',
    'buddylist.c',
    @@ -86,6 +87,7 @@
    'account.h',
    'accounts.h',
    'accountopt.h',
    + 'attention.h',
    'blistnode.h',
    'buddy.h',
    'buddylist.h',
    --- a/libpurple/protocol.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocol.c Thu Feb 15 23:17:27 2018 -0500
    @@ -864,56 +864,6 @@
    #undef DEFINE_PROTOCOL_FUNC
    /**************************************************************************
    - * Protocol Attention Interface API
    - **************************************************************************/
    -#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
    - PurpleProtocolAttentionIface *attention_iface = \
    - PURPLE_PROTOCOL_GET_ATTENTION_IFACE(protocol); \
    - if (attention_iface && attention_iface->funcname) \
    - attention_iface->funcname(__VA_ARGS__);
    -
    -#define DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol,defaultreturn,funcname,...) \
    - PurpleProtocolAttentionIface *attention_iface = \
    - PURPLE_PROTOCOL_GET_ATTENTION_IFACE(protocol); \
    - if (attention_iface && attention_iface->funcname) \
    - return attention_iface->funcname(__VA_ARGS__); \
    - else \
    - return defaultreturn;
    -
    -GType
    -purple_protocol_attention_iface_get_type(void)
    -{
    - static GType type = 0;
    -
    - if (G_UNLIKELY(type == 0)) {
    - static const GTypeInfo info = {
    - .class_size = sizeof(PurpleProtocolAttentionIface),
    - };
    -
    - type = g_type_register_static(G_TYPE_INTERFACE,
    - "PurpleProtocolAttentionIface", &info, 0);
    - }
    - return type;
    -}
    -
    -gboolean
    -purple_protocol_attention_iface_send(PurpleProtocol *protocol,
    - PurpleConnection *gc, const char *username, guint type)
    -{
    - DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, FALSE, send, gc, username, type);
    -}
    -
    -GList *
    -purple_protocol_attention_iface_get_types(PurpleProtocol *protocol,
    - PurpleAccount *account)
    -{
    - DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, get_types, account);
    -}
    -
    -#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
    -#undef DEFINE_PROTOCOL_FUNC
    -
    -/**************************************************************************
    * Protocol Media Interface API
    **************************************************************************/
    #define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
    --- a/libpurple/protocol.h Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocol.h Thu Feb 15 23:17:27 2018 -0500
    @@ -588,34 +588,6 @@
    #define PURPLE_PROTOCOL_GET_ROOMLIST_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_ROOMLIST_IFACE, \
    PurpleProtocolRoomlistIface))
    -#define PURPLE_TYPE_PROTOCOL_ATTENTION_IFACE (purple_protocol_attention_iface_get_type())
    -
    -typedef struct _PurpleProtocolAttentionIface PurpleProtocolAttentionIface;
    -
    -/**
    - * PurpleProtocolAttentionIface:
    - *
    - * The protocol attention interface.
    - *
    - * This interface provides attention API for sending and receiving
    - * zaps/nudges/buzzes etc.
    - */
    -struct _PurpleProtocolAttentionIface
    -{
    - /*< private >*/
    - GTypeInterface parent_iface;
    -
    - /*< public >*/
    - gboolean (*send)(PurpleConnection *gc, const char *username,
    - guint type);
    -
    - GList *(*get_types)(PurpleAccount *acct);
    -};
    -
    -#define PURPLE_PROTOCOL_HAS_ATTENTION_IFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL_ATTENTION_IFACE))
    -#define PURPLE_PROTOCOL_GET_ATTENTION_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), PURPLE_TYPE_PROTOCOL_ATTENTION_IFACE, \
    - PurpleProtocolAttentionIface))
    -
    #define PURPLE_TYPE_PROTOCOL_MEDIA_IFACE (purple_protocol_media_iface_get_type())
    typedef struct _PurpleProtocolMediaIface PurpleProtocolMediaIface;
    @@ -1078,23 +1050,6 @@
    PurpleRoomlistRoom *room);
    /**************************************************************************/
    -/* Protocol Attention Interface API */
    -/**************************************************************************/
    -
    -/**
    - * purple_protocol_attention_iface_get_type:
    - *
    - * Returns: The #GType for the protocol attention interface.
    - */
    -GType purple_protocol_attention_iface_get_type(void);
    -
    -gboolean purple_protocol_attention_iface_send(PurpleProtocol *protocol,
    - PurpleConnection *gc, const char *username, guint type);
    -
    -GList *purple_protocol_attention_iface_get_types(PurpleProtocol *protocol,
    - PurpleAccount *acct);
    -
    -/**************************************************************************/
    /* Protocol Media Interface API */
    /**************************************************************************/
    --- a/libpurple/protocols.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols.c Thu Feb 15 23:17:27 2018 -0500
    @@ -32,149 +32,6 @@
    static GHashTable *protocols = NULL;
    -/**************************************************************************/
    -/* Attention Type API */
    -/**************************************************************************/
    -
    -struct _PurpleAttentionType
    -{
    - const char *name; /* Shown in GUI elements */
    - const char *incoming_description; /* Shown when sent */
    - const char *outgoing_description; /* Shown when receied */
    - const char *icon_name; /* Icon to display (optional) */
    - const char *unlocalized_name; /* Unlocalized name for UIs needing it */
    -};
    -
    -
    -PurpleAttentionType *
    -purple_attention_type_new(const char *ulname, const char *name,
    - const char *inc_desc, const char *out_desc)
    -{
    - PurpleAttentionType *attn = g_new0(PurpleAttentionType, 1);
    -
    - purple_attention_type_set_name(attn, name);
    - purple_attention_type_set_incoming_desc(attn, inc_desc);
    - purple_attention_type_set_outgoing_desc(attn, out_desc);
    - purple_attention_type_set_unlocalized_name(attn, ulname);
    -
    - return attn;
    -}
    -
    -
    -void
    -purple_attention_type_set_name(PurpleAttentionType *type, const char *name)
    -{
    - g_return_if_fail(type != NULL);
    -
    - type->name = name;
    -}
    -
    -void
    -purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc)
    -{
    - g_return_if_fail(type != NULL);
    -
    - type->incoming_description = desc;
    -}
    -
    -void
    -purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc)
    -{
    - g_return_if_fail(type != NULL);
    -
    - type->outgoing_description = desc;
    -}
    -
    -void
    -purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name)
    -{
    - g_return_if_fail(type != NULL);
    -
    - type->icon_name = name;
    -}
    -
    -void
    -purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname)
    -{
    - g_return_if_fail(type != NULL);
    -
    - type->unlocalized_name = ulname;
    -}
    -
    -const char *
    -purple_attention_type_get_name(const PurpleAttentionType *type)
    -{
    - g_return_val_if_fail(type != NULL, NULL);
    -
    - return type->name;
    -}
    -
    -const char *
    -purple_attention_type_get_incoming_desc(const PurpleAttentionType *type)
    -{
    - g_return_val_if_fail(type != NULL, NULL);
    -
    - return type->incoming_description;
    -}
    -
    -const char *
    -purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type)
    -{
    - g_return_val_if_fail(type != NULL, NULL);
    -
    - return type->outgoing_description;
    -}
    -
    -const char *
    -purple_attention_type_get_icon_name(const PurpleAttentionType *type)
    -{
    - g_return_val_if_fail(type != NULL, NULL);
    -
    - if(type->icon_name == NULL || *(type->icon_name) == '\0')
    - return NULL;
    -
    - return type->icon_name;
    -}
    -
    -const char *
    -purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type)
    -{
    - g_return_val_if_fail(type != NULL, NULL);
    -
    - return type->unlocalized_name;
    -}
    -
    -/**************************************************************************
    - * GBoxed code for PurpleAttentionType
    - **************************************************************************/
    -
    -static PurpleAttentionType *
    -purple_attention_type_copy(PurpleAttentionType *attn)
    -{
    - PurpleAttentionType *attn_copy;
    -
    - g_return_val_if_fail(attn != NULL, NULL);
    -
    - attn_copy = g_new(PurpleAttentionType, 1);
    - *attn_copy = *attn;
    -
    - return attn_copy;
    -}
    -
    -GType
    -purple_attention_type_get_type(void)
    -{
    - static GType type = 0;
    -
    - if (type == 0) {
    - type = g_boxed_type_register_static("PurpleAttentionType",
    - (GBoxedCopyFunc)purple_attention_type_copy,
    - (GBoxedFreeFunc)g_free);
    - }
    -
    - return type;
    -}
    -
    /**************************************************************************
    * GBoxed code for PurpleProtocolChatEntry
    **************************************************************************/
    @@ -508,7 +365,7 @@
    g_return_if_fail(who != NULL);
    protocol = purple_protocols_find(purple_account_get_protocol_id(purple_connection_get_account(gc)));
    - g_return_if_fail(PURPLE_PROTOCOL_IMPLEMENTS(protocol, ATTENTION_IFACE, send));
    + g_return_if_fail(PURPLE_IS_PROTOCOL_ATTENTION(protocol));
    attn = purple_get_attention_type_from_code(purple_connection_get_account(gc), type_code);
    @@ -526,7 +383,7 @@
    purple_debug_info("server", "serv_send_attention: sending '%s' to %s\n",
    description, who);
    - if (!purple_protocol_attention_iface_send(protocol, gc, who, type_code))
    + if (!purple_protocol_attention_send(PURPLE_PROTOCOL_ATTENTION(protocol), gc, who, type_code))
    return;
    im = purple_im_conversation_new(purple_connection_get_account(gc), who);
    --- a/libpurple/protocols.h Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols.h Thu Feb 15 23:17:27 2018 -0500
    @@ -36,16 +36,6 @@
    typedef struct _PurpleProtocolAction PurpleProtocolAction;
    typedef void (*PurpleProtocolActionCallback)(PurpleProtocolAction *action);
    -#define PURPLE_TYPE_ATTENTION_TYPE (purple_attention_type_get_type())
    -
    -/**
    - * PurpleAttentionType:
    - *
    - * Represents "nudges" and "buzzes" that you may send to a buddy to attract
    - * their attention (or vice-versa).
    - */
    -typedef struct _PurpleAttentionType PurpleAttentionType;
    -
    /**************************************************************************/
    /* Basic Protocol Information */
    /**************************************************************************/
    @@ -157,135 +147,6 @@
    /* Attention Type API */
    /**************************************************************************/
    -/**
    - * purple_attention_type_get_type:
    - *
    - * Returns: The #GType for the #PurpleAttentionType boxed structure.
    - */
    -GType purple_attention_type_get_type(void);
    -
    -/**
    - * purple_attention_type_new:
    - * @ulname: A non-localized string that can be used by UIs in need of such
    - * non-localized strings. This should be the same as @name,
    - * without localization.
    - * @name: A localized string that the UI may display for the event. This
    - * should be the same string as @ulname, with localization.
    - * @inc_desc: A localized description shown when the event is received.
    - * @out_desc: A localized description shown when the event is sent.
    - *
    - * Creates a new #PurpleAttentionType object and sets its mandatory parameters.
    - *
    - * Returns: A pointer to the new object.
    - */
    -PurpleAttentionType *purple_attention_type_new(const char *ulname, const char *name,
    - const char *inc_desc, const char *out_desc);
    -
    -/**
    - * purple_attention_type_set_name:
    - * @type: The attention type.
    - * @name: The localized name that will be displayed by UIs. This should be
    - * the same string given as the unlocalized name, but with
    - * localization.
    - *
    - * Sets the displayed name of the attention-demanding event.
    - */
    -void purple_attention_type_set_name(PurpleAttentionType *type, const char *name);
    -
    -/**
    - * purple_attention_type_set_incoming_desc:
    - * @type: The attention type.
    - * @desc: The localized description for incoming events.
    - *
    - * Sets the description of the attention-demanding event shown in conversations
    - * when the event is received.
    - */
    -void purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc);
    -
    -/**
    - * purple_attention_type_set_outgoing_desc:
    - * @type: The attention type.
    - * @desc: The localized description for outgoing events.
    - *
    - * Sets the description of the attention-demanding event shown in conversations
    - * when the event is sent.
    - */
    -void purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc);
    -
    -/**
    - * purple_attention_type_set_icon_name:
    - * @type: The attention type.
    - * @name: The icon's name.
    - *
    - * Sets the name of the icon to display for the attention event; this is optional.
    - *
    - * Note: Icons are optional for attention events.
    - */
    -void purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name);
    -
    -/**
    - * purple_attention_type_set_unlocalized_name:
    - * @type: The attention type.
    - * @ulname: The unlocalized name. This should be the same string given as
    - * the localized name, but without localization.
    - *
    - * Sets the unlocalized name of the attention event; some UIs may need this,
    - * thus it is required.
    - */
    -void purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname);
    -
    -/**
    - * purple_attention_type_get_name:
    - * @type: The attention type.
    - *
    - * Get the attention type's name as displayed by the UI.
    - *
    - * Returns: The name.
    - */
    -const char *purple_attention_type_get_name(const PurpleAttentionType *type);
    -
    -/**
    - * purple_attention_type_get_incoming_desc:
    - * @type: The attention type.
    - *
    - * Get the attention type's description shown when the event is received.
    - *
    - * Returns: The description.
    - */
    -const char *purple_attention_type_get_incoming_desc(const PurpleAttentionType *type);
    -
    -/**
    - * purple_attention_type_get_outgoing_desc:
    - * @type: The attention type.
    - *
    - * Get the attention type's description shown when the event is sent.
    - *
    - * Returns: The description.
    - */
    -const char *purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type);
    -
    -/**
    - * purple_attention_type_get_icon_name:
    - * @type: The attention type.
    - *
    - * Get the attention type's icon name.
    - *
    - * Note: Icons are optional for attention events.
    - *
    - * Returns: The icon name or %NULL if unset/empty.
    - */
    -const char *purple_attention_type_get_icon_name(const PurpleAttentionType *type);
    -
    -/**
    - * purple_attention_type_get_unlocalized_name:
    - * @type: The attention type
    - *
    - * Get the attention type's unlocalized name; this is useful for some UIs.
    - *
    - * Returns: The unlocalized name.
    - */
    -const char *purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type);
    -
    /**************************************************************************/
    /* Protocol Action API */
    /**************************************************************************/
    --- a/libpurple/protocols/bonjour/jabber.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/bonjour/jabber.c Thu Feb 15 23:17:27 2018 -0500
    @@ -158,10 +158,6 @@
    events_node = purple_xmlnode_get_child_with_namespace(message_node, "x", "jabber:x:event");
    if (events_node != NULL) {
    -#if 0
    - if (purple_xmlnode_get_child(events_node, "composing") != NULL)
    - composing_event = TRUE;
    -#endif
    if (purple_xmlnode_get_child(events_node, "id") != NULL) {
    /* The user is just typing */
    /* TODO: Deal with typing notification */
    @@ -393,17 +389,7 @@
    if(bconv->pb != NULL)
    bb = purple_buddy_get_protocol_data(bconv->pb);
    -#if 0
    - if(bconv->pb != NULL) {
    - PurpleConversation *conv;
    - conv = purple_conversations_find_im_with_account(bconv->pb->name, bconv->pb->account);
    - if (conv != NULL) {
    - char *tmp = g_strdup_printf(_("%s has closed the conversation."), bconv->pb->name);
    - purple_conversation_write_system_message(conv, tmp, 0);
    - g_free(tmp);
    - }
    - }
    -#endif
    +
    /* Close the socket, clear the watcher and free memory */
    bonjour_jabber_close_conversation(bconv);
    if(bb)
    @@ -737,16 +723,6 @@
    return -1;
    }
    -#if 0
    - /* TODO: Why isn't this being used? */
    - data->socket = purple_network_listen(jdata->port, AF_UNSPEC, SOCK_STREAM, TRUE);
    -
    - if (jdata->socket == -1)
    - {
    - purple_debug_error("bonjour", "No se ha podido crear el socket\n");
    - }
    -#endif
    -
    return ret_port;
    }
    --- a/libpurple/protocols/gg/account.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/gg/account.c Thu Feb 15 23:17:27 2018 -0500
    @@ -149,10 +149,6 @@
    ggp_account_token *token, gpointer _register_data);
    static void ggp_account_register_dialog_ok(
    ggp_account_register_data *register_data, PurpleRequestFields *fields);
    -#if 0
    -static void ggp_account_register_dialog_invalid(
    - ggp_account_register_data *register_data, const gchar *message);
    -#endif
    static void ggp_account_register_dialog_cancel(
    ggp_account_register_data *register_data, PurpleRequestFields *fields);
    static void ggp_account_register_response(struct gg_http *h, gboolean success,
    @@ -295,20 +291,6 @@
    ggp_account_register_response, register_data, TRUE);
    }
    -#if 0
    -/* libgadu 1.12.x: use it for invalid token */
    -static void ggp_account_register_dialog_invalid(
    - ggp_account_register_data *register_data, const gchar *message)
    -{
    - purple_debug_warning("gg", "ggp_account_register_dialog_invalid: %s\n",
    - message);
    - ggp_account_register_dialog(register_data->gc, register_data->token,
    - register_data);
    - purple_notify_error(purple_connection_get_account(register_data->gc),
    - GGP_ACCOUNT_REGISTER_TITLE, message, NULL);
    -}
    -#endif
    -
    static void ggp_account_register_response(struct gg_http *h, gboolean success,
    gboolean cancelled, gpointer _register_data)
    {
    --- a/libpurple/protocols/gg/validator.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/gg/validator.c Thu Feb 15 23:17:27 2018 -0500
    @@ -31,29 +31,6 @@
    #include "utils.h"
    -#if 0
    -#include "account.h"
    -
    -gboolean ggp_validator_token(PurpleRequestField *field, gchar **errmsg,
    - void *token)
    -{
    - const char *value;
    -
    - g_return_val_if_fail(field != NULL, FALSE);
    - g_return_val_if_fail(purple_request_field_get_field_type(field) ==
    - PURPLE_REQUEST_FIELD_STRING, FALSE);
    -
    - value = purple_request_field_string_get_value(field);
    -
    - if (value != NULL && ggp_account_token_validate(token, value))
    - return TRUE;
    -
    - if (errmsg)
    - *errmsg = g_strdup(_("CAPTCHA validation failed"));
    - return FALSE;
    -}
    -#endif
    -
    gboolean ggp_validator_password(PurpleRequestField *field, gchar **errmsg,
    void *user_data)
    {
    --- a/libpurple/protocols/gg/validator.h Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/gg/validator.h Thu Feb 15 23:17:27 2018 -0500
    @@ -33,12 +33,6 @@
    #include <internal.h>
    #include <request.h>
    -#if 0
    -/* see account.h */
    -gboolean ggp_validator_token(PurpleRequestField *field, gchar **errmsg,
    - void *token);
    -#endif
    -
    gboolean ggp_validator_password(PurpleRequestField *field, gchar **errmsg,
    void *user_data);
    --- a/libpurple/protocols/irc/irc.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/irc/irc.c Thu Feb 15 23:17:27 2018 -0500
    @@ -687,11 +687,6 @@
    purple_debug(PURPLE_DEBUG_ERROR, "irc", "chat send on nonexistent chat\n");
    return -EINVAL;
    }
    -#if 0
    - if (*what == '/') {
    - return irc_parse_cmd(irc, convo->name, what + 1);
    - }
    -#endif
    purple_markup_html_to_xhtml(purple_message_get_contents(msg), NULL, &tmp);
    args[0] = purple_conversation_get_name(convo);
    args[1] = tmp;
    --- a/libpurple/protocols/jabber/auth_scram.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/auth_scram.c Thu Feb 15 23:17:27 2018 -0500
    @@ -46,35 +46,6 @@
    g_return_val_if_reached(NULL);
    }
    -#if 0
    -/* XXX: this code is not (yet) used */
    -static const struct {
    - const char *error;
    - const char *meaning;
    -} server_errors[] = {
    - { "invalid-encoding",
    - N_("Invalid Encoding")},
    - { "extensions-not-supported",
    - N_("Unsupported Extension") },
    - { "channel-bindings-dont-match",
    - N_("Unexpected response from the server. This may indicate a possible MITM attack") },
    - { "server-does-support-channel-binding",
    - N_("The server does support channel binding, but did not appear to advertise it. This indicates a likely MITM attack") },
    - { "channel-binding-not-supported",
    - N_("Server does not support channel binding") },
    - { "unsupported-channel-binding-type",
    - N_("Unsupported channel binding method") },
    - { "unknown-user",
    - N_("User not found") },
    - { "invalid-username-encoding",
    - N_("Invalid Username Encoding") },
    - { "no-resources",
    - N_("Resource Constraint") },
    - { "other-error",
    - N_("Unknown Error") }
    -};
    -#endif
    -
    guchar *jabber_scram_hi(const JabberScramHash *hash, const GString *str,
    GString *salt, guint iterations)
    {
    --- a/libpurple/protocols/jabber/buddy.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/buddy.c Thu Feb 15 23:17:27 2018 -0500
    @@ -2135,24 +2135,6 @@
    g_free(usi);
    }
    -#if 0
    -/* This is for gettext only -- it will see this even though there's an #if 0. */
    -
    -/*
    - * An incomplete list of server generated original language search
    - * comments for Jabber User Directories
    - *
    - * See discussion thread "Search comment for Jabber is not translatable"
    - * in purple-i18n@lists.sourceforge.net (March 2006)
    - */
    -static const char * jabber_user_dir_comments [] = {
    - /* current comment from Jabber User Directory users.jabber.org */
    - N_("Find a contact by entering the search criteria in the given fields. "
    - "Note: Each field supports wild card searches (%)"),
    - NULL
    -};
    -#endif
    -
    static void user_search_fields_result_cb(JabberStream *js, const char *from,
    JabberIqType type, const char *id,
    PurpleXmlNode *packet, gpointer data)
    --- a/libpurple/protocols/jabber/chat.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/chat.c Thu Feb 15 23:17:27 2018 -0500
    @@ -1214,9 +1214,6 @@
    PurpleXmlNode *packet, gpointer data)
    {
    JabberChat *chat;
    -#if 0
    - PurpleXmlNode *query, *x;
    -#endif
    int chat_id = GPOINTER_TO_INT(data);
    if(!(chat = jabber_chat_find_by_id(js, chat_id)))
    @@ -1225,27 +1222,6 @@
    /* defaults, in case the conference server doesn't
    * support this request */
    chat->xhtml = TRUE;
    -
    - /* disabling this until more MUC servers support
    - * announcing this */
    -#if 0
    - if (type == JABBER_IQ_ERROR) {
    - return;
    - }
    -
    - if(!(query = purple_xmlnode_get_child(packet, "query")))
    - return;
    -
    - chat->xhtml = FALSE;
    -
    - for(x = purple_xmlnode_get_child(query, "feature"); x; x = purple_xmlnode_get_next_twin(x)) {
    - const char *var = purple_xmlnode_get_attrib(x, "var");
    -
    - if(purple_strequal(var, NS_XHTML_IM)) {
    - chat->xhtml = TRUE;
    - }
    - }
    -#endif
    }
    void jabber_chat_disco_traffic(JabberChat *chat)
    --- a/libpurple/protocols/jabber/gtalk.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/gtalk.c Thu Feb 15 23:17:27 2018 -0500
    @@ -62,9 +62,6 @@
    ADD_VALUE(encryption_values, _("Require encryption"), "require_tls");
    ADD_VALUE(encryption_values, _("Use encryption if available"), "opportunistic_tls");
    ADD_VALUE(encryption_values, _("Use old-style SSL"), "old_ssl");
    -#if 0
    - ADD_VALUE(encryption_values, "None", "none");
    -#endif
    encryption_values = g_list_reverse(encryption_values);
    #undef ADD_VALUE
    --- a/libpurple/protocols/jabber/jabber.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/jabber.c Thu Feb 15 23:17:27 2018 -0500
    @@ -220,50 +220,9 @@
    static gboolean
    jabber_process_starttls(JabberStream *js, PurpleXmlNode *packet)
    {
    -#if 0
    - PurpleXmlNode *starttls;
    -
    - PurpleAccount *account;
    -
    - account = purple_connection_get_account(js->gc);
    -
    - /*
    - * This code DOES NOT EXIST, will never be enabled by default, and
    - * will never ever be supported (by me).
    - * It's literally *only* for developer testing.
    - */
    - {
    - const gchar *connection_security = purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS);
    - if (!purple_strequal(connection_security, "none")) {
    - jabber_send_raw(js,
    - "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1);
    - return TRUE;
    - }
    - }
    -#else
    jabber_send_raw(js,
    "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1);
    return TRUE;
    -#endif
    -
    -#if 0
    - starttls = purple_xmlnode_get_child(packet, "starttls");
    - if(purple_xmlnode_get_child(starttls, "required")) {
    - purple_connection_error(js->gc,
    - PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
    - _("Server requires TLS/SSL, but no TLS/SSL support was found."));
    - return TRUE;
    - }
    -
    - if (purple_strequal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
    - purple_connection_error(js->gc,
    - PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
    - _("You require encryption, but no TLS/SSL support was found."));
    - return TRUE;
    - }
    -
    - return FALSE;
    -#endif
    }
    void jabber_stream_features_parse(JabberStream *js, PurpleXmlNode *packet)
    @@ -2688,9 +2647,7 @@
    PurpleXmlNode *t = purple_xmlnode_get_child_with_namespace(error, "text", NS_XMPP_STANZAS);
    if (t)
    cdata = purple_xmlnode_get_data(t);
    -#if 0
    - cdata = purple_xmlnode_get_data(error);
    -#endif
    +
    code = purple_xmlnode_get_attrib(error, "code");
    /* Stanza errors */
    @@ -3211,7 +3168,7 @@
    return _jabber_send_buzz(js, who, error) ? PURPLE_CMD_RET_OK : PURPLE_CMD_RET_FAILED;
    }
    -GList *jabber_attention_types(PurpleAccount *account)
    +GList *jabber_attention_types(PurpleProtocolAttention *attn, PurpleAccount *account)
    {
    static GList *types = NULL;
    @@ -3223,7 +3180,7 @@
    return types;
    }
    -gboolean jabber_send_attention(PurpleConnection *gc, const char *username, guint code)
    +gboolean jabber_send_attention(PurpleProtocolAttention *attn, PurpleConnection *gc, const char *username, guint code)
    {
    JabberStream *js = purple_connection_get_protocol_data(gc);
    gchar *error = NULL;
    @@ -3762,56 +3719,6 @@
    g_hash_table_remove(jabber_cmds, protocol);
    }
    -#if 0
    -/* IPC functions */
    -
    -/**
    - * IPC function for determining if a contact supports a certain feature.
    - *
    - * @param account The PurpleAccount
    - * @param jid The full JID of the contact.
    - * @param feature The feature's namespace.
    - *
    - * @return TRUE if supports feature; else FALSE.
    - */
    -static gboolean
    -jabber_ipc_contact_has_feature(PurpleAccount *account, const gchar *jid,
    - const gchar *feature)
    -{
    - PurpleConnection *gc = purple_account_get_connection(account);
    - JabberStream *js;
    - JabberBuddy *jb;
    - JabberBuddyResource *jbr;
    - gchar *resource;
    -
    - if (!purple_account_is_connected(account))
    - return FALSE;
    - js = purple_connection_get_protocol_data(gc);
    -
    - if (!(resource = jabber_get_resource(jid)) ||
    - !(jb = jabber_buddy_find(js, jid, FALSE)) ||
    - !(jbr = jabber_buddy_find_resource(jb, resource))) {
    - g_free(resource);
    - return FALSE;
    - }
    -
    - g_free(resource);
    -
    - return jabber_resource_has_capability(jbr, feature);
    -}
    -
    -static void
    -jabber_ipc_add_feature(const gchar *feature)
    -{
    - if (!feature)
    - return;
    - jabber_add_feature(feature, 0);
    -
    - /* send presence with new caps info for all connected accounts */
    - jabber_caps_broadcast_change();
    -}
    -#endif
    -
    static PurpleAccount *find_acct(const char *protocol, const char *acct_id)
    {
    PurpleAccount *acct = NULL;
    @@ -4032,32 +3939,6 @@
    jabber_register_commands(protocol);
    -#if 0
    - /* IPC functions */
    - purple_plugin_ipc_register(plugin, "contact_has_feature", PURPLE_CALLBACK(jabber_ipc_contact_has_feature),
    - purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
    - G_TYPE_BOOLEAN, 3,
    - PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
    -
    - purple_plugin_ipc_register(plugin, "add_feature", PURPLE_CALLBACK(jabber_ipc_add_feature),
    - purple_marshal_VOID__POINTER,
    - G_TYPE_NONE, 1, G_TYPE_STRING);
    -
    - purple_plugin_ipc_register(plugin, "register_namespace_watcher",
    - PURPLE_CALLBACK(jabber_iq_signal_register),
    - purple_marshal_VOID__POINTER_POINTER,
    - G_TYPE_NONE, 2,
    - G_TYPE_STRING, /* node */
    - G_TYPE_STRING); /* namespace */
    -
    - purple_plugin_ipc_register(plugin, "unregister_namespace_watcher",
    - PURPLE_CALLBACK(jabber_iq_signal_unregister),
    - purple_marshal_VOID__POINTER_POINTER,
    - G_TYPE_NONE, 2,
    - G_TYPE_STRING, /* node */
    - G_TYPE_STRING); /* namespace */
    -#endif
    -
    purple_signal_register(protocol, "jabber-register-namespace-watcher",
    purple_marshal_VOID__POINTER_POINTER,
    G_TYPE_NONE, 2,
    @@ -4141,9 +4022,6 @@
    g_return_if_fail(plugin_ref > 0);
    purple_signals_unregister_by_instance(protocol);
    -#if 0
    - purple_plugin_ipc_unregister_all(plugin);
    -#endif
    jabber_unregister_commands(protocol);
    --plugin_ref;
    @@ -4249,10 +4127,10 @@
    }
    static void
    -jabber_protocol_attention_iface_init(PurpleProtocolAttentionIface *attention_iface)
    +jabber_protocol_attention_iface_init(PurpleProtocolAttentionInterface *iface)
    {
    - attention_iface->send = jabber_send_attention;
    - attention_iface->get_types = jabber_attention_types;
    + iface->send = jabber_send_attention;
    + iface->get_types = jabber_attention_types;
    }
    static void
    @@ -4291,7 +4169,7 @@
    PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_ROOMLIST_IFACE,
    jabber_protocol_roomlist_iface_init)
    - PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_ATTENTION_IFACE,
    + PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_ATTENTION,
    jabber_protocol_attention_iface_init)
    PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_MEDIA_IFACE,
    --- a/libpurple/protocols/jabber/jabber.h Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/jabber.h Thu Feb 15 23:17:27 2018 -0500
    @@ -59,6 +59,7 @@
    #include <gmodule.h>
    #include <gio/gio.h>
    +#include "attention.h"
    #include "circularbuffer.h"
    #include "connection.h"
    #include "http.h"
    @@ -418,8 +419,8 @@
    void jabber_register_gateway(JabberStream *js, const char *gateway);
    void jabber_register_account(PurpleAccount *account);
    void jabber_unregister_account(PurpleAccount *account, PurpleAccountUnregistrationCb cb, void *user_data);
    -gboolean jabber_send_attention(PurpleConnection *gc, const char *username, guint code);
    -GList *jabber_attention_types(PurpleAccount *account);
    +gboolean jabber_send_attention(PurpleProtocolAttention *attn, PurpleConnection *gc, const char *username, guint code);
    +GList *jabber_attention_types(PurpleProtocolAttention *attn, PurpleAccount *account);
    void jabber_convo_closed(PurpleConnection *gc, const char *who);
    PurpleChat *jabber_find_blist_chat(PurpleAccount *account, const char *name);
    gboolean jabber_offline_message(const PurpleBuddy *buddy);
    --- a/libpurple/protocols/jabber/jingle/jingle.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/jingle/jingle.c Thu Feb 15 23:17:27 2018 -0500
    @@ -51,24 +51,12 @@
    return JINGLE_TYPE_RAWUDP;
    else if (purple_strequal(type, JINGLE_TRANSPORT_ICEUDP))
    return JINGLE_TYPE_ICEUDP;
    -#if 0
    - else if (purple_strequal(type, JINGLE_TRANSPORT_SOCKS))
    - return JINGLE_TYPE_SOCKS;
    - else if (purple_strequal(type, JINGLE_TRANSPORT_IBB))
    - return JINGLE_TYPE_IBB;
    -#endif
    #ifdef USE_VV
    else if (purple_strequal(type, JINGLE_APP_RTP))
    return JINGLE_TYPE_RTP;
    else if (!strcmp(type, NS_GOOGLE_TRANSPORT_P2P))
    return JINGLE_TYPE_GOOGLE_P2P;
    #endif
    -#if 0
    - else if (purple_strequal(type, JINGLE_APP_FT))
    - return JINGLE_TYPE_FT;
    - else if (purple_strequal(type, JINGLE_APP_XML))
    - return JINGLE_TYPE_XML;
    -#endif
    else
    return G_TYPE_NONE;
    }
    --- a/libpurple/protocols/jabber/jingle/rtp.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/jingle/rtp.c Thu Feb 15 23:17:27 2018 -0500
    @@ -59,13 +59,6 @@
    static PurpleMedia *jingle_rtp_get_media(JingleSession *session);
    -#if 0
    -enum {
    - LAST_SIGNAL
    -};
    -static guint jingle_rtp_signals[LAST_SIGNAL] = {0};
    -#endif
    -
    enum {
    PROP_0,
    PROP_MEDIA_TYPE,
    --- a/libpurple/protocols/jabber/jutil.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/jutil.c Thu Feb 15 23:17:27 2018 -0500
    @@ -322,9 +322,6 @@
    const char *slash = NULL;
    const char *c;
    gboolean needs_validation = FALSE;
    -#if 0
    - gboolean node_is_required = FALSE;
    -#endif
    #ifndef USE_IDN
    char *node = NULL;
    char *domain;
    @@ -378,28 +375,6 @@
    /* We're good */
    break;
    -#if 0
    - if (slash != NULL) {
    - /* characters allowed only in the resource */
    - if (implement_me)
    - /* We're good */
    - break;
    - }
    -
    - /* characters allowed only in the node */
    - if (implement_me) {
    - /*
    - * Ok, this character is valid, but only if it's a part
    - * of the node and not the domain. But we don't know
    - * if "c" is a part of the node or the domain until after
    - * we've found the @. So set a flag for now and check
    - * that we found an @ later.
    - */
    - node_is_required = TRUE;
    - break;
    - }
    -#endif
    -
    /*
    * Hmm, this character is a bit more exotic. Better fall
    * back to using the more expensive UTF-8 compliant
    @@ -410,12 +385,6 @@
    }
    }
    -#if 0
    - if (node_is_required && at == NULL)
    - /* Found invalid characters in the domain */
    - return NULL;
    -#endif
    -
    if (!needs_validation) {
    /* JID is made of only ASCII characters--just lowercase and return */
    jid = g_new0(JabberID, 1);
    --- a/libpurple/protocols/jabber/parser.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/parser.c Thu Feb 15 23:17:27 2018 -0500
    @@ -94,23 +94,14 @@
    }
    if (js->stream_id == NULL) {
    -#if 0
    - /* This was underspecified in rfc3920 as only being a SHOULD, so
    - * we cannot rely on it. See #12331 and Oracle's server.
    - */
    - purple_connection_error(js->gc,
    - PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
    - _("XMPP stream missing ID"));
    -#else
    - /* Instead, let's make up a placeholder stream ID, which we need
    - * to do because we flag on it being NULL as a special case
    - * in this parsing code.
    + /* Let's make up a placeholder stream ID, which we need to do
    + * because we flag on it being NULL as a special case in this
    + * parsing code.
    */
    js->stream_id = g_strdup("");
    purple_debug_info("jabber", "Server failed to specify a stream "
    "ID (underspecified in rfc3920, but intended "
    "to be a MUST; digest legacy auth may fail.\n");
    -#endif
    }
    } else {
    --- a/libpurple/protocols/jabber/presence.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/presence.c Thu Feb 15 23:17:27 2018 -0500
    @@ -525,18 +525,6 @@
    jbr->commands_fetched = TRUE;
    }
    -#if 0
    - /*
    - * Versions of libpurple before 2.6.0 didn't advertise this capability, so
    - * we can't yet use Entity Capabilities to determine whether or not the
    - * other client supports Chat States.
    - */
    - if (jabber_resource_has_capability(jbr, "http://jabber.org/protocol/chatstates"))
    - jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED;
    - else
    - jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED;
    -#endif
    -
    out:
    g_free(userdata->from);
    g_free(userdata);
    --- a/libpurple/protocols/jabber/roster.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/roster.c Thu Feb 15 23:17:27 2018 -0500
    @@ -203,9 +203,6 @@
    JabberIqType type, const char *id, PurpleXmlNode *query)
    {
    PurpleXmlNode *item, *group;
    -#if 0
    - const char *ver;
    -#endif
    if (!jabber_is_own_account(js, from)) {
    purple_debug_warning("jabber", "Received bogon roster push from %s\n",
    @@ -285,14 +282,6 @@
    }
    }
    -#if 0
    - ver = purple_xmlnode_get_attrib(query, "ver");
    - if (ver) {
    - PurpleAccount *account = purple_connection_get_account(js->gc);
    - purple_account_set_string(account, "roster_ver", ver);
    - }
    -#endif
    -
    if (type == JABBER_IQ_SET) {
    JabberIq *ack = jabber_iq_new(js, JABBER_IQ_RESULT);
    jabber_iq_set_id(ack, id);
    --- a/libpurple/protocols/jabber/tests/test_jabber_scram.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/tests/test_jabber_scram.c Thu Feb 15 23:17:27 2018 -0500
    @@ -22,11 +22,10 @@
    assert_pbkdf2_equal("password", "salt", 1, "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6");
    assert_pbkdf2_equal("password", "salt", 2, "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57");
    assert_pbkdf2_equal("password", "salt", 4096, "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1");
    -
    -#if 0
    - /* This causes libcheck to time out :-D */
    + /* This test is insane and takes forever, so it's disabled */
    + /*
    assert_pbkdf2_equal("password", "salt", 16777216, "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84");
    -#endif
    + */
    }
    static void
    --- a/libpurple/protocols/jabber/useravatar.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/useravatar.c Thu Feb 15 23:17:27 2018 -0500
    @@ -46,27 +46,6 @@
    static void
    remove_avatar_0_12_nodes(JabberStream *js)
    {
    -#if 0
    - /* See note below for why this is #if 0'd */
    -
    - /* Publish an empty avatar according to the XEP-0084 v0.12 semantics */
    - PurpleXmlNode *publish, *item, *metadata;
    - /* publish the metadata */
    - publish = purple_xmlnode_new("publish");
    - purple_xmlnode_set_attrib(publish, "node", NS_AVATAR_0_12_METADATA);
    -
    - item = purple_xmlnode_new_child(publish, "item");
    - purple_xmlnode_set_attrib(item, "id", "stop");
    -
    - metadata = purple_xmlnode_new_child(item, "metadata");
    - purple_xmlnode_set_namespace(metadata, NS_AVATAR_0_12_METADATA);
    -
    - purple_xmlnode_new_child(metadata, "stop");
    -
    - /* publish */
    - jabber_pep_publish(js, publish);
    -#endif
    -
    /*
    * This causes ejabberd 2.0.0 to kill the connection unceremoniously.
    * See https://support.process-one.net/browse/EJAB-623. When adiumx.com
    --- a/libpurple/protocols/jabber/xmpp.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/jabber/xmpp.c Thu Feb 15 23:17:27 2018 -0500
    @@ -53,9 +53,6 @@
    ADD_VALUE(encryption_values, _("Require encryption"), "require_tls");
    ADD_VALUE(encryption_values, _("Use encryption if available"), "opportunistic_tls");
    ADD_VALUE(encryption_values, _("Use old-style SSL"), "old_ssl");
    -#if 0
    - ADD_VALUE(encryption_values, "None", "none");
    -#endif
    encryption_values = g_list_reverse(encryption_values);
    #undef ADD_VALUE
    --- a/libpurple/protocols/novell/novell.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/novell/novell.c Thu Feb 15 23:17:27 2018 -0500
    @@ -1533,20 +1533,6 @@
    purple_notify_user_info_add_pair_html(user_info, tag, value);
    }
    -#if 0
    - /* Hint for translators: "DN" here refers to a piece of information about
    - a user on the Novell protocol. "DN" is not an English word. I think
    - it's an abbreviation, possibly for "distinguished name" as defined in
    - the X.500 standard. It's probably fine to leave it untranslated. */
    - tag = _("DN");
    - value = nm_user_record_get_dn(user_record);
    - if (value) {
    - /* TODO: Check whether it's correct to call add_pair_html,
    - or if we should be using add_pair_plaintext */
    - purple_notify_user_info_add_pair_html(user_info, tag, value);
    - }
    -#endif /* if 0 */
    -
    tag = _("Full name");
    value = nm_user_record_get_full_name(user_record);
    if (value) {
    --- a/libpurple/protocols/sametime/sametime.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/sametime/sametime.c Thu Feb 15 23:17:27 2018 -0500
    @@ -426,11 +426,6 @@
    tmp);
    g_free(tmp);
    -#if 0
    - close(pd->socket);
    - pd->socket = 0;
    -#endif
    -
    return -1;
    }
    @@ -1353,18 +1348,6 @@
    /* better make sure we're connected */
    if(! purple_account_is_connected(acct)) return;
    -#if 0
    - /* if there's anyone in the group for this acct, offer to invite
    - them all to a conference */
    - group = (PurpleGroup *) node;
    - if(purple_group_on_account(group, acct)) {
    - act = purple_menu_action_new(_("Invite Group to Conference..."),
    - PURPLE_CALLBACK(blist_menu_group_invite),
    - pd, NULL);
    - *menu = g_list_append(*menu, NULL);
    - }
    -#endif
    -
    /* check if it's a NAB group for this account */
    owner = purple_blist_node_get_string(node, GROUP_KEY_OWNER);
    if(owner && purple_strequal(owner, purple_account_get_username(acct))) {
    @@ -2626,13 +2609,6 @@
    }
    }
    -#if 0
    - /* don't do this, to prevent the occasional weird sending of
    - formatted messages as plaintext when the other end closes the
    - conversation after we've begun composing the message */
    - convo_nofeatures(conv);
    -#endif
    -
    mwConversation_removeClientData(conv);
    }
    @@ -3559,42 +3535,6 @@
    }
    -#if 0
    -static void blist_menu_announce(PurpleBlistNode *node, gpointer data) {
    - PurpleBuddy *buddy = (PurpleBuddy *) node;
    - PurpleAccount *acct;
    - PurpleConnection *gc;
    - struct mwPurpleProtocolData *pd;
    - struct mwSession *session;
    - char *rcpt_name;
    - GList *rcpt;
    -
    - g_return_if_fail(node != NULL);
    - g_return_if_fail(PURPLE_IS_BUDDY(node));
    -
    - acct = buddy->account;
    - g_return_if_fail(acct != NULL);
    -
    - gc = purple_account_get_connection(acct);
    - g_return_if_fail(gc != NULL);
    -
    - pd = purple_connection_get_protocol_data(gc);
    - g_return_if_fail(pd != NULL);
    -
    - rcpt_name = g_strdup_printf("@U %s", buddy->name);
    - rcpt = g_list_prepend(NULL, rcpt_name);
    -
    - session = pd->session;
    - mwSession_sendAnnounce(session, FALSE,
    - "This is a TEST announcement. Please ignore.",
    - rcpt);
    -
    - g_list_free(rcpt);
    - g_free(rcpt_name);
    -}
    -#endif
    -
    -
    static GList *mw_protocol_blist_node_menu(PurpleBlistNode *node) {
    GList *l = NULL;
    PurpleMenuAction *act;
    @@ -3608,12 +3548,6 @@
    PURPLE_CALLBACK(blist_menu_conf), NULL, NULL);
    l = g_list_append(l, act);
    -#if 0
    - act = purple_menu_action_new(_("Send TEST Announcement"),
    - PURPLE_CALLBACK(blist_menu_announce), NULL, NULL);
    - l = g_list_append(l, act);
    -#endif
    -
    /** note: this never gets called for a PurpleGroup, have to use the
    blist-node-extended-menu signal for that. The function
    blist_node_menu_cb is assigned to this signal in the function
    @@ -4390,40 +4324,6 @@
    return;
    }
    -
    -#if 0
    - /* fall-through indicates that we couldn't find a matching user in
    - the resolve service (ether error or zero results), so we remove
    - this buddy */
    -
    - /* note: I can't really think of a good reason to alter the buddy
    - list in any way. There has been at least one report where the
    - resolve service isn't returning correct results anyway, so let's
    - just leave them in the list. I'm just going to if0 this section
    - out unless I can think of a very good reason to do this. -siege */
    -
    - DEBUG_INFO("no such buddy in community\n");
    - purple_blist_remove_buddy(buddy);
    - blist_schedule(pd);
    -
    - if(res && res->name) {
    - /* compose and display an error message */
    - const char *msgA;
    - const char *msgB;
    - char *msg;
    -
    - msgA = _("Unable to add user: user not found");
    -
    - msgB = _("The identifier '%s' did not match any users in your"
    - " Sametime community. This entry has been removed from"
    - " your buddy list.");
    - msg = g_strdup_printf(msgB, NSTR(res->name));
    -
    - purple_notify_error(gc, _("Unable to add user"), msgA, msg);
    -
    - g_free(msg);
    - }
    -#endif
    }
    @@ -5063,36 +4963,6 @@
    }
    }
    -#if 0
    -static PurplePluginPrefFrame *
    -mw_plugin_get_plugin_pref_frame(PurplePlugin *plugin) {
    - PurplePluginPrefFrame *frame;
    - PurplePluginPref *pref;
    -
    - frame = purple_plugin_pref_frame_new();
    -
    - pref = purple_plugin_pref_new_with_label(_("Remotely Stored Buddy List"));
    - purple_plugin_pref_frame_add(frame, pref);
    -
    -
    - pref = purple_plugin_pref_new_with_name(MW_PROTOCOL_OPT_BLIST_ACTION);
    - purple_plugin_pref_set_label(pref, _("Buddy List Storage Mode"));
    -
    - purple_plugin_pref_set_pref_type(pref, PURPLE_PLUGIN_PREF_CHOICE);
    - purple_plugin_pref_add_choice(pref, _("Local Buddy List Only"),
    - GINT_TO_POINTER(blist_choice_LOCAL));
    - purple_plugin_pref_add_choice(pref, _("Merge List from Server"),
    - GINT_TO_POINTER(blist_choice_MERGE));
    - purple_plugin_pref_add_choice(pref, _("Merge and Save List to Server"),
    - GINT_TO_POINTER(blist_choice_STORE));
    - purple_plugin_pref_add_choice(pref, _("Synchronize List with Server"),
    - GINT_TO_POINTER(blist_choice_SYNCH));
    -
    - purple_plugin_pref_frame_add(frame, pref);
    -
    - return frame;
    -}
    -#endif
    static void st_import_action_cb(PurpleConnection *gc, char *filename) {
    struct mwSametimeList *l;
    --- a/libpurple/protocols/silc/chat.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/silc/chat.c Thu Feb 15 23:17:27 2018 -0500
    @@ -192,27 +192,6 @@
    }
    -#if 0 /* XXX For now these are not implemented. We need better
    - listview dialog from Purple for these. */
    -/************************** Channel Invite List ******************************/
    -
    -static void
    -silcpurple_chat_invitelist(PurpleBlistNode *node, gpointer data);
    -{
    -
    -}
    -
    -
    -/**************************** Channel Ban List *******************************/
    -
    -static void
    -silcpurple_chat_banlist(PurpleBlistNode *node, gpointer data);
    -{
    -
    -}
    -#endif
    -
    -
    /************************* Channel Authentication ****************************/
    typedef struct {
    @@ -915,21 +894,6 @@
    NULL, NULL);
    m = g_list_append(m, act);
    -#if 0 /* XXX For now these are not implemented. We need better
    - listview dialog from Purple for these. */
    - if (mode & SILC_CHANNEL_UMODE_CHANOP) {
    - act = purple_menu_action_new(_("Invite List"),
    - PURPLE_CALLBACK(silcpurple_chat_invitelist),
    - NULL, NULL);
    - m = g_list_append(m, act);
    -
    - act = purple_menu_action_new(_("Ban List"),
    - PURPLE_CALLBACK(silcpurple_chat_banlist),
    - NULL, NULL);
    - m = g_list_append(m, act);
    - }
    -#endif
    -
    if (chu) {
    act = purple_menu_action_new(_("Add Private Group"),
    PURPLE_CALLBACK(silcpurple_chat_prv),
    --- a/libpurple/protocols/silc/ops.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/silc/ops.c Thu Feb 15 23:17:27 2018 -0500
    @@ -967,107 +967,6 @@
    }
    }
    -#if 0
    -static void
    -silcpurple_whois_more(SilcClientEntry client_entry, gint id)
    -{
    - SilcAttributePayload attr;
    - SilcAttribute attribute;
    - GString *s;
    - SilcVCardStruct vcard;
    - int i;
    -
    - if (id != 0)
    - return;
    -
    - memset(&vcard, 0, sizeof(vcard));
    -
    - s = g_string_new("");
    -
    - silc_dlist_start(client_entry->attrs);
    - while ((attr = silc_dlist_get(client_entry->attrs)) != SILC_LIST_END) {
    - attribute = silc_attribute_get_attribute(attr);
    - switch (attribute) {
    -
    - case SILC_ATTRIBUTE_USER_INFO:
    - if (!silc_attribute_get_object(attr, (void *)&vcard,
    - sizeof(vcard)))
    - continue;
    - g_string_append_printf(s, "%s:\n\n", _("Personal Information"));
    - if (vcard.full_name)
    - g_string_append_printf(s, "%s:\t\t%s\n",
    - _("Full Name"),
    - vcard.full_name);
    - if (vcard.first_name)
    - g_string_append_printf(s, "%s:\t%s\n",
    - _("First Name"),
    - vcard.first_name);
    - if (vcard.middle_names)
    - g_string_append_printf(s, "%s:\t%s\n",
    - _("Middle Name"),
    - vcard.middle_names);
    - if (vcard.family_name)
    - g_string_append_printf(s, "%s:\t%s\n",
    - _("Family Name"),
    - vcard.family_name);
    - if (vcard.nickname)
    - g_string_append_printf(s, "%s:\t\t%s\n",
    - _("Nickname"),
    - vcard.nickname);
    - if (vcard.bday)
    - g_string_append_printf(s, "%s:\t\t%s\n",
    - _("Birth Day"),
    - vcard.bday);
    - if (vcard.title)
    - g_string_append_printf(s, "%s:\t\t%s\n",
    - _("Job Title"),
    - vcard.title);
    - if (vcard.role)
    - g_string_append_printf(s, "%s:\t\t%s\n",
    - _("Job Role"),
    - vcard.role);
    - if (vcard.org_name)
    - g_string_append_printf(s, "%s:\t%s\n",
    - _("Organization"),
    - vcard.org_name);
    - if (vcard.org_unit)
    - g_string_append_printf(s, "%s:\t\t%s\n",
    - _("Unit"),
    - vcard.org_unit);
    - if (vcard.url)
    - g_string_append_printf(s, "%s:\t%s\n",
    - _("Homepage"),
    - vcard.url);
    - if (vcard.label)
    - g_string_append_printf(s, "%s:\t%s\n",
    - _("Address"),
    - vcard.label);
    - for (i = 0; i < vcard.num_tels; i++) {
    - if (vcard.tels[i].telnum)
    - g_string_append_printf(s, "%s:\t\t\t%s\n",
    - _("Phone"),
    - vcard.tels[i].telnum);
    - }
    - for (i = 0; i < vcard.num_emails; i++) {
    - if (vcard.emails[i].address)
    - g_string_append_printf(s, "%s:\t\t%s\n",
    - _("Email"),
    - vcard.emails[i].address);
    - }
    - if (vcard.note)
    - g_string_append_printf(s, "\n%s:\t\t%s\n",
    - _("Note"),
    - vcard.note);
    - break;
    - }
    - }
    -
    - purple_notify_info(NULL, _("User Information"), _("User Information"),
    - s->str);
    - g_string_free(s, TRUE);
    -}
    -#endif
    -
    /* Command reply handler. Delivers a reply to command that was sent
    earlier. The `conn' is the associated client connection. The `command'
    @@ -1306,15 +1205,6 @@
    }
    }
    -#if 0 /* XXX for now, let's not show attrs here */
    - if (client_entry->attrs)
    - purple_request_action(gc, _("User Information"),
    - _("User Information"),
    - buf, 1, client_entry, 2,
    - _("OK"), G_CALLBACK(silcpurple_whois_more),
    - _("_More..."), G_CALLBACK(silcpurple_whois_more), gc->account, NULL, NULL);
    - else
    -#endif /* 0 */
    purple_notify_userinfo(gc, client_entry->nickname, user_info, NULL, NULL);
    purple_notify_user_info_destroy(user_info);
    }
    --- a/libpurple/protocols/silc/silc.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/silc/silc.c Thu Feb 15 23:17:27 2018 -0500
    @@ -1038,14 +1038,6 @@
    purple_request_fields_add_group(fields, g);
    g = purple_request_field_group_new(NULL);
    -#if 0
    - f = purple_request_field_label_new("l2", _("Online Services"));
    - purple_request_field_group_add_field(g, f);
    - f = purple_request_field_bool_new("services",
    - _("Let others see what services you are using"),
    - TRUE);
    - purple_request_field_group_add_field(g, f);
    -#endif
    #ifdef HAVE_SYS_UTSNAME_H
    f = purple_request_field_bool_new("device",
    _("Let others see what computer you are using"),
    @@ -2091,20 +2083,6 @@
    "prpl-silc", silcpurple_cmd_generic,
    _("ping: Send PING to the connected server"), NULL);
    cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
    -
    -#if 0 /* Purple doesn't handle these yet */
    - id = purple_cmd_register("users", "w", PURPLE_CMD_P_PROTOCOL,
    - PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
    - "prpl-silc", silcpurple_cmd_users,
    - _("users &lt;channel&gt;: List users in channel"));
    - cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
    -
    - id = purple_cmd_register("names", "ww", PURPLE_CMD_P_PROTOCOL,
    - PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
    - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_names,
    - _("names [-count|-ops|-halfops|-voices|-normal] &lt;channel(s)&gt;: List specific users in channel(s)"));
    - cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
    -#endif
    }
    static void
    @@ -2135,14 +2113,6 @@
    NULL
    };
    -#if 0
    -static SilcBool silcpurple_debug_cb(char *file, char *function, int line,
    - char *message, void *context)
    -{
    - purple_debug_info("SILC", "%s:%d:%s - %s\n", file ? file : "(null)", line, function ? function : "(null)", message ? message : "(null)");
    - return TRUE;
    -}
    -#endif
    static void
    silcpurple_protocol_init(PurpleProtocol *protocol)
    @@ -2349,13 +2319,6 @@
    silc_log_set_callback(SILC_LOG_ERROR, silcpurple_log_error, NULL);
    silcpurple_register_commands();
    -#if 0
    -silc_log_debug(TRUE);
    -silc_log_set_debug_string("*client*");
    -silc_log_quick(TRUE);
    -silc_log_set_debug_callbacks(silcpurple_debug_cb, NULL, NULL, NULL);
    -#endif
    -
    return TRUE;
    }
    --- a/libpurple/protocols/simple/ntlm.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/simple/ntlm.c Thu Feb 15 23:17:27 2018 -0500
    @@ -80,14 +80,6 @@
    guint32 flags; /* 0x00008201 */
    /* guint32 flags2; */ /* unknown, used in windows messenger */
    /* guint32 flags3; */
    -
    -#if 0
    - guint8 dom[*]; /* domain string (unicode UTF-16LE) */
    - guint8 user[*]; /* username string (unicode UTF-16LE) */
    - guint8 host[*]; /* host string (unicode UTF-16LE) */
    - guint8 lm_resp[*]; /* LanManager response */
    - guint8 nt_resp[*]; /* NT response */
    -#endif
    };
    guint8 *
    --- a/libpurple/protocols/zephyr/ZFmtSmRLst.c Wed Jan 03 15:40:46 2018 +0100
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,48 +0,0 @@
    -/* This file is part of the Project Athena Zephyr Notification System.
    - * It contains source for the ZFormatSmallRawNoticeList function.
    - *
    - * Created by: John T. Kohl
    - *
    - * Copyright (c) 1988 by the Massachusetts Institute of Technology.
    - * For copying and distribution information, see the file
    - * "mit-copyright.h".
    - */
    -
    -#include "internal.h"
    -
    -#if 0
    -Code_t ZFormatSmallRawNoticeList(notice, list, nitems, buffer, ret_len)
    - ZNotice_t *notice;
    - char *list[];
    - int nitems;
    - ZPacket_t buffer;
    - int *ret_len;
    -{
    - Code_t retval;
    - int hdrlen, i, size;
    - char *ptr;
    -
    - if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
    - &hdrlen, NULL, NULL)) != ZERR_NONE)
    - return (retval);
    -
    - size = 0;
    - for (i=0;i<nitems;i++)
    - size += strlen(list[i])+1;
    -
    - *ret_len = hdrlen+size;
    -
    - if (*ret_len > Z_MAXPKTLEN)
    - return (ZERR_PKTLEN);
    -
    - ptr = buffer+hdrlen;
    -
    - for (;nitems;nitems--, list++) {
    - i = strlen(*list)+1;
    - (void) memcpy(ptr, *list, i);
    - ptr += i;
    - }
    -
    - return (ZERR_NONE);
    -}
    -#endif
    --- a/libpurple/protocols/zephyr/ZMkAuth.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/zephyr/ZMkAuth.c Thu Feb 15 23:17:27 2018 -0500
    @@ -24,15 +24,6 @@
    static KTEXT_ST last_authent;
    #endif
    -#if 0
    -Code_t ZResetAuthentication () {
    -#ifdef ZEPHYR_USES_KERBEROS
    - last_authent_time = 0L;
    -#endif
    - return ZERR_NONE;
    -}
    -#endif
    -
    Code_t ZMakeAuthentication(notice, buffer, buffer_len, len)
    register ZNotice_t *notice;
    char *buffer;
    --- a/libpurple/protocols/zephyr/ZPeekIfNot.c Wed Jan 03 15:40:46 2018 +0100
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,53 +0,0 @@
    -/* This file is part of the Project Athena Zephyr Notification System.
    - * It contains source for the ZPeekIfNotice function.
    - *
    - * Created by: Robert French
    - *
    - * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
    - * For copying and distribution information, see the file
    - * "mit-copyright.h".
    - */
    -
    -#include "internal.h"
    -
    -#if 0
    -Code_t ZPeekIfNotice(notice, from, predicate, args)
    - ZNotice_t *notice;
    - struct sockaddr_in *from;
    - int (*predicate)();
    - char *args;
    -{
    - ZNotice_t tmpnotice;
    - Code_t retval;
    - char *buffer;
    - struct _Z_InputQ *qptr;
    -
    - if ((retval = Z_WaitForComplete()) != ZERR_NONE)
    - return (retval);
    -
    - for (;;) {
    - qptr = Z_GetFirstComplete();
    - while (qptr) {
    - if ((retval = ZParseNotice(qptr->packet, qptr->packet_len,
    - &tmpnotice)) != ZERR_NONE)
    - return (retval);
    - if ((*predicate)(&tmpnotice, args)) {
    - if (!(buffer = (char *) malloc((unsigned) qptr->packet_len)))
    - return (ENOMEM);
    - (void) memcpy(buffer, qptr->packet, qptr->packet_len);
    - if (from)
    - *from = qptr->from;
    - if ((retval = ZParseNotice(buffer, qptr->packet_len,
    - notice)) != ZERR_NONE) {
    - free(buffer);
    - return (retval);
    - }
    - return (ZERR_NONE);
    - }
    - qptr = Z_GetNextComplete(qptr);
    - }
    - if ((retval = Z_ReadWait()) != ZERR_NONE)
    - return (retval);
    - }
    -}
    -#endif
    --- a/libpurple/protocols/zephyr/ZRetSubs.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/zephyr/ZRetSubs.c Thu Feb 15 23:17:27 2018 -0500
    @@ -42,22 +42,6 @@
    return(Z_RetSubs(&notice, nsubs, ZAUTH));
    }
    -#if 0
    -Code_t ZRetrieveDefaultSubscriptions(nsubs)
    - int *nsubs;
    -{
    - ZNotice_t notice;
    -
    - (void) memset((char *)&notice, 0, sizeof(notice));
    - notice.z_message = (char *) 0;
    - notice.z_message_len = 0;
    - notice.z_opcode = CLIENT_GIMMEDEFS;
    -
    - return(Z_RetSubs(&notice, nsubs, ZNOAUTH));
    -
    -}
    -#endif
    -
    static Code_t Z_RetSubs(notice, nsubs, auth_routine)
    register ZNotice_t *notice;
    int *nsubs;
    --- a/libpurple/protocols/zephyr/ZSendRLst.c Wed Jan 03 15:40:46 2018 +0100
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,46 +0,0 @@
    -/* This file is part of the Project Athena Zephyr Notification System.
    - * It contains source for the ZSendRawList function.
    - *
    - * Created by: John T. Kohl
    - *
    - * Copyright (c) 1988 by the Massachusetts Institute of Technology.
    - * For copying and distribution information, see the file
    - * "mit-copyright.h".
    - */
    -
    -#include "internal.h"
    -
    -#if 0
    -Code_t ZSendRawList(notice, list, nitems)
    - ZNotice_t *notice;
    - char *list[];
    - int nitems;
    -{
    - return(ZSrvSendRawList(notice, list, nitems, Z_XmitFragment));
    -}
    -
    -Code_t ZSrvSendRawList(notice, list, nitems, send_routine)
    - ZNotice_t *notice;
    - char *list[];
    - int nitems;
    - Code_t (*send_routine)();
    -{
    - Code_t retval;
    - ZNotice_t newnotice;
    - char *buffer;
    - int len;
    -
    - if ((retval = ZFormatRawNoticeList(notice, list, nitems, &buffer,
    - &len)) != ZERR_NONE)
    - return (retval);
    -
    - if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
    - return (retval);
    -
    - retval = Z_SendFragmentedNotice(&newnotice, len, NULL, send_routine);
    -
    - free(buffer);
    -
    - return (retval);
    -}
    -#endif
    --- a/libpurple/protocols/zephyr/ZSendRaw.c Wed Jan 03 15:40:46 2018 +0100
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,35 +0,0 @@
    -/* This file is part of the Project Athena Zephyr Notification System.
    - * It contains source for the ZSendRawNotice function.
    - *
    - * Created by: Robert French
    - *
    - * Copyright (c) 1987 by the Massachusetts Institute of Technology.
    - * For copying and distribution information, see the file
    - * "mit-copyright.h".
    - */
    -
    -#include "internal.h"
    -
    -#if 0
    -Code_t ZSendRawNotice(notice)
    - ZNotice_t *notice;
    -{
    - Code_t retval;
    - ZNotice_t newnotice;
    - char *buffer;
    - int len;
    -
    - if ((retval = ZFormatRawNotice(notice, &buffer, &len)) !=
    - ZERR_NONE)
    - return (retval);
    -
    - if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
    - return (retval);
    -
    - retval = Z_SendFragmentedNotice(&newnotice, len, NULL, Z_XmitFragment);
    -
    - free(buffer);
    -
    - return (retval);
    -}
    -#endif
    --- a/libpurple/protocols/zephyr/meson.build Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/protocols/zephyr/meson.build Thu Feb 15 23:17:27 2018 -0500
    @@ -12,7 +12,6 @@
    'ZFmtNotice.c',
    'ZFmtRaw.c',
    'ZFmtRawLst.c',
    - 'ZFmtSmRLst.c',
    'ZFmtSmRaw.c',
    'ZFreeNot.c',
    'ZGetLocs.c',
    @@ -27,7 +26,6 @@
    'ZNewLocU.c',
    'ZOpenPort.c',
    'ZParseNot.c',
    - 'ZPeekIfNot.c',
    'ZPeekNot.c',
    'ZPeekPkt.c',
    'ZPending.c',
    @@ -38,8 +36,6 @@
    'ZSendList.c',
    'ZSendNot.c',
    'ZSendPkt.c',
    - 'ZSendRLst.c',
    - 'ZSendRaw.c',
    'ZSetDest.c',
    'ZSetFD.c',
    'ZSetSrv.c',
    --- a/libpurple/server.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/server.c Thu Feb 15 23:17:27 2018 -0500
    @@ -295,10 +295,10 @@
    protocol = purple_protocols_find(purple_account_get_protocol_id(account));
    /* Lookup the attention type in the protocol's attention_types list, if any. */
    - if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, ATTENTION_IFACE, get_types)) {
    + if (PURPLE_IS_PROTOCOL_ATTENTION(protocol)) {
    GList *attention_types;
    - attention_types = purple_protocol_attention_iface_get_types(protocol, account);
    + attention_types = purple_protocol_attention_get_types(protocol, account);
    attn = (PurpleAttentionType *)g_list_nth_data(attention_types, type_code);
    } else {
    attn = NULL;
    --- a/libpurple/server.h Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/server.h Thu Feb 15 23:17:27 2018 -0500
    @@ -29,6 +29,7 @@
    */
    #include "accounts.h"
    +#include "attention.h"
    #include "conversations.h"
    #include "group.h"
    #include "message.h"
    --- a/libpurple/tests/meson.build Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/tests/meson.build Thu Feb 15 23:17:27 2018 -0500
    @@ -1,5 +1,7 @@
    PROGS = [
    + 'attention_type',
    'image',
    + 'protocol_attention',
    'protocol_xfer',
    'smiley',
    'smiley_list',
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/libpurple/tests/test_attention_type.c Thu Feb 15 23:17:27 2018 -0500
    @@ -0,0 +1,181 @@
    +/*
    + * 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"
    +
    +/******************************************************************************
    + * Tests
    + *****************************************************************************/
    +static void
    +test_purple_attention_type_new(void) {
    + PurpleAttentionType *type = NULL;
    +
    + type = purple_attention_type_new("id", "name", "incoming", "outgoing");
    +
    + /* check the values new sets */
    + g_assert_cmpstr(purple_attention_type_get_unlocalized_name(type), ==, "id");
    + g_assert_cmpstr(purple_attention_type_get_name(type), ==, "name");
    + g_assert_cmpstr(purple_attention_type_get_incoming_desc(type), ==, "incoming");
    + g_assert_cmpstr(purple_attention_type_get_outgoing_desc(type), ==, "outgoing");
    +
    + /* check that default values are correct */
    + g_assert_cmpstr(purple_attention_type_get_icon_name(type), ==, NULL);
    +
    + g_free(type);
    +}
    +
    +static void
    +test_purple_attention_type_copy(void) {
    + PurpleAttentionType *type1 = NULL, *type2 = NULL;
    +
    + type1 = purple_attention_type_new("id", "name", "incoming", "outgoing");
    +
    + type2 = purple_attention_type_copy(type1);
    +
    + /* check the values new sets */
    + g_assert_cmpstr(purple_attention_type_get_unlocalized_name(type2), ==, "id");
    + g_assert_cmpstr(purple_attention_type_get_name(type2), ==, "name");
    + g_assert_cmpstr(purple_attention_type_get_incoming_desc(type2), ==, "incoming");
    + g_assert_cmpstr(purple_attention_type_get_outgoing_desc(type2), ==, "outgoing");
    +
    + /* check that default values are correct */
    + g_assert_cmpstr(purple_attention_type_get_icon_name(type2), ==, NULL);
    +
    + g_free(type1);
    + g_free(type2);
    +}
    +
    +static void
    +test_purple_attention_type_set_unlocalized_name(void) {
    + PurpleAttentionType *type = NULL;
    +
    + type = purple_attention_type_new("id", "name", "incoming", "outgoing");
    +
    + purple_attention_type_set_unlocalized_name(type, "this-is-my-id");
    + g_assert_cmpstr(purple_attention_type_get_unlocalized_name(type), ==, "this-is-my-id");
    +
    + g_free(type);
    +}
    +
    +static void
    +test_purple_attention_type_set_name(void) {
    + PurpleAttentionType *type = NULL;
    +
    + type = purple_attention_type_new("id", "name", "incoming", "outgoing");
    +
    + purple_attention_type_set_name(type, "this-is-my-name");
    + g_assert_cmpstr(purple_attention_type_get_name(type), ==, "this-is-my-name");
    +
    + g_free(type);
    +}
    +
    +static void
    +test_purple_attention_type_set_incoming_desc(void) {
    + PurpleAttentionType *type = NULL;
    +
    + type = purple_attention_type_new("id", "name", "incoming", "outgoing");
    +
    + purple_attention_type_set_incoming_desc(type, "this-is-my-incoming-desc");
    + g_assert_cmpstr(purple_attention_type_get_incoming_desc(type), ==, "this-is-my-incoming-desc");
    +
    + g_free(type);
    +}
    +
    +static void
    +test_purple_attention_type_set_outgoing_desc(void) {
    + PurpleAttentionType *type = NULL;
    +
    + type = purple_attention_type_new("id", "name", "incoming", "outgoing");
    +
    + purple_attention_type_set_outgoing_desc(type, "this-is-my-outgoing-desc");
    + g_assert_cmpstr(purple_attention_type_get_outgoing_desc(type), ==, "this-is-my-outgoing-desc");
    +
    + g_free(type);
    +}
    +
    +static void
    +test_purple_attention_type_set_icon_name(void) {
    + PurpleAttentionType *type = NULL;
    +
    + type = purple_attention_type_new("id", "name", "incoming", "outgoing");
    +
    + purple_attention_type_set_icon_name(type, "this-is-my-icon-name");
    + g_assert_cmpstr(purple_attention_type_get_icon_name(type), ==, "this-is-my-icon-name");
    +
    + g_free(type);
    +}
    +
    +/******************************************************************************
    + * Main
    + *****************************************************************************/
    +gint
    +main(gint argc, gchar **argv) {
    + gint res = 0;
    +
    + g_test_init(&argc, &argv, NULL);
    +
    + g_test_set_nonfatal_assertions();
    +
    + g_test_add_func(
    + "/attention-type/new",
    + test_purple_attention_type_new
    + );
    +
    + g_test_add_func(
    + "/attention-type/copy",
    + test_purple_attention_type_copy
    + );
    +
    + g_test_add_func(
    + "/attention-type/set-unlocalized-name",
    + test_purple_attention_type_set_unlocalized_name
    + );
    +
    + g_test_add_func(
    + "/attention-type/set-name",
    + test_purple_attention_type_set_name
    + );
    +
    + g_test_add_func(
    + "/attention-type/set-incoming-desc",
    + test_purple_attention_type_set_incoming_desc
    + );
    +
    + g_test_add_func(
    + "/attention-type/set-outgoing-desc",
    + test_purple_attention_type_set_outgoing_desc
    + );
    +
    + g_test_add_func(
    + "/attention-type/set-icon-name",
    + test_purple_attention_type_set_icon_name
    + );
    +
    + res = g_test_run();
    +
    + return res;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/libpurple/tests/test_protocol_attention.c Thu Feb 15 23:17:27 2018 -0500
    @@ -0,0 +1,156 @@
    +/*
    + * 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"
    +
    +/******************************************************************************
    + * PurpleProtcolAttention Implementations
    + *****************************************************************************/
    +static GType test_purple_protocol_attention_get_type(void);
    +
    +typedef struct {
    + PurpleProtocol parent;
    +
    + gboolean send_called;
    +} TestPurpleProtocolAttention;
    +
    +typedef struct {
    + PurpleProtocolClass parent;
    +} TestPurpleProtocolAttentionClass;
    +
    +
    +static gboolean
    +test_purple_protocol_attention_send(PurpleProtocolAttention *attn, PurpleConnection *c, const gchar *username, guint type) {
    + TestPurpleProtocolAttention *test_attn = (TestPurpleProtocolAttention *)attn;
    +
    + test_attn->send_called = TRUE;
    +
    + return TRUE;
    +}
    +
    +static GList *
    +test_purple_protocol_attention_get_types(PurpleProtocolAttention *attn, PurpleAccount *acct) {
    + GList *types = NULL;
    +
    + types = g_list_append(types, purple_attention_type_new("id", "name", "incoming", "outgoing"));
    +
    + return types;
    +}
    +
    +static void
    +test_purple_protocol_attention_iface_init(PurpleProtocolAttentionInterface *iface) {
    + iface->send = test_purple_protocol_attention_send;
    + iface->get_types = test_purple_protocol_attention_get_types;
    +}
    +
    +G_DEFINE_TYPE_WITH_CODE(
    + TestPurpleProtocolAttention,
    + test_purple_protocol_attention,
    + PURPLE_TYPE_PROTOCOL,
    + G_IMPLEMENT_INTERFACE(
    + PURPLE_TYPE_PROTOCOL_ATTENTION,
    + test_purple_protocol_attention_iface_init
    + )
    +);
    +
    +static void
    +test_purple_protocol_attention_init(TestPurpleProtocolAttention *prplattn) {
    + PurpleProtocol *prpl = PURPLE_PROTOCOL(prplattn);
    +
    + prpl->id = "prpl-attention";
    +}
    +
    +static void
    +test_purple_protocol_attention_class_init(TestPurpleProtocolAttentionClass *klass) {
    +}
    +
    +/******************************************************************************
    + * Tests
    + *****************************************************************************/
    +static void
    +test_purple_protocol_attention_can_send(void) {
    + TestPurpleProtocolAttention *attn = g_object_new(test_purple_protocol_attention_get_type(), NULL);
    + PurpleAccount *a = purple_account_new("prpl-attn-can-send", "prpl-attn");
    + PurpleConnection *c = g_object_new(PURPLE_TYPE_CONNECTION, "account", a, NULL);
    + gboolean actual = FALSE;
    +
    + attn->send_called = FALSE;
    + actual = purple_protocol_attention_send(PURPLE_PROTOCOL_ATTENTION(attn), c, "someguy", 0);
    + g_assert_true(actual);
    +
    + g_assert_true(attn->send_called);
    +}
    +
    +static void
    +test_purple_protocol_attention_can_get_types(void) {
    + TestPurpleProtocolAttention *attn = g_object_new(test_purple_protocol_attention_get_type(), NULL);
    + PurpleAccount *a = purple_account_new("prpl-attn-can-get-types", "prpl-attn");
    + GList *types = NULL;
    + PurpleAttentionType *type = NULL;
    +
    + types = purple_protocol_attention_get_types(PURPLE_PROTOCOL_ATTENTION(attn), a);
    + g_assert_true(g_list_length(types) == 1);
    +
    + /* take the first item and cast it into type */
    + type = (PurpleAttentionType *)(types->data);
    + g_assert(type);
    +
    + g_assert_cmpstr(purple_attention_type_get_unlocalized_name(type), ==, "id");
    + g_assert_cmpstr(purple_attention_type_get_name(type), ==, "name");
    + g_assert_cmpstr(purple_attention_type_get_incoming_desc(type), ==, "incoming");
    + g_assert_cmpstr(purple_attention_type_get_outgoing_desc(type), ==, "outgoing");
    +}
    +
    +/******************************************************************************
    + * 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-attention/send",
    + test_purple_protocol_attention_can_send
    + );
    +
    + g_test_add_func(
    + "/protocol-attention/get-types",
    + test_purple_protocol_attention_can_get_types
    + );
    +
    + res = g_test_run();
    +
    + return res;
    +}
    --- a/libpurple/win32/libc_interface.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/win32/libc_interface.c Thu Feb 15 23:17:27 2018 -0500
    @@ -409,13 +409,6 @@
    errno = EAGAIN;
    return -1;
    }
    -#if 0
    - else if( ret == 0 ) {
    - /* connection has been gracefully closed */
    - errno = WSAENOTCONN;
    - return -1;
    - }
    -#endif
    else {
    /* success reading socket */
    return ret;
    @@ -933,10 +926,6 @@
    {
    if (purple_strequal(tzname, win32_tzmap[i].wstd))
    {
    -#if 0
    - purple_debug_info("wpurple", "TZ \"%s\" matches Windows timezone \"%s\"\n",
    - win32_tzmap[i].ustd, tzname);
    -#endif
    /* Cache the Result */
    if (i > 0) {
    if (win32_tzmap[0].wstd[0] != '\0')
    @@ -949,10 +938,6 @@
    }
    if (purple_strequal(tzname, win32_tzmap[i].wdst))
    {
    -#if 0
    - purple_debug_info("wpurple", "TZ \"%s\" matches Windows timezone \"%s\"\n",
    - win32_tzmap[i].udst, tzname);
    -#endif
    /* Cache the Result */
    if (i > 0) {
    if (win32_tzmap[0].wdst[0] != '\0')
    @@ -1056,10 +1041,6 @@
    {
    if (purple_strequal(localtzname, win32_tzmap[i].wstd))
    {
    -#if 0
    - purple_debug_info("wpurple", "TZ \"%s\" matches localized Windows timezone \"%s\" (\"%s\")\n",
    - win32_tzmap[i].ustd, tzname, localtzname);
    -#endif
    /* Cache the Result */
    if (win32_tzmap[0].wstd[0] != '\0')
    g_free(win32_tzmap[0].wstd);
    @@ -1070,10 +1051,6 @@
    }
    if (purple_strequal(localtzname, win32_tzmap[i].wdst))
    {
    -#if 0
    - purple_debug_info("wpurple", "TZ \"%s\" matches localized Windows timezone \"%s\" (\"%s\")\n",
    - win32_tzmap[i].udst, tzname, localtzname);
    -#endif
    /* Cache the Result */
    if (win32_tzmap[0].wdst[0] != '\0')
    g_free(win32_tzmap[0].wdst);
    --- a/libpurple/win32/libc_internal.h Wed Jan 03 15:40:46 2018 +0100
    +++ b/libpurple/win32/libc_internal.h Thu Feb 15 23:17:27 2018 -0500
    @@ -77,36 +77,12 @@
    union
    {
    struct sockaddr ifru_addr;
    -#if 0
    - struct sockaddr ifru_dstaddr;
    - struct sockaddr ifru_broadaddr;
    - struct sockaddr ifru_netmask;
    - struct sockaddr ifru_hwaddr;
    - short int ifru_flags;
    - int ifru_ivalue;
    - int ifru_mtu;
    -#endif
    char *ifru_data;
    } ifr_ifru;
    };
    # define ifr_name ifr_ifrn.ifrn_name /* interface name */
    # define ifr_addr ifr_ifru.ifru_addr /* address */
    -#if 0
    -# define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
    -# define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
    -# define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
    -# define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
    -# define ifr_flags ifr_ifru.ifru_flags /* flags */
    -# define ifr_metric ifr_ifru.ifru_ivalue /* metric */
    -# define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
    -#endif
    # define ifr_data ifr_ifru.ifru_data /* for use by interface */
    -#if 0
    -# define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
    -# define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
    -# define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
    -#endif
    -
    struct ifconf
    {
    --- a/meson.build Wed Jan 03 15:40:46 2018 +0100
    +++ b/meson.build Thu Feb 15 23:17:27 2018 -0500
    @@ -406,7 +406,7 @@
    # Check Pidgin dependencies
    # #######################################################################
    if get_option('gtkui')
    - gtk = dependency('gtk+-3.0', version : '>= 3.4.2')
    + gtk = dependency('gtk+-3.0', version : '>= 3.10.0')
    # We only really need Pango >= 1.4 for decent RTL support
    pango = dependency('pango', version : '>= 1.4.0')
    conf.set('HAVE_PANGO14', pango.found())
    --- a/pidgin/gtkconv.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/pidgin/gtkconv.c Thu Feb 15 23:17:27 2018 -0500
    @@ -31,6 +31,7 @@
    #include <gdk/gdkkeysyms.h>
    #include "account.h"
    +#include "attention.h"
    #include "cmds.h"
    #include "core.h"
    #include "debug.h"
    @@ -3444,8 +3445,8 @@
    if (pc != NULL)
    protocol = purple_connection_get_protocol(pc);
    - if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, ATTENTION_IFACE, get_types)) {
    - list = purple_protocol_attention_iface_get_types(protocol, purple_connection_get_account(pc));
    + if (protocol && PURPLE_IS_PROTOCOL_ATTENTION(protocol)) {
    + list = purple_protocol_attention_get_types(PURPLE_PROTOCOL_ATTENTION(protocol), purple_connection_get_account(pc));
    /* Multiple attention types */
    if (list && list->next) {
    @@ -7432,7 +7433,7 @@
    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, can_send_file);
    - gtk_action_set_sensitive(win->menu->get_attention, (PURPLE_PROTOCOL_IMPLEMENTS(protocol, ATTENTION_IFACE, send)));
    + gtk_action_set_sensitive(win->menu->get_attention, (PURPLE_IS_PROTOCOL_ATTENTION(protocol)));
    gtk_action_set_sensitive(win->menu->alias,
    (account != NULL) &&
    (purple_blist_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
    --- a/pidgin/gtkwebviewtoolbar.c Wed Jan 03 15:40:46 2018 +0100
    +++ b/pidgin/gtkwebviewtoolbar.c Thu Feb 15 23:17:27 2018 -0500
    @@ -1682,7 +1682,7 @@
    for the time being it is always disabled for chats */
    gtk_action_set_sensitive(priv->attention,
    conv && protocol && PURPLE_IS_IM_CONVERSATION(conv) &&
    - PURPLE_PROTOCOL_IMPLEMENTS(protocol, ATTENTION_IFACE, send));
    + PURPLE_IS_PROTOCOL_ATTENTION(protocol));
    update_smiley_button(toolbar);
    }