changeset 26065:7caa7e2ce870

Implement a new ready signal.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Sun, 04 Jan 2009 07:42:12 +0000
parents f7a2045f9346
children 607d82dce00e
files libpurple/media.c libpurple/protocols/jabber/jingle/rtp.c
diffstat 2 files changed, 99 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media.c	Sun Jan 04 05:21:25 2009 +0000
+++ b/libpurple/media.c	Sun Jan 04 07:42:12 2009 +0000
@@ -53,6 +53,9 @@
 	FsSession *session;
 
 	PurpleMediaSessionType type;
+
+	gboolean codecs_ready;
+	gboolean accepted;
 };
 
 struct _PurpleMediaStream
@@ -118,6 +121,7 @@
 	CANDIDATES_PREPARED,
 	CANDIDATE_PAIR,
 	CODECS_READY,
+	READY_NEW,
 	LAST_SIGNAL
 };
 static guint purple_media_signals[LAST_SIGNAL] = {0};
@@ -228,7 +232,10 @@
 					 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
 					 g_cclosure_marshal_VOID__STRING,
 					 G_TYPE_NONE, 1, G_TYPE_STRING);
-
+	purple_media_signals[READY_NEW] = g_signal_new("ready-new", G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+					 purple_smarshal_VOID__STRING_STRING,
+					 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
 	g_type_class_add_private(klass, sizeof(PurpleMediaPrivate));
 }
 
@@ -628,6 +635,50 @@
 	return NULL;
 }
 
+/* This could also emit when participants are ready */
+static void
+purple_media_emit_ready(PurpleMedia *media, PurpleMediaSession *session, const gchar *participant)
+{
+	GList *sessions;
+	gboolean conf_ready = TRUE;
+
+	if ((session != NULL) && ((session->accepted == FALSE) ||
+			(purple_media_codecs_ready(media, session->id) == FALSE)))
+		return;
+
+	sessions = g_hash_table_get_values(media->priv->sessions);
+
+	for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+		PurpleMediaSession *session_data = sessions->data;
+		GList *streams = purple_media_get_streams(media,
+				session_data->id, NULL);
+
+		if ((session_data->accepted == FALSE) ||
+				(purple_media_codecs_ready(
+				media, session_data->id) == FALSE))
+			conf_ready = FALSE;
+
+		for (; streams; streams = g_list_delete_link(streams, streams)) {
+			PurpleMediaStream *stream = streams->data;
+			if (stream->candidates_prepared == TRUE &&
+					session_data == session)
+				g_signal_emit(media, purple_media_signals[READY_NEW],
+						0, session_data->id, stream->participant);
+		}
+
+		if (session == session_data || session == NULL)
+			g_signal_emit(media, purple_media_signals[READY_NEW],
+					0, session_data->id, NULL);
+	}
+
+	if (conf_ready == TRUE) {
+		g_list_free(sessions);
+	} else {
+		g_signal_emit(media, purple_media_signals[READY_NEW],
+				0, NULL, NULL);
+	}
+}
+
 static gboolean
 media_bus_call(GstBus *bus, GstMessage *msg, gpointer media)
 {
@@ -699,9 +750,16 @@
 				for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
 					PurpleMediaSession *session = sessions->data;
 					if (session->session == fssession) {
-						g_signal_emit(session->media,
-								purple_media_signals[CODECS_READY],
-								0, session->id);
+						gboolean ready;
+						g_object_get(session->session, "codecs-ready", &ready, NULL);
+						if (session->codecs_ready == FALSE && ready == TRUE) {
+							g_signal_emit(session->media,
+									purple_media_signals[CODECS_READY],
+									0, session->id);
+							purple_media_emit_ready(media, session, NULL);
+						}
+						session->codecs_ready = ready;
+
 						g_list_free(sessions);
 						break;
 					}
@@ -766,7 +824,18 @@
 void
 purple_media_accept(PurpleMedia *media)
 {
+	GList *sessions;
+
 	g_signal_emit(media, purple_media_signals[ACCEPTED], 0);
+
+	sessions = g_hash_table_get_values(media->priv->sessions);
+
+	for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+		PurpleMediaSession *session = sessions->data;
+		session->accepted = TRUE;
+
+		purple_media_emit_ready(media, session, NULL);
+	}
 }
 
 void
@@ -796,7 +865,17 @@
 void
 purple_media_got_accept(PurpleMedia *media)
 {
-    g_signal_emit(media, purple_media_signals[GOT_ACCEPT], 0);
+	GList *sessions;
+
+	g_signal_emit(media, purple_media_signals[GOT_ACCEPT], 0);
+
+	sessions = g_hash_table_get_values(media->priv->sessions);
+
+	for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+		PurpleMediaSession *session = sessions->data;
+		session->accepted = TRUE;
+		purple_media_emit_ready(media, session, NULL);
+	}
 }
 
 GList*
@@ -1027,11 +1106,19 @@
 {
 	gchar *name;
 	FsParticipant *participant;
+	PurpleMediaStream *stream_data;
+
 	g_object_get(stream, "participant", &participant, NULL);
 	g_object_get(participant, "cname", &name, NULL);
 	g_object_unref(participant);
+
+	stream_data = purple_media_get_stream(session->media, session->id, name);
+	stream_data->candidates_prepared = TRUE;
+
 	g_signal_emit(session->media, purple_media_signals[CANDIDATES_PREPARED],
 			0, session->id, name);
+
+	purple_media_emit_ready(session->media, session, name);
 	g_free(name);
 }
 
--- a/libpurple/protocols/jabber/jingle/rtp.c	Sun Jan 04 05:21:25 2009 +0000
+++ b/libpurple/protocols/jabber/jingle/rtp.c	Sun Jan 04 07:42:12 2009 +0000
@@ -363,6 +363,11 @@
 	}
 }
 
+static void
+jingle_rtp_ready_new_cb(PurpleMedia *media, gchar *sid, gchar *name, JingleSession *session) {
+	purple_debug_info("rtp", "ready-new: session: %s name: %s\n", sid, name);
+}
+
 static PurpleMedia *
 jingle_rtp_create_media(JingleContent *content)
 {
@@ -404,6 +409,8 @@
 				 G_CALLBACK(jingle_rtp_candidate_pair_established_cb), session);
 	g_signal_connect(G_OBJECT(media), "codecs-ready",
 				 G_CALLBACK(jingle_rtp_codecs_ready_cb), session);
+	g_signal_connect(G_OBJECT(media), "ready-new",
+				 G_CALLBACK(jingle_rtp_ready_new_cb), session);
 
 	g_object_unref(session);
 	return media;