| 3614 } |
3620 } |
| 3615 |
3621 |
| 3616 return g_list_reverse(ret); |
3622 return g_list_reverse(ret); |
| 3617 } |
3623 } |
| 3618 |
3624 |
| 3619 static void |
|
| 3620 vv_plugin_changed_cb(const gchar *name, PurplePrefType type, |
|
| 3621 gconstpointer value, gpointer data) |
|
| 3622 { |
|
| 3623 GtkWidget *vbox = data; |
|
| 3624 GtkSizeGroup *sg; |
|
| 3625 GtkWidget *widget; |
|
| 3626 gchar *pref; |
|
| 3627 GList *devices; |
|
| 3628 |
|
| 3629 sg = g_object_get_data(G_OBJECT(vbox), "size-group"); |
|
| 3630 widget = g_object_get_data(G_OBJECT(vbox), "device-hbox"); |
|
| 3631 gtk_widget_destroy(widget); |
|
| 3632 |
|
| 3633 pref = g_strdup(name); |
|
| 3634 strcpy(pref + strlen(pref) - strlen("plugin"), "device"); |
|
| 3635 devices = get_vv_element_devices(value); |
|
| 3636 if (g_list_find_custom(devices, purple_prefs_get_string(pref), |
|
| 3637 (GCompareFunc)strcmp) == NULL) |
|
| 3638 purple_prefs_set_string(pref, g_list_next(devices)->data); |
|
| 3639 widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"), |
|
| 3640 PURPLE_PREF_STRING, pref, devices); |
|
| 3641 g_list_free_full(devices, g_free); |
|
| 3642 gtk_size_group_add_widget(sg, widget); |
|
| 3643 gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5); |
|
| 3644 |
|
| 3645 g_object_set_data(G_OBJECT(vbox), "device-hbox", |
|
| 3646 gtk_widget_get_parent(widget)); |
|
| 3647 g_signal_connect_swapped(widget, "destroy", G_CALLBACK(g_free), pref); |
|
| 3648 } |
|
| 3649 |
|
| 3650 static void |
|
| 3651 make_vv_frame(GtkWidget *parent, GtkSizeGroup *sg, |
|
| 3652 const gchar *name, const gchar **plugin_strs, |
|
| 3653 const gchar *plugin_pref, const gchar *device_pref) |
|
| 3654 { |
|
| 3655 GtkWidget *vbox, *widget; |
|
| 3656 GList *plugins, *devices; |
|
| 3657 |
|
| 3658 vbox = pidgin_make_frame(parent, name); |
|
| 3659 |
|
| 3660 /* Setup plugin preference */ |
|
| 3661 plugins = get_vv_element_plugins(plugin_strs); |
|
| 3662 widget = pidgin_prefs_dropdown_from_list(vbox, _("_Plugin"), |
|
| 3663 PURPLE_PREF_STRING, plugin_pref, |
|
| 3664 plugins); |
|
| 3665 g_list_free(plugins); |
|
| 3666 gtk_size_group_add_widget(sg, widget); |
|
| 3667 gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5); |
|
| 3668 |
|
| 3669 /* Setup device preference */ |
|
| 3670 devices = get_vv_element_devices(purple_prefs_get_string(plugin_pref)); |
|
| 3671 if (g_list_find_custom(devices, purple_prefs_get_string(device_pref), |
|
| 3672 (GCompareFunc)strcmp) == NULL) |
|
| 3673 purple_prefs_set_string(device_pref, g_list_next(devices)->data); |
|
| 3674 widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"), |
|
| 3675 PURPLE_PREF_STRING, device_pref, |
|
| 3676 devices); |
|
| 3677 g_list_free_full(devices, g_free); |
|
| 3678 gtk_size_group_add_widget(sg, widget); |
|
| 3679 gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5); |
|
| 3680 |
|
| 3681 widget = gtk_widget_get_parent(widget); |
|
| 3682 g_object_set_data(G_OBJECT(vbox), "size-group", sg); |
|
| 3683 g_object_set_data(G_OBJECT(vbox), "device-hbox", widget); |
|
| 3684 purple_prefs_connect_callback(vbox, plugin_pref, vv_plugin_changed_cb, |
|
| 3685 vbox); |
|
| 3686 g_signal_connect_swapped(vbox, "destroy", |
|
| 3687 G_CALLBACK(purple_prefs_disconnect_by_handle), vbox); |
|
| 3688 } |
|
| 3689 |
|
| 3690 static GstElement * |
3625 static GstElement * |
| 3691 create_test_element(PurpleMediaElementType type) |
3626 create_test_element(PurpleMediaElementType type) |
| 3692 { |
3627 { |
| 3693 PurpleMediaElementInfo *element_info; |
3628 PurpleMediaElementInfo *element_info; |
| 3694 |
3629 |
| 3781 gdouble percent; |
3717 gdouble percent; |
| 3782 gdouble threshold; |
3718 gdouble threshold; |
| 3783 GstElement *valve; |
3719 GstElement *valve; |
| 3784 |
3720 |
| 3785 percent = gst_msg_db_to_percent(msg, "rms"); |
3721 percent = gst_msg_db_to_percent(msg, "rms"); |
| 3786 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ctx->level), percent); |
3722 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(voice_level), percent); |
| 3787 |
3723 |
| 3788 percent = gst_msg_db_to_percent(msg, "decay"); |
3724 percent = gst_msg_db_to_percent(msg, "decay"); |
| 3789 threshold = gtk_range_get_value(GTK_RANGE(ctx->threshold)) / 100.0; |
3725 threshold = gtk_range_get_value(GTK_RANGE(voice_threshold)) / 100.0; |
| 3790 valve = gst_bin_get_by_name(GST_BIN(GST_ELEMENT_PARENT(src)), "valve"); |
3726 valve = gst_bin_get_by_name(GST_BIN(GST_ELEMENT_PARENT(src)), "valve"); |
| 3791 g_object_set(valve, "drop", (percent < threshold), NULL); |
3727 g_object_set(valve, "drop", (percent < threshold), NULL); |
| 3792 g_object_set(ctx->level, "text", |
3728 g_object_set(voice_level, "text", |
| 3793 (percent < threshold) ? _("DROP") : " ", NULL); |
3729 (percent < threshold) ? _("DROP") : " ", NULL); |
| 3794 } |
3730 } |
| 3795 |
3731 |
| 3796 g_free(name); |
3732 g_free(name); |
| 3797 } |
3733 } |
| 3809 gst_object_unref(voice_pipeline); |
3745 gst_object_unref(voice_pipeline); |
| 3810 voice_pipeline = NULL; |
3746 voice_pipeline = NULL; |
| 3811 } |
3747 } |
| 3812 |
3748 |
| 3813 static void |
3749 static void |
| |
3750 enable_voice_test(void) |
| |
3751 { |
| |
3752 GstBus *bus; |
| |
3753 |
| |
3754 voice_pipeline = create_voice_pipeline(); |
| |
3755 bus = gst_pipeline_get_bus(GST_PIPELINE(voice_pipeline)); |
| |
3756 gst_bus_add_signal_watch(bus); |
| |
3757 g_signal_connect(bus, "message", G_CALLBACK(gst_bus_cb), NULL); |
| |
3758 gst_object_unref(bus); |
| |
3759 } |
| |
3760 |
| |
3761 static void |
| 3814 toggle_voice_test_cb(GtkToggleButton *test, gpointer data) |
3762 toggle_voice_test_cb(GtkToggleButton *test, gpointer data) |
| 3815 { |
3763 { |
| 3816 BusCbCtx *ctx = data; |
|
| 3817 GstBus *bus; |
|
| 3818 |
|
| 3819 if (gtk_toggle_button_get_active(test)) { |
3764 if (gtk_toggle_button_get_active(test)) { |
| 3820 gtk_widget_set_sensitive(ctx->level, TRUE); |
3765 gtk_widget_set_sensitive(voice_level, TRUE); |
| 3821 voice_pipeline = create_voice_pipeline(); |
3766 enable_voice_test(); |
| 3822 bus = gst_pipeline_get_bus(GST_PIPELINE(voice_pipeline)); |
3767 |
| 3823 gst_bus_add_signal_watch(bus); |
3768 g_signal_connect(voice_volume, "value-changed", |
| 3824 g_signal_connect(bus, "message", G_CALLBACK(gst_bus_cb), ctx); |
3769 G_CALLBACK(on_volume_change_cb), NULL); |
| 3825 gst_object_unref(bus); |
|
| 3826 |
|
| 3827 g_signal_connect(ctx->volume, "value-changed", |
|
| 3828 G_CALLBACK(on_volume_change_cb), voice_pipeline); |
|
| 3829 g_signal_connect(test, "destroy", |
3770 g_signal_connect(test, "destroy", |
| 3830 G_CALLBACK(voice_test_destroy_cb), NULL); |
3771 G_CALLBACK(voice_test_destroy_cb), NULL); |
| 3831 g_signal_connect(prefsnotebook, "switch-page", |
3772 g_signal_connect(prefsnotebook, "switch-page", |
| 3832 G_CALLBACK(vv_test_switch_page_cb), test); |
3773 G_CALLBACK(vv_test_switch_page_cb), test); |
| 3833 } else { |
3774 } else { |
| 3834 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ctx->level), 0.0); |
3775 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(voice_level), 0.0); |
| 3835 gtk_widget_set_sensitive(ctx->level, FALSE); |
3776 gtk_widget_set_sensitive(voice_level, FALSE); |
| 3836 g_object_disconnect(ctx->volume, "any-signal::value-changed", |
3777 g_object_disconnect(voice_volume, "any-signal::value-changed", |
| 3837 G_CALLBACK(on_volume_change_cb), voice_pipeline, |
3778 G_CALLBACK(on_volume_change_cb), NULL, |
| 3838 NULL); |
3779 NULL); |
| 3839 g_object_disconnect(test, "any-signal::destroy", |
3780 g_object_disconnect(test, "any-signal::destroy", |
| 3840 G_CALLBACK(voice_test_destroy_cb), NULL, |
3781 G_CALLBACK(voice_test_destroy_cb), NULL, |
| 3841 NULL); |
3782 NULL); |
| 3842 g_object_disconnect(prefsnotebook, "any-signal::switch-page", |
3783 g_object_disconnect(prefsnotebook, "any-signal::switch-page", |
| 3912 |
3852 |
| 3913 level = gtk_progress_bar_new(); |
3853 level = gtk_progress_bar_new(); |
| 3914 gtk_box_pack_start(GTK_BOX(vbox), level, FALSE, FALSE, 0); |
3854 gtk_box_pack_start(GTK_BOX(vbox), level, FALSE, FALSE, 0); |
| 3915 gtk_widget_set_sensitive(level, FALSE); |
3855 gtk_widget_set_sensitive(level, FALSE); |
| 3916 |
3856 |
| 3917 ctx = g_new(BusCbCtx, 1); |
3857 voice_volume = volume; |
| 3918 ctx->volume = volume; |
3858 voice_level = level; |
| 3919 ctx->level = level; |
3859 voice_threshold = threshold; |
| 3920 ctx->threshold = threshold; |
|
| 3921 g_signal_connect(test, "toggled", |
3860 g_signal_connect(test, "toggled", |
| 3922 G_CALLBACK(toggle_voice_test_cb), ctx); |
3861 G_CALLBACK(toggle_voice_test_cb), NULL); |
| 3923 } |
3862 } |
| 3924 |
3863 |
| 3925 static GstElement * |
3864 static GstElement * |
| 3926 create_video_pipeline(void) |
3865 create_video_pipeline(void) |
| 3927 { |
3866 { |
| 3979 window_id); |
3918 window_id); |
| 3980 #endif |
3919 #endif |
| 3981 } |
3920 } |
| 3982 |
3921 |
| 3983 static void |
3922 static void |
| 3984 toggle_video_test_cb(GtkToggleButton *test, gpointer data) |
3923 enable_video_test(void) |
| 3985 { |
3924 { |
| 3986 GtkWidget *video = data; |
|
| 3987 GstBus *bus; |
3925 GstBus *bus; |
| 3988 |
3926 GdkWindow *window = gtk_widget_get_window(video_drawing_area); |
| 3989 if (gtk_toggle_button_get_active(test)) { |
3927 gulong window_id = 0; |
| 3990 GdkWindow *window = gtk_widget_get_window(video); |
|
| 3991 gulong window_id = 0; |
|
| 3992 |
3928 |
| 3993 #ifdef GDK_WINDOWING_WIN32 |
3929 #ifdef GDK_WINDOWING_WIN32 |
| 3994 if (GDK_IS_WIN32_WINDOW(window)) |
3930 if (GDK_IS_WIN32_WINDOW(window)) |
| 3995 window_id = GPOINTER_TO_UINT(GDK_WINDOW_HWND(window)); |
3931 window_id = GPOINTER_TO_UINT(GDK_WINDOW_HWND(window)); |
| 3996 else |
3932 else |
| 3997 #endif |
3933 #endif |
| 3998 #ifdef GDK_WINDOWING_X11 |
3934 #ifdef GDK_WINDOWING_X11 |
| 3999 if (GDK_IS_X11_WINDOW(window)) |
3935 if (GDK_IS_X11_WINDOW(window)) |
| 4000 window_id = gdk_x11_window_get_xid(window); |
3936 window_id = gdk_x11_window_get_xid(window); |
| 4001 else |
3937 else |
| 4002 #endif |
3938 #endif |
| 4003 #ifdef GDK_WINDOWING_QUARTZ |
3939 #ifdef GDK_WINDOWING_QUARTZ |
| 4004 if (GDK_IS_QUARTZ_WINDOW(window)) |
3940 if (GDK_IS_QUARTZ_WINDOW(window)) |
| 4005 window_id = (gulong)gdk_quartz_window_get_nsview(window); |
3941 window_id = (gulong)gdk_quartz_window_get_nsview(window); |
| 4006 else |
3942 else |
| 4007 #endif |
3943 #endif |
| 4008 g_warning("Unsupported GDK backend"); |
3944 g_warning("Unsupported GDK backend"); |
| 4009 #if !(defined(GDK_WINDOWING_WIN32) \ |
3945 #if !(defined(GDK_WINDOWING_WIN32) \ |
| 4010 || defined(GDK_WINDOWING_X11) \ |
3946 || defined(GDK_WINDOWING_X11) \ |
| 4011 || defined(GDK_WINDOWING_QUARTZ)) |
3947 || defined(GDK_WINDOWING_QUARTZ)) |
| 4012 # error "Unsupported GDK windowing system" |
3948 # error "Unsupported GDK windowing system" |
| 4013 #endif |
3949 #endif |
| 4014 |
3950 |
| 4015 video_pipeline = create_video_pipeline(); |
3951 video_pipeline = create_video_pipeline(); |
| 4016 bus = gst_pipeline_get_bus(GST_PIPELINE(video_pipeline)); |
3952 bus = gst_pipeline_get_bus(GST_PIPELINE(video_pipeline)); |
| 4017 #if GST_CHECK_VERSION(1,0,0) |
3953 #if GST_CHECK_VERSION(1,0,0) |
| 4018 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL, NULL); |
3954 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL, NULL); |
| 4019 #else |
3955 #else |
| 4020 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL); |
3956 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL); |
| 4021 #endif |
3957 #endif |
| 4022 g_signal_connect(bus, "sync-message::element", |
3958 g_signal_connect(bus, "sync-message::element", |
| 4023 G_CALLBACK(window_id_cb), (gpointer)window_id); |
3959 G_CALLBACK(window_id_cb), (gpointer)window_id); |
| 4024 gst_object_unref(bus); |
3960 gst_object_unref(bus); |
| 4025 |
3961 |
| 4026 gst_element_set_state(GST_ELEMENT(video_pipeline), GST_STATE_PLAYING); |
3962 gst_element_set_state(GST_ELEMENT(video_pipeline), GST_STATE_PLAYING); |
| 4027 |
3963 } |
| |
3964 |
| |
3965 static void |
| |
3966 toggle_video_test_cb(GtkToggleButton *test, gpointer data) |
| |
3967 { |
| |
3968 if (gtk_toggle_button_get_active(test)) { |
| |
3969 enable_video_test(); |
| 4028 g_signal_connect(test, "destroy", |
3970 g_signal_connect(test, "destroy", |
| 4029 G_CALLBACK(video_test_destroy_cb), NULL); |
3971 G_CALLBACK(video_test_destroy_cb), NULL); |
| 4030 g_signal_connect(prefsnotebook, "switch-page", |
3972 g_signal_connect(prefsnotebook, "switch-page", |
| 4031 G_CALLBACK(vv_test_switch_page_cb), test); |
3973 G_CALLBACK(vv_test_switch_page_cb), test); |
| 4032 } else { |
3974 } else { |
| 4049 GdkRGBA color = {0.0, 0.0, 0.0, 1.0}; |
3991 GdkRGBA color = {0.0, 0.0, 0.0, 1.0}; |
| 4050 #else |
3992 #else |
| 4051 GdkColor color = {0, 0, 0, 0}; |
3993 GdkColor color = {0, 0, 0, 0}; |
| 4052 #endif |
3994 #endif |
| 4053 |
3995 |
| 4054 video = gtk_drawing_area_new(); |
3996 video_drawing_area = video = gtk_drawing_area_new(); |
| 4055 gtk_box_pack_start(GTK_BOX(vbox), video, TRUE, TRUE, 0); |
3997 gtk_box_pack_start(GTK_BOX(vbox), video, TRUE, TRUE, 0); |
| 4056 #if GTK_CHECK_VERSION(3,0,0) |
3998 #if GTK_CHECK_VERSION(3,0,0) |
| 4057 gtk_widget_override_background_color(video, GTK_STATE_FLAG_NORMAL, &color); |
3999 gtk_widget_override_background_color(video, GTK_STATE_FLAG_NORMAL, &color); |
| 4058 #else |
4000 #else |
| 4059 gtk_widget_modify_bg(video, GTK_STATE_NORMAL, &color); |
4001 gtk_widget_modify_bg(video, GTK_STATE_NORMAL, &color); |
| 4062 |
4004 |
| 4063 test = gtk_toggle_button_new_with_label(_("Test Video")); |
4005 test = gtk_toggle_button_new_with_label(_("Test Video")); |
| 4064 gtk_box_pack_start(GTK_BOX(vbox), test, FALSE, FALSE, 0); |
4006 gtk_box_pack_start(GTK_BOX(vbox), test, FALSE, FALSE, 0); |
| 4065 |
4007 |
| 4066 g_signal_connect(test, "toggled", |
4008 g_signal_connect(test, "toggled", |
| 4067 G_CALLBACK(toggle_video_test_cb), video); |
4009 G_CALLBACK(toggle_video_test_cb), NULL); |
| |
4010 } |
| |
4011 |
| |
4012 static void |
| |
4013 vv_plugin_changed_cb(const gchar *name, PurplePrefType type, |
| |
4014 gconstpointer value, gpointer data) |
| |
4015 { |
| |
4016 GtkWidget *vbox = data; |
| |
4017 GtkSizeGroup *sg; |
| |
4018 GtkWidget *widget; |
| |
4019 gchar *pref; |
| |
4020 GList *devices; |
| |
4021 |
| |
4022 sg = g_object_get_data(G_OBJECT(vbox), "size-group"); |
| |
4023 widget = g_object_get_data(G_OBJECT(vbox), "device-hbox"); |
| |
4024 gtk_widget_destroy(widget); |
| |
4025 |
| |
4026 pref = g_strdup(name); |
| |
4027 strcpy(pref + strlen(pref) - strlen("plugin"), "device"); |
| |
4028 devices = get_vv_element_devices(value); |
| |
4029 if (g_list_find_custom(devices, purple_prefs_get_string(pref), |
| |
4030 (GCompareFunc)strcmp) == NULL) |
| |
4031 purple_prefs_set_string(pref, g_list_next(devices)->data); |
| |
4032 widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"), |
| |
4033 PURPLE_PREF_STRING, pref, devices); |
| |
4034 g_list_free_full(devices, g_free); |
| |
4035 gtk_size_group_add_widget(sg, widget); |
| |
4036 gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5); |
| |
4037 |
| |
4038 g_object_set_data(G_OBJECT(vbox), "device-hbox", |
| |
4039 gtk_widget_get_parent(widget)); |
| |
4040 g_signal_connect_swapped(widget, "destroy", G_CALLBACK(g_free), pref); |
| |
4041 |
| |
4042 /* Refresh test viewers */ |
| |
4043 if (strstr(name, "audio") && voice_pipeline) { |
| |
4044 voice_test_destroy_cb(NULL, NULL); |
| |
4045 enable_voice_test(); |
| |
4046 } else if(strstr(name, "video") && video_pipeline) { |
| |
4047 video_test_destroy_cb(NULL, NULL); |
| |
4048 enable_video_test(); |
| |
4049 } |
| |
4050 } |
| |
4051 |
| |
4052 static void |
| |
4053 make_vv_frame(GtkWidget *parent, GtkSizeGroup *sg, |
| |
4054 const gchar *name, const gchar **plugin_strs, |
| |
4055 const gchar *plugin_pref, const gchar *device_pref) |
| |
4056 { |
| |
4057 GtkWidget *vbox, *widget; |
| |
4058 GList *plugins, *devices; |
| |
4059 |
| |
4060 vbox = pidgin_make_frame(parent, name); |
| |
4061 |
| |
4062 /* Setup plugin preference */ |
| |
4063 plugins = get_vv_element_plugins(plugin_strs); |
| |
4064 widget = pidgin_prefs_dropdown_from_list(vbox, _("_Plugin"), |
| |
4065 PURPLE_PREF_STRING, plugin_pref, |
| |
4066 plugins); |
| |
4067 g_list_free(plugins); |
| |
4068 gtk_size_group_add_widget(sg, widget); |
| |
4069 gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5); |
| |
4070 |
| |
4071 /* Setup device preference */ |
| |
4072 devices = get_vv_element_devices(purple_prefs_get_string(plugin_pref)); |
| |
4073 if (g_list_find_custom(devices, purple_prefs_get_string(device_pref), |
| |
4074 (GCompareFunc)strcmp) == NULL) |
| |
4075 purple_prefs_set_string(device_pref, g_list_next(devices)->data); |
| |
4076 widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"), |
| |
4077 PURPLE_PREF_STRING, device_pref, |
| |
4078 devices); |
| |
4079 g_list_free_full(devices, g_free); |
| |
4080 gtk_size_group_add_widget(sg, widget); |
| |
4081 gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5); |
| |
4082 |
| |
4083 widget = gtk_widget_get_parent(widget); |
| |
4084 g_object_set_data(G_OBJECT(vbox), "size-group", sg); |
| |
4085 g_object_set_data(G_OBJECT(vbox), "device-hbox", widget); |
| |
4086 purple_prefs_connect_callback(vbox, plugin_pref, vv_plugin_changed_cb, |
| |
4087 vbox); |
| |
4088 g_signal_connect_swapped(vbox, "destroy", |
| |
4089 G_CALLBACK(purple_prefs_disconnect_by_handle), vbox); |
| 4068 } |
4090 } |
| 4069 |
4091 |
| 4070 static GtkWidget * |
4092 static GtkWidget * |
| 4071 vv_page(void) |
4093 vv_page(void) |
| 4072 { |
4094 { |