pidgin/gtkprefs.c

branch
soc.2013.gobjectification.plugins
changeset 37112
37fdcf3855d3
parent 37109
94d1a2589d5a
parent 35569
5e1cfb0cb4e6
child 37128
7ffe330ea8ea
equal deleted inserted replaced
37111:efe4b7c5218a 37112:37fdcf3855d3
177 "ximagesink", "X Window System", 177 "ximagesink", "X Window System",
178 "xvimagesink", "X Window System (Xv)", 178 "xvimagesink", "X Window System (Xv)",
179 NULL 179 NULL
180 }; 180 };
181 181
182 typedef struct { 182 static GtkWidget *voice_level;
183 GtkWidget *level; 183 static GtkWidget *voice_threshold;
184 GtkWidget *threshold; 184 static GtkWidget *voice_volume;
185 GtkWidget *volume;
186 } BusCbCtx;
187
188 static GstElement *voice_pipeline; 185 static GstElement *voice_pipeline;
186
187 static GtkWidget *video_drawing_area;
189 static GstElement *video_pipeline; 188 static GstElement *video_pipeline;
190 189
191 #endif 190 #endif
192 191
193 /* 192 /*
559 prefs_smiley_themes_combo_box = NULL; 558 prefs_smiley_themes_combo_box = NULL;
560 559
561 keyring_page_cleanup(); 560 keyring_page_cleanup();
562 561
563 sample_webview = NULL; 562 sample_webview = NULL;
563
564 #if USE_VV
565 voice_level = NULL;
566 voice_threshold = NULL;
567 voice_volume = NULL;
568 video_drawing_area = NULL;
569 #endif
564 570
565 notebook_page = 0; 571 notebook_page = 0;
566 prefsnotebook = NULL; 572 prefsnotebook = NULL;
567 prefs = NULL; 573 prefs = NULL;
568 } 574 }
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
3734 3669
3735 return pipeline; 3670 return pipeline;
3736 } 3671 }
3737 3672
3738 static void 3673 static void
3739 on_volume_change_cb(GtkWidget *w, gdouble value, GstBin *pipeline) 3674 on_volume_change_cb(GtkWidget *w, gdouble value, gpointer data)
3740 { 3675 {
3741 GstElement *volume; 3676 GstElement *volume;
3742 3677
3743 g_return_if_fail(pipeline != NULL); 3678 if (!voice_pipeline)
3744 3679 return;
3745 volume = gst_bin_get_by_name(pipeline, "volume"); 3680
3681 volume = gst_bin_get_by_name(GST_BIN(voice_pipeline), "volume");
3746 g_object_set(volume, "volume", 3682 g_object_set(volume, "volume",
3747 gtk_scale_button_get_value(GTK_SCALE_BUTTON(w)) * 10.0, NULL); 3683 gtk_scale_button_get_value(GTK_SCALE_BUTTON(w)) * 10.0, NULL);
3748 } 3684 }
3749 3685
3750 static gdouble 3686 static gdouble
3767 percent = pow(10, value_db / 20); 3703 percent = pow(10, value_db / 20);
3768 return (percent > 1.0) ? 1.0 : percent; 3704 return (percent > 1.0) ? 1.0 : percent;
3769 } 3705 }
3770 3706
3771 static gboolean 3707 static gboolean
3772 gst_bus_cb(GstBus *bus, GstMessage *msg, BusCbCtx *ctx) 3708 gst_bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
3773 { 3709 {
3774 if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT && 3710 if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT &&
3775 gst_structure_has_name(gst_message_get_structure(msg), "level")) { 3711 gst_structure_has_name(gst_message_get_structure(msg), "level")) {
3776 3712
3777 GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg)); 3713 GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
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",
3873 GtkWidget *hbox; 3814 GtkWidget *hbox;
3874 GtkWidget *label; 3815 GtkWidget *label;
3875 GtkWidget *level; 3816 GtkWidget *level;
3876 GtkWidget *volume; 3817 GtkWidget *volume;
3877 GtkWidget *threshold; 3818 GtkWidget *threshold;
3878 BusCbCtx *ctx;
3879 char *tmp; 3819 char *tmp;
3880 3820
3881 label = gtk_label_new(NULL); 3821 label = gtk_label_new(NULL);
3882 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 3822 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
3883 3823
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 {

mercurial