[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