summaryrefslogtreecommitdiff
path: root/src/base-call-channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base-call-channel.c')
-rw-r--r--src/base-call-channel.c754
1 files changed, 161 insertions, 593 deletions
diff --git a/src/base-call-channel.c b/src/base-call-channel.c
index 9812268..52af824 100644
--- a/src/base-call-channel.c
+++ b/src/base-call-channel.c
@@ -1,7 +1,8 @@
/*
- * base-call-channel.c - Source for GabbleBaseCallChannel
+ * base-call-channel.c - Source for RingBaseCallChannel
* Copyright © 2009–2010 Collabora Ltd.
* @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+ * @author Tom Swindell <t.swindell@rubyx.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,189 +19,86 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <gio/gio.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/enums.h>
-#include <telepathy-glib/exportable-channel.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/channel-iface.h>
-#include <telepathy-glib/svc-channel.h>
-#include <telepathy-glib/svc-properties-interface.h>
-#include <telepathy-glib/base-connection.h>
-#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
-#include "base-call-channel.h"
-#include "base-call-content.h"
+#include "util.h"
+#include "ring-call-content.h"
+#include "ring-call-member.h"
+#include "base-call-channel.h"
#include "ring-connection.h"
+/*
#define DEBUG_FLAG RING_DEBUG_MEDIA
-#include "ring-debug.h"
+#include "debug.h"
+*/
-static void call_iface_init (gpointer, gpointer);
-static void gabble_base_call_channel_close (TpBaseChannel *base);
+G_DEFINE_TYPE(RingBaseCallChannel, ring_base_call_channel,
+ TP_TYPE_BASE_MEDIA_CALL_CHANNEL);
-G_DEFINE_TYPE_WITH_CODE(GabbleBaseCallChannel, gabble_base_call_channel,
- TP_TYPE_BASE_CHANNEL,
- G_IMPLEMENT_INTERFACE (TP_TYPE_BASE_MEDIA_CALL_CHANNEL,
- call_iface_init)
-);
+static void ring_base_call_channel_hangup (
+ TpBaseCallChannel *base,
+ guint reason,
+ const gchar *detailed_reason,
+ const gchar *message);
-static const gchar *gabble_base_call_channel_interfaces[] = {
- NULL
-};
+static void ring_base_call_channel_close (TpBaseChannel *base);
/* properties */
enum
{
PROP_OBJECT_PATH_PREFIX = 1,
-
- PROP_INITIAL_AUDIO,
- PROP_INITIAL_VIDEO,
- PROP_MUTABLE_CONTENTS,
- PROP_HARDWARE_STREAMING,
- PROP_CONTENTS,
-
- PROP_CALL_STATE,
- PROP_CALL_FLAGS,
- PROP_CALL_STATE_DETAILS,
- PROP_CALL_STATE_REASON,
-
- PROP_CALL_MEMBERS,
-
LAST_PROPERTY
};
-enum
-{
- ENDED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0, };
-
-
/* private structure */
-struct _GabbleBaseCallChannelPrivate
+struct _RingBaseCallChannelPrivate
{
gchar *object_path_prefix;
gboolean dispose_has_run;
- GList *contents;
-
- TpCallState state;
- TpCallFlags flags;
- GHashTable *details;
- GValueArray *reason;
-
- /* handle -> TpCallMemberFlags hash */
+ /* handle -> CallMember object hash */
GHashTable *members;
};
static void
-gabble_base_call_channel_constructed (GObject *obj)
+ring_base_call_channel_init (RingBaseCallChannel *self)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (obj);
- TpBaseChannel *base = TP_BASE_CHANNEL (self);
-
- if (G_OBJECT_CLASS (gabble_base_call_channel_parent_class)->constructed
- != NULL)
- G_OBJECT_CLASS (gabble_base_call_channel_parent_class)->constructed (obj);
-
- if (tp_base_channel_is_requested (base))
- gabble_base_call_channel_set_state (self,
- TP_CALL_STATE_PENDING_INITIATOR);
- else
- gabble_base_call_channel_set_state (self,
- TP_CALL_STATE_INITIALISING);
-}
-
-static void
-gabble_base_call_channel_init (GabbleBaseCallChannel *self)
-{
- GabbleBaseCallChannelPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- GABBLE_TYPE_BASE_CALL_CHANNEL, GabbleBaseCallChannelPrivate);
+ RingBaseCallChannelPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ RING_TYPE_BASE_CALL_CHANNEL, RingBaseCallChannelPrivate);
self->priv = priv;
- priv->reason = tp_value_array_build (3,
- G_TYPE_UINT, 0,
- G_TYPE_UINT, 0,
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
-
- priv->details = tp_asv_new (NULL, NULL);
-
- priv->members = g_hash_table_new (NULL, NULL);
+ priv->members = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_object_unref);
}
-static void gabble_base_call_channel_dispose (GObject *object);
-static void gabble_base_call_channel_finalize (GObject *object);
+static void ring_base_call_channel_dispose (GObject *object);
+static void ring_base_call_channel_finalize (GObject *object);
static void
-gabble_base_call_channel_get_property (GObject *object,
+ring_base_call_channel_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (object);
- GabbleBaseCallChannelPrivate *priv = self->priv;
- GabbleBaseCallChannelClass *klass = GABBLE_BASE_CALL_CHANNEL_GET_CLASS (self);
+ RingBaseCallChannel *self = RING_BASE_CALL_CHANNEL (object);
+ RingBaseCallChannelPrivate *priv = self->priv;
switch (property_id)
{
case PROP_OBJECT_PATH_PREFIX:
g_value_set_string (value, priv->object_path_prefix);
break;
- case PROP_INITIAL_AUDIO:
- g_value_set_boolean (value, self->initial_audio);
- break;
- case PROP_INITIAL_VIDEO:
- g_value_set_boolean (value, self->initial_video);
- break;
- case PROP_MUTABLE_CONTENTS:
- g_value_set_boolean (value, klass->mutable_contents);
- break;
- case PROP_CONTENTS:
- {
- GPtrArray *arr = g_ptr_array_sized_new (2);
- GList *l;
-
- for (l = priv->contents; l != NULL; l = g_list_next (l))
- {
- GabbleBaseCallContent *c = GABBLE_BASE_CALL_CONTENT (l->data);
- g_ptr_array_add (arr,
- (gpointer) gabble_base_call_content_get_object_path (c));
- }
-
- g_value_set_boxed (value, arr);
- g_ptr_array_free (arr, TRUE);
- break;
- }
- case PROP_HARDWARE_STREAMING:
- g_value_set_boolean (value, klass->hardware_streaming);
- break;
- case PROP_CALL_STATE:
- g_value_set_uint (value, priv->state);
- break;
- case PROP_CALL_FLAGS:
- g_value_set_uint (value, priv->flags);
- break;
- case PROP_CALL_STATE_DETAILS:
- g_value_set_boxed (value, priv->details);
- break;
- case PROP_CALL_STATE_REASON:
- g_value_set_boxed (value, priv->reason);
- break;
- case PROP_CALL_MEMBERS:
- g_value_set_boxed (value, priv->members);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -208,25 +106,19 @@ gabble_base_call_channel_get_property (GObject *object,
}
static void
-gabble_base_call_channel_set_property (GObject *object,
+ring_base_call_channel_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (object);
- GabbleBaseCallChannelPrivate *priv = self->priv;
+ RingBaseCallChannel *self = RING_BASE_CALL_CHANNEL (object);
+ RingBaseCallChannelPrivate *priv = self->priv;
switch (property_id)
{
case PROP_OBJECT_PATH_PREFIX:
priv->object_path_prefix = g_value_dup_string (value);
break;
- case PROP_INITIAL_AUDIO:
- self->initial_audio = g_value_get_boolean (value);
- break;
- case PROP_INITIAL_VIDEO:
- self->initial_video = g_value_get_boolean (value);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -234,10 +126,10 @@ gabble_base_call_channel_set_property (GObject *object,
}
static gchar *
-gabble_base_call_channel_get_object_path_suffix (TpBaseChannel *base)
+ring_base_call_channel_get_object_path_suffix (TpBaseChannel *base)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (base);
- GabbleBaseCallChannelPrivate *priv = self->priv;
+ RingBaseCallChannel *self = RING_BASE_CALL_CHANNEL (base);
+ RingBaseCallChannelPrivate *priv = self->priv;
g_assert (priv->object_path_prefix != NULL);
@@ -245,70 +137,30 @@ gabble_base_call_channel_get_object_path_suffix (TpBaseChannel *base)
}
static void
-gabble_base_call_channel_fill_immutable_properties (
- TpBaseChannel *chan,
- GHashTable *properties)
+ring_base_call_channel_class_init (
+ RingBaseCallChannelClass *ring_base_call_channel_class)
{
- TP_BASE_CHANNEL_CLASS (gabble_base_call_channel_parent_class)
- ->fill_immutable_properties (chan, properties);
-
- tp_dbus_properties_mixin_fill_properties_hash (
- G_OBJECT (chan), properties,
- TP_IFACE_CHANNEL_TYPE_CALL, "InitialAudio",
- TP_IFACE_CHANNEL_TYPE_CALL, "InitialVideo",
- TP_IFACE_CHANNEL_TYPE_CALL, "MutableContents",
- TP_IFACE_CHANNEL_TYPE_CALL, "HardwareStreaming",
- NULL);
-}
-
-static void
-gabble_base_call_channel_class_init (
- GabbleBaseCallChannelClass *gabble_base_call_channel_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (gabble_base_call_channel_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (ring_base_call_channel_class);
TpBaseChannelClass *base_channel_class =
- TP_BASE_CHANNEL_CLASS (gabble_base_call_channel_class);
+ TP_BASE_CHANNEL_CLASS (ring_base_call_channel_class);
+ TpBaseCallChannelClass *tp_base_call_channel_class =
+ TP_BASE_CALL_CHANNEL_CLASS (ring_base_call_channel_class);
GParamSpec *param_spec;
- static TpDBusPropertiesMixinPropImpl call_props[] = {
- { "CallMembers", "call-members", NULL },
- { "MutableContents", "mutable-contents", NULL },
- { "InitialAudio", "initial-audio", NULL },
- { "InitialVideo", "initial-video", NULL },
- { "Contents", "contents", NULL },
- { "HardwareStreaming", "hardware-streaming", NULL },
- { "CallState", "call-state", NULL },
- { "CallFlags", "call-flags", NULL },
- { "CallStateReason", "call-state-reason", NULL },
- { "CallStateDetails", "call-state-details", NULL },
- { NULL }
- };
-
- g_type_class_add_private (gabble_base_call_channel_class,
- sizeof (GabbleBaseCallChannelPrivate));
-
- object_class->constructed = gabble_base_call_channel_constructed;
-
- object_class->get_property = gabble_base_call_channel_get_property;
- object_class->set_property = gabble_base_call_channel_set_property;
-
- object_class->dispose = gabble_base_call_channel_dispose;
- object_class->finalize = gabble_base_call_channel_finalize;
-
- base_channel_class->channel_type = TP_IFACE_CHANNEL_TYPE_CALL;
- base_channel_class->interfaces = gabble_base_call_channel_interfaces;
+
+ g_type_class_add_private (ring_base_call_channel_class,
+ sizeof (RingBaseCallChannelPrivate));
+
+ object_class->get_property = ring_base_call_channel_get_property;
+ object_class->set_property = ring_base_call_channel_set_property;
+
+ object_class->dispose = ring_base_call_channel_dispose;
+ object_class->finalize = ring_base_call_channel_finalize;
+
base_channel_class->get_object_path_suffix =
- gabble_base_call_channel_get_object_path_suffix;
- base_channel_class->fill_immutable_properties =
- gabble_base_call_channel_fill_immutable_properties;
- base_channel_class->close = gabble_base_call_channel_close;
-
- signals[ENDED] = g_signal_new ("ended",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ ring_base_call_channel_get_object_path_suffix;
+ base_channel_class->close = ring_base_call_channel_close;
+
+ tp_base_call_channel_class->hangup = ring_base_call_channel_hangup;
param_spec = g_param_spec_string ("object-path-prefix", "Object path prefix",
"prefix of the object path",
@@ -316,446 +168,162 @@ gabble_base_call_channel_class_init (
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_OBJECT_PATH_PREFIX,
param_spec);
-
- param_spec = g_param_spec_boolean ("initial-audio", "InitialAudio",
- "Whether the channel initially contained an audio stream",
- FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_AUDIO,
- param_spec);
-
- param_spec = g_param_spec_boolean ("initial-video", "InitialVideo",
- "Whether the channel initially contained an video stream",
- FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
- param_spec);
-
- param_spec = g_param_spec_boolean ("mutable-contents", "MutableContents",
- "Whether the set of streams on this channel are mutable once requested",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MUTABLE_CONTENTS,
- param_spec);
-
- param_spec = g_param_spec_boxed ("contents", "Contents",
- "The contents of the channel",
- TP_ARRAY_TYPE_OBJECT_PATH_LIST,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONTENTS,
- param_spec);
-
- param_spec = g_param_spec_boolean ("hardware-streaming", "HardwareStreaming",
- "True if all the streaming is done by hardware",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_HARDWARE_STREAMING,
- param_spec);
-
- param_spec = g_param_spec_uint ("call-state", "CallState",
- "The status of the call",
- TP_CALL_STATE_UNKNOWN,
- NUM_TP_CALL_STATES,
- TP_CALL_STATE_UNKNOWN,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_STATE, param_spec);
-
- param_spec = g_param_spec_uint ("call-flags", "CallFlags",
- "Flags representing the status of the call",
- 0, G_MAXUINT, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_FLAGS,
- param_spec);
-
- param_spec = g_param_spec_boxed ("call-state-reason", "CallStateReason",
- "The reason why the call is in the current state",
- TP_STRUCT_TYPE_CALL_STATE_REASON,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_STATE_REASON,
- param_spec);
-
- param_spec = g_param_spec_boxed ("call-state-details", "CallStateDetails",
- "The reason why the call is in the current state",
- TP_HASH_TYPE_QUALIFIED_PROPERTY_VALUE_MAP,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_STATE_DETAILS,
- param_spec);
-
- param_spec = g_param_spec_boxed ("call-members", "CallMembers",
- "The members",
- TP_HASH_TYPE_CALL_MEMBER_MAP,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CALL_MEMBERS,
- param_spec);
-
- tp_dbus_properties_mixin_implement_interface (object_class,
- TP_IFACE_QUARK_CHANNEL_TYPE_CALL,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- call_props);
}
void
-gabble_base_call_channel_dispose (GObject *object)
+ring_base_call_channel_dispose (GObject *object)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (object);
- GabbleBaseCallChannelPrivate *priv = self->priv;
+ RingBaseCallChannel *self = RING_BASE_CALL_CHANNEL (object);
+ RingBaseCallChannelPrivate *priv = self->priv;
if (priv->dispose_has_run)
return;
self->priv->dispose_has_run = TRUE;
- g_list_foreach (priv->contents, (GFunc) gabble_base_call_content_deinit, NULL);
- g_list_foreach (priv->contents, (GFunc) g_object_unref, NULL);
- tp_clear_pointer (&priv->contents, g_list_free);
-
tp_clear_pointer (&priv->members, g_hash_table_unref);
- if (G_OBJECT_CLASS (gabble_base_call_channel_parent_class)->dispose)
- G_OBJECT_CLASS (gabble_base_call_channel_parent_class)->dispose (object);
+ if (G_OBJECT_CLASS (ring_base_call_channel_parent_class)->dispose)
+ G_OBJECT_CLASS (ring_base_call_channel_parent_class)->dispose (object);
}
void
-gabble_base_call_channel_finalize (GObject *object)
+ring_base_call_channel_finalize (GObject *object)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (object);
- GabbleBaseCallChannelPrivate *priv = self->priv;
+ RingBaseCallChannel *self = RING_BASE_CALL_CHANNEL (object);
+ RingBaseCallChannelPrivate *priv = self->priv;
- g_hash_table_unref (priv->details);
- g_value_array_free (priv->reason);
- g_free (self->priv->object_path_prefix);
+ g_free (priv->object_path_prefix);
- G_OBJECT_CLASS (gabble_base_call_channel_parent_class)->finalize (object);
+ G_OBJECT_CLASS (ring_base_call_channel_parent_class)->finalize (object);
}
-void
-gabble_base_call_channel_set_state (GabbleBaseCallChannel *self,
- TpCallState state)
+RingCallContent *
+ring_base_call_channel_add_content (RingBaseCallChannel *self,
+ const gchar *name,
+ TpCallContentDisposition disposition)
{
- GabbleBaseCallChannelPrivate *priv = self->priv;
-
- DEBUG ("changing from %u to %u", priv->state, state);
-
- if (state == priv->state)
- return;
-
- /* signal when going to the ended state */
- if (state == TP_CALL_STATE_ENDED)
- g_signal_emit (self, signals[ENDED], 0);
-
- priv->state = state;
-
- if (priv->state != TP_CALL_STATE_INITIALISING)
- priv->flags &= ~TP_CALL_FLAG_LOCALLY_RINGING;
-
- if (tp_base_channel_is_registered (TP_BASE_CHANNEL (self)))
- tp_svc_channel_type_call_emit_call_state_changed (self, priv->state,
- priv->flags, priv->reason, priv->details);
-}
-
-TpCallState
-gabble_base_call_channel_get_state (GabbleBaseCallChannel *self)
-{
- return self->priv->state;
-}
-
-void
-gabble_base_call_channel_update_flags (GabbleBaseCallChannel *self,
- TpCallFlags set_flags,
- TpCallFlags clear_flags)
-{
- GabbleBaseCallChannelPrivate *priv = self->priv;
- TpCallFlags old_flags = priv->flags;
-
- priv->flags = (old_flags | set_flags) & ~clear_flags;
- DEBUG ("was %u; set %u and cleared %u; now %u", old_flags, set_flags,
- clear_flags, priv->flags);
-
- if (priv->flags != old_flags)
- tp_svc_channel_type_call_emit_call_state_changed (self, priv->state,
- priv->flags, priv->reason, priv->details);
+ TpBaseChannel *base = TP_BASE_CHANNEL (self);
+ gchar *object_path;
+ TpBaseCallContent *content;
+ gchar *escaped;
+
+ /* FIXME could clash when other party in a one-to-one call creates a stream
+ * with the same media type and name */
+ escaped = tp_escape_as_identifier (name);
+ object_path = g_strdup_printf ("%s/Content_%s",
+ tp_base_channel_get_object_path (base),
+ escaped);
+ g_free (escaped);
+
+ content = g_object_new (RING_TYPE_CALL_CONTENT,
+ "connection", tp_base_channel_get_connection (base),
+ "object-path", object_path,
+ "disposition", disposition,
+ //"media-type", wocky_jingle_media_type_to_tp (mtype),
+ "name", name,
+ NULL);
+
+ g_free (object_path);
+
+ tp_base_call_channel_add_content (TP_BASE_CALL_CHANNEL (self),
+ content);
+
+ return RING_CALL_CONTENT (content);
}
-static gboolean
-base_call_channel_update_member (GabbleBaseCallChannel *self,
- TpHandle contact,
- TpCallMemberFlags set_flags,
- TpCallMemberFlags clear_flags,
- TpCallMemberFlags *new_flags)
+static void
+call_member_flags_changed_cb (RingCallMember *member,
+ TpCallMemberFlags flags,
+ gpointer user_data)
{
- gpointer old_flags_p;
-
- DEBUG ("updating member #%u, setting %u and clearing %u", contact, set_flags,
- clear_flags);
-
- if (g_hash_table_lookup_extended (self->priv->members,
- GUINT_TO_POINTER (contact), NULL, &old_flags_p))
- {
- TpCallMemberFlags old_flags = GPOINTER_TO_UINT (old_flags_p);
-
- *new_flags = (old_flags | set_flags) & ~clear_flags;
-
- DEBUG ("previous flags: %u; new flags: %u", old_flags, *new_flags);
-
- if (old_flags == *new_flags)
- return FALSE;
- }
- else
- {
- *new_flags = set_flags & ~clear_flags;
- DEBUG ("not previously a member; new flags: %u", *new_flags);
- }
+ TpBaseCallChannel *base = TP_BASE_CALL_CHANNEL (user_data);
- g_hash_table_insert (self->priv->members, GUINT_TO_POINTER (contact),
- GUINT_TO_POINTER (*new_flags));
- return TRUE;
+ tp_base_call_channel_update_member_flags (base,
+ ring_call_member_get_handle (member),
+ flags,
+ 0, TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", "");
}
-gboolean
-gabble_base_call_channel_update_members (
- GabbleBaseCallChannel *self,
- TpHandle contact,
- TpCallMemberFlags set_flags,
- TpCallMemberFlags clear_flags,
- ...)
+RingCallMember *
+ring_base_call_channel_get_member_from_handle (
+ RingBaseCallChannel *self,
+ TpHandle handle)
{
- GHashTable *updates = g_hash_table_new (NULL, NULL);
- gboolean updated = FALSE;
- va_list args;
-
- va_start (args, clear_flags);
-
- do
- {
- TpCallMemberFlags new_flags;
-
- if (base_call_channel_update_member (self, contact, set_flags,
- clear_flags, &new_flags))
- {
- g_hash_table_insert (updates,
- GUINT_TO_POINTER (contact),
- GUINT_TO_POINTER (new_flags));
- updated = TRUE;
- }
-
- contact = va_arg (args, TpHandle);
-
- if (contact != 0)
- {
- set_flags = va_arg (args, TpCallMemberFlags);
- clear_flags = va_arg (args, TpCallMemberFlags);
- }
- }
- while (contact != 0);
-
- if (updated)
- {
- GArray *empty = g_array_new (FALSE, FALSE, sizeof (TpHandle));
-
- tp_svc_channel_type_call_emit_call_members_changed (self, updates, NULL,
- empty, empty);
- g_array_unref (empty);
- }
-
- g_hash_table_unref (updates);
- return updated;
+ return g_hash_table_lookup (self->priv->members, GUINT_TO_POINTER (handle));
}
-gboolean
-gabble_base_call_channel_remove_members (
- GabbleBaseCallChannel *self,
- TpHandle contact,
- ...)
+RingCallMember *
+ring_base_call_channel_ensure_member_from_handle (
+ RingBaseCallChannel *self,
+ TpHandle handle)
{
- GArray *removed = g_array_new (FALSE, FALSE, sizeof (TpHandle));
- gboolean updated = FALSE;
- va_list args;
+ RingBaseCallChannelPrivate *priv = self->priv;
+ RingCallMember *m;
- va_start (args, contact);
-
- do
+ m = g_hash_table_lookup (priv->members, GUINT_TO_POINTER (handle));
+ if (m == NULL)
{
- if (g_hash_table_remove (self->priv->members, GUINT_TO_POINTER (contact)))
- {
- g_array_append_val (removed, contact);
- updated = TRUE;
- }
-
- contact = va_arg (args, TpHandle);
- }
- while (contact != 0);
-
- if (updated)
- {
- GHashTable *empty = g_hash_table_new (NULL, NULL);
-
- tp_svc_channel_type_call_emit_call_members_changed (self, empty,
- removed);
- g_hash_table_unref (empty);
+ m = RING_CALL_MEMBER (g_object_new (RING_TYPE_CALL_MEMBER,
+ "target", handle,
+ "call", self,
+ NULL));
+ g_hash_table_insert (priv->members, GUINT_TO_POINTER (handle), m);
+
+ tp_base_call_channel_update_member_flags (TP_BASE_CALL_CHANNEL (self),
+ ring_call_member_get_handle (m),
+ ring_call_member_get_flags (m),
+ 0, TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", "");
+
+ ring_signal_connect_weak (m, "flags-changed",
+ G_CALLBACK (call_member_flags_changed_cb), G_OBJECT (self));
}
- g_array_unref (removed);
- return updated;
+ return m;
}
void
-gabble_base_call_channel_add_content (GabbleBaseCallChannel *self,
- GabbleBaseCallContent *content)
+ring_base_call_channel_remove_member (RingBaseCallChannel *self,
+ RingCallMember *member)
{
- self->priv->contents = g_list_prepend (self->priv->contents,
- g_object_ref (content));
+ TpHandle h = ring_call_member_get_handle (member);
- if (tp_base_channel_is_registered (TP_BASE_CHANNEL (self)))
- tp_svc_channel_type_call_emit_content_added (self,
- gabble_base_call_content_get_object_path (content),
- gabble_base_call_content_get_media_type (content));
-}
-
-static void
-gabble_base_call_channel_close (TpBaseChannel *base)
-{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (base);
- GabbleBaseCallChannelPrivate *priv = self->priv;
-
- DEBUG ("Closing media channel %s", tp_base_channel_get_object_path (base));
-
- /* shutdown all our contents */
- g_list_foreach (priv->contents, (GFunc) gabble_base_call_content_deinit,
- NULL);
- g_list_foreach (priv->contents, (GFunc) g_object_unref, NULL);
- tp_clear_pointer (&priv->contents, g_list_free);
-
- tp_base_channel_destroyed (base);
-}
-
-static void
-gabble_base_call_channel_ringing (TpSvcChannelTypeCall *iface,
- DBusGMethodInvocation *context)
-{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (iface);
- GabbleBaseCallChannelPrivate *priv = self->priv;
- TpBaseChannel *tp_base = TP_BASE_CHANNEL (self);
+ g_assert (g_hash_table_lookup (self->priv->members,
+ GUINT_TO_POINTER (h))== member);
- if (tp_base_channel_is_requested (tp_base))
- {
- GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "Call was requested. Ringing doesn't make sense." };
- dbus_g_method_return_error (context, &e);
- }
- else if (priv->state != TP_CALL_STATE_INITIALISING)
- {
- GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "Call is not in the right state for Ringing." };
- dbus_g_method_return_error (context, &e);
- }
- else
- {
- if ((priv->flags & TP_CALL_FLAG_LOCALLY_RINGING) == 0)
- {
- DEBUG ("Client is ringing");
- priv->flags |= TP_CALL_FLAG_LOCALLY_RINGING;
- gabble_base_call_channel_set_state (self, priv->state);
- }
-
- tp_svc_channel_type_call_return_from_ringing (context);
- }
+ ring_call_member_shutdown (member);
+ tp_base_call_channel_remove_member (TP_BASE_CALL_CHANNEL (self),
+ ring_call_member_get_handle (member),
+ 0, TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", "");
+ g_hash_table_remove (self->priv->members, GUINT_TO_POINTER (h));
}
static void
-gabble_base_call_channel_accept (TpSvcChannelTypeCall *iface,
- DBusGMethodInvocation *context)
+ring_base_call_channel_shutdown_all_members (RingBaseCallChannel *self)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (iface);
- GabbleBaseCallChannelPrivate *priv = self->priv;
- GabbleBaseCallChannelClass *base_class =
- GABBLE_BASE_CALL_CHANNEL_GET_CLASS (self);
- TpBaseChannel *tp_base = TP_BASE_CHANNEL (self);
-
- DEBUG ("Client accepted the call");
+ GHashTableIter iter;
+ gpointer value;
- if (tp_base_channel_is_requested (tp_base))
- {
- if (priv->state == TP_CALL_STATE_PENDING_INITIATOR)
- {
- gabble_base_call_channel_set_state (self,
- TP_CALL_STATE_INITIALISING);
- }
- else
- {
- DEBUG ("Invalid state for Accept: Channel requested and "
- "state == %d", priv->state);
- goto err;
- }
- }
- else if (priv->state < TP_CALL_STATE_ACCEPTED)
- {
- gabble_base_call_channel_set_state (self,
- TP_CALL_STATE_ACCEPTED);
- }
- else
- {
- DEBUG ("Invalid state for Accept: state == %d", priv->state);
- goto err;
- }
-
- if (base_class->accept != NULL)
- base_class->accept (self);
-
- tp_svc_channel_type_call_return_from_accept (context);
- return;
-
-err:
- {
- GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "Invalid state for Accept" };
- dbus_g_method_return_error (context, &e);
- }
+ g_hash_table_iter_init (&iter, self->priv->members);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ ring_call_member_shutdown (RING_CALL_MEMBER (value));
}
static void
-gabble_base_call_channel_hangup (TpSvcChannelTypeCall *iface,
- guint reason,
- const gchar *detailed_reason,
- const gchar *message,
- DBusGMethodInvocation *context)
+ring_base_call_channel_hangup (TpBaseCallChannel *base,
+ guint reason,
+ const gchar *detailed_reason,
+ const gchar *message)
{
- GabbleBaseCallChannel *self = GABBLE_BASE_CALL_CHANNEL (iface);
- GabbleBaseCallChannelClass *base_class =
- GABBLE_BASE_CALL_CHANNEL_GET_CLASS (self);
-
- if (base_class->hangup)
- base_class->hangup (self, reason, detailed_reason, message);
-
- gabble_base_call_channel_set_state ( GABBLE_BASE_CALL_CHANNEL (self),
- TP_CALL_STATE_ENDED);
-
- tp_svc_channel_type_call_return_from_hangup (context);
+ ring_base_call_channel_shutdown_all_members (
+ RING_BASE_CALL_CHANNEL (base));
}
static void
-gabble_base_call_channel_add_content_dbus (RingSvcChannelTypeCall *iface,
- const gchar *name,
- TpMediaStreamType mtype,
- DBusGMethodInvocation *context)
+ring_base_call_channel_close (TpBaseChannel *base)
{
- GError e = { TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
- "Contents cannot be added; only a single audio content is supported" };
+ ring_base_call_channel_shutdown_all_members (
+ RING_BASE_CALL_CHANNEL (base));
- dbus_g_method_return_error (context, &e);
-}
-
-
-static void
-call_iface_init (gpointer g_iface, gpointer iface_data)
-{
- RingSvcChannelTypeCallClass *klass = g_iface;
-
-#define IMPLEMENT(x, suffix) ring_svc_channel_type_call_implement_##x (\
- klass, gabble_base_call_channel_##x##suffix)
- IMPLEMENT(ringing,);
- IMPLEMENT(accept,);
- IMPLEMENT(hangup,);
- IMPLEMENT(add_content, _dbus);
-#undef IMPLEMENT
+ TP_BASE_CHANNEL_CLASS (ring_base_call_channel_parent_class)->close (base);
}