[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 "&#8212;">
+  <!ENTITY ellipsis "&#8230;">
+]>
+
+<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