Mercurial > pidgin.yaz
comparison pidgin/gtkmedia.c @ 25686:3bf9748fdef0
Preliminary video embedded in the conversation window. It's still kind of buggy.
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Tue, 10 Jun 2008 05:18:29 +0000 |
parents | 54adcf17d271 |
children | ddbea813862e |
comparison
equal
deleted
inserted
replaced
25685:c2231cf3be71 | 25686:3bf9748fdef0 |
---|---|
26 #include <string.h> | 26 #include <string.h> |
27 #include "debug.h" | 27 #include "debug.h" |
28 #include "internal.h" | 28 #include "internal.h" |
29 #include "connection.h" | 29 #include "connection.h" |
30 #include "media.h" | 30 #include "media.h" |
31 #include "pidgin.h" | |
31 | 32 |
32 #include "gtkmedia.h" | 33 #include "gtkmedia.h" |
33 | 34 |
34 #ifdef USE_VV | 35 #ifdef USE_VV |
36 | |
37 #include <gst/interfaces/xoverlay.h> | |
35 | 38 |
36 typedef enum | 39 typedef enum |
37 { | 40 { |
38 /* Waiting for response */ | 41 /* Waiting for response */ |
39 PIDGIN_MEDIA_WAITING = 1, | 42 PIDGIN_MEDIA_WAITING = 1, |
58 | 61 |
59 GtkWidget *send_progress; | 62 GtkWidget *send_progress; |
60 GtkWidget *recv_progress; | 63 GtkWidget *recv_progress; |
61 | 64 |
62 PidginMediaState state; | 65 PidginMediaState state; |
66 | |
67 GtkWidget *display; | |
68 GtkWidget *local_video; | |
69 GtkWidget *remote_video; | |
63 }; | 70 }; |
64 | 71 |
65 #define PIDGIN_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PIDGIN_TYPE_MEDIA, PidginMediaPrivate)) | 72 #define PIDGIN_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PIDGIN_TYPE_MEDIA, PidginMediaPrivate)) |
66 | 73 |
67 static void pidgin_media_class_init (PidginMediaClass *klass); | 74 static void pidgin_media_class_init (PidginMediaClass *klass); |
176 gtk_widget_show(media->priv->send_progress); | 183 gtk_widget_show(media->priv->send_progress); |
177 gtk_widget_show(media->priv->recv_progress); | 184 gtk_widget_show(media->priv->recv_progress); |
178 | 185 |
179 gtk_widget_show_all(media->priv->accept); | 186 gtk_widget_show_all(media->priv->accept); |
180 gtk_widget_show_all(media->priv->reject); | 187 gtk_widget_show_all(media->priv->reject); |
188 | |
189 media->priv->display = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
181 } | 190 } |
182 | 191 |
183 static gboolean | 192 static gboolean |
184 level_message_cb(GstBus *bus, GstMessage *message, PidginMedia *gtkmedia) | 193 level_message_cb(GstBus *bus, GstMessage *message, PidginMedia *gtkmedia) |
185 { | 194 { |
244 } | 253 } |
245 if (gtkmedia->priv->send_level) | 254 if (gtkmedia->priv->send_level) |
246 gst_object_unref(gtkmedia->priv->send_level); | 255 gst_object_unref(gtkmedia->priv->send_level); |
247 if (gtkmedia->priv->recv_level) | 256 if (gtkmedia->priv->recv_level) |
248 gst_object_unref(gtkmedia->priv->recv_level); | 257 gst_object_unref(gtkmedia->priv->recv_level); |
258 if (gtkmedia->priv->display) | |
259 gtk_widget_destroy(gtkmedia->priv->display); | |
249 } | 260 } |
250 | 261 |
251 static void | 262 static void |
252 pidgin_media_emit_message(PidginMedia *gtkmedia, const char *msg) | 263 pidgin_media_emit_message(PidginMedia *gtkmedia, const char *msg) |
253 { | 264 { |
254 g_signal_emit(gtkmedia, pidgin_media_signals[MESSAGE], 0, msg); | 265 g_signal_emit(gtkmedia, pidgin_media_signals[MESSAGE], 0, msg); |
266 } | |
267 | |
268 GtkWidget * | |
269 pidgin_media_get_display_widget(GtkWidget *gtkmedia) | |
270 { | |
271 return PIDGIN_MEDIA_GET_PRIVATE(gtkmedia)->display; | |
255 } | 272 } |
256 | 273 |
257 static gboolean | 274 static gboolean |
258 media_bus_call(GstBus *bus, GstMessage *msg, gpointer gtkmedia) | 275 media_bus_call(GstBus *bus, GstMessage *msg, gpointer gtkmedia) |
259 { | 276 { |
282 } | 299 } |
283 | 300 |
284 return TRUE; | 301 return TRUE; |
285 } | 302 } |
286 | 303 |
304 static gboolean | |
305 create_window (GstBus *bus, GstMessage *message, PidginMedia *gtkmedia) | |
306 { | |
307 char *name; | |
308 | |
309 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT) | |
310 return TRUE; | |
311 | |
312 if (!gst_structure_has_name(message->structure, "prepare-xwindow-id")) | |
313 return TRUE; | |
314 | |
315 name = gst_object_get_name(GST_MESSAGE_SRC (message)); | |
316 purple_debug_info("gtkmedia", "prepare-xwindow-id object name: %s\n", name); | |
317 | |
318 /* The XOverlay's name is the sink's name with a suffix */ | |
319 if (!strncmp(name, "purplevideosink", strlen("purplevideosink"))) | |
320 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)), | |
321 GDK_WINDOW_XWINDOW(gtkmedia->priv->remote_video->window)); | |
322 else if (!strncmp(name, "purplelocalvideosink", strlen("purplelocalvideosink"))) | |
323 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)), | |
324 GDK_WINDOW_XWINDOW(gtkmedia->priv->local_video->window)); | |
325 g_free(name); | |
326 return TRUE; | |
327 } | |
328 | |
287 static void | 329 static void |
288 pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia) | 330 pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia) |
289 { | 331 { |
290 GstElement *element = purple_media_get_pipeline(media); | 332 GstElement *element = purple_media_get_pipeline(media); |
291 | 333 |
292 GstElement *audiosendbin, *audiosendlevel; | 334 GstElement *audiosendbin = NULL, *audiosendlevel = NULL; |
293 GstElement *audiorecvbin, *audiorecvlevel; | 335 GstElement *audiorecvbin = NULL, *audiorecvlevel = NULL; |
294 GstElement *videosendbin; | 336 GstElement *videosendbin = NULL; |
295 GstElement *videorecvbin; | 337 GstElement *videorecvbin = NULL; |
296 | 338 |
297 GList *sessions = purple_media_get_session_names(media); | 339 GList *sessions = purple_media_get_session_names(media); |
298 GstBus *bus; | 340 GstBus *bus; |
299 | 341 |
300 purple_media_audio_init_src(&audiosendbin, &audiosendlevel); | |
301 purple_media_audio_init_recv(&audiorecvbin, &audiorecvlevel); | |
302 | |
303 purple_media_video_init_src(&videosendbin); | |
304 purple_media_video_init_recv(&videorecvbin); | |
305 | |
306 for (; sessions; sessions = sessions->next) { | 342 for (; sessions; sessions = sessions->next) { |
307 if (purple_media_get_session_type(media, sessions->data) & PURPLE_MEDIA_AUDIO) { | 343 if (purple_media_get_session_type(media, sessions->data) & PURPLE_MEDIA_AUDIO) { |
344 if (!audiosendbin) | |
345 purple_media_audio_init_src(&audiosendbin, &audiosendlevel); | |
346 if (!audiorecvbin) | |
347 purple_media_audio_init_recv(&audiorecvbin, &audiorecvlevel); | |
308 purple_media_set_src(media, sessions->data, audiosendbin); | 348 purple_media_set_src(media, sessions->data, audiosendbin); |
309 purple_media_set_sink(media, sessions->data, audiorecvbin); | 349 purple_media_set_sink(media, sessions->data, audiorecvbin); |
310 } else if (purple_media_get_session_type(media, sessions->data) & PURPLE_MEDIA_VIDEO) { | 350 } else if (purple_media_get_session_type(media, sessions->data) & PURPLE_MEDIA_VIDEO) { |
351 if (!videosendbin) | |
352 purple_media_video_init_src(&videosendbin); | |
353 if (!videorecvbin) | |
354 purple_media_video_init_recv(&videorecvbin); | |
311 purple_media_set_src(media, sessions->data, videosendbin); | 355 purple_media_set_src(media, sessions->data, videosendbin); |
312 purple_media_set_sink(media, sessions->data, videorecvbin); | 356 purple_media_set_sink(media, sessions->data, videorecvbin); |
313 } | 357 } |
314 } | 358 } |
315 g_list_free(sessions); | 359 g_list_free(sessions); |
318 g_object_set(gtkmedia, "send-level", audiosendlevel, | 362 g_object_set(gtkmedia, "send-level", audiosendlevel, |
319 "recv-level", audiorecvlevel, | 363 "recv-level", audiorecvlevel, |
320 NULL); | 364 NULL); |
321 } | 365 } |
322 | 366 |
367 if (videorecvbin || videosendbin) { | |
368 GtkWidget *aspect; | |
369 GtkWidget *remote_video; | |
370 GtkWidget *local_video; | |
371 | |
372 gtk_widget_show(gtkmedia->priv->display); | |
373 | |
374 aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE); | |
375 gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN); | |
376 gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display), aspect, TRUE, TRUE, 0); | |
377 | |
378 remote_video = gtk_drawing_area_new(); | |
379 gtk_container_add(GTK_CONTAINER(aspect), remote_video); | |
380 gtk_widget_set_size_request (GTK_WIDGET(remote_video), 100, -1); | |
381 gtk_widget_show(remote_video); | |
382 gtk_widget_show(aspect); | |
383 | |
384 aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE); | |
385 gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN); | |
386 gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display), aspect, TRUE, TRUE, 0); | |
387 | |
388 local_video = gtk_drawing_area_new(); | |
389 gtk_container_add(GTK_CONTAINER(aspect), local_video); | |
390 gtk_widget_show(local_video); | |
391 gtk_widget_show(aspect); | |
392 | |
393 gtkmedia->priv->local_video = local_video; | |
394 gtkmedia->priv->remote_video = remote_video; | |
395 } | |
396 | |
323 bus = gst_pipeline_get_bus(GST_PIPELINE(element)); | 397 bus = gst_pipeline_get_bus(GST_PIPELINE(element)); |
324 gst_bus_add_signal_watch(GST_BUS(bus)); | 398 gst_bus_add_signal_watch(GST_BUS(bus)); |
325 g_signal_connect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), "message", G_CALLBACK(level_message_cb), gtkmedia); | 399 g_signal_connect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), |
400 "message", G_CALLBACK(level_message_cb), gtkmedia); | |
401 if (videorecvbin || videosendbin) | |
402 gst_bus_set_sync_handler(bus, (GstBusSyncHandler)create_window, gtkmedia); | |
326 gst_bus_add_watch(bus, media_bus_call, gtkmedia); | 403 gst_bus_add_watch(bus, media_bus_call, gtkmedia); |
327 gst_object_unref(bus); | 404 gst_object_unref(bus); |
328 } | 405 } |
329 | 406 |
330 static void | 407 static void |