# HG changeset patch # User Mike Ruprecht # Date 1231387838 0 # Node ID dd3bdf6916236adde1d106336e0abde9cb75d4b6 # Parent ba22c9420221d4cd5d645a6eaf3c9984be3c3a82# Parent 6c8eabbef4d3e3afd987b45783a95f72ced67d56 merge of '856023a0b4273c54f6041597332bd5a0fb63ea0e' and 'e13834da8fb12496c12a2b1bbee9fd93028a75b1' diff -r ba22c9420221 -r dd3bdf691623 libpurple/media.c --- 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); } } diff -r ba22c9420221 -r dd3bdf691623 libpurple/protocols/jabber/google.c --- 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); diff -r ba22c9420221 -r dd3bdf691623 pidgin/gtkmedia.c --- 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);