## TpBaseContactList TpBaseContactList — channel manager for ContactList channels |

## Synopsis

    #include <telepathy-glib/telepathy-glib.h>

    struct              TpBaseContactList;
    struct              TpBaseContactListClass;
    void                tp_base_contact_list_mixin_class_init
                                                            (TpBaseConnectionClass *cls);
    void                tp_base_contact_list_mixin_register_with_contacts_mixin
                                                            (TpBaseConnection *conn);
    void                tp_base_contact_list_mixin_list_iface_init
                                                            (TpSvcConnectionInterfaceContactListClass *klass);
    void                tp_base_contact_list_mixin_groups_iface_init
                                                            (TpSvcConnectionInterfaceContactGroupsClass *klass);
    void                tp_base_contact_list_mixin_blocking_iface_init
                                                            (TpSvcConnectionInterfaceContactBlockingClass *klass);
    TpContactListState  tp_base_contact_list_get_state      (TpBaseContactList *self,
                                                             GError **error);
    TpBaseConnection *  tp_base_contact_list_get_connection (TpBaseContactList *self,
                                                             GError **error);
    void                tp_base_contact_list_set_list_pending
                                                            (TpBaseContactList *self);
    void                tp_base_contact_list_set_list_failed
                                                            (TpBaseContactList *self,
                                                             GQuark domain,
                                                             gint code,
                                                             const gchar *message);
    void                tp_base_contact_list_set_list_received
                                                            (TpBaseContactList *self);
    void                tp_base_contact_list_contacts_changed
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *changed,
                                                             TpHandleSet *removed);
    void                tp_base_contact_list_one_contact_changed
                                                            (TpBaseContactList *self,
                                                             TpHandle changed);
    void                tp_base_contact_list_one_contact_removed
                                                            (TpBaseContactList *self,
                                                             TpHandle removed);
    gboolean            (*TpBaseContactListBooleanFunc)     (TpBaseContactList *self);
    gboolean            tp_base_contact_list_false_func     (TpBaseContactList *self);
    gboolean            tp_base_contact_list_true_func      (TpBaseContactList *self);
    gboolean            tp_base_contact_list_get_contact_list_persists
                                                            (TpBaseContactList *self);
    TpHandleSet *       (*TpBaseContactListDupContactsFunc) (TpBaseContactList *self);
    TpHandleSet *       tp_base_contact_list_dup_contacts   (TpBaseContactList *self);
    void                (*TpBaseContactListDupStatesFunc)   (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             TpSubscriptionState *subscribe,
                                                             TpSubscriptionState *publish,
                                                             gchar **publish_request);
    void                tp_base_contact_list_dup_states     (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             TpSubscriptionState *subscribe,
                                                             TpSubscriptionState *publish,
                                                             gchar **publish_request);
    guint               (*TpBaseContactListUIntFunc)        (TpBaseContactList *self);
    void                (*TpBaseContactListAsyncFunc)       (TpBaseContactList *self,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            (*TpBaseContactListAsyncFinishFunc) (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_download_async (TpBaseContactList *self,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_download_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    gboolean            tp_base_contact_list_get_download_at_connection
                                                            (TpBaseContactList *self);

    #define             TP_TYPE_MUTABLE_CONTACT_LIST
    struct              TpMutableContactListInterface;
    gboolean            tp_base_contact_list_can_change_contact_list
                                                            (TpBaseContactList *self);
    gboolean            tp_base_contact_list_get_request_uses_message
                                                            (TpBaseContactList *self);
    void                (*TpBaseContactListRequestSubscriptionFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             const gchar *message,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    void                tp_base_contact_list_request_subscription_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             const gchar *message,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_request_subscription_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                (*TpBaseContactListActOnContactsFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    void                tp_base_contact_list_authorize_publication_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_authorize_publication_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_store_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_store_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_remove_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_remove_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_unsubscribe_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_unsubscribe_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_unpublish_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_unpublish_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

    #define             TP_TYPE_CONTACT_GROUP_LIST
    struct              TpContactGroupListInterface;
    gchar *             (*TpBaseContactListNormalizeFunc)   (TpBaseContactList *self,
                                                             const gchar *s);
    gchar *             tp_base_contact_list_normalize_group
                                                            (TpBaseContactList *self,
                                                             const gchar *s);
    GStrv               (*TpBaseContactListDupContactGroupsFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandle contact);
    GStrv               tp_base_contact_list_dup_contact_groups
                                                            (TpBaseContactList *self,
                                                             TpHandle contact);
    GStrv               (*TpBaseContactListDupGroupsFunc)   (TpBaseContactList *self);
    GStrv               tp_base_contact_list_dup_groups     (TpBaseContactList *self);
    TpHandleSet *       (*TpBaseContactListDupGroupMembersFunc)
                                                            (TpBaseContactList *self,
                                                             const gchar *group);
    TpHandleSet *       tp_base_contact_list_dup_group_members
                                                            (TpBaseContactList *self,
                                                             const gchar *group);
    void                tp_base_contact_list_group_renamed  (TpBaseContactList *self,
                                                             const gchar *old_name,
                                                             const gchar *new_name);
    void                tp_base_contact_list_groups_changed (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             const gchar * const *added,
                                                             gssize n_added,
                                                             const gchar * const *removed,
                                                             gssize n_removed);
    void                tp_base_contact_list_one_contact_groups_changed
                                                            (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             const gchar * const *added,
                                                             gssize n_added,
                                                             const gchar * const *removed,
                                                             gssize n_removed);
    void                tp_base_contact_list_groups_created (TpBaseContactList *self,
                                                             const gchar * const *created,
                                                             gssize n_created);
    void                tp_base_contact_list_groups_removed (TpBaseContactList *self,
                                                             const gchar * const *removed,
                                                             gssize n_removed);
    gboolean            tp_base_contact_list_has_disjoint_groups
                                                            (TpBaseContactList *self);

    #define             TP_TYPE_MUTABLE_CONTACT_GROUP_LIST
    struct              TpMutableContactGroupListInterface;
    void                (*TpBaseContactListSetContactGroupsFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             const gchar * const *normalized_names,
                                                             gsize n_names,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    void                tp_base_contact_list_set_contact_groups_async
                                                            (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             const gchar * const *normalized_names,
                                                             gsize n_names,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_set_contact_groups_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                (*TpBaseContactListGroupContactsFunc)
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    void                tp_base_contact_list_add_to_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_add_to_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_remove_from_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_remove_from_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_set_group_members_async
                                                            (TpBaseContactList *self,
                                                             const gchar *normalized_group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_set_group_members_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                (*TpBaseContactListRemoveGroupFunc) (TpBaseContactList *self,
                                                             const gchar *group,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    void                tp_base_contact_list_remove_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_remove_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                (*TpBaseContactListRenameGroupFunc) (TpBaseContactList *self,
                                                             const gchar *old_name,
                                                             const gchar *new_name,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    void                tp_base_contact_list_rename_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *old_name,
                                                             const gchar *new_name,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_rename_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    TpContactMetadataStorageType tp_base_contact_list_get_group_storage
                                                            (TpBaseContactList *self);

    #define             TP_TYPE_BLOCKABLE_CONTACT_LIST
    struct              TpBlockableContactListInterface;
    void                (*TpBaseContactListBlockContactsWithAbuseFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             gboolean report_abusive,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_can_block      (TpBaseContactList *self);
    TpHandleSet *       tp_base_contact_list_dup_blocked_contacts
                                                            (TpBaseContactList *self);
    void                tp_base_contact_list_block_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_block_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_block_contacts_with_abuse_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             gboolean report_abusive,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_block_contacts_with_abuse_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_unblock_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            tp_base_contact_list_unblock_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);
    void                tp_base_contact_list_contact_blocking_changed
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *changed);

## Object Hierarchy

      GObject
       +----TpBaseContactList

## Implemented Interfaces

TpBaseContactList implements TpChannelManager.

## Properties

      "connection"               TpBaseConnection*     : Read / Write / Construct Only
      "download-at-connection"   gboolean              : Read / Write / Construct

## Description

This class represents a connection's contact list (roster, buddy list etc.) inside a connection manager. It can be used to implement the ContactList D-Bus interface on the Connection.

Connections that use TpBaseContactList must also have the TpContactsMixin.

Connection managers should subclass TpBaseContactList, implementing the virtual methods for core functionality in TpBaseContactListClass. Then, in the connection manager's TpBaseConnection subclass:

- in G_DEFINE_TYPE_WITH_CODE, implement TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_LIST using `tp_base_contact_list_mixin_list_iface_init()`:

      1
      2
      3
      4
      5
      6
      7
      G_DEFINE_TYPE_WITH_CODE (MyConnection, my_connection,
          TP_TYPE_BASE_CONNECTION,
          // ...
          G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_LIST,
              tp_base_contact_list_mixin_list_iface_init);
          // ...
          )

- in the `class_init` method, call `tp_base_contact_list_mixin_class_init()` after `tp_contacts_mixin_class_init()`:

      1
      2
      3
      4
      5
      // ...
      tp_contacts_mixin_class_init (object_class,
          G_STRUCT_OFFSET (MyConnectionClass, contacts_mixin));
      tp_base_contact_list_mixin_class_init (base_connection_class);
      // ...

  and include `TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST` in the output of TpBaseConnectionClass.get_interfaces_always_present;

- in the TpBaseConnectionClass.create_channel_managers implementation, create an instance of the TpBaseContactList subclass, and include it in the returned GPtrArray;

- in the `constructed` method, call `tp_base_contact_list_mixin_register_with_contacts_mixin()` on the connection.

To support user-defined contact groups too, additionally implement `TP_TYPE_CONTACT_GROUP_LIST` in the TpBaseContactList subclass, add the `TP_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS` interface to the output of TpBaseConnectionClass.get interfaces_always_present, and implement the `TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_GROUPS` in the TpBaseConnection subclass using `tp_base_contact_list_mixin_groups_iface_init()`.

Optionally, one or more of the TP_TYPE_MUTABLE_CONTACT_LIST, TP_TYPE_MUTABLE_CONTACT_GROUP_LIST, and TP_TYPE_BLOCKABLE_CONTACT_LIST GObject interfaces may also be implemented, as appropriate to the protocol.

In versions of the Telepathy D-Bus Interface Specification prior to 0.21.0, this functionality was provided as a collection of individual ContactList channels. As a result, this object also implements the TpChannelManager interface, so that it can provide those channels. The channel objects are internal to this object, and not considered to be part of the API.

## Details

### struct TpBaseContactList

    struct TpBaseContactList;

A connection's contact list (roster, buddy list) inside a connection manager. Each TpBaseConnection may have at most one TpBaseContactList.

This abstract base class provides the Telepathy "view" of the contact list: subclasses must provide access to the "model" by implementing its virtual methods in terms of the protocol's real contact list (e.g. the XMPP roster object in Wocky).

The implementation must call `tp_base_contact_list_set_list_received()` exactly once, when the initial set of contacts has been received (or immediately, if that condition is not meaningful for the protocol).

Since 0.13.0

### struct TpBaseContactListClass

    struct TpBaseContactListClass {
        GObjectClass parent_class;

        TpBaseContactListDupContactsFunc dup_contacts;
        TpBaseContactListDupStatesFunc dup_states;
        TpBaseContactListBooleanFunc get_contact_list_persists;

        TpBaseContactListAsyncFunc download_async;
        TpBaseContactListAsyncFinishFunc download_finish;
    };

The class of a TpBaseContactList.

Additional functionality can be added by implementing GInterfaces. Most subclasses should implement `TP_TYPE_MUTABLE_CONTACT_LIST`, which allows the contact list to be altered.

Subclasses may implement `TP_TYPE_BLOCKABLE_CONTACT_LIST` if contacts can be blocked from communicating with the user.

GObjectClass `parent_class`; | the parent class
TpBaseContactListDupContactsFunc `dup_contacts`; | the implementation of `tp_base_contact_list_dup_contacts()`; every subclass must implement this itself
TpBaseContactListDupStatesFunc `dup_states`; | the implementation of `tp_base_contact_list_dup_states()`; every subclass must implement this itself
TpBaseContactListBooleanFunc `get_contact_list_persists`; | the implementation of `tp_base_contact_list_get_contact_list_persists()`; if a subclass does not implement this itself, the default implementation always returns `TRUE`, which is correct for most protocols
TpBaseContactListAsyncFunc `download_async`; | the implementation of `tp_base_contact_list_download_async()`; if a subclass does not implement this itself, the default implementation will raise TP_ERROR_NOT_IMPLEMENTED asynchronously. Since: 0.18.0
TpBaseContactListAsyncFinishFunc `download_finish`; | the implementation of `tp_base_contact_list_download_finish()`. Since: 0.18.0

Since 0.13.0

### tp_base_contact_list_mixin_class_init ()

    void                tp_base_contact_list_mixin_class_init
                                                            (TpBaseConnectionClass *cls);

Register the TpBaseContactList to be used like a mixin in `cls`. Before this function is called, the TpContactsMixin must be initialized with `tp_contacts_mixin_class_init()`.

If the connection implements TpSvcConnectionInterfaceContactGroups, this function automatically sets up that interface as well as ContactList. In this case, when the TpBaseContactList is created later, it must implement `TP_TYPE_CONTACT_GROUP_LIST`.

`cls` : | A subclass of TpBaseConnection that has a TpContactsMixinClass, and implements TpSvcConnectionInterfaceContactList using TpBaseContactList

Since 0.13.0

### tp_base_contact_list_mixin_register_with_contacts_mixin ()

    void                tp_base_contact_list_mixin_register_with_contacts_mixin
                                                            (TpBaseConnection *conn);

Register the ContactList interface with the Contacts interface to make it inspectable. Before this function is called, the TpContactsMixin must be initialized with `tp_contacts_mixin_init()`, and `conn` must have a TpBaseContactList in its list of channel managers (by creating it in its TpBaseConnectionClass.create_channel_managers implementation).

If the connection implements TpSvcConnectionInterfaceContactGroups the TpBaseContactList implements `TP_TYPE_CONTACT_GROUP_LIST`, this function automatically also registers the ContactGroups interface with the contacts mixin.

`conn` : | An instance of TpBaseConnection that uses a TpContactsMixin, and implements TpSvcConnectionInterfaceContactList using TpBaseContactList

Since 0.13.0

### tp_base_contact_list_mixin_list_iface_init ()

    void                tp_base_contact_list_mixin_list_iface_init
                                                            (TpSvcConnectionInterfaceContactListClass *klass);

Use the TpBaseContactList like a mixin, to implement the ContactList D-Bus interface.

This function should be passed to `G_IMPLEMENT_INTERFACE()` for TpSvcConnectionInterfaceContactList.

`klass` : | the service-side D-Bus interface

Since 0.13.0

### tp_base_contact_list_mixin_groups_iface_init ()

    void                tp_base_contact_list_mixin_groups_iface_init
                                                            (TpSvcConnectionInterfaceContactGroupsClass *klass);

Use the TpBaseContactList like a mixin, to implement the ContactGroups D-Bus interface.

This function should be passed to `G_IMPLEMENT_INTERFACE()` for TpSvcConnectionInterfaceContactGroups.

`klass` : | the service-side D-Bus interface

Since 0.13.0

### tp_base_contact_list_mixin_blocking_iface_init ()

    void                tp_base_contact_list_mixin_blocking_iface_init
                                                            (TpSvcConnectionInterfaceContactBlockingClass *klass);

Use the TpBaseContactList like a mixin, to implement the ContactBlocking D-Bus interface.

This function should be passed to `G_IMPLEMENT_INTERFACE()` for TpSvcConnectionInterfaceContactBlocking

`klass` : | the service-side D-Bus interface

Since 0.15.1

### tp_base_contact_list_get_state ()

    TpContactListState  tp_base_contact_list_get_state      (TpBaseContactList *self,
                                                             GError **error);

Return how much progress this object has made towards retrieving the contact list.

If this contact list's connection has disconnected, or retrieving the contact list has failed, return `TP_CONTACT_LIST_STATE_FAILURE`.

`self` : | a contact list
`error` : | used to raise an error if something other than `TP_CONTACT_LIST_STATE_SUCCESS` is returned
Returns : | the state of the contact list

Since 0.13.0

### tp_base_contact_list_get_connection ()

    TpBaseConnection *  tp_base_contact_list_get_connection (TpBaseContactList *self,
                                                             GError **error);

Return the Connection this contact list uses. If this contact list's connection has already disconnected, return `NULL` instead.

`self` : | a contact list
`error` : | used to raise an error if `NULL` is returned
Returns : | the connection, or `NULL`. [transfer none]

Since 0.13.0

### tp_base_contact_list_set_list_pending ()

    void                tp_base_contact_list_set_list_pending
                                                            (TpBaseContactList *self);

Record that receiving the initial contact list is in progress.

`self` : | the contact list manager

Since 0.13.0

### tp_base_contact_list_set_list_failed ()

    void                tp_base_contact_list_set_list_failed
                                                            (TpBaseContactList *self,
                                                             GQuark domain,
                                                             gint code,
                                                             const gchar *message);

Record that receiving the initial contact list has failed.

This method cannot be called after `tp_base_contact_list_set_list_received()` is called.

`self` : | the contact list manager
`domain` : | a GError domain
`code` : | a GError code
`message` : | a GError message

Since 0.13.0

### tp_base_contact_list_set_list_received ()

    void                tp_base_contact_list_set_list_received
                                                            (TpBaseContactList *self);

Record that the initial contact list has been received. This allows the contact list manager to reply to requests for the list of contacts that were previously made, and reply to subsequent requests immediately.

This method can be called at most once for a contact list manager.

In protocols where there's no good definition of the point at which the initial contact list has been received (such as link-local XMPP), this method may be called immediately.

The TpBaseContactListDupContactsFunc and TpBaseContactListDupStatesFunc must already give correct results when entering this method.

If implemented, `tp_base_contact_list_dup_blocked_contacts()` must also give correct results when entering this method.

`self` : | the contact list manager

Since 0.13.0

### tp_base_contact_list_contacts_changed ()

    void                tp_base_contact_list_contacts_changed
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *changed,
                                                             TpHandleSet *removed);

Emit signals for a change to the contact list.

The results of TpBaseContactListDupContactsFunc and TpBaseContactListDupStatesFunc must already reflect the contacts' new statuses when entering this method (in practice, this means that implementations must update their own cache of contacts before calling this method).

`self` : | the contact list manager
`changed` : | a set of contacts added to the contact list or with a changed status. [allow-none]
`removed` : | a set of contacts removed from the contact list. [allow-none]

Since 0.13.0

### tp_base_contact_list_one_contact_changed ()

    void                tp_base_contact_list_one_contact_changed
                                                            (TpBaseContactList *self,
                                                             TpHandle changed);

Convenience wrapper around `tp_base_contact_list_contacts_changed()` for a single handle in the 'changed' set and no 'removed' set.

`self` : | the contact list manager
`changed` : | a contact handle

Since 0.13.0

### tp_base_contact_list_one_contact_removed ()

    void                tp_base_contact_list_one_contact_removed
                                                            (TpBaseContactList *self,
                                                             TpHandle removed);

Convenience wrapper around `tp_base_contact_list_contacts_changed()` for a single handle in the 'removed' set and no 'changed' set.

`self` : | the contact list manager
`removed` : | a contact handle

Since 0.13.0

### TpBaseContactListBooleanFunc ()

    gboolean            (*TpBaseContactListBooleanFunc)     (TpBaseContactList *self);

Signature of a virtual method that returns a boolean result. These are used for feature-discovery.

For the simple cases of a constant result, use `tp_base_contact_list_true_func()` or `tp_base_contact_list_false_func()`.

`self` : | a contact list manager
Returns : | a boolean result

Since 0.13.0

### tp_base_contact_list_false_func ()

    gboolean            tp_base_contact_list_false_func     (TpBaseContactList *self);

An implementation of TpBaseContactListBooleanFunc that returns `FALSE`, for use in simple cases.

`self` : | ignored
Returns : | `FALSE`

Since 0.13.0

### tp_base_contact_list_true_func ()

    gboolean            tp_base_contact_list_true_func      (TpBaseContactList *self);

An implementation of TpBaseContactListBooleanFunc that returns `TRUE`, for use in simple cases.

`self` : | ignored
Returns : | `TRUE`

Since 0.13.0

### tp_base_contact_list_get_contact_list_persists ()

    gboolean            tp_base_contact_list_get_contact_list_persists
                                                            (TpBaseContactList *self);

Return whether subscriptions on this protocol persist between sessions (i.e. are stored on the server).

This is a virtual method, implemented using TpBaseContactListClass.get_contact_list_persists.

The default implementation is `tp_base_contact_list_true_func()`, which is correct for most protocols. Protocols where the contact list isn't stored should use `tp_base_contact_list_false_func()` as their implementation.

In the rare case of a protocol where subscriptions sometimes persist and this is detected while connecting, the subclass can implement another TpBaseContactListBooleanFunc (whose result must remain constant after the TpBaseConnection has moved to state `TP_CONNECTION_STATUS_CONNECTED`), and use that as the implementation.

`self` : | a contact list manager
Returns : | `TRUE` if subscriptions persist

Since 0.13.0

### TpBaseContactListDupContactsFunc ()

    TpHandleSet *       (*TpBaseContactListDupContactsFunc) (TpBaseContactList *self);

Signature of a virtual method to list contacts with a particular state; the required state is defined by the particular virtual method being implemented.

The implementation is expected to have a cache of contacts on the contact list, which is updated based on protocol events.

`self` : | the contact list manager
Returns : | a set of contacts with the desired state. [transfer full]

Since 0.13.0

### tp_base_contact_list_dup_contacts ()

    TpHandleSet *       tp_base_contact_list_dup_contacts   (TpBaseContactList *self);

Return the contact list. It is incorrect to call this method before `tp_base_contact_list_set_list_received()` has been called, or after the connection has disconnected.

This is a virtual method, implemented using TpBaseContactListClass.dup_contacts. Every subclass of TpBaseContactList must implement this method.

If the contact list implements `TP_TYPE_BLOCKABLE_CONTACT_LIST`, blocked contacts should not appear in the result of this method unless they are considered to be on the contact list for some other reason.

`self` : | a contact list manager
Returns : | a new TpHandleSet of contact handles. [transfer full]

Since 0.13.0

### TpBaseContactListDupStatesFunc ()

    void                (*TpBaseContactListDupStatesFunc)   (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             TpSubscriptionState *subscribe,
                                                             TpSubscriptionState *publish,
                                                             gchar **publish_request);

Signature of a virtual method to get contacts' presences. It should return `subscribe` = `TP_SUBSCRIPTION_STATE_NO`, `publish` = `TP_SUBSCRIPTION_STATE_NO` and `publish_request` = "", without error, for any contact not on the contact list.

`self` : | the contact list manager
`contact` : | the contact
`subscribe` : | used to return the state of the user's subscription to `contact`'s presence. [out][allow-none]
`publish` : | used to return the state of `contact`'s subscription to the user's presence. [out][allow-none]
`publish_request` : | if `publish` will be set to `TP_SUBSCRIPTION_STATE_ASK`, used to return the message that `contact` sent when they requested permission to see the user's presence; otherwise, used to return an empty string. [out][allow-none][transfer full]

Since 0.13.0

### tp_base_contact_list_dup_states ()

    void                tp_base_contact_list_dup_states     (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             TpSubscriptionState *subscribe,
                                                             TpSubscriptionState *publish,
                                                             gchar **publish_request);

Return the presence subscription state of `contact`. It is incorrect to call this method before `tp_base_contact_list_set_list_received()` has been called, or after the connection has disconnected.

This is a virtual method, implemented using TpBaseContactListClass.dup_states. Every subclass of TpBaseContactList must implement this method.

`self` : | a contact list manager
`contact` : | the contact
`subscribe` : | used to return the state of the user's subscription to `contact`'s presence. [out][allow-none]
`publish` : | used to return the state of `contact`'s subscription to the user's presence. [out][allow-none]
`publish_request` : | if `publish` will be set to `TP_SUBSCRIPTION_STATE_ASK`, used to return the message that `contact` sent when they requested permission to see the user's presence; otherwise, used to return an empty string. [out][allow-none][transfer full]

Since 0.13.0

### TpBaseContactListUIntFunc ()

    guint               (*TpBaseContactListUIntFunc)        (TpBaseContactList *self);

Signature of a virtual method that returns an unsigned integer result. These are used for feature-discovery.

`self` : | a contact list manager
Returns : | an unsigned integer result

Since 0.13.0

### TpBaseContactListAsyncFunc ()

    void                (*TpBaseContactListAsyncFunc)       (TpBaseContactList *self,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of a virtual method that needs no additional information.

`self` : | the contact list manager
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.18.0

### TpBaseContactListAsyncFinishFunc ()

    gboolean            (*TpBaseContactListAsyncFinishFunc) (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Signature of a virtual method to finish an async operation.

`self` : | the contact list manager
`result` : | the result of the asynchronous operation
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success, or `FALSE` if `error` is set

Since 0.13.0

### tp_base_contact_list_download_async ()

    void                tp_base_contact_list_download_async (TpBaseContactList *self,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Download the contact list when it is not done automatically at connection.

If the TpBaseContactList subclass does not override download_async, the default implementation will raise TP_ERROR_NOT_IMPLEMENTED asynchronously.

`self` : | a contact list manager
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.18.0

### tp_base_contact_list_download_finish ()

    gboolean            tp_base_contact_list_download_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_download_async()`.

This is a virtual method which may be implemented using TpBaseContactListClass.download_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_download_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.18.0

### tp_base_contact_list_get_download_at_connection ()

    gboolean            tp_base_contact_list_get_download_at_connection
                                                            (TpBaseContactList *self);

This function returns the "download-at-connection" property.

`self` : | a contact list manager
Returns : | the "download-at-connection" property

Since 0.18.0

### TP_TYPE_MUTABLE_CONTACT_LIST

    #define             TP_TYPE_MUTABLE_CONTACT_LIST

Interface representing a TpBaseContactList on which the contact list can potentially be changed.

Since 0.13.0

### struct TpMutableContactListInterface

    struct TpMutableContactListInterface {
        GTypeInterface parent;

        /* _async mandatory-to-implement, _finish has a default implementation
         * suitable for a GSimpleAsyncResult */

        TpBaseContactListRequestSubscriptionFunc request_subscription_async;
        TpBaseContactListAsyncFinishFunc request_subscription_finish;

        TpBaseContactListActOnContactsFunc authorize_publication_async;
        TpBaseContactListAsyncFinishFunc authorize_publication_finish;

        TpBaseContactListActOnContactsFunc remove_contacts_async;
        TpBaseContactListAsyncFinishFunc remove_contacts_finish;

        TpBaseContactListActOnContactsFunc unsubscribe_async;
        TpBaseContactListAsyncFinishFunc unsubscribe_finish;

        TpBaseContactListActOnContactsFunc unpublish_async;
        TpBaseContactListAsyncFinishFunc unpublish_finish;

        /* optional-to-implement */

        TpBaseContactListActOnContactsFunc store_contacts_async;
        TpBaseContactListAsyncFinishFunc store_contacts_finish;

        TpBaseContactListBooleanFunc can_change_contact_list;
        TpBaseContactListBooleanFunc get_request_uses_message;
    };

The interface vtable for a `TP_TYPE_MUTABLE_CONTACT_LIST`.

GTypeInterface `parent`; | the parent interface
TpBaseContactListRequestSubscriptionFunc `request_subscription_async`; | the implementation of `tp_base_contact_list_request_subscription_async()`; must always be provided
TpBaseContactListAsyncFinishFunc `request_subscription_finish`; | the implementation of `tp_base_contact_list_request_subscription_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListActOnContactsFunc `authorize_publication_async`; | the implementation of `tp_base_contact_list_authorize_publication_async()`; must always be provided
TpBaseContactListAsyncFinishFunc `authorize_publication_finish`; | the implementation of `tp_base_contact_list_authorize_publication_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListActOnContactsFunc `remove_contacts_async`; | the implementation of `tp_base_contact_list_remove_contacts_async()`; must always be provided
TpBaseContactListAsyncFinishFunc `remove_contacts_finish`; | the implementation of `tp_base_contact_list_remove_contacts_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListActOnContactsFunc `unsubscribe_async`; | the implementation of `tp_base_contact_list_unsubscribe_async()`; must always be provided
TpBaseContactListAsyncFinishFunc `unsubscribe_finish`; | the implementation of `tp_base_contact_list_unsubscribe_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListActOnContactsFunc `unpublish_async`; | the implementation of `tp_base_contact_list_unpublish_async()`; must always be provided
TpBaseContactListAsyncFinishFunc `unpublish_finish`; | the implementation of `tp_base_contact_list_unpublish_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListActOnContactsFunc `store_contacts_async`; | the implementation of `tp_base_contact_list_store_contacts_async()`; if not reimplemented, the default implementation is `NULL`, which is interpreted as "do nothing"
TpBaseContactListAsyncFinishFunc `store_contacts_finish`; | the implementation of `tp_base_contact_list_store_contacts_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListBooleanFunc `can_change_contact_list`; | the implementation of `tp_base_contact_list_can_change_contact_list()`; if not reimplemented, the default implementation always returns `TRUE`
TpBaseContactListBooleanFunc `get_request_uses_message`; | the implementation of `tp_base_contact_list_get_request_uses_message()`; if not reimplemented, the default implementation always returns `TRUE`

Since 0.13.0

### tp_base_contact_list_can_change_contact_list ()

    gboolean            tp_base_contact_list_can_change_contact_list
                                                            (TpBaseContactList *self);

Return whether the contact list can be changed.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, this method always returns `FALSE`.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST` this is a virtual method, implemented using TpMutableContactListInterface.can_change_contact_list. The default implementation always returns `TRUE`.

In the rare case of a protocol where subscriptions can only sometimes be changed and this is detected while connecting, the TpBaseContactList subclass should implement `TP_TYPE_MUTABLE_CONTACT_LIST`. TpMutableContactListInterface.can_change_contact_list to its own implementation, whose result must remain constant after the TpBaseConnection has moved to state `TP_CONNECTION_STATUS_CONNECTED`.

(For instance, this could be useful for XMPP, where subscriptions can normally be altered, but on connections to Facebook Chat servers this is not actually supported.)

`self` : | a contact list manager
Returns : | `TRUE` if the contact list can be changed

Since 0.13.0

### tp_base_contact_list_get_request_uses_message ()

    gboolean            tp_base_contact_list_get_request_uses_message
                                                            (TpBaseContactList *self);

Return whether the `tp_base_contact_list_request_subscription_async()` method's `message` argument is actually used.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, this method is meaningless, and always returns `FALSE`.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method, implemented using TpMutableContactListInterface.get_request_uses_message. The default implementation always returns `TRUE`, which is correct for most protocols; subclasses may reimplement this method with `tp_base_contact_list_false_func()` or a custom implementation if desired.

`self` : | a contact list manager
Returns : | `TRUE` if `tp_base_contact_list_request_subscription_async()` will not ignore its `message` argument

Since 0.13.0

### TpBaseContactListRequestSubscriptionFunc ()

    void                (*TpBaseContactListRequestSubscriptionFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             const gchar *message,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of a virtual method to request permission to see some contacts' presence.

The virtual method should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before it calls `callback`.

`self` : | the contact list manager
`contacts` : | the contacts whose subscription is to be requested
`message` : | an optional human-readable message from the user
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_request_subscription_async ()

    void                tp_base_contact_list_request_subscription_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             const gchar *message,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Request permission to see some contacts' presence.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpMutableContactListInterface.request_subscription_async. The implementation should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before it calls `callback`.

If `message` will be ignored, TpMutableContactListInterface.get_request_uses_message should also be reimplemented to return `FALSE`.

`self` : | a contact list manager
`contacts` : | the contacts whose subscription is to be requested
`message` : | an optional human-readable message from the user
`callback` : | a callback to call when the request for subscription succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_request_subscription_finish ()

    gboolean            tp_base_contact_list_request_subscription_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_request_subscription_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpMutableContactListInterface.request_subscription_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_request_subscription_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### TpBaseContactListActOnContactsFunc ()

    void                (*TpBaseContactListActOnContactsFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of a virtual method that acts on a set of contacts and needs no additional information, such as removing contacts, approving or cancelling presence publication, cancelling presence subscription, or removing contacts.

The virtual method should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before returning.

`self` : | the contact list manager
`contacts` : | the contacts on which to act
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_authorize_publication_async ()

    void                tp_base_contact_list_authorize_publication_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Give permission for some contacts to see the local user's presence.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpMutableContactListInterface.authorize_publication_async. The implementation should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before it calls `callback`.

`self` : | a contact list manager
`contacts` : | the contacts to whom presence will be published
`callback` : | a callback to call when the authorization succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_authorize_publication_finish ()

    gboolean            tp_base_contact_list_authorize_publication_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_authorize_publication_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpMutableContactListInterface.authorize_publication_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_authorize_publication_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_store_contacts_async ()

    void                tp_base_contact_list_store_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Store `contacts` on the contact list, without attempting to subscribe to them or send presence to them. If this is not possible, do nothing.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method, which may be implemented using TpMutableContactListInterface.store_contacts_async. The implementation should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before calling `callback`.

If the implementation of TpMutableContactListInterface.store_contacts_async is `NULL` (which is the default), this method calls `callback` to signal success, but does nothing in the underlying protocol.

`self` : | a contact list manager
`contacts` : | the contacts to be stored
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_store_contacts_finish ()

    gboolean            tp_base_contact_list_store_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_store_contacts_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpMutableContactListInterface.store_contacts_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_store_contacts_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_remove_contacts_async ()

    void                tp_base_contact_list_remove_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Remove `contacts` from the contact list entirely; this includes the effect of both `tp_base_contact_list_unsubscribe_async()` and `tp_base_contact_list_unpublish_async()`, and also reverses the effect of `tp_base_contact_list_store_contacts_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, this method does nothing.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpMutableContactListInterface.remove_contacts_async. The implementation should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before calling `callback`.

`self` : | a contact list manager
`contacts` : | the contacts to be removed
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_remove_contacts_finish ()

    gboolean            tp_base_contact_list_remove_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_remove_contacts_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpMutableContactListInterface.remove_contacts_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_remove_contacts_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_unsubscribe_async ()

    void                tp_base_contact_list_unsubscribe_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Cancel a pending subscription request to `contacts`, or attempt to stop receiving their presence.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpMutableContactListInterface.unsubscribe_async. The implementation should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before calling `callback`.

`self` : | a contact list manager
`contacts` : | the contacts whose presence will no longer be received
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_unsubscribe_finish ()

    gboolean            tp_base_contact_list_unsubscribe_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_unsubscribe_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpMutableContactListInterface.unsubscribe_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_unsubscribe_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_unpublish_async ()

    void                tp_base_contact_list_unpublish_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Reject a pending subscription request from `contacts`, or attempt to stop sending presence to them.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpMutableContactListInterface.unpublish_async. The implementation should call `tp_base_contact_list_contacts_changed()` for any contacts it has changed, before calling `callback`.

`self` : | a contact list manager
`contacts` : | the contacts to whom presence will no longer be published
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_unpublish_finish ()

    gboolean            tp_base_contact_list_unpublish_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_unpublish_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpMutableContactListInterface.unpublish_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_unpublish_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### TP_TYPE_CONTACT_GROUP_LIST

    #define             TP_TYPE_CONTACT_GROUP_LIST

Interface representing a TpBaseContactList on which contacts can be in user-defined groups, which cannot necessarily be edited (`TP_TYPE_MUTABLE_CONTACT_GROUP_LIST` represents a list where these groups exist and can also be edited).

Since 0.13.0

### struct TpContactGroupListInterface

    struct TpContactGroupListInterface {
        GTypeInterface parent;
        /* mandatory to implement */
        TpBaseContactListDupGroupsFunc dup_groups;
        TpBaseContactListDupGroupMembersFunc dup_group_members;
        TpBaseContactListDupContactGroupsFunc dup_contact_groups;
        /* optional to implement */
        TpBaseContactListBooleanFunc has_disjoint_groups;
        TpBaseContactListNormalizeFunc normalize_group;
    };

The interface vtable for a `TP_TYPE_CONTACT_GROUP_LIST`.

GTypeInterface `parent`; | the parent interface
TpBaseContactListDupGroupsFunc `dup_groups`; | the implementation of `tp_base_contact_list_dup_groups()`; must always be implemented
TpBaseContactListDupGroupMembersFunc `dup_group_members`; | the implementation of `tp_base_contact_list_dup_group_members()`; must always be implemented
TpBaseContactListDupContactGroupsFunc `dup_contact_groups`; | the implementation of `tp_base_contact_list_dup_contact_groups()`; must always be implemented
TpBaseContactListBooleanFunc `has_disjoint_groups`; | the implementation of `tp_base_contact_list_has_disjoint_groups()`; if not reimplemented, the default implementation always returns `FALSE`
TpBaseContactListNormalizeFunc `normalize_group`; | the implementation of `tp_base_contact_list_normalize_group()`; if not reimplemented, the default implementation is `NULL`, which allows any UTF-8 string as a group name (including the empty string) and assumes that any distinct group names can coexist

Since 0.13.0

### TpBaseContactListNormalizeFunc ()

    gchar *             (*TpBaseContactListNormalizeFunc)   (TpBaseContactList *self,
                                                             const gchar *s);

Signature of a virtual method to normalize strings in a contact list manager.

`self` : | a contact list manager
`s` : | a non-`NULL` name to normalize
Returns : | a normalized form of `s`, or `NULL` on error

Since 0.13.0

### tp_base_contact_list_normalize_group ()

    gchar *             tp_base_contact_list_normalize_group
                                                            (TpBaseContactList *self,
                                                             const gchar *s);

Return a normalized form of the group name `s`, or `NULL` if a group of a sufficiently similar name cannot be created.

If the TpBaseContactList subclass does not implement `TP_TYPE_CONTACT_GROUP_LIST`, this method is meaningless, and always returns `NULL`.

For implementations of `TP_TYPE_CONTACT_GROUP_LIST`, this is a virtual method, implemented using TpContactGroupListInterface.normalize_group. If unimplemented, the default behaviour is to use the group's name as-is.

Protocols where this default is not suitable (for instance, if group names cannot be the empty string, or can only contain XML character data, or can only contain a particular Unicode normal form like NFKC) should reimplement this virtual method.

`self` : | a contact list manager
`s` : | a non-`NULL` group name to normalize
Returns : | a normalized form of `s`, or `NULL` on error

Since 0.13.0

### TpBaseContactListDupContactGroupsFunc ()

    GStrv               (*TpBaseContactListDupContactGroupsFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandle contact);

Signature of a virtual method that lists the groups to which `contact` belongs.

If `contact` is not on the contact list, this method must return either `NULL` or an empty array, without error.

`self` : | a contact list manager
`contact` : | a non-zero contact handle
Returns : | an array of groups. [array zero-terminated=1][element-type utf8][transfer full]

Since 0.13.0

### tp_base_contact_list_dup_contact_groups ()

    GStrv               tp_base_contact_list_dup_contact_groups
                                                            (TpBaseContactList *self,
                                                             TpHandle contact);

Return a list of groups of which `contact` is a member. It is incorrect to call this method before `tp_base_contact_list_set_list_received()` has been called, after the connection has disconnected, or on a TpBaseContactList that does not implement `TP_TYPE_CONTACT_GROUP_LIST`.

If `contact` is not on the contact list, this method must return either `NULL` or an empty array.

For implementations of `TP_TYPE_CONTACT_GROUP_LIST`, this is a virtual method, implemented using TpContactGroupListInterface.dup_contact_groups. It must always be implemented.

`self` : | a contact list manager
`contact` : | a contact handle
Returns : | an array of groups. [array zero-terminated=1][element-type utf8][transfer full]

Since 0.13.0

### TpBaseContactListDupGroupsFunc ()

    GStrv               (*TpBaseContactListDupGroupsFunc)   (TpBaseContactList *self);

Signature of a virtual method that lists every group that exists on a connection.

`self` : | a contact list manager
Returns : | an array of groups. [array zero-terminated=1][element-type utf8][transfer full]

Since 0.13.0

### tp_base_contact_list_dup_groups ()

    GStrv               tp_base_contact_list_dup_groups     (TpBaseContactList *self);

Return a list of all groups on this connection. It is incorrect to call this method before `tp_base_contact_list_set_list_received()` has been called, after the connection has disconnected, or on a TpBaseContactList that does not implement `TP_TYPE_CONTACT_GROUP_LIST`.

For implementations of `TP_TYPE_CONTACT_GROUP_LIST`, this is a virtual method, implemented using TpContactGroupListInterface.dup_groups. It must always be implemented.

`self` : | a contact list manager
Returns : | an array of groups. [array zero-terminated=1][element-type utf8][transfer full]

Since 0.13.0

### TpBaseContactListDupGroupMembersFunc ()

    TpHandleSet *       (*TpBaseContactListDupGroupMembersFunc)
                                                            (TpBaseContactList *self,
                                                             const gchar *group);

Signature of a virtual method that lists the members of a group.

`self` : | a contact list manager
`group` : | a normalized group name
Returns : | a set of contact (`TP_HANDLE_TYPE_CONTACT`) handles. [transfer full]

Since 0.13.0

### tp_base_contact_list_dup_group_members ()

    TpHandleSet *       tp_base_contact_list_dup_group_members
                                                            (TpBaseContactList *self,
                                                             const gchar *group);

Return the set of members of `group`. It is incorrect to call this method before `tp_base_contact_list_set_list_received()` has been called, after the connection has disconnected, or on a TpBaseContactList that does not implement `TP_TYPE_CONTACT_GROUP_LIST`.

If `group` does not exist, this method must return either `NULL` or an empty set, without error.

For implementations of `TP_TYPE_CONTACT_GROUP_LIST`, this is a virtual method, implemented using TpContactGroupListInterface.dup_group_members. It must always be implemented.

`self` : | a contact list manager
`group` : | a normalized group name
Returns : | a set of contact (`TP_HANDLE_TYPE_CONTACT`) handles

Since 0.13.0

### tp_base_contact_list_group_renamed ()

    void                tp_base_contact_list_group_renamed  (TpBaseContactList *self,
                                                             const gchar *old_name,
                                                             const gchar *new_name);

Called by subclasses when a group has been renamed.

Calling `tp_base_contact_list_dup_group_members()` for `old_name` during this method should return the group's old members. If this is done correctly by a subclass, then `tp_base_contact_list_groups_changed()` will automatically be emitted for the members, and the subclass does not need to do so.

It is an error to call this method on a contact list that does not implement `TP_TYPE_CONTACT_GROUP_LIST`.

`self` : | a contact list manager
`old_name` : | the group's old name
`new_name` : | the group's new name

Since 0.13.0

### tp_base_contact_list_groups_changed ()

    void                tp_base_contact_list_groups_changed (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             const gchar * const *added,
                                                             gssize n_added,
                                                             const gchar * const *removed,
                                                             gssize n_removed);

Called by subclasses when groups' membership has been changed.

If any of the groups in `added` are not already known to exist, this method also signals that they were created, as if `tp_base_contact_list_groups_created()` had been called first.

It is an error to call this method on a contact list that does not implement `TP_TYPE_CONTACT_GROUP_LIST`.

`self` : | a contact list manager
`contacts` : | a set containing one or more contacts
`added` : | zero or more groups to which the `contacts` were added, or `NULL` (which has the same meaning as an empty list). [array length=n_added][element-type utf8][allow-none]
`n_added` : | the number of groups added, or -1 if `added` is `NULL`-terminated
`removed` : | zero or more groups from which the `contacts` were removed, or `NULL` (which has the same meaning as an empty list). [array zero-terminated=1][element-type utf8][allow-none]
`n_removed` : | the number of groups removed, or -1 if `removed` is `NULL`-terminated

Since 0.13.0

### tp_base_contact_list_one_contact_groups_changed ()

    void                tp_base_contact_list_one_contact_groups_changed
                                                            (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             const gchar * const *added,
                                                             gssize n_added,
                                                             const gchar * const *removed,
                                                             gssize n_removed);

Convenience wrapper around `tp_base_contact_list_groups_changed()` for a single handle in the 'contacts' set.

(There is no equivalent function for `added` and `removed` having trivial contents, because you can already use `NULL, 0` for an empty list or `&group_name, 1` for a single group.)

`self` : | the contact list manager
`contact` : | a contact handle
`added` : | zero or more groups to which `contact` was added, or `NULL`. [array length=n_added][element-type utf8][allow-none]
`n_added` : | the number of groups added, or -1 if `added` is `NULL`-terminated
`removed` : | zero or more groups from which the `contact` was removed, or `NULL`. [array zero-terminated=1][element-type utf8][allow-none]
`n_removed` : | the number of groups removed, or -1 if `removed` is `NULL`-terminated

Since 0.13.0

### tp_base_contact_list_groups_created ()

    void                tp_base_contact_list_groups_created (TpBaseContactList *self,
                                                             const gchar * const *created,
                                                             gssize n_created);

Called by subclasses when new groups have been created. This will typically be followed by a call to `tp_base_contact_list_groups_changed()` to add some members to those groups.

It is an error to call this method on a contact list that does not implement `TP_TYPE_CONTACT_GROUP_LIST`.

`self` : | a contact list manager
`created` : | zero or more groups that were created. [array length=n_created][element-type utf8][allow-none]
`n_created` : | the number of groups created, or -1 if `created` is `NULL`-terminated

Since 0.13.0

### tp_base_contact_list_groups_removed ()

    void                tp_base_contact_list_groups_removed (TpBaseContactList *self,
                                                             const gchar * const *removed,
                                                             gssize n_removed);

Called by subclasses when groups have been removed.

Calling `tp_base_contact_list_dup_group_members()` during this method should return the groups' old members. If this is done correctly by a subclass, then `tp_base_contact_list_groups_changed()` will automatically be emitted for the old members, and the subclass does not need to do so.

It is an error to call this method on a contact list that does not implement `TP_TYPE_CONTACT_GROUP_LIST`.

`self` : | a contact list manager
`removed` : | zero or more groups that were removed. [array length=n_removed][element-type utf8][allow-none]
`n_removed` : | the number of groups removed, or -1 if `removed` is `NULL`-terminated

Since 0.13.0

### tp_base_contact_list_has_disjoint_groups ()

    gboolean            tp_base_contact_list_has_disjoint_groups
                                                            (TpBaseContactList *self);

Return whether groups in this protocol are disjoint (i.e. each contact can be in at most one group). This is merely informational: subclasses are responsible for making appropriate calls to `tp_base_contact_list_groups_changed()`, etc.

If the TpBaseContactList subclass does not implement `TP_TYPE_CONTACT_GROUP_LIST`, this method is meaningless, and always returns `FALSE`.

For implementations of `TP_TYPE_CONTACT_GROUP_LIST`, this is a virtual method, implemented using TpContactGroupListInterface.has_disjoint_groups.

The default implementation is `tp_base_contact_list_false_func()`; subclasses where groups are disjoint should use `tp_base_contact_list_true_func()` instead. In the unlikely event that a protocol can have disjoint groups, or not, determined at runtime, it can use a custom implementation.

`self` : | a contact list manager
Returns : | `TRUE` if groups are disjoint

Since 0.13.0

### TP_TYPE_MUTABLE_CONTACT_GROUP_LIST

    #define             TP_TYPE_MUTABLE_CONTACT_GROUP_LIST

Interface representing a TpBaseContactList on which user-defined contact groups can potentially be changed. `TP_TYPE_CONTACT_GROUP_LIST` is a prerequisite for this interface.

Since 0.13.0

### struct TpMutableContactGroupListInterface

    struct TpMutableContactGroupListInterface {
        GTypeInterface parent;

        /* _async mandatory-to-implement, _finish has a default implementation
         * suitable for a GSimpleAsyncResult */

        TpBaseContactListSetContactGroupsFunc set_contact_groups_async;
        TpBaseContactListAsyncFinishFunc set_contact_groups_finish;

        TpBaseContactListGroupContactsFunc set_group_members_async;
        TpBaseContactListAsyncFinishFunc set_group_members_finish;

        TpBaseContactListGroupContactsFunc add_to_group_async;
        TpBaseContactListAsyncFinishFunc add_to_group_finish;

        TpBaseContactListGroupContactsFunc remove_from_group_async;
        TpBaseContactListAsyncFinishFunc remove_from_group_finish;

        TpBaseContactListRemoveGroupFunc remove_group_async;
        TpBaseContactListAsyncFinishFunc remove_group_finish;

        /* optional to implement */

        TpBaseContactListRenameGroupFunc rename_group_async;
        TpBaseContactListAsyncFinishFunc rename_group_finish;
        TpBaseContactListUIntFunc get_group_storage;
    };

The interface vtable for a `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`.

GTypeInterface `parent`; | the parent interface
TpBaseContactListSetContactGroupsFunc `set_contact_groups_async`; | the implementation of `tp_base_contact_list_set_contact_groups_async()`; must always be implemented
TpBaseContactListAsyncFinishFunc `set_contact_groups_finish`; | the implementation of `tp_base_contact_list_set_contact_groups_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListGroupContactsFunc `set_group_members_async`; | the implementation of `tp_base_contact_list_set_group_members_async()`; must always be implemented
TpBaseContactListAsyncFinishFunc `set_group_members_finish`; | the implementation of `tp_base_contact_list_set_group_members_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListGroupContactsFunc `add_to_group_async`; | the implementation of `tp_base_contact_list_add_to_group_async()`; must always be implemented
TpBaseContactListAsyncFinishFunc `add_to_group_finish`; | the implementation of `tp_base_contact_list_add_to_group_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListGroupContactsFunc `remove_from_group_async`; | the implementation of `tp_base_contact_list_remove_from_group_async()`; must always be implemented
TpBaseContactListAsyncFinishFunc `remove_from_group_finish`; | the implementation of `tp_base_contact_list_remove_from_group_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListRemoveGroupFunc `remove_group_async`; | the implementation of `tp_base_contact_list_remove_group_async()`; must always be implemented
TpBaseContactListAsyncFinishFunc `remove_group_finish`; | the implementation of `tp_base_contact_list_remove_group_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListRenameGroupFunc `rename_group_async`; | the implementation of `tp_base_contact_list_rename_group_async()`; the default implementation results in group renaming being emulated via a call to `add_to_group_async` and a call to `remove_group_async`
TpBaseContactListAsyncFinishFunc `rename_group_finish`; | the implementation of `tp_base_contact_list_rename_group_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListUIntFunc `get_group_storage`; | the implementation of `tp_base_contact_list_get_group_storage()`; the default implementation is `NULL`, which results in `TP_CONTACT_METADATA_STORAGE_TYPE_ANYONE` being advertised

Since 0.13.0

### TpBaseContactListSetContactGroupsFunc ()

    void                (*TpBaseContactListSetContactGroupsFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             const gchar * const *normalized_names,
                                                             gsize n_names,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of an implementation of `tp_base_contact_list_set_contact_groups_async()`.

`self` : | a contact list manager
`contact` : | a contact handle
`normalized_names` : | the normalized names of some groups. [array length=n_names]
`n_names` : | the number of groups
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_set_contact_groups_async ()

    void                tp_base_contact_list_set_contact_groups_async
                                                            (TpBaseContactList *self,
                                                             TpHandle contact,
                                                             const gchar * const *normalized_names,
                                                             gsize n_names,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Add `contact` to each group in `normalized_names`, creating them if necessary, and remove `contact` from any other groups of which they are a member.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which must be implemented, using TpMutableContactGroupListInterface.set_contact_groups_async. The implementation should call `tp_base_contact_list_groups_changed()` for any changes it successfully made, before returning.

`self` : | a contact list manager
`contact` : | a contact handle
`normalized_names` : | the normalized names of some groups. [array length=n_names]
`n_names` : | the number of groups
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_set_contact_groups_finish ()

    gboolean            tp_base_contact_list_set_contact_groups_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_set_contact_groups_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which may be implemented using TpMutableContactGroupListInterface.set_contact_groups_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_set_contact_groups_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### TpBaseContactListGroupContactsFunc ()

    void                (*TpBaseContactListGroupContactsFunc)
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of a virtual method that alters a group's members.

`self` : | a contact list manager
`group` : | a group
`contacts` : | a set of contact handles
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_add_to_group_async ()

    void                tp_base_contact_list_add_to_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Add `contacts` to `group`, creating it if necessary.

If `group` does not exist, the implementation should create it, even if `contacts` is empty.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which must be implemented, using TpMutableContactGroupListInterface.add_to_group_async. The implementation should call `tp_base_contact_list_groups_changed()` for any changes it successfully made, before calling `callback`.

`self` : | a contact list manager
`group` : | the normalized name of a group
`contacts` : | some contacts (may be an empty set)
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_add_to_group_finish ()

    gboolean            tp_base_contact_list_add_to_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_add_to_group_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which may be implemented using TpMutableContactGroupListInterface.add_to_group_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_add_to_group_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_remove_from_group_async ()

    void                tp_base_contact_list_remove_from_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Remove `contacts` from `group`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which must be implemented, using TpMutableContactGroupListInterface.remove_from_group_async. The implementation should call `tp_base_contact_list_groups_changed()` for any changes it successfully made, before calling `callback`.

`self` : | a contact list manager
`group` : | the normalized name of a group
`contacts` : | some contacts
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_remove_from_group_finish ()

    gboolean            tp_base_contact_list_remove_from_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_remove_from_group_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which may be implemented using TpMutableContactGroupListInterface.remove_from_group_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_remove_from_group_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_set_group_members_async ()

    void                tp_base_contact_list_set_group_members_async
                                                            (TpBaseContactList *self,
                                                             const gchar *normalized_group,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Set the members of `normalized_group` to be exactly `contacts` (i.e. add `contacts`, and simultaneously remove all members not in `contacts`).

If `normalized_group` does not exist, the implementation should create it, even if `contacts` is empty.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which must be implemented, using TpMutableContactGroupListInterface.set_group_members_async. The implementation should call `tp_base_contact_list_groups_changed()` for any changes it successfully made, before calling `callback`.

`self` : | a contact list manager
`normalized_group` : | the normalized name of a group
`contacts` : | the contacts who should be in the group
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_set_group_members_finish ()

    gboolean            tp_base_contact_list_set_group_members_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_set_group_members_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which may be implemented using TpMutableContactGroupListInterface.set_group_members_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_set_group_members_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### TpBaseContactListRemoveGroupFunc ()

    void                (*TpBaseContactListRemoveGroupFunc) (TpBaseContactList *self,
                                                             const gchar *group,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of a method that deletes groups.

`self` : | a contact list manager
`group` : | the normalized name of a group
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_remove_group_async ()

    void                tp_base_contact_list_remove_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *group,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Remove a group entirely, removing any members in the process.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which must be implemented, using TpMutableContactGroupListInterface.remove_group_async. The implementation should call `tp_base_contact_list_groups_removed()` for any groups it successfully removed, before calling `callback`.

`self` : | a contact list manager
`group` : | the normalized name of a group
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_remove_group_finish ()

    gboolean            tp_base_contact_list_remove_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_remove_group_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which may be implemented using TpMutableContactGroupListInterface.remove_group_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_remove_group_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### TpBaseContactListRenameGroupFunc ()

    void                (*TpBaseContactListRenameGroupFunc) (TpBaseContactList *self,
                                                             const gchar *old_name,
                                                             const gchar *new_name,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of a method that renames groups.

`self` : | a contact list manager
`old_name` : | a group
`new_name` : | a new name for the group
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_rename_group_async ()

    void                tp_base_contact_list_rename_group_async
                                                            (TpBaseContactList *self,
                                                             const gchar *old_name,
                                                             const gchar *new_name,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Rename a group; if possible, do so as an atomic operation. If this protocol can't do that, emulate renaming in terms of other operations.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which may be implemented, using TpMutableContactGroupListInterface.rename_group_async.

If this virtual method is not implemented, the default is to implement renaming a group as creating the new group, adding all the old group's members to it, and removing the old group: this is appropriate for protocols like XMPP, in which groups behave more like tags.

The implementation should call `tp_base_contact_list_group_renamed()` before calling `callback`.

`self` : | a contact list manager
`old_name` : | the normalized name of a group, which must exist
`new_name` : | a new normalized name for the group name
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.13.0

### tp_base_contact_list_rename_group_finish ()

    gboolean            tp_base_contact_list_rename_group_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_rename_group_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method which may be implemented using TpMutableContactGroupListInterface.rename_group_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_rename_group_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_get_group_storage ()

    TpContactMetadataStorageType tp_base_contact_list_get_group_storage
                                                            (TpBaseContactList *self);

Return the extent to which user-defined groups can be set in this protocol. If this is `TP_CONTACT_METADATA_STORAGE_TYPE_NONE`, methods that would alter the group list will not be called.

If the TpBaseContactList subclass does not implement `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this method is meaningless, and always returns `TP_CONTACT_METADATA_STORAGE_TYPE_NONE`.

For implementations of `TP_TYPE_MUTABLE_CONTACT_GROUP_LIST`, this is a virtual method, implemented using TpMutableContactGroupListInterface.get_group_storage.

The default implementation is `NULL`, which is treated as equivalent to an implementation that always returns `TP_CONTACT_METADATA_STORAGE_TYPE_ANYONE`. A custom implementation can also be used.

`self` : | a contact list manager
Returns : | a TpContactMetadataStorageType

Since 0.13.0

### TP_TYPE_BLOCKABLE_CONTACT_LIST

    #define             TP_TYPE_BLOCKABLE_CONTACT_LIST

Interface representing a TpBaseContactList on which contacts can be blocked from communicating with the user.

Since 0.13.0

### struct TpBlockableContactListInterface

    struct TpBlockableContactListInterface {
        GTypeInterface parent;

        /* mandatory to implement */

        TpBaseContactListDupContactsFunc dup_blocked_contacts;

        /* unblock_contacts_async is mandatory to implement; either
         * block_contacts_async or block_contacts_with_abuse_async (but not both!)
         * must also be implemented. _finish have default implementations
         * suitable for a GSimpleAsyncResult */

        TpBaseContactListActOnContactsFunc block_contacts_async;
        TpBaseContactListAsyncFinishFunc block_contacts_finish;
        TpBaseContactListActOnContactsFunc unblock_contacts_async;
        TpBaseContactListAsyncFinishFunc unblock_contacts_finish;

        /* optional to implement */
        TpBaseContactListBooleanFunc can_block;

        /* see above. block_contacts_finish is the corresponding _finish function.
         */
        TpBaseContactListBlockContactsWithAbuseFunc block_contacts_with_abuse_async;
    };

The interface vtable for a `TP_TYPE_BLOCKABLE_CONTACT_LIST`.

GTypeInterface `parent`; | the parent interface
TpBaseContactListDupContactsFunc `dup_blocked_contacts`; | the implementation of `tp_base_contact_list_dup_blocked_contacts()`; must always be provided
TpBaseContactListActOnContactsFunc `block_contacts_async`; | the implementation of `tp_base_contact_list_block_contacts_async()`; either this or `block_contacts_with_abuse_async` must always be provided
TpBaseContactListAsyncFinishFunc `block_contacts_finish`; | the implementation of `tp_base_contact_list_block_contacts_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListActOnContactsFunc `unblock_contacts_async`; | the implementation of `tp_base_contact_list_unblock_contacts_async()`; must always be provided
TpBaseContactListAsyncFinishFunc `unblock_contacts_finish`; | the implementation of `tp_base_contact_list_unblock_contacts_finish()`; the default implementation may be used if `result` is a GSimpleAsyncResult
TpBaseContactListBooleanFunc `can_block`; | the implementation of `tp_base_contact_list_can_block()`; if not reimplemented, the default implementation always returns `TRUE`
TpBaseContactListBlockContactsWithAbuseFunc `block_contacts_with_abuse_async`; | the implementation of `tp_base_contact_list_block_contacts_async()`; either this or `block_contacts_async` must always be provided. If the underlying protocol does not support reporting contacts as abusive, implement `block_contacts_async` instead. Since: 0.15.1

Since 0.13.0

### TpBaseContactListBlockContactsWithAbuseFunc ()

    void                (*TpBaseContactListBlockContactsWithAbuseFunc)
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             gboolean report_abusive,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Signature of a virtual method that blocks a set of contacts, optionally reporting them to the server operator as abusive.

`self` : | the contact list manager
`contacts` : | the contacts to block
`report_abusive` : | whether to report the contacts as abusive to the server operator
`callback` : | a callback to call on success, failure or disconnection
`user_data` : | user data for the callback

Since 0.15.1

### tp_base_contact_list_can_block ()

    gboolean            tp_base_contact_list_can_block      (TpBaseContactList *self);

Return whether this contact list has a list of blocked contacts. If it does, that list is assumed to be modifiable.

If the TpBaseContactList subclass does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this method always returns `FALSE`.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method, implemented using TpBlockableContactListInterface.can_block. The default implementation always returns `TRUE`.

In the case of a protocol where blocking may or may not work and this is detected while connecting, the subclass can implement another TpBaseContactListBooleanFunc (whose result must remain constant after the TpBaseConnection has moved to state `TP_CONNECTION_STATUS_CONNECTED`), and use that as the implementation.

(For instance, this could be useful for XMPP, where support for contact blocking is server-dependent: telepathy-gabble 0.8.x implements it for connections to Google Talk servers, but not for any other server.)

`self` : | a contact list manager
Returns : | `TRUE` if communication from contacts can be blocked

Since 0.13.0

### tp_base_contact_list_dup_blocked_contacts ()

    TpHandleSet *       tp_base_contact_list_dup_blocked_contacts
                                                            (TpBaseContactList *self);

Return the list of blocked contacts. It is incorrect to call this method before `tp_base_contact_list_set_list_received()` has been called, after the connection has disconnected, or on a TpBaseContactList that does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method, implemented using TpBlockableContactListInterface.dup_blocked_contacts. It must always be implemented.

`self` : | a contact list manager
Returns : | a new TpHandleSet of contact handles. [transfer full]

Since 0.13.0

### tp_base_contact_list_block_contacts_async ()

    void                tp_base_contact_list_block_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Request that the given contacts are prevented from communicating with the user, and that presence is not sent to them even if they have a valid presence subscription, if possible. This is equivalent to calling `tp_base_contact_list_block_contacts_with_abuse_async()`, passing FALSE as the report_abusive argument.

If the TpBaseContactList subclass does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpBlockableContactListInterface.block_contacts_async or TpBlockableContactListInterface.block_contacts_with_abuse_async. The implementation should call `tp_base_contact_list_contact_blocking_changed()` for any contacts it has changed, before calling `callback`.

`self` : | a contact list manager
`contacts` : | contacts whose communications should be blocked
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_block_contacts_finish ()

    gboolean            tp_base_contact_list_block_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_block_contacts_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpBlockableContactListInterface.block_contacts_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_block_contacts_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_block_contacts_with_abuse_async ()

    void                tp_base_contact_list_block_contacts_with_abuse_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             gboolean report_abusive,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Request that the given contacts are prevented from communicating with the user, and that presence is not sent to them even if they have a valid presence subscription, if possible. If the TpBaseContactList subclass implements TpBlockableContactListInterface.block_contacts_with_abuse_async and `report_abusive` is TRUE, also report the given contacts as abusive to the server operator.

If the TpBaseContactList subclass does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpBlockableContactListInterface.block_contacts_async or TpBlockableContactListInterface.block_contacts_with_abuse_async. The implementation should call `tp_base_contact_list_contact_blocking_changed()` for any contacts it has changed, before calling `callback`.

`self` : | a contact list manager
`contacts` : | contacts whose communications should be blocked
`report_abusive` : | whether to report the contacts as abusive to the server operator
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.15.1

### tp_base_contact_list_block_contacts_with_abuse_finish ()

    gboolean            tp_base_contact_list_block_contacts_with_abuse_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_block_contacts_with_abuse_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpBlockableContactListInterface.block_contacts_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_block_contacts_with_abuse_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.15.1

### tp_base_contact_list_unblock_contacts_async ()

    void                tp_base_contact_list_unblock_contacts_async
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *contacts,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Reverse the effects of `tp_base_contact_list_block_contacts_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this method does nothing.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method which must be implemented, using TpBlockableContactListInterface.unblock_contacts_async. The implementation should call `tp_base_contact_list_contact_blocking_changed()` for any contacts it has changed, before calling `callback`.

`self` : | a contact list manager
`contacts` : | contacts whose communications should no longer be blocked
`callback` : | a callback to call when the operation succeeds or fails
`user_data` : | optional data to pass to `callback`

Since 0.13.0

### tp_base_contact_list_unblock_contacts_finish ()

    gboolean            tp_base_contact_list_unblock_contacts_finish
                                                            (TpBaseContactList *self,
                                                             GAsyncResult *result,
                                                             GError **error);

Interpret the result of an asynchronous call to `tp_base_contact_list_unblock_contacts_async()`.

If the TpBaseContactList subclass does not implement `TP_TYPE_BLOCKABLE_CONTACT_LIST`, it is an error to call this method.

For implementations of `TP_TYPE_BLOCKABLE_CONTACT_LIST`, this is a virtual method which may be implemented using TpBlockableContactListInterface.unblock_contacts_finish. If the `result` will be a GSimpleAsyncResult, the default implementation may be used.

`self` : | a contact list manager
`result` : | the result passed to `callback` by an implementation of `tp_base_contact_list_unblock_contacts_async()`
`error` : | used to raise an error if `FALSE` is returned
Returns : | `TRUE` on success or `FALSE` on error

Since 0.13.0

### tp_base_contact_list_contact_blocking_changed ()

    void                tp_base_contact_list_contact_blocking_changed
                                                            (TpBaseContactList *self,
                                                             TpHandleSet *changed);

Emit signals for a change to the blocked contacts list.

`tp_base_contact_list_dup_blocked_contacts()` must already reflect the contacts' new statuses when entering this method (in practice, this means that implementations must update their own cache of contacts before calling this method).

It is an error to call this method if `tp_base_contact_list_can_block()` would return `FALSE`.

`self` : | the contact list manager
`changed` : | a set of contacts who were blocked or unblocked

Since 0.13.0

## Property Details

### The `"connection"` property

      "connection"               TpBaseConnection*     : Read / Write / Construct Only

The connection that owns this channel manager. Read-only except during construction.

Since 0.13.0

### The `"download-at-connection"` property

      "download-at-connection"   gboolean              : Read / Write / Construct

Whether the roster should be automatically downloaded at connection.

This property doesn't change anything in TpBaseContactsList's behaviour. Implementations should check this property when they become connected and in their Download method, and behave accordingly.

Default value: TRUE

Since 0.18.0