[Telepathy-commits] [telepathy-glib/master] echo2 example CM: update to new API

Simon McVittie simon.mcvittie at collabora.co.uk
Thu Dec 18 10:41:34 PST 2008


20080512145346-53eee-ef803468910f21b3ddb03edc5c9b8bb6879e123f.gz
---
 examples/cm/echo-message-parts/chan.c |  150 +++++++++++++++++++++++++++++----
 1 files changed, 132 insertions(+), 18 deletions(-)

diff --git a/examples/cm/echo-message-parts/chan.c b/examples/cm/echo-message-parts/chan.c
index 800c293..fdaf295 100644
--- a/examples/cm/echo-message-parts/chan.c
+++ b/examples/cm/echo-message-parts/chan.c
@@ -68,7 +68,7 @@ struct _ExampleEcho2ChannelPrivate
 };
 
 static const char * example_echo_2_channel_interfaces[] = {
-    TP_IFACE_CHANNEL_INTERFACE_MESSAGE_PARTS,
+    TP_IFACE_CHANNEL_INTERFACE_MESSAGES,
     NULL };
 /* FIXME: when supported, add TP_IFACE_CHANNEL_INTERFACE_DESTROYABLE */
 
@@ -79,6 +79,7 @@ example_echo_2_channel_init (ExampleEcho2Channel *self)
       ExampleEcho2ChannelPrivate);
 }
 
+
 static gboolean
 send_message (GObject *object,
               TpMessageMixinOutgoingMessage *message)
@@ -87,24 +88,138 @@ send_message (GObject *object,
   TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
       (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
   time_t timestamp = time (NULL);
-  TpChannelTextMessageType message_type = message->message_type;
-  GPtrArray *parts = g_boxed_copy (dbus_g_type_get_collection ("GPtrArray",
-        TP_HASH_TYPE_MESSAGE_PART), message->parts);
+  GPtrArray *parts;
+  gboolean valid;
+  guint i;
 
-  tp_handle_ref (contact_repo, self->priv->handle);
+  g_return_val_if_fail (message->parts->len >= 1, FALSE);
+
+  parts = g_ptr_array_sized_new (message->parts->len);
+
+  /* Copy/modify the headers for the "received" message */
+    {
+      GHashTable *header = g_hash_table_new_full (g_str_hash, g_str_equal,
+            NULL, (GDestroyNotify) tp_g_value_slice_free);
+      TpChannelTextMessageType message_type;
+
+      tp_handle_ref (contact_repo, self->priv->handle);
+
+      g_hash_table_insert (header, "message-sender",
+          tp_g_value_slice_new_uint (self->priv->handle));
+
+      message_type = tp_asv_get_uint32 (g_ptr_array_index (message->parts, 0),
+          "message-type", &valid);
+
+      /* The check for 'valid' means that if message-type is missing or of the
+       * wrong type, fall back to NORMAL (this is in fact a no-op, since
+       * NORMAL == 0 and tp_asv_get_uint32 returns 0 on missing or wrongly
+       * typed values) */
+      if (valid && message_type != TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL)
+        g_hash_table_insert (header, "message-type",
+            tp_g_value_slice_new_uint (message_type));
+
+      g_hash_table_insert (header, "message-sent",
+          tp_g_value_slice_new_uint (timestamp));
+
+      g_hash_table_insert (header, "message-received",
+          tp_g_value_slice_new_uint (timestamp));
+
+      g_ptr_array_add (parts, header);
+    }
+
+  /* Copy the content for the "received" message */
+  for (i = 1; i < message->parts->len; i++)
+    {
+      GHashTable *input = g_ptr_array_index (message->parts, i);
+      GHashTable *output;
+      const gchar *s;
+      GValue *value;
+
+      /* in this example we ignore interface-specific parts */
+
+      s = tp_asv_get_string (input, "type");
+
+      if (s == NULL)
+        continue;
+
+      s = tp_asv_get_string (input, "interface");
+
+      if (s != NULL)
+        continue;
+
+      /* OK, we want to copy this part */
+
+      output = g_hash_table_new_full (g_str_hash, g_str_equal,
+            NULL, (GDestroyNotify) tp_g_value_slice_free);
+
+      s = tp_asv_get_string (input, "type");
+      g_assert (s != NULL);   /* already checked */
+      g_hash_table_insert (output, "type",
+          tp_g_value_slice_new_string (s));
+
+      s = tp_asv_get_string (input, "identifier");
 
-  /* This consumes one ref to the handle, and the array of parts, so we
-   * mustn't unref/free them here */
-  tp_message_mixin_take_received (object, timestamp, self->priv->handle,
-      message_type, parts);
+      if (s != NULL)
+        g_hash_table_insert (output, "identifier",
+            tp_g_value_slice_new_string (s));
+
+      s = tp_asv_get_string (input, "alternative");
+
+      if (s != NULL)
+        g_hash_table_insert (output, "alternative",
+            tp_g_value_slice_new_string (s));
+
+      s = tp_asv_get_string (input, "lang");
+
+      if (s != NULL)
+        g_hash_table_insert (output, "lang",
+            tp_g_value_slice_new_string (s));
+
+      value = g_hash_table_lookup (input, "content");
+
+      if (value != NULL)
+        g_hash_table_insert (output, "content",
+            tp_g_value_slice_dup (value));
+
+      g_ptr_array_add (parts, output);
+    }
 
   /* "OK, we've sent the message" (after calling this, message must not be
    * dereferenced) */
   tp_message_mixin_sent (object, message, "", NULL);
 
+  /* Pretend the other user sent us back the same message. After this call,
+   * the parts array is owned by the mixin, and must not be modified or freed
+   * until clean_up_received() is called */
+  tp_message_mixin_take_received (object, parts, NULL);
+
   return TRUE;
 }
 
+
+static void
+clean_up_received (GObject *obj,
+                   GPtrArray *parts,
+                   gpointer user_data)
+{
+  ExampleEcho2Channel *self = EXAMPLE_ECHO_2_CHANNEL (obj);
+  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
+      (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
+  TpHandle sender;
+
+  /* this is what we passed to tp_message_mixin_take_received() */
+  g_assert (user_data == NULL);
+
+  sender = tp_asv_get_uint32 (g_ptr_array_index (parts, 0), "sender", NULL);
+
+  if (sender != 0)
+    tp_handle_unref (contact_repo, sender);
+
+  g_ptr_array_foreach (parts, (GFunc) g_hash_table_destroy, NULL);
+  g_ptr_array_free (parts, TRUE);
+}
+
+
 static GObject *
 constructor (GType type,
              guint n_props,
@@ -117,6 +232,11 @@ constructor (GType type,
   TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
       (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
   DBusGConnection *bus;
+  static TpChannelTextMessageType const types[] = {
+      TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
+      TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION,
+      TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE
+  };
 
   tp_handle_ref (contact_repo, self->priv->handle);
 
@@ -127,9 +247,10 @@ constructor (GType type,
   dbus_g_connection_register_g_object (bus, self->priv->object_path, object);
 
   tp_message_mixin_init (object, G_STRUCT_OFFSET (ExampleEcho2Channel, text),
-      contact_repo);
+      clean_up_received);
 
-  tp_message_mixin_implement_sending (object, send_message);
+  tp_message_mixin_implement_sending (object, send_message,
+      (sizeof (types) / sizeof (types[0])), types);
 
   return object;
 }
@@ -454,15 +575,8 @@ static void
 channel_get_interfaces (TpSvcChannel *iface,
                         DBusGMethodInvocation *context)
 {
-<<<<<<< HEAD:examples/cm/echo-message-parts/chan.c
   tp_svc_channel_return_from_get_interfaces (context,
       example_echo_2_channel_interfaces);
-=======
-  const char *interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_MESSAGES,
-      NULL };
-
-  tp_svc_channel_return_from_get_interfaces (context, interfaces);
->>>>>>> 4146aa4... echo-message-parts example: adapt to new interface name:examples/cm/echo-message-parts/chan.c
 }
 
 static void
-- 
1.5.6.5




More information about the Telepathy-commits mailing list