| 350 TRUE, TRUE, PIDGIN_HIG_BOX_SPACE); |
350 TRUE, TRUE, PIDGIN_HIG_BOX_SPACE); |
| 351 gtk_widget_show(vbox); |
351 gtk_widget_show(vbox); |
| 352 |
352 |
| 353 g_signal_connect(G_OBJECT(media), "delete-event", |
353 g_signal_connect(G_OBJECT(media), "delete-event", |
| 354 G_CALLBACK(pidgin_media_delete_event_cb), media); |
354 G_CALLBACK(pidgin_media_delete_event_cb), media); |
| |
355 |
| |
356 media->priv->recv_progressbars = |
| |
357 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
| |
358 media->priv->remote_videos = |
| |
359 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
| |
360 } |
| |
361 |
| |
362 static gchar * |
| |
363 create_key(const gchar *session_id, const gchar *participant) |
| |
364 { |
| |
365 return g_strdup_printf("%s_%s", session_id, participant); |
| |
366 } |
| |
367 |
| |
368 static void |
| |
369 pidgin_media_insert_widget(PidginMedia *gtkmedia, GtkWidget *widget, |
| |
370 const gchar *session_id, const gchar *participant) |
| |
371 { |
| |
372 gchar *key = create_key(session_id, participant); |
| |
373 PurpleMediaSessionType type = |
| |
374 purple_media_get_session_type(gtkmedia->priv->media, session_id); |
| |
375 |
| |
376 if (type & PURPLE_MEDIA_AUDIO) |
| |
377 g_hash_table_insert(gtkmedia->priv->recv_progressbars, key, widget); |
| |
378 else if (type & PURPLE_MEDIA_VIDEO) |
| |
379 g_hash_table_insert(gtkmedia->priv->remote_videos, key, widget); |
| |
380 } |
| |
381 |
| |
382 static GtkWidget * |
| |
383 pidgin_media_get_widget(PidginMedia *gtkmedia, |
| |
384 const gchar *session_id, const gchar *participant) |
| |
385 { |
| |
386 GtkWidget *widget = NULL; |
| |
387 gchar *key = create_key(session_id, participant); |
| |
388 PurpleMediaSessionType type = |
| |
389 purple_media_get_session_type(gtkmedia->priv->media, session_id); |
| |
390 |
| |
391 if (type & PURPLE_MEDIA_AUDIO) |
| |
392 widget = g_hash_table_lookup(gtkmedia->priv->recv_progressbars, key); |
| |
393 else if (type & PURPLE_MEDIA_VIDEO) |
| |
394 widget = g_hash_table_lookup(gtkmedia->priv->remote_videos, key); |
| |
395 |
| |
396 g_free(key); |
| |
397 return widget; |
| |
398 } |
| |
399 |
| |
400 static void |
| |
401 pidgin_media_remove_widget(PidginMedia *gtkmedia, |
| |
402 const gchar *session_id, const gchar *participant) |
| |
403 { |
| |
404 GtkWidget *widget = pidgin_media_get_widget(gtkmedia, session_id, participant); |
| |
405 |
| |
406 if (widget) { |
| |
407 PurpleMediaSessionType type = |
| |
408 purple_media_get_session_type(gtkmedia->priv->media, session_id); |
| |
409 gchar *key = create_key(session_id, participant); |
| |
410 GtkRequisition req; |
| |
411 |
| |
412 if (type & PURPLE_MEDIA_AUDIO) { |
| |
413 g_hash_table_remove(gtkmedia->priv->recv_progressbars, key); |
| |
414 |
| |
415 if (g_hash_table_size(gtkmedia->priv->recv_progressbars) == 0 && |
| |
416 gtkmedia->priv->send_progress) { |
| |
417 |
| |
418 gtk_widget_destroy(gtkmedia->priv->send_progress); |
| |
419 gtkmedia->priv->send_progress = NULL; |
| |
420 |
| |
421 gtk_widget_destroy(gtkmedia->priv->mute); |
| |
422 gtkmedia->priv->mute = NULL; |
| |
423 } |
| |
424 } else if (type & PURPLE_MEDIA_VIDEO) { |
| |
425 g_hash_table_remove(gtkmedia->priv->remote_videos, key); |
| |
426 |
| |
427 if (g_hash_table_size(gtkmedia->priv->remote_videos) == 0 && |
| |
428 gtkmedia->priv->local_video) { |
| |
429 |
| |
430 gtk_widget_destroy(gtkmedia->priv->local_video); |
| |
431 gtkmedia->priv->local_video = NULL; |
| |
432 |
| |
433 gtk_widget_destroy(gtkmedia->priv->pause); |
| |
434 gtkmedia->priv->pause = NULL; |
| |
435 } |
| |
436 } |
| |
437 |
| |
438 g_free(key); |
| |
439 |
| |
440 gtk_widget_destroy(widget); |
| |
441 |
| |
442 gtk_widget_size_request(GTK_WIDGET(gtkmedia), &req); |
| |
443 gtk_window_resize(GTK_WINDOW(gtkmedia), req.width, req.height); |
| |
444 } |
| 355 } |
445 } |
| 356 |
446 |
| 357 static void |
447 static void |
| 358 level_message_cb(PurpleMedia *media, gchar *session_id, gchar *participant, |
448 level_message_cb(PurpleMedia *media, gchar *session_id, gchar *participant, |
| 359 double level, PidginMedia *gtkmedia) |
449 double level, PidginMedia *gtkmedia) |
| 360 { |
450 { |
| 361 GtkWidget *progress; |
451 GtkWidget *progress = NULL; |
| 362 if (participant == NULL) |
452 if (participant == NULL) |
| 363 progress = gtkmedia->priv->send_progress; |
453 progress = gtkmedia->priv->send_progress; |
| 364 else |
454 else |
| 365 progress = gtkmedia->priv->recv_progress; |
455 progress = pidgin_media_get_widget(gtkmedia, session_id, participant); |
| 366 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level * 5); |
456 |
| |
457 if (progress) |
| |
458 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level * 5); |
| 367 } |
459 } |
| 368 |
460 |
| 369 |
461 |
| 370 static void |
462 static void |
| 371 pidgin_media_disconnect_levels(PurpleMedia *media, PidginMedia *gtkmedia) |
463 pidgin_media_disconnect_levels(PurpleMedia *media, PidginMedia *gtkmedia) |
| 434 |
533 |
| 435 static gboolean |
534 static gboolean |
| 436 realize_cb_cb(PidginMediaRealizeData *data) |
535 realize_cb_cb(PidginMediaRealizeData *data) |
| 437 { |
536 { |
| 438 PidginMediaPrivate *priv = data->gtkmedia->priv; |
537 PidginMediaPrivate *priv = data->gtkmedia->priv; |
| 439 gulong window_id; |
538 GdkWindow *window = NULL; |
| 440 |
539 |
| |
540 if (data->participant == NULL) |
| |
541 #if GTK_CHECK_VERSION(2, 14, 0) |
| |
542 window = gtk_widget_get_window(priv->local_video); |
| |
543 #else |
| |
544 window = (priv->local_video)->window; |
| |
545 #endif |
| |
546 else { |
| |
547 GtkWidget *widget = pidgin_media_get_widget(data->gtkmedia, |
| |
548 data->session_id, data->participant); |
| |
549 if (widget) |
| |
550 #if GTK_CHECK_VERSION(2, 14, 0) |
| |
551 window = gtk_widget_get_window(widget); |
| |
552 #else |
| |
553 window = widget->window; |
| |
554 #endif |
| |
555 } |
| |
556 |
| |
557 if (window) { |
| |
558 gulong window_id; |
| 441 #ifdef _WIN32 |
559 #ifdef _WIN32 |
| 442 if (data->participant == NULL) |
560 window_id = GDK_WINDOW_HWND(window); |
| 443 window_id = GDK_WINDOW_HWND(priv->local_video->window); |
|
| 444 else |
|
| 445 window_id = GDK_WINDOW_HWND(priv->remote_video->window); |
|
| 446 #elif defined(HAVE_X11) |
561 #elif defined(HAVE_X11) |
| 447 if (data->participant == NULL) |
562 window_id = gdk_x11_window_get_xid(window); |
| 448 window_id = gdk_x11_window_get_xid(gtk_widget_get_window(priv->local_video)); |
|
| 449 else |
|
| 450 window_id = gdk_x11_window_get_xid(gtk_widget_get_window(priv->remote_video)); |
|
| 451 #else |
563 #else |
| 452 # error "Unsupported windowing system" |
564 # error "Unsupported windowing system" |
| 453 #endif |
565 #endif |
| 454 |
566 |
| 455 purple_media_set_output_window(priv->media, data->session_id, |
567 purple_media_set_output_window(priv->media, data->session_id, |
| 456 data->participant, window_id); |
568 data->participant, window_id); |
| |
569 } |
| 457 |
570 |
| 458 g_free(data->session_id); |
571 g_free(data->session_id); |
| 459 g_free(data->participant); |
572 g_free(data->participant); |
| 460 g_free(data); |
573 g_free(data); |
| 461 return FALSE; |
574 return FALSE; |
| 561 double val = (double)gtk_range_get_value(GTK_RANGE(range)); |
679 double val = (double)gtk_range_get_value(GTK_RANGE(range)); |
| 562 #endif |
680 #endif |
| 563 purple_media_set_output_volume(media, NULL, NULL, val); |
681 purple_media_set_output_volume(media, NULL, NULL, val); |
| 564 } |
682 } |
| 565 |
683 |
| |
684 static void |
| |
685 destroy_parent_widget_cb(GtkWidget *widget, GtkWidget *parent) |
| |
686 { |
| |
687 g_return_if_fail(GTK_IS_WIDGET(parent)); |
| |
688 |
| |
689 gtk_widget_destroy(parent); |
| |
690 } |
| |
691 |
| 566 static GtkWidget * |
692 static GtkWidget * |
| 567 pidgin_media_add_audio_widget(PidginMedia *gtkmedia, |
693 pidgin_media_add_audio_widget(PidginMedia *gtkmedia, |
| 568 PurpleMediaSessionType type) |
694 PurpleMediaSessionType type, const gchar *sid) |
| 569 { |
695 { |
| 570 GtkWidget *volume_widget, *progress_parent, *volume, *progress; |
696 GtkWidget *volume_widget, *progress_parent, *volume, *progress; |
| 571 double value; |
697 double value; |
| 572 |
698 |
| 573 if (type & PURPLE_MEDIA_SEND_AUDIO) { |
699 if (type & PURPLE_MEDIA_SEND_AUDIO) { |
| 617 gtkmedia->priv->send_progress = progress; |
743 gtkmedia->priv->send_progress = progress; |
| 618 } else if (type & PURPLE_MEDIA_RECV_AUDIO) { |
744 } else if (type & PURPLE_MEDIA_RECV_AUDIO) { |
| 619 g_signal_connect (G_OBJECT(volume), "value-changed", |
745 g_signal_connect (G_OBJECT(volume), "value-changed", |
| 620 G_CALLBACK(pidgin_media_output_volume_changed), |
746 G_CALLBACK(pidgin_media_output_volume_changed), |
| 621 gtkmedia->priv->media); |
747 gtkmedia->priv->media); |
| 622 gtkmedia->priv->recv_progress = progress; |
748 |
| 623 } |
749 pidgin_media_insert_widget(gtkmedia, progress, sid, gtkmedia->priv->screenname); |
| |
750 } |
| |
751 |
| |
752 g_signal_connect(G_OBJECT(progress), "destroy", |
| |
753 G_CALLBACK(destroy_parent_widget_cb), |
| |
754 volume_widget); |
| 624 |
755 |
| 625 gtk_widget_show_all(volume_widget); |
756 gtk_widget_show_all(volume_widget); |
| 626 |
757 |
| 627 return volume_widget; |
758 return volume_widget; |
| 628 } |
759 } |
| 689 gtk_widget_modify_bg(remote_video, GTK_STATE_NORMAL, &color); |
820 gtk_widget_modify_bg(remote_video, GTK_STATE_NORMAL, &color); |
| 690 g_signal_connect(G_OBJECT(remote_video), "realize", |
821 g_signal_connect(G_OBJECT(remote_video), "realize", |
| 691 G_CALLBACK(realize_cb), data); |
822 G_CALLBACK(realize_cb), data); |
| 692 gtk_container_add(GTK_CONTAINER(aspect), remote_video); |
823 gtk_container_add(GTK_CONTAINER(aspect), remote_video); |
| 693 gtk_widget_set_size_request (GTK_WIDGET(remote_video), 320, 240); |
824 gtk_widget_set_size_request (GTK_WIDGET(remote_video), 320, 240); |
| |
825 g_signal_connect(G_OBJECT(remote_video), "destroy", |
| |
826 G_CALLBACK(destroy_parent_widget_cb), aspect); |
| |
827 |
| 694 gtk_widget_show(remote_video); |
828 gtk_widget_show(remote_video); |
| 695 gtk_widget_show(aspect); |
829 gtk_widget_show(aspect); |
| 696 |
830 |
| 697 gtkmedia->priv->remote_video = remote_video; |
831 pidgin_media_insert_widget(gtkmedia, remote_video, |
| 698 } |
832 data->session_id, data->participant); |
| 699 |
833 } |
| 700 if (type & PURPLE_MEDIA_SEND_VIDEO) { |
834 |
| |
835 if (type & PURPLE_MEDIA_SEND_VIDEO && !gtkmedia->priv->local_video) { |
| 701 PidginMediaRealizeData *data; |
836 PidginMediaRealizeData *data; |
| 702 GtkWidget *aspect; |
837 GtkWidget *aspect; |
| 703 GtkWidget *local_video; |
838 GtkWidget *local_video; |
| 704 GdkColor color = {0, 0, 0, 0}; |
839 GdkColor color = {0, 0, 0, 0}; |
| 705 |
840 |
| 716 gtk_widget_modify_bg(local_video, GTK_STATE_NORMAL, &color); |
851 gtk_widget_modify_bg(local_video, GTK_STATE_NORMAL, &color); |
| 717 g_signal_connect(G_OBJECT(local_video), "realize", |
852 g_signal_connect(G_OBJECT(local_video), "realize", |
| 718 G_CALLBACK(realize_cb), data); |
853 G_CALLBACK(realize_cb), data); |
| 719 gtk_container_add(GTK_CONTAINER(aspect), local_video); |
854 gtk_container_add(GTK_CONTAINER(aspect), local_video); |
| 720 gtk_widget_set_size_request (GTK_WIDGET(local_video), 80, 60); |
855 gtk_widget_set_size_request (GTK_WIDGET(local_video), 80, 60); |
| |
856 g_signal_connect(G_OBJECT(local_video), "destroy", |
| |
857 G_CALLBACK(destroy_parent_widget_cb), aspect); |
| 721 |
858 |
| 722 gtk_widget_show(local_video); |
859 gtk_widget_show(local_video); |
| 723 gtk_widget_show(aspect); |
860 gtk_widget_show(aspect); |
| 724 |
861 |
| 725 gtkmedia->priv->pause = |
862 gtkmedia->priv->pause = |
| 734 gtkmedia->priv->local_video = local_video; |
871 gtkmedia->priv->local_video = local_video; |
| 735 } |
872 } |
| 736 if (type & PURPLE_MEDIA_RECV_AUDIO) { |
873 if (type & PURPLE_MEDIA_RECV_AUDIO) { |
| 737 gtk_box_pack_end(GTK_BOX(recv_widget), |
874 gtk_box_pack_end(GTK_BOX(recv_widget), |
| 738 pidgin_media_add_audio_widget(gtkmedia, |
875 pidgin_media_add_audio_widget(gtkmedia, |
| 739 PURPLE_MEDIA_RECV_AUDIO), FALSE, FALSE, 0); |
876 PURPLE_MEDIA_RECV_AUDIO, sid), FALSE, FALSE, 0); |
| 740 } |
877 } |
| 741 |
878 |
| 742 if (type & PURPLE_MEDIA_SEND_AUDIO) { |
879 if (type & PURPLE_MEDIA_SEND_AUDIO) { |
| 743 gtkmedia->priv->mute = |
880 gtkmedia->priv->mute = |
| 744 gtk_toggle_button_new_with_mnemonic("_Mute"); |
881 gtk_toggle_button_new_with_mnemonic("_Mute"); |
| 802 pidgin_media_state_changed_cb(PurpleMedia *media, PurpleMediaState state, |
939 pidgin_media_state_changed_cb(PurpleMedia *media, PurpleMediaState state, |
| 803 gchar *sid, gchar *name, PidginMedia *gtkmedia) |
940 gchar *sid, gchar *name, PidginMedia *gtkmedia) |
| 804 { |
941 { |
| 805 purple_debug_info("gtkmedia", "state: %d sid: %s name: %s\n", |
942 purple_debug_info("gtkmedia", "state: %d sid: %s name: %s\n", |
| 806 state, sid ? sid : "(null)", name ? name : "(null)"); |
943 state, sid ? sid : "(null)", name ? name : "(null)"); |
| 807 if (sid == NULL && name == NULL) { |
944 if (state == PURPLE_MEDIA_STATE_END) { |
| 808 if (state == PURPLE_MEDIA_STATE_END) { |
945 if (sid != NULL && name != NULL) { |
| |
946 pidgin_media_remove_widget(gtkmedia, sid, name); |
| |
947 } else if (sid == NULL && name == NULL) { |
| 809 pidgin_media_emit_message(gtkmedia, |
948 pidgin_media_emit_message(gtkmedia, |
| 810 _("The call has been terminated.")); |
949 _("The call has been terminated.")); |
| 811 gtk_widget_destroy(GTK_WIDGET(gtkmedia)); |
950 gtk_widget_destroy(GTK_WIDGET(gtkmedia)); |
| 812 } |
951 } |
| 813 } else if (state == PURPLE_MEDIA_STATE_NEW && |
952 } else if (state == PURPLE_MEDIA_STATE_NEW && |