[telepathy-gabble/master] Add Conference properties to GabbleMucChannel

Danielle Madeley danielle.madeley at collabora.co.uk
Fri Jan 15 08:30:45 PST 2010


---
 src/muc-channel.c |   95 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/muc-factory.c |   46 ++++++++++++++++++++++----
 2 files changed, 134 insertions(+), 7 deletions(-)

diff --git a/src/muc-channel.c b/src/muc-channel.c
index b37e10f..a60243c 100644
--- a/src/muc-channel.c
+++ b/src/muc-channel.c
@@ -37,6 +37,8 @@
 #include <telepathy-glib/interfaces.h>
 #include <telepathy-glib/channel-iface.h>
 
+#include <extensions/extensions.h>
+
 #define DEBUG_FLAG GABBLE_DEBUG_MUC
 #include "connection.h"
 #include "conn-aliasing.h"
@@ -79,6 +81,7 @@ G_DEFINE_TYPE_WITH_CODE (GabbleMucChannel, gabble_muc_channel,
     G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CHAT_STATE,
       chat_state_iface_init)
+    G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_CHANNEL_INTERFACE_CONFERENCE, NULL);
     )
 
 static void gabble_muc_channel_send (GObject *obj, TpMessage *message,
@@ -90,6 +93,7 @@ static const gchar *gabble_muc_channel_interfaces[] = {
     TP_IFACE_PROPERTIES_INTERFACE,
     TP_IFACE_CHANNEL_INTERFACE_CHAT_STATE,
     TP_IFACE_CHANNEL_INTERFACE_MESSAGES,
+    GABBLE_IFACE_CHANNEL_INTERFACE_CONFERENCE,
     NULL
 };
 
@@ -128,6 +132,10 @@ enum
   PROP_SELF_JID,
   PROP_WOCKY_MUC,
   PROP_TUBE,
+  PROP_INITIAL_CHANNELS,
+  PROP_INITIAL_INVITEE_HANDLES,
+  PROP_INITIAL_INVITEE_IDS,
+  PROP_SUPPORTS_NON_MERGES,
   LAST_PROPERTY
 };
 
@@ -257,6 +265,10 @@ struct _GabbleMucChannelPrivate
 
   WockyMuc *wmuc;
   GabbleTubesChannel *tube;
+
+  GPtrArray *initial_channels;
+  GArray *initial_handles;
+  char **initial_ids;
 };
 
 #define GABBLE_MUC_CHANNEL_GET_PRIVATE(o) \
@@ -923,6 +935,17 @@ gabble_muc_channel_get_property (GObject    *object,
       break;
     case PROP_TUBE:
       g_value_set_object (value, priv->tube);
+    case PROP_INITIAL_CHANNELS:
+      g_value_set_boxed (value, priv->initial_channels);
+      break;
+    case PROP_INITIAL_INVITEE_HANDLES:
+      g_value_set_boxed (value, priv->initial_handles);
+      break;
+    case PROP_INITIAL_INVITEE_IDS:
+      g_value_set_boxed (value, priv->initial_ids);
+      break;
+    case PROP_SUPPORTS_NON_MERGES:
+      g_value_set_boolean (value, TRUE); /* always supports non-merges */
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -982,6 +1005,15 @@ gabble_muc_channel_set_property (GObject     *object,
     case PROP_REQUESTED:
       priv->requested = g_value_get_boolean (value);
       break;
+    case PROP_INITIAL_CHANNELS:
+      priv->initial_channels = g_value_dup_boxed (value);
+      break;
+    case PROP_INITIAL_INVITEE_HANDLES:
+      priv->initial_handles = g_value_dup_boxed (value);
+      break;
+    case PROP_INITIAL_INVITEE_IDS:
+      priv->initial_ids = g_value_dup_boxed (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -1011,12 +1043,27 @@ gabble_muc_channel_class_init (GabbleMucChannelClass *gabble_muc_channel_class)
       { "InitiatorID", "initiator-id", NULL },
       { NULL }
   };
+  static TpDBusPropertiesMixinPropImpl conference_props[] = {
+      { "Channels", "initial-channels", NULL, },
+      { "InitialChannels", "initial-channels", NULL },
+      { "InitialInviteeHandles", "initial-invitee-handles", NULL },
+      { "InitialInviteeIDs", "initial-invitee-ids", NULL },
+      { "InvitationMessage", "invitation-message", NULL },
+      { "SupportsNonMerges", "supports-non-merges", NULL },
+      { NULL }
+  };
   static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
       { TP_IFACE_CHANNEL,
         tp_dbus_properties_mixin_getter_gobject_properties,
         NULL,
         channel_props,
       },
+      {
+        GABBLE_IFACE_CHANNEL_INTERFACE_CONFERENCE,
+        tp_dbus_properties_mixin_getter_gobject_properties,
+        NULL,
+        conference_props,
+      },
       { NULL }
   };
   GObjectClass *object_class = G_OBJECT_CLASS (gabble_muc_channel_class);
@@ -1120,6 +1167,36 @@ gabble_muc_channel_class_init (GabbleMucChannelClass *gabble_muc_channel_class)
       WOCKY_TYPE_MUC, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class, PROP_WOCKY_MUC, param_spec);
 
+  param_spec = g_param_spec_boxed ("initial-channels", "Initial Channels",
+      "The initial channels offered with this Conference",
+      TP_ARRAY_TYPE_OBJECT_PATH_LIST,
+      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_INITIAL_CHANNELS,
+      param_spec);
+
+  param_spec = g_param_spec_boxed ("initial-invitee-handles",
+      "Initial Invitee Handles",
+      "The handles of the Conference's initial invitees",
+      DBUS_TYPE_G_UINT_ARRAY,
+      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_INITIAL_INVITEE_HANDLES,
+      param_spec);
+
+  param_spec = g_param_spec_boxed ("initial-invitee-ids",
+      "Initial Invitee IDs",
+      "The identifiers of the Conference's initial invitees",
+      G_TYPE_STRV,
+      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_INITIAL_INVITEE_IDS,
+      param_spec);
+
+  param_spec = g_param_spec_boolean ("supports-non-merges",
+      "Supports Non Merges",
+      "If true, this Conference can be created from less than two Channels",
+      TRUE, G_PARAM_READABLE);
+  g_object_class_install_property (object_class, PROP_SUPPORTS_NON_MERGES,
+      param_spec);
+
   signals[READY] =
     g_signal_new ("ready",
                   G_OBJECT_CLASS_TYPE (gabble_muc_channel_class),
@@ -1254,6 +1331,24 @@ gabble_muc_channel_finalize (GObject *object)
 
   g_free (priv->password);
 
+  if (priv->initial_channels)
+    {
+      g_boxed_free (TP_ARRAY_TYPE_OBJECT_PATH_LIST, priv->initial_channels);
+      priv->initial_channels = NULL;
+    }
+
+  if (priv->initial_handles)
+    {
+      g_boxed_free (DBUS_TYPE_G_UINT_ARRAY, priv->initial_handles);
+      priv->initial_handles = NULL;
+    }
+
+  if (priv->initial_ids)
+    {
+      g_boxed_free (G_TYPE_STRV, priv->initial_ids);
+      priv->initial_ids = NULL;
+    }
+
   tp_properties_mixin_finalize (object);
 
   tp_group_mixin_finalize (object);
diff --git a/src/muc-factory.c b/src/muc-factory.c
index 4530fea..8f6eb8d 100644
--- a/src/muc-factory.c
+++ b/src/muc-factory.c
@@ -418,12 +418,16 @@ new_muc_channel (GabbleMucFactory *fac,
                  gboolean invited,
                  TpHandle inviter,
                  const gchar *message,
-                 gboolean requested)
+                 gboolean requested,
+                 GHashTable *initial_channels,
+                 GArray *initial_handles,
+                 char **initial_ids)
 {
   GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
   TpBaseConnection *conn = (TpBaseConnection *) priv->conn;
   GabbleMucChannel *chan;
   char *object_path;
+  GPtrArray *initial_channels_array = NULL;
 
   g_assert (g_hash_table_lookup (priv->text_channels,
         GUINT_TO_POINTER (handle)) == NULL);
@@ -431,6 +435,20 @@ new_muc_channel (GabbleMucFactory *fac,
   object_path = g_strdup_printf ("%s/MucChannel%u",
       conn->object_path, handle);
 
+  if (initial_channels != NULL)
+    {
+      GHashTableIter iter;
+      gpointer key;
+
+      initial_channels_array = g_ptr_array_sized_new (
+          g_hash_table_size (initial_channels));
+      g_hash_table_iter_init (&iter, initial_channels);
+      while (g_hash_table_iter_next (&iter, &key, NULL))
+        {
+          g_ptr_array_add (initial_channels_array, key);
+        }
+    }
+
   DEBUG ("creating new chan, object path %s", object_path);
 
   chan = g_object_new (GABBLE_TYPE_MUC_CHANNEL,
@@ -441,6 +459,9 @@ new_muc_channel (GabbleMucFactory *fac,
        "initiator-handle", invited ? inviter : conn->self_handle,
        "invitation-message", message,
        "requested", requested,
+       "initial-channels", initial_channels_array,
+       "initial-invitee-handles", initial_handles,
+       "initial-invitee-ids", initial_ids,
        NULL);
 
   g_signal_connect (chan, "closed", (GCallback) muc_channel_closed_cb, fac);
@@ -449,6 +470,10 @@ new_muc_channel (GabbleMucFactory *fac,
   g_hash_table_insert (priv->text_channels, GUINT_TO_POINTER (handle), chan);
 
   g_free (object_path);
+  if (initial_channels_array != NULL)
+    {
+      g_ptr_array_free (initial_channels_array, TRUE);
+    }
 
   if (_gabble_muc_channel_is_ready (chan))
     muc_ready_cb (chan, fac);
@@ -486,7 +511,8 @@ do_invite (GabbleMucFactory *fac,
   if (g_hash_table_lookup (priv->text_channels,
         GUINT_TO_POINTER (room_handle)) == NULL)
     {
-      new_muc_channel (fac, room_handle, TRUE, inviter_handle, reason, FALSE);
+      new_muc_channel (fac, room_handle, TRUE, inviter_handle, reason, FALSE,
+          NULL, NULL, NULL);
     }
   else
     {
@@ -978,7 +1004,10 @@ ensure_muc_channel (GabbleMucFactory *fac,
                     GabbleMucFactoryPrivate *priv,
                     TpHandle handle,
                     GabbleMucChannel **ret,
-                    gboolean requested)
+                    gboolean requested,
+                    GHashTable *initial_channels,
+                    GArray *initial_handles,
+                    char **initial_ids)
 {
   TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn;
 
@@ -987,7 +1016,7 @@ ensure_muc_channel (GabbleMucFactory *fac,
   if (*ret == NULL)
     {
       *ret = new_muc_channel (fac, handle, FALSE, base_conn->self_handle, NULL,
-          requested);
+          requested, initial_channels, initial_handles, initial_ids);
       return FALSE;
     }
 
@@ -1116,7 +1145,8 @@ ensure_tubes_channel (GabbleMucFactory *self,
   TpHandle initiator = base_conn->self_handle;
   gboolean result;
 
-  result = ensure_muc_channel (self, priv, handle, &text_chan, FALSE);
+  result = ensure_muc_channel (self, priv, handle, &text_chan, FALSE,
+      NULL, NULL, NULL);
 
   /* this refs the tube channel object */
   *tubes_chan = gabble_muc_channel_open_tube (text_chan, initiator, requested);
@@ -1293,7 +1323,8 @@ handle_conference_channel (GabbleMucFactory *self,
     }
 
   /* FIXME: MUC channel needs to expose Conference interface */
-  if (ensure_muc_channel (self, priv, room, &text_chan, TRUE))
+  if (ensure_muc_channel (self, priv, room, &text_chan, TRUE,
+        final_channels, final_handles, final_ids))
     {
       if (require_new)
         {
@@ -1369,7 +1400,8 @@ handle_text_channel_request (GabbleMucFactory *self,
           error))
     return FALSE;
 
-  if (ensure_muc_channel (self, priv, handle, &text_chan, TRUE))
+  if (ensure_muc_channel (self, priv, handle, &text_chan, TRUE,
+        NULL, NULL, NULL))
     {
       if (require_new)
         {
-- 
1.5.6.5




More information about the telepathy-commits mailing list