summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2008-08-15 16:55:15 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2008-08-15 16:55:15 +0100
commit12581896df69cb3f702c8c9986d995ac37ce7074 (patch)
tree67c5136b5fe3ab2abd448c043f71d60f0ff3a39e
parent4a561fcd747f9bbbe91bbbed7523b492ea0e974e (diff)
parenta60bb121f3ca4909c276eabaf37f47e0314abd2f (diff)
downloadtelepathy-glib-12581896df69cb3f702c8c9986d995ac37ce7074.tar.gz
Merge commit 'sjoerd/inspectotron' into spec-update
-rw-r--r--docs/reference/telepathy-glib-docs.sgml2
-rw-r--r--docs/reference/telepathy-glib-sections.txt67
-rw-r--r--spec/Connection.xml7
-rw-r--r--spec/Connection_Interface_Aliasing.xml23
-rw-r--r--spec/Connection_Interface_Capabilities.xml2
-rw-r--r--spec/Connection_Interface_Contacts.xml36
-rw-r--r--spec/Connection_Interface_Presence.xml4
-rw-r--r--spec/Connection_Manager.xml2
-rw-r--r--spec/all.xml2
-rw-r--r--telepathy-glib/Makefile.am2
-rw-r--r--telepathy-glib/base-connection.c48
-rw-r--r--telepathy-glib/base-connection.h2
-rw-r--r--telepathy-glib/connection.xml1
-rw-r--r--telepathy-glib/contacts-mixin.c430
-rw-r--r--telepathy-glib/contacts-mixin.h111
-rw-r--r--telepathy-glib/extra-gtkdoc.h13
-rw-r--r--telepathy-glib/presence-mixin.c100
-rw-r--r--telepathy-glib/presence-mixin.h3
18 files changed, 818 insertions, 37 deletions
diff --git a/docs/reference/telepathy-glib-docs.sgml b/docs/reference/telepathy-glib-docs.sgml
index fbbe0b0c3..48ebe2944 100644
--- a/docs/reference/telepathy-glib-docs.sgml
+++ b/docs/reference/telepathy-glib-docs.sgml
@@ -31,6 +31,7 @@
<xi:include href="xml/connection.xml"/>
<xi:include href="xml/connection-aliasing.xml"/>
<xi:include href="xml/connection-avatars.xml"/>
+ <xi:include href="xml/connection-contacts.xml"/>
<xi:include href="xml/connection-caps.xml"/>
<xi:include href="xml/connection-simple-presence.xml"/>
<xi:include href="xml/connection-presence.xml"/>
@@ -64,6 +65,7 @@
<xi:include href="xml/base-connection-manager.xml"/>
<xi:include href="xml/base-connection.xml"/>
<xi:include href="xml/channel-factory-iface.xml"/>
+ <xi:include href="xml/contacts-mixin.xml"/>
<xi:include href="xml/dbus-properties-mixin.xml"/>
<xi:include href="xml/presence-mixin.xml"/>
<xi:include href="xml/properties-mixin.xml"/>
diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index 5ce6cbf92..7419edad6 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -43,6 +43,7 @@ tp_base_connection_finish_shutdown
tp_base_connection_add_interfaces
tp_base_connection_dbus_request_handles
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED
+tp_base_connection_register_with_contacts_mixin
<SUBSECTION Standard>
TP_BASE_CONNECTION
TP_IS_BASE_CONNECTION
@@ -604,6 +605,18 @@ TP_TYPE_SVC_CONNECTION
tp_svc_connection_get_type
TP_SVC_CONNECTION_GET_CLASS
<SUBSECTION>
+TpSvcConnectionInterfaceContacts
+TpSvcConnectionInterfaceContactsClass
+tp_svc_connection_interface_contacts_get_contact_attributes_impl
+tp_svc_connection_interface_contacts_implement_get_contact_attributes
+tp_svc_connection_interface_contacts_return_from_get_contact_attributes
+<SUBSECTION Standard>
+TP_IS_SVC_CONNECTION_INTERFACE_CONTACTS
+TP_SVC_CONNECTION_INTERFACE_CONTACTS
+TP_SVC_CONNECTION_INTERFACE_CONTACTS_GET_CLASS
+tp_svc_connection_interface_contacts_get_type
+TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS
+<SUBSECTION>
TpSvcConnectionInterfaceSimplePresence
TpSvcConnectionInterfaceSimplePresenceClass
tp_svc_connection_interface_simple_presence_emit_presences_changed
@@ -694,6 +707,9 @@ tp_svc_connection_interface_aliasing_return_from_get_alias_flags
tp_svc_connection_interface_aliasing_request_aliases_impl
tp_svc_connection_interface_aliasing_implement_request_aliases
tp_svc_connection_interface_aliasing_return_from_request_aliases
+tp_svc_connection_interface_aliasing_get_aliases_impl
+tp_svc_connection_interface_aliasing_implement_get_aliases
+tp_svc_connection_interface_aliasing_return_from_get_aliases
tp_svc_connection_interface_aliasing_set_aliases_impl
tp_svc_connection_interface_aliasing_implement_set_aliases
tp_svc_connection_interface_aliasing_return_from_set_aliases
@@ -870,6 +886,10 @@ TP_ARRAY_TYPE_CAPABILITY_PAIR_LIST
TP_STRUCT_TYPE_CONTACT_CAPABILITY
TP_ARRAY_TYPE_CONTACT_CAPABILITY_LIST
<SUBSECTION>
+# Connection - Contacts
+TP_HASH_TYPE_CONTACT_ATTRIBUTES_MAP
+TP_HASH_TYPE_SINGLE_CONTACT_ATTRIBUTES_MAP
+<SUBSECTION>
# Connection - SimplePresence
TP_HASH_TYPE_SIMPLE_CONTACT_PRESENCES
TP_HASH_TYPE_SIMPLE_STATUS_SPEC_MAP
@@ -947,6 +967,7 @@ tp_type_dbus_array_uuusa_7bsv_7du
tp_type_dbus_array_uuuuus
tp_type_dbus_array_uuuuuu
tp_type_dbus_array_uv
+tp_type_dbus_hash_ua_7bsv_7d
tp_type_dbus_hash_s_28ubba_7bss_7d_29
tp_type_dbus_hash_sa_7bsv_7d
tp_type_dbus_hash_s_28ubb_29
@@ -1066,6 +1087,36 @@ TP_PROPERTIES_MIXIN
</SECTION>
<SECTION>
+<INCLUDE>telepathy-glib/contacts-mixin.h</INCLUDE>
+<FILE>contacts-mixin</FILE>
+
+<TITLE>TpContactsMixin</TITLE>
+TpContactsMixin
+TpContactsMixinClass
+tp_contacts_mixin_add_contact_attributes_iface
+tp_contacts_mixin_class_get_offset_quark
+tp_contacts_mixin_class_init
+tp_contacts_mixin_finalize
+tp_contacts_mixin_get_offset_quark
+tp_contacts_mixin_iface_init
+tp_contacts_mixin_init
+tp_contacts_mixin_set_contact_attribute
+TpContactsMixinFillContactAttributesFunc
+<SUBSECTION Private>
+TP_CONTACTS_MIXIN_CLASS_OFFSET
+TP_CONTACTS_MIXIN_CLASS_OFFSET_QUARK
+TP_CONTACTS_MIXIN_OFFSET
+TP_CONTACTS_MIXIN_OFFSET_QUARK
+tp_contacts_mixin_class_get_offset_quark
+tp_contacts_mixin_get_offset_quark
+TpContactsMixinClassPrivate
+TpContactsMixinPrivate
+<SUBSECTION Standard>
+TP_CONTACTS_MIXIN_CLASS
+TP_CONTACTS_MIXIN
+</SECTION>
+
+<SECTION>
<INCLUDE>telepathy-glib/presence-mixin.h</INCLUDE>
<FILE>presence-mixin</FILE>
TpPresenceStatusOptionalArgumentSpec
@@ -1087,6 +1138,7 @@ tp_presence_mixin_emit_one_presence_update
tp_presence_mixin_iface_init
tp_presence_mixin_simple_presence_iface_init
tp_presence_mixin_simple_presence_init_dbus_properties
+tp_presence_mixin_simple_presence_register_with_contacts_mixin
<SUBSECTION Private>
TP_PRESENCE_MIXIN_CLASS_OFFSET_QUARK
TP_PRESENCE_MIXIN_CLASS_OFFSET
@@ -1473,6 +1525,8 @@ TP_IFACE_CONNECTION_INTERFACE_AVATARS
TP_IFACE_QUARK_CONNECTION_INTERFACE_AVATARS
TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES
TP_IFACE_QUARK_CONNECTION_INTERFACE_CAPABILITIES
+TP_IFACE_CONNECTION_INTERFACE_CONTACTS
+TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACTS
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE
TP_IFACE_QUARK_CONNECTION_INTERFACE_SIMPLE_PRESENCE
TP_IFACE_CONNECTION_INTERFACE_PRESENCE
@@ -1528,6 +1582,7 @@ tp_iface_quark_channel_type_tubes
tp_iface_quark_connection
tp_iface_quark_connection_interface_aliasing
tp_iface_quark_connection_interface_avatars
+tp_iface_quark_connection_interface_contacts
tp_iface_quark_connection_interface_capabilities
tp_iface_quark_connection_interface_simple_presence
tp_iface_quark_connection_interface_presence
@@ -1969,12 +2024,15 @@ tp_cli_connection_connect_to_status_changed
<INCLUDE>telepathy-glib/connection.h</INCLUDE>
tp_cli_connection_interface_aliasing_run_get_alias_flags
tp_cli_connection_interface_aliasing_run_request_aliases
+tp_cli_connection_interface_aliasing_run_get_aliases
tp_cli_connection_interface_aliasing_run_set_aliases
tp_cli_connection_interface_aliasing_call_get_alias_flags
tp_cli_connection_interface_aliasing_call_request_aliases
+tp_cli_connection_interface_aliasing_call_get_aliases
tp_cli_connection_interface_aliasing_call_set_aliases
tp_cli_connection_interface_aliasing_callback_for_get_alias_flags
tp_cli_connection_interface_aliasing_callback_for_request_aliases
+tp_cli_connection_interface_aliasing_callback_for_get_aliases
tp_cli_connection_interface_aliasing_callback_for_set_aliases
tp_cli_connection_interface_aliasing_connect_to_aliases_changed
tp_cli_connection_interface_aliasing_signal_callback_aliases_changed
@@ -2026,6 +2084,15 @@ tp_cli_connection_interface_capabilities_signal_callback_capabilities_changed
</SECTION>
<SECTION>
+<FILE>connection-contacts</FILE>
+<TITLE>connection-contacts</TITLE>
+<INCLUDE>telepathy-glib/connection.h</INCLUDE>
+tp_cli_connection_interface_contacts_call_get_contact_attributes
+tp_cli_connection_interface_contacts_callback_for_get_contact_attributes
+tp_cli_connection_interface_contacts_run_get_contact_attributes
+</SECTION>
+
+<SECTION>
<FILE>connection-simple-presence</FILE>
<TITLE>connection-simple-presence</TITLE>
<INCLUDE>telepathy-glib/connection.h</INCLUDE>
diff --git a/spec/Connection.xml b/spec/Connection.xml
index b350f140e..f5d914e07 100644
--- a/spec/Connection.xml
+++ b/spec/Connection.xml
@@ -100,7 +100,7 @@ USA.</p>
<tp:possible-errors>
<tp:error name="org.freedesktop.Telepathy.Error.Disconnected">
<tp:docstring>
- Before version 0.17.UNRELEASED calling GetInterfaces while
+ Before version 0.17.8 calling GetInterfaces while
on a connection that is not yet CONNECTED wasn't allowed. If a
CM returns this error, its list of interfaces should be regarded
as empty until it becomes CONNECTED.
@@ -657,9 +657,8 @@ USA.</p>
functionality, such as the Connection.Interface.Presence for receiving and
reporting presence information, and Connection.Interface.Aliasing for
connections where contacts may set and change an alias for themselves.
- These interfaces can be discovered using GetInterfaces after the
- connection, has been established and must not change subsequently at
- runtime.</p>
+ These interfaces can be discovered using the
+ <tp:member-ref>GetInterfaces</tp:member-ref> method.</p>
<p>Contacts, rooms, and server-stored lists (such as subscribed contacts,
block lists, or allow lists) on a service are all represented by
diff --git a/spec/Connection_Interface_Aliasing.xml b/spec/Connection_Interface_Aliasing.xml
index c975adfff..5f3a7df17 100644
--- a/spec/Connection_Interface_Aliasing.xml
+++ b/spec/Connection_Interface_Aliasing.xml
@@ -103,6 +103,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
<tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
</tp:possible-errors>
</method>
+ <method name="GetAliases">
+ <arg direction="in" name="contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of handles representing contacts
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a{us}" tp:type="Alias_Map">
+ <tp:docstring>
+ A dictionary mapping contact handles to aliases
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request the value of several contacts' aliases at once. This SHOULD
+ only return cached aliases, falling back on the handle name if none is
+ present. Also if there was no cached alias, a request SHOULD be started
+ of which the result is later signal by
+ <tp:member-ref>AliasesChanged</tp:member-ref>.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
<method name="SetAliases">
<arg direction="in" name="aliases" type="a{us}" tp:type="Alias_Map">
<tp:docstring>
diff --git a/spec/Connection_Interface_Capabilities.xml b/spec/Connection_Interface_Capabilities.xml
index 3e84c6b7b..95fbaafad 100644
--- a/spec/Connection_Interface_Capabilities.xml
+++ b/spec/Connection_Interface_Capabilities.xml
@@ -47,7 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
to them which are implemented by available client processes.</p>
</tp:docstring>
- <tp:changed version="0.17.UNRELEASED">Previously, this interface
+ <tp:changed version="0.17.8">Previously, this interface
also expressed capabilities of the connection itself, indicating what
sorts of channels could be requested (for instance, the ability to
open chatroom lists or chatrooms). However, this was never very
diff --git a/spec/Connection_Interface_Contacts.xml b/spec/Connection_Interface_Contacts.xml
index 3e3851169..327d80981 100644
--- a/spec/Connection_Interface_Contacts.xml
+++ b/spec/Connection_Interface_Contacts.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" ?>
-<node name="/Connection_Interface_Contact_Attributes" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+<node name="/Connection_Interface_Contacts" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<tp:copyright> Copyright (C) 2005-2008 Collabora Limited </tp:copyright>
<tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
<tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
@@ -18,8 +18,7 @@
along with this library; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
</tp:license>
- <interface name="org.freedesktop.Telepathy.Connection.Interface.Contacts.DRAFT"
- tp:causes-havoc="experimental">
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Contacts">
<tp:requires interface="org.freedesktop.Telepathy.Connection"/>
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
@@ -38,25 +37,29 @@
<dl>
<dt>org.freedesktop.Telepathy.Connection/contact-id
(type s)</dt>
- <dd>The same string that would be returned by <tp:dbus-ref
- namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>
+ <dd>The same string that would be returned by
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>
(always present in the result)
</dd>
<dt>org.freedesktop.Telepathy.Connection.Interface.Aliasing/alias
(type s)</dt>
- <dd>The contact's alias as defined by the <tp:dbus-ref
- namespace="org.freedesktop.Telepathy.Connection.Interface">Aliasing</tp:dbus-ref>
- interface (always present with some value, possibly the
+ <dd>The same string that would be returned by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Aliasing">GetAliases</tp:dbus-ref>
+ (always present with some value, possibly the
same as Connection/contact-id, if information from the
Aliasing interface was requested)
</dd>
<dt>org.freedesktop.Telepathy.Connection.Interface.Avatars/token
(type s</dt>
<dd>The same string that would be returned by <tp:dbus-ref
- namespace="org.freedesktop.Telepathy.Connection.Interface.Avatars">GetAvatarTokens</tp:dbus-ref>
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Avatars">GetKnownAvatarTokens</tp:dbus-ref>
(omitted from the result if the contact's avatar token is not known,
present as an empty string if the contact is known not to have
- an avatar)
+ an avatar). Unlike in the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Avatars">GetKnownAvatarTokens</tp:dbus-ref>
+ method, the avatar tokens for the self handle aren't required to be
+ present. This attribute should not be used to determine whether or
+ not the Avatar needs to be set.
</dd>
<dt>org.freedesktop.Telepathy.Connection.Interface.SimplePresence/presence
(type (uss), <tp:type>Simple_Presence</tp:type>)</dt>
@@ -109,7 +112,7 @@
</tp:mapping>
<tp:mapping name="Contact_Attributes_Map">
- <tp:docstring>Mapping returned by InspectContacts, representing a
+ <tp:docstring>Mapping returned by GetContactAttributes, representing a
collection of Contacts and their requested attributes.</tp:docstring>
<tp:member type="u" tp:type="Contact_Handle" name="Contact">
@@ -126,16 +129,16 @@
</tp:member>
</tp:mapping>
- <property name="InspectableInterfaces" access="read" type="as"
+ <property name="ContactAttributeInterfaces" access="read" type="as"
tp:type="DBus_Interface[]">
<tp:docstring>
A list of D-Bus interfaces for which
- <tp:member-ref>InspectContacts</tp:member-ref> is expected to work.
+ <tp:member-ref>GetContactAttributes</tp:member-ref> is expected to work.
This cannot change during the lifetime of the Connection.
</tp:docstring>
</property>
- <method name="InspectContacts">
+ <method name="GetContactAttributes">
<tp:docstring>
Return any number of contact attributes for the given handles.
</tp:docstring>
@@ -156,7 +159,8 @@
<p>It is an error to request interfaces that are not supported by
this Connection (i.e. mentioned in the
- <tp:member-ref>InspectableInterfaces</tp:member-ref> property).</p>
+ <tp:member-ref>ContactAttributeInterfaces</tp:member-ref>
+ property).</p>
<tp:rationale>
<p>This makes it possible to distinguish between interfaces for
@@ -215,7 +219,7 @@
<tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
<tp:docstring>
One of the requested interfaces is not supported (mentioned in
- <tp:member-ref>InspectableInterfaces</tp:member-ref>).
+ <tp:member-ref>ContactAttributeInterfaces</tp:member-ref>).
</tp:docstring>
</tp:error>
</tp:possible-errors>
diff --git a/spec/Connection_Interface_Presence.xml b/spec/Connection_Interface_Presence.xml
index 489ac238a..4ba59b631 100644
--- a/spec/Connection_Interface_Presence.xml
+++ b/spec/Connection_Interface_Presence.xml
@@ -367,14 +367,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
</tp:docstring>
</tp:enumvalue>
<tp:enumvalue suffix="Unknown" value="7">
- <tp:added version="0.17.UNRELEASED"/>
+ <tp:added version="0.17.8"/>
<tp:docstring>
Unknown, unable to determine presence for this contact, for example
if the protocol only allows presence of subscribed contacts.
</tp:docstring>
</tp:enumvalue>
<tp:enumvalue suffix="Error" value="8">
- <tp:added version="0.17.UNRELEASED"/>
+ <tp:added version="0.17.8"/>
<tp:docstring>
Error, an error occurred while trying to determine presence. The
message, if set, is an error from the server.
diff --git a/spec/Connection_Manager.xml b/spec/Connection_Manager.xml
index 760e57476..33f1ede45 100644
--- a/spec/Connection_Manager.xml
+++ b/spec/Connection_Manager.xml
@@ -334,7 +334,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
this property fails, clients SHOULD assume that its value is
an empty list.</p>
</tp:docstring>
- <tp:added version="0.17.UNRELEASED"/>
+ <tp:added version="0.17.8"/>
</property>
<!-- FIXME: One thing we could perhaps use Interfaces for would be a
diff --git a/spec/all.xml b/spec/all.xml
index 1a620d977..586beb331 100644
--- a/spec/all.xml
+++ b/spec/all.xml
@@ -3,7 +3,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude">
<tp:title>Telepathy D-Bus Interface Specification</tp:title>
-<tp:version>0.17.8</tp:version>
+<tp:version>0.17.8.1</tp:version>
<tp:copyright>Copyright (C) 2005-2008 Collabora Limited</tp:copyright>
<tp:copyright>Copyright (C) 2005-2008 Nokia Corporation</tp:copyright>
diff --git a/telepathy-glib/Makefile.am b/telepathy-glib/Makefile.am
index 5e53f545b..2f2757a18 100644
--- a/telepathy-glib/Makefile.am
+++ b/telepathy-glib/Makefile.am
@@ -103,6 +103,7 @@ tpginclude_HEADERS = \
media-interfaces.h \
connection.h \
connection-manager.h \
+ contacts-mixin.h \
dbus.h \
dbus-properties-mixin.h \
defs.h \
@@ -205,6 +206,7 @@ libtelepathy_glib_internal_la_SOURCES = \
channel-internal.h \
connection.c \
connection-manager.c \
+ contacts-mixin.c \
dbus.c \
dbus-internal.h \
dbus-properties-mixin.c \
diff --git a/telepathy-glib/base-connection.c b/telepathy-glib/base-connection.c
index 7a8ac6913..d367ce339 100644
--- a/telepathy-glib/base-connection.c
+++ b/telepathy-glib/base-connection.c
@@ -42,10 +42,12 @@
#include <dbus/dbus-glib-lowlevel.h>
#include <telepathy-glib/connection-manager.h>
+#include <telepathy-glib/contacts-mixin.h>
#include <telepathy-glib/channel-factory-iface.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/util.h>
+#include <telepathy-glib/interfaces.h>
#define DEBUG_FLAG TP_DEBUG_CONNECTION
#include "debug-internal.h"
@@ -1719,3 +1721,49 @@ service_iface_init (gpointer g_iface, gpointer iface_data)
IMPLEMENT(dbus_,request_handles);
#undef IMPLEMENT
}
+
+static void
+tp_base_connection_fill_contact_attributes (GObject *obj,
+ const GArray *contacts, GHashTable *attributes_hash)
+{
+ TpBaseConnection *self = TP_BASE_CONNECTION (obj);
+ TpBaseConnectionPrivate *priv =
+ TP_BASE_CONNECTION_GET_PRIVATE (self);
+ guint i;
+
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpHandle handle;
+ const gchar *tmp;
+ GValue *val;
+
+
+ handle = g_array_index (contacts, TpHandle, i);
+ tmp = tp_handle_inspect (priv->handles[TP_HANDLE_TYPE_CONTACT], handle);
+ g_assert (tmp != NULL);
+
+ val = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_static_string (val, tmp);
+
+ tp_contacts_mixin_set_contact_attribute (attributes_hash,
+ handle, TP_IFACE_CONNECTION"/contact-id", val);
+ }
+}
+
+/**
+ * tp_base_connection_register_with_contacts_mixin:
+ * @self: An instance of the #TpBaseConnections that uses the Contacts
+ * mixin
+ *
+ * Register the Connection interface with the Contacts interface to make it
+ * inspectable. The Contacts mixin should be initialized before this function
+ * is called
+ */
+void
+tp_base_connection_register_with_contacts_mixin (TpBaseConnection *self)
+{
+ tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (self),
+ TP_IFACE_CONNECTION,
+ tp_base_connection_fill_contact_attributes);
+}
+
diff --git a/telepathy-glib/base-connection.h b/telepathy-glib/base-connection.h
index ab4f215a7..cad945a8e 100644
--- a/telepathy-glib/base-connection.h
+++ b/telepathy-glib/base-connection.h
@@ -263,6 +263,8 @@ void tp_base_connection_add_interfaces (TpBaseConnection *self,
void tp_base_connection_dbus_request_handles (TpSvcConnection *iface,
guint handle_type, const gchar **names, DBusGMethodInvocation *context);
+void tp_base_connection_register_with_contacts_mixin (TpBaseConnection *self);
+
/* TYPE MACROS */
#define TP_TYPE_BASE_CONNECTION \
(tp_base_connection_get_type ())
diff --git a/telepathy-glib/connection.xml b/telepathy-glib/connection.xml
index f2790884b..d3df19242 100644
--- a/telepathy-glib/connection.xml
+++ b/telepathy-glib/connection.xml
@@ -11,5 +11,6 @@
<xi:include href="../spec/Connection_Interface_Capabilities.xml"/>
<xi:include href="../spec/Connection_Interface_Simple_Presence.xml"/>
<xi:include href="../spec/Connection_Interface_Presence.xml"/>
+<xi:include href="../spec/Connection_Interface_Contacts.xml"/>
</tp:spec>
diff --git a/telepathy-glib/contacts-mixin.c b/telepathy-glib/contacts-mixin.c
new file mode 100644
index 000000000..c6da33f7b
--- /dev/null
+++ b/telepathy-glib/contacts-mixin.c
@@ -0,0 +1,430 @@
+/*
+ * contacts-mixin.c - Source for TpContactsMixin
+ * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008 Nokia Corporation
+ * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * SECTION:contacts-mixin
+ * @title: TpContactsMixin
+ * @short_description: a mixin implementation of the contacts connection
+ * interface
+ * @see_also: #TpSvcConnectionInterfaceContacts
+ *
+ * This mixin can be added to a #TpBaseConnection subclass to implement the
+ * Contacts interface in a generic way.
+ *
+ * To use the contacts mixin, include a #TpContactsMixinClass somewhere in
+ * your class structure and a #TpContactsMixin somewhere in your instance
+ * structure, and call tp_contacts_mixin_class_init() from your class_init
+ * function, tp_contacts_mixin_init() from your init function or constructor,
+ * and tp_contacts_mixin_finalize() from your dispose or finalize function.
+ *
+ * To use the contacts mixin as the implementation of
+ * #TpSvcConnectionInterfaceContacts, in the function you pass to
+ * G_IMPLEMENT_INTERFACE, you should call tp_contacts_mixin_iface_init.
+ * TpContactsMixin implements all of the D-Bus methods and properties in the
+ * Contacts interface.
+ *
+ * To add interfaces with contact attributes to this interface use
+ * tp_contacts_mixin_add_contact_attributes_iface:
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+
+#include <telepathy-glib/contacts-mixin.h>
+
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib.h>
+
+#include <telepathy-glib/base-connection.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/enums.h>
+#include <telepathy-glib/errors.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/interfaces.h>
+
+#define DEBUG_FLAG TP_DEBUG_CONNECTION
+
+#include "debug-internal.h"
+
+struct _TpContactsMixinPrivate
+{
+ /* String interface name -> FillContactAttributes func */
+ GHashTable *interfaces;
+};
+
+enum {
+ MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES,
+ NUM_MIXIN_CONTACTS_DBUS_PROPERTIES
+};
+
+static TpDBusPropertiesMixinPropImpl known_contacts_props[] = {
+ { "ContactAttributeInterfaces", NULL, NULL },
+ { NULL }
+};
+
+static void
+tp_presence_mixin_get_contacts_dbus_property (GObject *object,
+ GQuark interface,
+ GQuark name,
+ GValue *value,
+ gpointer unused
+ G_GNUC_UNUSED)
+{
+ static GQuark q[NUM_MIXIN_CONTACTS_DBUS_PROPERTIES] = { 0, };
+ TpContactsMixin *self = TP_CONTACTS_MIXIN (object);
+
+ DEBUG ("called.");
+
+ if (G_UNLIKELY (q[0] == 0))
+ {
+ q[MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES] =
+ g_quark_from_static_string ("ContactAttributeInterfaces");
+ }
+
+ g_return_if_fail (object != NULL);
+
+ if (name == q[MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES])
+ {
+ gchar **interfaces;
+ GHashTableIter iter;
+ gpointer key;
+ int i = 0;
+
+ g_assert (G_VALUE_HOLDS(value, G_TYPE_STRV));
+
+ /* FIXME, cache this when connected ? */
+ interfaces = g_malloc0(
+ (g_hash_table_size (self->priv->interfaces) + 1) * sizeof (gchar *));
+
+ g_hash_table_iter_init (&iter, self->priv->interfaces);
+ while (g_hash_table_iter_next (&iter, &key, NULL))
+ {
+ interfaces[i] = g_strdup ((gchar *) key);
+ i++;
+ }
+ g_value_take_boxed (value, interfaces);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+}
+
+
+/**
+ * tp_contacts_mixin_class_get_offset_quark:
+ *
+ * <!--no documentation beyond Returns: needed-->
+ *
+ * Returns: the quark used for storing mixin offset on a GObjectClass
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+GQuark
+tp_contacts_mixin_class_get_offset_quark ()
+{
+ static GQuark offset_quark = 0;
+
+ if (G_UNLIKELY (offset_quark == 0))
+ offset_quark = g_quark_from_static_string (
+ "TpContactsMixinClassOffsetQuark");
+
+ return offset_quark;
+}
+
+/**
+ * tp_contacts_mixin_get_offset_quark:
+ *
+ * <!--no documentation beyond Returns: needed-->
+ *
+ * Returns: the quark used for storing mixin offset on a GObject
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+GQuark
+tp_contacts_mixin_get_offset_quark ()
+{
+ static GQuark offset_quark = 0;
+
+ if (G_UNLIKELY (offset_quark == 0))
+ offset_quark = g_quark_from_static_string ("TpContactsMixinOffsetQuark");
+
+ return offset_quark;
+}
+
+
+/**
+ * tp_contacts_mixin_class_init:
+ * @obj_cls: The class of the implementation that uses this mixin
+ * @offset: The byte offset of the TpContactsMixinClass within the class
+ * structure
+ *
+ * Initialize the contacts mixin. Should be called from the implementation's
+ * class_init function like so:
+ *
+ * <informalexample><programlisting>
+ * tp_contacts_mixin_class_init ((GObjectClass *)klass,
+ * G_STRUCT_OFFSET (SomeObjectClass, contacts_mixin));
+ * </programlisting></informalexample>
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+
+void
+tp_contacts_mixin_class_init (GObjectClass *obj_cls, glong offset)
+{
+ TpContactsMixinClass *mixin_cls;
+
+ g_assert (G_IS_OBJECT_CLASS (obj_cls));
+
+ g_type_set_qdata (G_OBJECT_CLASS_TYPE (obj_cls),
+ TP_CONTACTS_MIXIN_CLASS_OFFSET_QUARK,
+ GINT_TO_POINTER (offset));
+
+ mixin_cls = TP_CONTACTS_MIXIN_CLASS (obj_cls);
+
+ tp_dbus_properties_mixin_implement_interface (obj_cls,
+ TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACTS,
+ tp_presence_mixin_get_contacts_dbus_property,
+ NULL, known_contacts_props);
+}
+
+
+/**
+ * tp_contacts_mixin_init:
+ * @obj: An instance of the implementation that uses this mixin
+ * @offset: The byte offset of the TpContactsMixin within the object structure
+ *
+ * Initialize the text mixin. Should be called from the implementation's
+ * instance init function like so:
+ *
+ * <informalexample><programlisting>
+ * tp_contacts_mixin_init ((GObject *)self,
+ * G_STRUCT_OFFSET (SomeObject, text_mixin));
+ * </programlisting></informalexample>
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+void
+tp_contacts_mixin_init (GObject *obj, gsize offset)
+{
+ TpContactsMixin *mixin;
+
+ g_assert (G_IS_OBJECT (obj));
+
+ g_type_set_qdata (G_OBJECT_TYPE (obj),
+ TP_CONTACTS_MIXIN_OFFSET_QUARK,
+ GSIZE_TO_POINTER (offset));
+
+ mixin = TP_CONTACTS_MIXIN (obj);
+
+ mixin->priv = g_slice_new0 (TpContactsMixinPrivate);
+ mixin->priv->interfaces = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+}
+
+/**
+ * tp_contacts_mixin_finalize:
+ * @obj: An object with this mixin.
+ *
+ * Free resources held by the contacts mixin.
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+void
+tp_contacts_mixin_finalize (GObject *obj)
+{
+ TpContactsMixin *mixin = TP_CONTACTS_MIXIN (obj);
+
+ DEBUG ("%p", obj);
+
+ /* free any data held directly by the object here */
+ g_hash_table_destroy (mixin->priv->interfaces);
+ g_slice_free (TpContactsMixinPrivate, mixin->priv);
+}
+
+static void
+tp_contacts_mixin_get_contact_attributes (
+ TpSvcConnectionInterfaceContacts *iface, const GArray *handles,
+ const char **interfaces, gboolean hold, DBusGMethodInvocation *context)
+{
+ TpContactsMixin *self = TP_CONTACTS_MIXIN (iface);
+ GHashTable *result;
+ guint i;
+ TpBaseConnection *conn = TP_BASE_CONNECTION (iface);
+ TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
+ TP_HANDLE_TYPE_CONTACT);
+ GArray *valid_handles;
+
+ TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (conn, context);
+
+ /* first validate the given interfaces */
+ for (i = 0; interfaces[i] != NULL; i++) {
+ if (g_hash_table_lookup (self->priv->interfaces, interfaces[i]) == NULL)
+ {
+ GError einval = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Non-inspectable Interface given" };
+
+ dbus_g_method_return_error (context, &einval);
+ return;
+ }
+ }
+
+
+ /* Setup handle array and hash with valid handles, optionally holding them */
+ valid_handles = g_array_sized_new (TRUE, TRUE, sizeof(TpHandle),
+ handles->len);
+ result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
+ (GDestroyNotify) g_hash_table_destroy);
+
+ for (i = 0 ; i < handles->len ; i++)
+ {
+ TpHandle h;
+ h = g_array_index (handles, TpHandle, i);
+ if (tp_handle_is_valid (contact_repo, h, NULL))
+ {
+ GHashTable *attr_hash = g_hash_table_new_full (g_str_hash,
+ g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free);
+ g_array_append_val (valid_handles, h);
+ g_hash_table_insert (result, GUINT_TO_POINTER(h), attr_hash);
+ }
+ }
+
+ if (hold)
+ {
+ gchar *sender = dbus_g_method_get_sender (context);
+ tp_handles_client_hold (contact_repo, sender, valid_handles, NULL);
+ }
+
+ /* ensure the handles don't disappear while calling out to various functions
+ */
+ tp_handles_ref (contact_repo, valid_handles);
+
+ for (i = 0; interfaces[i] != NULL; i++)
+ {
+ TpContactsMixinFillContactAttributesFunc func;
+
+ func = g_hash_table_lookup (self->priv->interfaces, interfaces[i]);
+
+ g_assert (func != NULL);
+
+ func (G_OBJECT(iface), valid_handles, result);
+ }
+
+ tp_svc_connection_interface_contacts_return_from_get_contact_attributes (
+ context, result);
+
+ g_hash_table_destroy (result);
+
+ tp_handles_unref (contact_repo, valid_handles);
+}
+
+/**
+ * tp_contacts_mixin_iface_init:
+ * @g_iface: A pointer to the #TpSvcConnectionInterfaceContacts in an object
+ * class
+ * @iface_data: Ignored
+ *
+ * Fill in the vtable entries needed to implement the contacts interface
+ * using this mixin. This function should usually be called via
+ * G_IMPLEMENT_INTERFACE.
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+void
+tp_contacts_mixin_iface_init (gpointer g_iface, gpointer iface_data)
+{
+ TpSvcConnectionInterfaceContactsClass *klass =
+ (TpSvcConnectionInterfaceContactsClass *) g_iface;
+
+#define IMPLEMENT(x) tp_svc_connection_interface_contacts_implement_##x ( \
+ klass, tp_contacts_mixin_##x)
+ IMPLEMENT(get_contact_attributes);
+#undef IMPLEMENT
+}
+
+/**
+ * tp_contacts_mixin_add_contact_attributes_iface:
+ * @obj: An instance of the implementation that uses this mixin
+ * @interface: Name of the interface that has ContactAttributes
+ * @fill_contact_attributes: Contact attribute filler function
+ *
+ * Declare that the given interface has contact attributes which can be added
+ * to the attributes hash using the filler function. All the handles in the
+ * handle array passed to the filler function are guaranteed to be valid and
+ * referenced.
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+
+void
+tp_contacts_mixin_add_contact_attributes_iface (GObject *obj,
+ const gchar *interface,
+ TpContactsMixinFillContactAttributesFunc fill_contact_attributes)
+{
+ TpContactsMixin *self = TP_CONTACTS_MIXIN (obj);
+
+ g_assert (g_hash_table_lookup (self->priv->interfaces, interface) == NULL);
+ g_assert (fill_contact_attributes != NULL);
+
+ g_hash_table_insert (self->priv->interfaces, g_strdup (interface),
+ fill_contact_attributes);
+}
+
+/**
+ * tp_contacts_mixin_set_contact_attribute:
+ * @contact_attributes: contacts attribute hash as passed to
+ * TpContactsMixinFillContactAttributesFunc
+ * @handle: Handle to set the attribute on
+ * @attribute: attribute name
+ * @value: slice allocated GValue containing the value of the attribute, for
+ * instance with tp_g_value_slice_new. Ownership of the GValue is taken over by
+ * the mixin
+ *
+ * Utility function to set attribute for handle to value in the attributes hash
+ * as passed to a TpContactsMixinFillContactAttributesFunc.
+ *
+ * Since: 0.7.UNRELEASED
+ *
+ */
+
+void
+tp_contacts_mixin_set_contact_attribute (GHashTable *contact_attributes,
+ TpHandle handle, gchar *attribute, GValue *value)
+{
+ GHashTable *attributes;
+
+ attributes = g_hash_table_lookup (contact_attributes,
+ GUINT_TO_POINTER (handle));
+
+ g_assert (attributes != NULL);
+ g_assert (G_IS_VALUE (value));
+
+ g_hash_table_insert (attributes, g_strdup (attribute), value);
+}
+
diff --git a/telepathy-glib/contacts-mixin.h b/telepathy-glib/contacts-mixin.h
new file mode 100644
index 000000000..f374932f9
--- /dev/null
+++ b/telepathy-glib/contacts-mixin.h
@@ -0,0 +1,111 @@
+/*
+ * contacts-mixin.h - Header for TpContactsMixin
+ * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TP_CONTACTS_MIXIN_H__
+#define __TP_CONTACTS_MIXIN_H__
+
+#include <telepathy-glib/svc-connection.h>
+#include <telepathy-glib/handle-repo.h>
+
+#include "util.h"
+
+G_BEGIN_DECLS
+
+typedef struct _TpContactsMixinClass TpContactsMixinClass;
+typedef struct _TpContactsMixinClassPrivate TpContactsMixinClassPrivate;
+typedef struct _TpContactsMixin TpContactsMixin;
+typedef struct _TpContactsMixinPrivate TpContactsMixinPrivate;
+
+/**
+ * TpContactsMixinFillContactAttributesFunc:
+ * @obj: An object implementing the presence interface with this mixin
+ * @contacts: The contacts for which attributes are requested
+ * @attributes_hash: hash of handle => hash of attributes, containing all the
+ * contacts in the contacts array
+ *
+ * This function is called to add attributes of contacts
+ *
+ */
+typedef void (*TpContactsMixinFillContactAttributesFunc) (GObject *obj,
+ const GArray *contacts, GHashTable *attributes_hash);
+
+/**
+ * TpContactsMixinClass:
+ *
+ * Structure to be included in the class structure of objects that
+ * use this mixin. Initialize it with tp_contacts_mixin_class_init().
+ *
+ * There are no public fields.
+ */
+struct _TpContactsMixinClass {
+ /*<private>*/
+ TpContactsMixinClassPrivate *priv;
+};
+
+/**
+ * TpContactsMixin:
+ *
+ * Structure to be included in the instance structure of objects that
+ * use this mixin. Initialize it with tp_contacts_mixin_init().
+ *
+ * There are no public fields.
+ */
+struct _TpContactsMixin {
+ /*<private>*/
+ TpContactsMixinPrivate *priv;
+};
+
+/* TYPE MACROS */
+#define TP_CONTACTS_MIXIN_CLASS_OFFSET_QUARK \
+ (tp_contacts_mixin_class_get_offset_quark ())
+#define TP_CONTACTS_MIXIN_CLASS_OFFSET(o) \
+ (GPOINTER_TO_UINT (g_type_get_qdata (G_OBJECT_CLASS_TYPE (o), \
+ TP_CONTACTS_MIXIN_CLASS_OFFSET_QUARK)))
+#define TP_CONTACTS_MIXIN_CLASS(o) \
+ ((TpContactsMixinClass *) tp_mixin_offset_cast (o, \
+ TP_CONTACTS_MIXIN_CLASS_OFFSET (o)))
+
+#define TP_CONTACTS_MIXIN_OFFSET_QUARK (tp_contacts_mixin_get_offset_quark ())
+#define TP_CONTACTS_MIXIN_OFFSET(o) \
+ (GPOINTER_TO_UINT (g_type_get_qdata (G_OBJECT_TYPE (o), \
+ TP_CONTACTS_MIXIN_OFFSET_QUARK)))
+#define TP_CONTACTS_MIXIN(o) \
+ ((TpContactsMixin *) tp_mixin_offset_cast (o, TP_CONTACTS_MIXIN_OFFSET (o)))
+
+GQuark tp_contacts_mixin_class_get_offset_quark (void);
+GQuark tp_contacts_mixin_get_offset_quark (void);
+
+void tp_contacts_mixin_class_init (GObjectClass *obj_cls, glong offset);
+
+void tp_contacts_mixin_init (GObject *obj, gsize offset);
+void tp_contacts_mixin_finalize (GObject *obj);
+
+void tp_contacts_mixin_iface_init (gpointer g_iface, gpointer iface_data);
+
+void tp_contacts_mixin_add_contact_attributes_iface (GObject *obj,
+ const gchar *interface,
+ TpContactsMixinFillContactAttributesFunc fill_contact_attributes);
+
+void tp_contacts_mixin_set_contact_attribute (GHashTable *contact_attributes,
+ TpHandle handle, gchar *attribute, GValue *value);
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_CONTACTS_MIXIN_H__ */
diff --git a/telepathy-glib/extra-gtkdoc.h b/telepathy-glib/extra-gtkdoc.h
index 967698374..9607c30e4 100644
--- a/telepathy-glib/extra-gtkdoc.h
+++ b/telepathy-glib/extra-gtkdoc.h
@@ -398,6 +398,19 @@
*/
/**
+ * SECTION:connection-contacts
+ * @title: Connection Contacts interface
+ * @short_description: client-side wrappers for the Contacts interface
+ * @see_also: #TpConnection
+ *
+ * This interface allows a client to get information from various connection
+ * interfaces in one dbus call.
+ *
+ * This section documents the auto-generated C wrappers for the
+ * Contacts interface, used with #TpConnection objects.
+ */
+
+/**
* SECTION:connection-simple-presence
* @title: Connection SimplePresence interface
* @short_description: client-side wrappers for the SimplePresence interface
diff --git a/telepathy-glib/presence-mixin.c b/telepathy-glib/presence-mixin.c
index 76cd0a5a6..ec5d136ea 100644
--- a/telepathy-glib/presence-mixin.c
+++ b/telepathy-glib/presence-mixin.c
@@ -72,6 +72,7 @@
#include <telepathy-glib/errors.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/contacts-mixin.h>
#define DEBUG_FLAG TP_DEBUG_PRESENCE
@@ -1164,22 +1165,17 @@ out:
g_hash_table_destroy (optional_arguments);
}
-static void
-construct_simple_presence_hash_foreach (gpointer key,
- gpointer value,
- gpointer user_data)
+static GValueArray *
+construct_simple_presence_value_array (TpPresenceStatus *status,
+ const TpPresenceStatusSpec *supported_statuses)
{
- TpHandle handle = GPOINTER_TO_UINT (key);
- TpPresenceStatus *status = (TpPresenceStatus *) value;
- struct _i_absolutely_love_g_hash_table_foreach *data =
- (struct _i_absolutely_love_g_hash_table_foreach *) user_data;
- GValueArray *presence;
- const gchar *status_name;
TpConnectionPresenceType status_type;
+ const gchar *status_name;
const gchar *message = NULL;
+ GValueArray *presence;
- status_name = data->supported_statuses[status->index].name;
- status_type = data->supported_statuses[status->index].presence_type;
+ status_name = supported_statuses[status->index].name;
+ status_type = supported_statuses[status->index].presence_type;
if (status->optional_arguments != NULL)
{
@@ -1206,6 +1202,23 @@ construct_simple_presence_hash_foreach (gpointer key,
g_value_init (g_value_array_get_nth (presence, 2), G_TYPE_STRING);
g_value_set_string (g_value_array_get_nth (presence, 2), message);
+ return presence;
+}
+
+static void
+construct_simple_presence_hash_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ TpHandle handle = GPOINTER_TO_UINT (key);
+ TpPresenceStatus *status = (TpPresenceStatus *) value;
+ struct _i_absolutely_love_g_hash_table_foreach *data =
+ (struct _i_absolutely_love_g_hash_table_foreach *) user_data;
+ GValueArray *presence;
+
+ presence = construct_simple_presence_value_array (status,
+ data->supported_statuses);
+
g_hash_table_insert (data->presence_hash, GUINT_TO_POINTER (handle),
presence);
}
@@ -1315,3 +1328,66 @@ tp_presence_mixin_simple_presence_iface_init (gpointer g_iface,
IMPLEMENT(get_presences);
#undef IMPLEMENT
}
+
+static void
+simple_presence_fill_contact_attributes_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ TpHandle handle = GPOINTER_TO_UINT (key);
+ TpPresenceStatus *status = (TpPresenceStatus *) value;
+ struct _i_absolutely_love_g_hash_table_foreach *data =
+ (struct _i_absolutely_love_g_hash_table_foreach *) user_data;
+ GValue *val;
+ GValueArray *presence;
+
+ presence = construct_simple_presence_value_array (status,
+ data->supported_statuses);
+
+ val = tp_g_value_slice_new (G_TYPE_VALUE_ARRAY);
+ g_value_set_boxed (val, presence);
+
+ tp_contacts_mixin_set_contact_attribute (data->presence_hash,
+ handle,
+ TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE"/presence",
+ val);
+}
+
+static void
+tp_presence_mixin_simple_presence_fill_contact_attributes (GObject *obj,
+ const GArray *contacts, GHashTable *attributes_hash)
+{
+ TpPresenceMixinClass *mixin_cls =
+ TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (obj));
+ struct _i_absolutely_love_g_hash_table_foreach data = {
+ mixin_cls->statuses, NULL, attributes_hash };
+ GHashTable *contact_statuses;
+
+ contact_statuses = mixin_cls->get_contact_statuses (obj, contacts, NULL);
+
+ g_assert (contact_statuses != NULL);
+
+ data.contact_statuses = contact_statuses;
+ g_hash_table_foreach (contact_statuses,
+ simple_presence_fill_contact_attributes_foreach, &data);
+
+ g_hash_table_destroy (contact_statuses);
+}
+
+/**
+ * tp_presence_mixin_simple_presence_register_with_contacts_mixin:
+ * @obj: An instance that of the implementation that uses both the Contacts
+ * mixin and this mixin
+ *
+ * Register the SimplePresence interface with the Contacts interface to make it
+ * inspectable. The Contacts mixin should be initialized before this function
+ * is called
+ */
+void
+tp_presence_mixin_simple_presence_register_with_contacts_mixin (GObject *obj)
+{
+ tp_contacts_mixin_add_contact_attributes_iface (obj,
+ TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
+ tp_presence_mixin_simple_presence_fill_contact_attributes);
+}
+
diff --git a/telepathy-glib/presence-mixin.h b/telepathy-glib/presence-mixin.h
index 00f7b66f6..37ad7ded9 100644
--- a/telepathy-glib/presence-mixin.h
+++ b/telepathy-glib/presence-mixin.h
@@ -259,6 +259,9 @@ void tp_presence_mixin_iface_init (gpointer g_iface, gpointer iface_data);
void tp_presence_mixin_simple_presence_iface_init (gpointer g_iface, gpointer iface_data);
void tp_presence_mixin_simple_presence_init_dbus_properties (GObjectClass *cls);
+void tp_presence_mixin_simple_presence_register_with_contacts_mixin (
+ GObject *obj);
+
G_END_DECLS
#endif /* #ifndef __TP_PRESENCE_MIXIN_H__ */