[telepathy-doc/master] Beginning of a section on services
Davyd Madeley
davyd at madeley.id.au
Sat Aug 1 03:24:50 PDT 2009
---
docs/book/C/channel-dispatcher.xml | 40 ++++--
docs/book/C/services.xml | 146 ++++++++++++++++++++
docs/book/C/telepathy.xml | 2 +
docs/book/Makefile.am | 3 +-
docs/examples/glib_mc5_observer/example-observer.c | 4 +
5 files changed, 184 insertions(+), 11 deletions(-)
create mode 100644 docs/book/C/services.xml
diff --git a/docs/book/C/channel-dispatcher.xml b/docs/book/C/channel-dispatcher.xml
index 280d602..afed8f8 100644
--- a/docs/book/C/channel-dispatcher.xml
+++ b/docs/book/C/channel-dispatcher.xml
@@ -55,7 +55,10 @@
a user's session bus. Every running or activatable Telepathy client must
provide a D-Bus well-known name of the form
<literal>org.freedesktop.Telepathy.Client.clientname</literal>
- (e.g. <literal>org.freedesktop.Telepathy.Client.Empathy</literal>).
+ (e.g. <literal>org.freedesktop.Telepathy.Client.Empathy</literal>) and
+ an object with path of the form
+ <literal>/org/freedesktop/Telepathy/Client/clientname</literal>
+ (e.g. <literal>/org/freedesktop/Telepathy/Client/Empathy</literal>).
</para>
<note>
@@ -116,14 +119,31 @@
acknowledging text messages.
</para>
- <para>
- All Telepathy clients must implement the
- <interfacename>org.freedesktop.Telepathy.Client</interfacename>
- interface plus (at least) one of
- <interfacename>org.freedesktop.Telepathy.Client.Observer</interfacename>,
- <interfacename>org.freedesktop.Telepathy.Client.Approver</interfacename>
- or
- <interfacename>org.freedesktop.Telepathy.Client.Handler</interfacename>.
- </para>
+ <sect2 id="sect.channel-dispatcher.clients.impl">
+ <title>Implementing a Telepathy Client</title>
+
+ <para>
+ Telepathy clients are services that implement a D-Bus API which is
+ called by the Channel Dispatcher (just as the client itself makes
+ method calls to the Account Manager and Connection Managers).
+ </para>
+
+ <para>
+ All Telepathy clients must implement the
+ <interfacename>org.freedesktop.Telepathy.Client</interfacename>
+ interface plus (at least) one of
+ <interfacename>org.freedesktop.Telepathy.Client.Observer</interfacename>,
+ <interfacename>org.freedesktop.Telepathy.Client.Approver</interfacename>
+ or
+ <interfacename>org.freedesktop.Telepathy.Client.Handler</interfacename>.
+ </para>
+
+ <para>
+ The various Telepathy binding APIs provide straightforward procedures
+ for implementing a Telepathy service (such as a Client). These methods
+ are documented in <xref linkend="chapter.services"/>.
+ </para>
+
+ </sect2>
</sect1>
</chapter>
diff --git a/docs/book/C/services.xml b/docs/book/C/services.xml
new file mode 100644
index 0000000..1307a78
--- /dev/null
+++ b/docs/book/C/services.xml
@@ -0,0 +1,146 @@
+<?xml version='1.0'?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+ <!ENTITY mdash "—">
+ <!ENTITY ellipsis "…">
+]>
+
+<chapter id="chapter.services">
+ <title>Implementing Telepathy Services</title>
+
+ <para>
+ Occasionally you may wish to implement your own Telepathy service, a
+ program that implements a Telepathy API interface (most commonly this
+ will be <interfacename>org.freedesktop.Telepathy.Client</interfacename>,
+ but maybe you will be implement a Connection Manager, or some other
+ Telepathy interface).
+ </para>
+ <para>
+ This is done by implementing the D-Bus API for each interface as
+ detailed in the
+ <ulink url="http://telepathy.freedesktop.org/spec/">Telepathy
+ Specification</ulink>. To make this simpler, the various Telepathy API
+ bindings provide support for writing Telepathy services.
+ </para>
+
+ <sect1 id="sect.services.glib">
+ <title>telepathy-glib</title>
+
+ <important>
+ <title>Implementing GObjects</title>
+ <para>
+ This section of the manual assumes that you're already familiar with
+ implementing a GObject in the C programming language. If you're not, we
+ recommend reading the FIXME NEED SOME RESOURCES HERE.
+ </para>
+ </important>
+
+ <para>
+ The <application>telepathy-glib</application> bindings provide a
+ mechanism for implementing D-Bus interfaces as
+ <classname>GInterface</classname> interfaces on a
+ <classname>GObject</classname>. These interfaces begin with the
+ namespace <classname>TpSvc</classname>&ellipsis; and have GTypes beginning
+ with <type>TP_TYPE_SVC_</type>&ellipsis;.
+ </para>
+
+ <para>
+ <application>telepathy-glib</application> also provides class mixins
+ that can be used to implement support for functionality such as D-Bus
+ properties and other Telepathy interfaces.
+ </para>
+
+ <para>
+ <classname>GObject</classname>s that implement these interfaces and
+ mixins can be published via D-Bus using the standard
+ <application>dbus-glib</application> function call
+ <function>dbus_g_connection_register_g_object</function>.
+ </para>
+
+ <sect2 id="sect.services.glib.iface">
+ <title>Implementing a D-Bus Interface</title>
+
+ <para>
+ D-Bus method interfaces are provided by
+ <application>telepathy-glib</application> as regular GInterfaces to
+ be implemented by your class.
+ </para>
+
+ <para>
+ For example, we have implemented our own class
+ <classname>ExampleObserver</classname> which implements the
+ <interfacename>Client</interfacename> and
+ <interfacename>Client.Observer</interfacename> interfaces (also the
+ D-Bus properties mixin, <link>see below</link>). The type definition
+ for this class is presented in
+ <xref linkend="ex.services.glib.iface.define-type"/>.
+ </para>
+
+ <example id="ex.services.glib.iface.define-type"
+ file="glib_mc5_observer/example-observer.c">
+ <title>Defining the Type</title>
+ </example>
+
+ <tip>
+ <para>
+ In <xref linkend="ex.services.glib.iface.define-type"/>, interfaces
+ that implement no methods (i.e. <classname>Client</classname>) do not
+ need to provide initialisation methods and <literal>NULL</literal> may
+ be passed instead.
+ </para>
+ </tip>
+
+ <para>
+ Unlike with most GInterfaces, which use a vcall table to map interface
+ methods to implementations, <application>telepathy-glib</application>
+ uses method calls. This is simply to avoid potential ABI problems in
+ the future.
+ </para>
+
+ <para>
+ Each method has an "implement" function, of the form
+ <literal>tp_svc_interface_name_implement_method_name</literal> which
+ accepts a method of the prototype
+ <literal>tp_svc_interface_name_method_name_impl</literal>. For example,
+ the method call
+ <methodname>Client.Observer.ObserveChannels</methodname> is connected
+ using the function
+ <function>tp_svc_client_observer_implement_observe_channels</function>
+ which accepts a function with the prototype of
+ <function>tp_svc_client_observer_observe_channels_impl</function>.
+ This is shown in
+ <xref linkend="ex.services.glib.iface.long-iface-init"/>.
+ </para>
+
+ <example id="ex.services.glib.iface.long-iface-init">
+ <title>Initialising the Interface</title>
+ <programlisting language="c">
+<![CDATA[static void
+observer_iface_init (gpointer g_iface, gpointer iface_data)
+{
+ TpSvcClientObserverClass *klass = (TpSvcClientObserverClass *) g_iface;
+
+ tp_svc_client_observer_implement_observe_channels (klass,
+ example_observer_observer_channels);
+}]]></programlisting>
+ </example>
+
+ <tip>
+ <para>
+ To save excessive typing for interfaces with lots of methods, you can
+ use a temporary <literal>IMPLEMENT</literal> macro, as demonstrated
+ in <xref linkend="ex.services.glib.iface.iface-init"/> which is
+ functionality identical to
+ <xref linkend="ex.services.glib.iface.long-iface-init"/>.
+ </para>
+
+ <example id="ex.services.glib.iface.iface-init"
+ file="glib_mc5_observer/example-observer.c">
+ <title>Initialising the Interface</title>
+ </example>
+ </tip>
+
+ </sect2>
+
+ </sect1>
+</chapter>
diff --git a/docs/book/C/telepathy.xml b/docs/book/C/telepathy.xml
index 1c333b7..322038a 100644
--- a/docs/book/C/telepathy.xml
+++ b/docs/book/C/telepathy.xml
@@ -104,6 +104,8 @@ added in future.
</para>
</chapter>
+<xi:include href="services.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<index id="refindex">
</index>
diff --git a/docs/book/Makefile.am b/docs/book/Makefile.am
index 6c57ab2..2d68d7d 100644
--- a/docs/book/Makefile.am
+++ b/docs/book/Makefile.am
@@ -24,7 +24,8 @@ DOC_INCLUDES = \
contactinfo.xml \
messaging.xml \
filetransfer.xml \
- tubes.xml
+ tubes.xml \
+ services.xml
# these are figures that need to be rasterised
DOC_FIGURES_SRC = \
diff --git a/docs/examples/glib_mc5_observer/example-observer.c b/docs/examples/glib_mc5_observer/example-observer.c
index e9d4518..b47ef31 100644
--- a/docs/examples/glib_mc5_observer/example-observer.c
+++ b/docs/examples/glib_mc5_observer/example-observer.c
@@ -10,12 +10,14 @@ static void observer_iface_init (gpointer, gpointer);
// #define EXAMPLE_OBSERVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EXAMPLE_TYPE_OBSERVER, ExampleObserverPrivate))
+/* begin ex.services.glib.iface.define-type */
G_DEFINE_TYPE_WITH_CODE (ExampleObserver, example_observer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT, NULL);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT_OBSERVER, observer_iface_init);
);
+/* end ex.services.glib.iface.define-type */
static const char *client_interfaces[] = {
TP_IFACE_CLIENT_OBSERVER,
@@ -154,6 +156,7 @@ example_observer_init (ExampleObserver *self)
{
}
+/* begin ex.services.glib.iface.iface-init */
static void
observer_iface_init (gpointer g_iface, gpointer iface_data)
{
@@ -164,6 +167,7 @@ observer_iface_init (gpointer g_iface, gpointer iface_data)
IMPLEMENT (observe_channels);
#undef IMPLEMENT
}
+/* end ex.services.glib.iface.iface-init */
ExampleObserver *
example_observer_new (void)
--
1.5.6.5
More information about the telepathy-commits
mailing list