[telepathy-gabble/master] Create initial streams as per request

Will Thompson will.thompson at collabora.co.uk
Tue Apr 14 10:11:11 PDT 2009


---
 src/media-channel.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/media-channel.h |    5 ++++
 src/media-factory.c |   61 +++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 127 insertions(+), 5 deletions(-)

diff --git a/src/media-channel.c b/src/media-channel.c
index b23b649..c2b5f9f 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -1881,6 +1881,72 @@ gabble_media_channel_request_streams (TpSvcChannelTypeStreamedMedia *iface,
     }
 }
 
+/**
+ * gabble_media_channel_request_initial_streams:
+ * @chan: an outgoing call, which must have just been constructed.
+ * @succeeded_cb: called with arguments @user_data and a GPtrArray of
+ *                TP_STRUCT_TYPE_MEDIA_STREAM_INFO if the request succeeds.
+ * @failed_cb: called with arguments @user_data and a GError * if the request
+ *             fails.
+ * @user_data: context for the callbacks.
+ *
+ * Request streams corresponding to the values of InitialAudio and InitialVideo
+ * in the channel request.
+ */
+void
+gabble_media_channel_request_initial_streams (GabbleMediaChannel *chan,
+    GFunc succeeded_cb,
+    GFunc failed_cb,
+    gpointer user_data)
+{
+  GabbleMediaChannelPrivate *priv = chan->priv;
+
+  /* This has to be an outgoing call... */
+  g_assert (priv->creator == priv->conn->parent.self_handle);
+  /* ...which has just been constructed. */
+  g_assert (priv->session == NULL);
+
+  if (priv->initial_peer == 0)
+    {
+      /* This is a ye olde anonymous channel, so InitialAudio/Video should be
+       * impossible.
+       */
+      g_assert (!priv->initial_audio);
+      g_assert (!priv->initial_video);
+    }
+
+  if (!priv->initial_audio && !priv->initial_video)
+    {
+      GPtrArray *empty = g_ptr_array_sized_new (0);
+
+      succeeded_cb (user_data, empty);
+
+      g_ptr_array_free (empty, TRUE);
+    }
+  else
+    {
+      GArray *types = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2);
+      guint media_type;
+
+      if (priv->initial_audio)
+        {
+          media_type = TP_MEDIA_STREAM_TYPE_AUDIO;
+          g_array_append_val (types, media_type);
+        }
+
+      if (priv->initial_video)
+        {
+          media_type = TP_MEDIA_STREAM_TYPE_VIDEO;
+          g_array_append_val (types, media_type);
+        }
+
+      media_channel_request_streams (chan, priv->initial_peer, types,
+          succeeded_cb, failed_cb, user_data);
+
+      g_array_free (types, TRUE);
+    }
+}
+
 static gboolean
 contact_is_media_capable (GabbleMediaChannel *chan,
     TpHandle peer,
diff --git a/src/media-channel.h b/src/media-channel.h
index f542e95..f00e85f 100644
--- a/src/media-channel.h
+++ b/src/media-channel.h
@@ -77,6 +77,11 @@ _gabble_media_channel_typeflags_to_caps (TpChannelMediaCapabilities flags);
 TpChannelMediaCapabilities
 _gabble_media_channel_caps_to_typeflags (GabblePresenceCapabilities caps);
 
+void gabble_media_channel_request_initial_streams (GabbleMediaChannel *chan,
+    GFunc succeeded_cb,
+    GFunc failed_cb,
+    gpointer user_data);
+
 G_END_DECLS
 
 #endif /* #ifndef __GABBLE_MEDIA_CHANNEL_H__*/
diff --git a/src/media-factory.c b/src/media-factory.c
index 873c74b..96ab3be 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -453,6 +453,58 @@ typedef enum
 } RequestMethod;
 
 
+typedef struct
+{
+    GabbleMediaFactory *self;
+    GabbleMediaChannel *channel;
+    gpointer request_token;
+} MediaChannelRequest;
+
+
+static MediaChannelRequest *
+media_channel_request_new (GabbleMediaFactory *self,
+    GabbleMediaChannel *channel,
+    gpointer request_token)
+{
+  MediaChannelRequest *mcr = g_slice_new0 (MediaChannelRequest);
+
+  mcr->self = self;
+  mcr->channel = channel;
+  mcr->request_token = request_token;
+
+  return mcr;
+}
+
+static void
+media_channel_request_free (MediaChannelRequest *mcr)
+{
+  g_slice_free (MediaChannelRequest, mcr);
+}
+
+static void
+media_channel_request_succeeded_cb (MediaChannelRequest *mcr,
+    GPtrArray *streams)
+{
+  GSList *request_tokens;
+
+  request_tokens = g_slist_prepend (NULL, mcr->request_token);
+  tp_channel_manager_emit_new_channel (mcr->self,
+      TP_EXPORTABLE_CHANNEL (mcr->channel), request_tokens);
+  g_slist_free (request_tokens);
+
+  media_channel_request_free (mcr);
+}
+
+static void
+media_channel_request_failed_cb (MediaChannelRequest *mcr,
+    GError *error)
+{
+  tp_channel_manager_emit_request_failed (mcr->self, mcr->request_token,
+      error->domain, error->code, error->message);
+
+  media_channel_request_free (mcr);
+}
+
 static gboolean
 gabble_media_factory_requestotron (TpChannelManager *manager,
                                    gpointer request_token,
@@ -465,7 +517,6 @@ gabble_media_factory_requestotron (TpChannelManager *manager,
   TpHandle handle;
   GabbleMediaChannel *channel = NULL;
   GError *error = NULL;
-  GSList *request_tokens;
   gboolean require_target_handle, add_peer_to_remote_pending;
   gboolean initial_audio, initial_video;
 
@@ -581,10 +632,10 @@ gabble_media_factory_requestotron (TpChannelManager *manager,
 
   g_assert (channel != NULL);
 
-  request_tokens = g_slist_prepend (NULL, request_token);
-  tp_channel_manager_emit_new_channel (self,
-      TP_EXPORTABLE_CHANNEL (channel), request_tokens);
-  g_slist_free (request_tokens);
+  gabble_media_channel_request_initial_streams (channel,
+      (GFunc) media_channel_request_succeeded_cb,
+      (GFunc) media_channel_request_failed_cb,
+      media_channel_request_new (self, channel, request_token));
 
   return TRUE;
 
-- 
1.5.6.5




More information about the telepathy-commits mailing list