changeset 26090:dd3bdf691623

merge of '856023a0b4273c54f6041597332bd5a0fb63ea0e' and 'e13834da8fb12496c12a2b1bbee9fd93028a75b1'
author Mike Ruprecht <maiku@soc.pidgin.im>
date Thu, 08 Jan 2009 04:10:38 +0000
parents ba22c9420221 (current diff) 6c8eabbef4d3 (diff)
children 59188d904773
files
diffstat 3 files changed, 184 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media.c	Thu Jan 08 04:10:31 2009 +0000
+++ b/libpurple/media.c	Thu Jan 08 04:10:38 2009 +0000
@@ -92,6 +92,7 @@
 
 static void purple_media_class_init (PurpleMediaClass *klass);
 static void purple_media_init (PurpleMedia *media);
+static void purple_media_dispose (GObject *object);
 static void purple_media_finalize (GObject *object);
 static void purple_media_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 static void purple_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
@@ -179,6 +180,7 @@
 	GObjectClass *gobject_class = (GObjectClass*)klass;
 	parent_class = g_type_class_peek_parent(klass);
 	
+	gobject_class->dispose = purple_media_dispose;
 	gobject_class->finalize = purple_media_finalize;
 	gobject_class->set_property = purple_media_set_property;
 	gobject_class->get_property = purple_media_get_property;
@@ -274,7 +276,6 @@
 purple_media_stream_free(PurpleMediaStream *stream)
 {
 	g_free(stream->participant);
-	g_object_unref(stream->stream);
 
 	if (stream->local_candidates)
 		fs_candidate_list_destroy(stream->local_candidates);
@@ -293,19 +294,63 @@
 purple_media_session_free(PurpleMediaSession *session)
 {
 	g_free(session->id);
-	g_object_unref(session->session);
 	g_free(session);
 }
 
 static void
-purple_media_finalize (GObject *media)
+purple_media_dispose(GObject *media)
+{
+	PurpleMediaPrivate *priv = PURPLE_MEDIA_GET_PRIVATE(media);
+	GList *iter = NULL;
+
+	purple_debug_info("media","purple_media_dispose\n");
+
+	purple_media_manager_remove_media(purple_media_manager_get(),
+			PURPLE_MEDIA(media));
+
+	if (priv->pipeline) {
+		GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(priv->pipeline));
+		gst_bus_remove_signal_watch(bus);
+		gst_object_unref(bus);
+		gst_element_set_state(priv->pipeline, GST_STATE_NULL);
+		gst_object_unref(priv->pipeline);
+		priv->pipeline = NULL;
+	}
+
+	for (iter = priv->streams; iter; iter = g_list_next(iter)) {
+		PurpleMediaStream *stream = iter->data;
+		if (stream->stream) {
+			g_object_unref(stream->stream);
+			stream->stream = NULL;
+		}
+	}
+
+	if (priv->sessions) {
+		GList *sessions = g_hash_table_get_values(priv->sessions);
+		for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+			PurpleMediaSession *session = sessions->data;
+			if (session->session) {
+				g_object_unref(session->session);
+				session->session = NULL;
+			}
+		}
+	}
+
+	if (priv->participants) {
+		GList *participants = g_hash_table_get_values(priv->participants);
+		for (; participants; participants = g_list_delete_link(participants, participants))
+			g_object_unref(participants->data);
+	}
+
+	G_OBJECT_CLASS(parent_class)->finalize(media);
+}
+
+static void
+purple_media_finalize(GObject *media)
 {
 	PurpleMediaPrivate *priv = PURPLE_MEDIA_GET_PRIVATE(media);
 	purple_debug_info("media","purple_media_finalize\n");
 
-	purple_media_manager_remove_media(purple_media_manager_get(),
-			PURPLE_MEDIA(media));
-
 	for (; priv->streams; priv->streams = g_list_delete_link(priv->streams, priv->streams))
 		purple_media_stream_free(priv->streams->data);
 
@@ -317,24 +362,9 @@
 		g_hash_table_destroy(priv->sessions);
 	}
 
-	if (priv->participants) {
-		GList *participants = g_hash_table_get_values(priv->participants);
-		for (; participants; participants = g_list_delete_link(participants, participants))
-			g_object_unref(participants->data);
-		g_hash_table_destroy(priv->participants);
-	}
-
-	if (priv->pipeline) {
-		GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(priv->pipeline));
-		gst_bus_remove_signal_watch(bus);
-		gst_object_unref(bus);
-		gst_element_set_state(priv->pipeline, GST_STATE_NULL);
-		gst_object_unref(priv->pipeline);
-	}
-
 	gst_object_unref(priv->conference);
 
-	parent_class->finalize(media);
+	G_OBJECT_CLASS(parent_class)->finalize(media);
 }
 
 static void
@@ -822,6 +852,21 @@
 	return media->priv->pipeline;
 }
 
+static void
+purple_media_set_remote_candidates(PurpleMediaStream *stream)
+{
+	GError *err = NULL;
+
+	fs_stream_set_remote_candidates(stream->stream,
+			stream->remote_candidates, &err);
+
+	if (err) {
+		purple_debug_error("media", "Error adding remote"
+				" candidates: %s\n", err->message);
+		g_error_free(err);
+	}
+}
+
 void
 purple_media_error(PurpleMedia *media, const gchar *error, ...)
 {
@@ -854,6 +899,7 @@
 purple_media_accept(PurpleMedia *media)
 {
 	GList *sessions;
+	GList *streams;
 
 	g_signal_emit(media, purple_media_signals[ACCEPTED], 0);
 
@@ -865,6 +911,12 @@
 
 		purple_media_emit_ready(media, session, NULL);
 	}
+
+	streams = media->priv->streams;
+
+	for (; streams; streams = g_list_next(streams)) {
+		purple_media_set_remote_candidates(streams->data);
+	}
 }
 
 void
@@ -910,6 +962,7 @@
 purple_media_got_accept(PurpleMedia *media)
 {
 	GList *sessions;
+	GList *streams;
 
 	g_signal_emit(media, purple_media_signals[GOT_ACCEPT], 0);
 
@@ -919,6 +972,12 @@
 		PurpleMediaSession *session = sessions->data;
 		session->accepted = TRUE;
 	}
+
+	streams = media->priv->streams;
+
+	for (; streams; streams = g_list_next(streams)) {
+		purple_media_set_remote_candidates(streams->data);
+	}
 }
 
 GList*
@@ -1435,16 +1494,11 @@
 				   const gchar *name, GList *remote_candidates)
 {
 	PurpleMediaStream *stream = purple_media_get_stream(media, sess_id, name);
-	GError *err = NULL;
 	stream->remote_candidates = g_list_concat(stream->remote_candidates,
 			fs_candidate_list_copy(remote_candidates));
 
-	fs_stream_set_remote_candidates(stream->stream, stream->remote_candidates, &err);
-
-	if (err) {
-		purple_debug_error("media", "Error adding remote candidates: %s\n",
-				   err->message);
-		g_error_free(err);
+	if (stream->session->accepted == TRUE) {
+		purple_media_set_remote_candidates(stream);
 	}
 }
 
--- a/libpurple/protocols/jabber/google.c	Thu Jan 08 04:10:31 2009 +0000
+++ b/libpurple/protocols/jabber/google.c	Thu Jan 08 04:10:38 2009 +0000
@@ -79,7 +79,8 @@
 static void
 google_session_destroy(GoogleSession *session)
 {
-	g_hash_table_remove(sessions, &(session->id));
+	if (sessions != NULL)
+		g_hash_table_remove(sessions, &(session->id));
 	g_free(session->id.id);
 	g_free(session->id.initiator);
 	g_free(session->remote_jid);
--- a/pidgin/gtkmedia.c	Thu Jan 08 04:10:31 2009 +0000
+++ b/pidgin/gtkmedia.c	Thu Jan 08 04:10:38 2009 +0000
@@ -75,6 +75,7 @@
 
 static void pidgin_media_class_init (PidginMediaClass *klass);
 static void pidgin_media_init (PidginMedia *media);
+static void pidgin_media_dispose (GObject *object);
 static void pidgin_media_finalize (GObject *object);
 static void pidgin_media_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 static void pidgin_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
@@ -130,6 +131,7 @@
 /*	GtkContainerClass *container_class = (GtkContainerClass*)klass; */
 	parent_class = g_type_class_peek_parent(klass);
 
+	gobject_class->dispose = pidgin_media_dispose;
 	gobject_class->finalize = pidgin_media_finalize;
 	gobject_class->set_property = pidgin_media_set_property;
 	gobject_class->get_property = pidgin_media_get_property;
@@ -259,20 +261,56 @@
 }
 
 static void
-pidgin_media_finalize (GObject *media)
+pidgin_media_dispose(GObject *media)
+{
+	PidginMedia *gtkmedia = PIDGIN_MEDIA(media);
+	purple_debug_info("gtkmedia", "pidgin_media_dispose\n");
+
+	if (gtkmedia->priv->media) {
+		GstElement *videosendbin = NULL, *videorecvbin = NULL;
+
+		purple_media_get_elements(gtkmedia->priv->media, NULL, NULL,
+					  &videosendbin, &videorecvbin);
+
+		if (videorecvbin) {
+			gst_element_set_locked_state(videorecvbin, TRUE);
+			gst_element_set_state(videorecvbin, GST_STATE_NULL);
+		}
+		if (videosendbin) {
+			gst_element_set_locked_state(videosendbin, TRUE);
+			gst_element_set_state(videosendbin, GST_STATE_NULL);
+		}
+
+		pidgin_media_disconnect_levels(gtkmedia->priv->media, gtkmedia);
+		g_object_unref(gtkmedia->priv->media);
+		gtkmedia->priv->media = NULL;
+	}
+
+	if (gtkmedia->priv->send_level) {
+		gst_object_unref(gtkmedia->priv->send_level);
+		gtkmedia->priv->send_level = NULL;
+	}
+
+	if (gtkmedia->priv->recv_level) {
+		gst_object_unref(gtkmedia->priv->recv_level);
+		gtkmedia->priv->recv_level = NULL;
+	}
+
+	G_OBJECT_CLASS(parent_class)->dispose(media);
+}
+
+static void
+pidgin_media_finalize(GObject *media)
 {
 	PidginMedia *gtkmedia = PIDGIN_MEDIA(media);
 	purple_debug_info("gtkmedia", "pidgin_media_finalize\n");
-	if (gtkmedia->priv->media) {
-		pidgin_media_disconnect_levels(gtkmedia->priv->media, gtkmedia);
-		g_object_unref(gtkmedia->priv->media);
+
+	if (gtkmedia->priv->display) {
+		gtk_widget_destroy(gtkmedia->priv->display);
+		gtkmedia->priv->display = NULL;
 	}
-	if (gtkmedia->priv->send_level)
-		gst_object_unref(gtkmedia->priv->send_level);
-	if (gtkmedia->priv->recv_level)
-		gst_object_unref(gtkmedia->priv->recv_level);
-	if (gtkmedia->priv->display)
-		gtk_widget_destroy(gtkmedia->priv->display);
+
+	G_OBJECT_CLASS(parent_class)->finalize(media);
 }
 
 static void
@@ -324,6 +362,25 @@
 	g_signal_emit(gtkmedia, pidgin_media_signals[ERROR], 0, error);
 }
 
+static gboolean
+plug_delete_event_cb(GtkWidget *widget, gpointer data)
+{
+	return TRUE;
+}
+
+static gboolean
+plug_removed_cb(GtkWidget *widget, gpointer data)
+{
+	return TRUE;
+}
+
+static void
+socket_realize_cb(GtkWidget *widget, gpointer data)
+{
+	gtk_socket_add_id(GTK_SOCKET(widget),
+			gtk_plug_get_id(GTK_PLUG(data)));
+}
+
 static void
 pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia)
 {
@@ -375,13 +432,28 @@
 	if (videorecvbool) {
 		GtkWidget *aspect;
 		GtkWidget *remote_video;
+		GtkWidget *plug;
+		GtkWidget *socket;
 
 		aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE);
 		gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN);
 		gtk_box_pack_start(GTK_BOX(recv_widget), aspect, TRUE, TRUE, 0);
 
+		plug = gtk_plug_new(0);
+		g_signal_connect(G_OBJECT(plug), "delete-event",
+				G_CALLBACK(plug_delete_event_cb), plug);
+		gtk_widget_show(plug);
+
+		socket = gtk_socket_new();
+		g_signal_connect(G_OBJECT(socket), "realize",
+				G_CALLBACK(socket_realize_cb), plug);
+		g_signal_connect(G_OBJECT(socket), "plug-removed",
+				G_CALLBACK(plug_removed_cb), NULL);
+		gtk_container_add(GTK_CONTAINER(aspect), socket);
+		gtk_widget_show(socket);
+
 		remote_video = gtk_drawing_area_new();
-		gtk_container_add(GTK_CONTAINER(aspect), remote_video);
+		gtk_container_add(GTK_CONTAINER(plug), remote_video);
 		gtk_widget_set_size_request (GTK_WIDGET(remote_video), 100, -1);
 		gtk_widget_show(remote_video);
 		gtk_widget_show(aspect);
@@ -391,16 +463,30 @@
 	if (videosendbin) {
 		GtkWidget *aspect;
 		GtkWidget *local_video;
+		GtkWidget *plug;
+		GtkWidget *socket;
 
 		aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE);
 		gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN);
 		gtk_box_pack_start(GTK_BOX(send_widget), aspect, TRUE, TRUE, 0);
 
+		plug = gtk_plug_new(0);
+		g_signal_connect(G_OBJECT(plug), "delete-event",
+				G_CALLBACK(plug_delete_event_cb), plug);
+		gtk_widget_show(plug);
+
+		socket = gtk_socket_new();
+		g_signal_connect(G_OBJECT(socket), "realize",
+				G_CALLBACK(socket_realize_cb), plug);
+		g_signal_connect(G_OBJECT(socket), "plug-removed",
+				G_CALLBACK(plug_removed_cb), NULL);
+		gtk_container_add(GTK_CONTAINER(aspect), socket);
+		gtk_widget_show(socket);
+
 		local_video = gtk_drawing_area_new();
 		g_signal_connect(G_OBJECT(local_video), "realize",
 				G_CALLBACK(realize_cb), videosendbin);
-
-		gtk_container_add(GTK_CONTAINER(aspect), local_video);
+		gtk_container_add(GTK_CONTAINER(plug), local_video);
 		gtk_widget_set_size_request (GTK_WIDGET(local_video), 100, -1);
 
 		gtk_widget_show(local_video);