diff -r 133e5eca834c -r ec2fc1bc9024 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Mon Mar 02 16:34:05 2009 +0000 +++ b/pidgin/gtkprefs.c Mon Mar 02 18:47:27 2009 +0000 @@ -28,6 +28,9 @@ #include "pidgin.h" #include "debug.h" +#ifdef USE_VV +#include "mediamanager.h" +#endif #include "notify.h" #include "prefs.h" #include "proxy.h" @@ -145,6 +148,26 @@ return pidgin_add_widget_to_vbox(GTK_BOX(page), title, sg, entry, TRUE, NULL); } +GtkWidget * +pidgin_prefs_labeled_password(GtkWidget *page, const gchar *title, + const char *key, GtkSizeGroup *sg) +{ + GtkWidget *entry; + const gchar *value; + + value = purple_prefs_get_string(key); + + entry = gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry), value); + g_signal_connect(G_OBJECT(entry), "changed", + G_CALLBACK(entry_set), (char*)key); + gtk_widget_show(entry); + + return pidgin_add_widget_to_vbox(GTK_BOX(page), title, sg, entry, TRUE, NULL); +} + + static void dropdown_set(GObject *w, const char *key) { @@ -156,12 +179,10 @@ if (type == PURPLE_PREF_INT) { int_value = GPOINTER_TO_INT(g_object_get_data(w, "value")); - purple_prefs_set_int(key, int_value); } else if (type == PURPLE_PREF_STRING) { str_value = (const char *)g_object_get_data(w, "value"); - purple_prefs_set_string(key, str_value); } else if (type == PURPLE_PREF_BOOLEAN) { @@ -1210,7 +1231,7 @@ _("Never"), "never", NULL); gtk_size_group_add_widget(sg, label); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); vbox = pidgin_make_frame(ret, _("Conversation Window Hiding")); label = pidgin_prefs_dropdown(vbox, _("_Hide new IM conversations:"), @@ -1220,7 +1241,7 @@ _("Always"), "always", NULL); gtk_size_group_add_widget(sg, label); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); /* All the tab options! */ @@ -1255,7 +1276,7 @@ #endif NULL); gtk_size_group_add_widget(sg, label); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); names = pidgin_conv_placement_get_options(); label = pidgin_prefs_dropdown_from_list(vbox2, _("N_ew conversations:"), @@ -1406,6 +1427,28 @@ purple_network_set_public_ip(gtk_entry_get_text(entry)); } +static gboolean network_stun_server_changed_cb(GtkWidget *widget, + GdkEventFocus *event, gpointer data) +{ + GtkEntry *entry = GTK_ENTRY(widget); + purple_prefs_set_string("/purple/network/stun_server", + gtk_entry_get_text(entry)); + purple_network_set_stun_server(gtk_entry_get_text(entry)); + + return FALSE; +} + +static gboolean network_turn_server_changed_cb(GtkWidget *widget, + GdkEventFocus *event, gpointer data) +{ + GtkEntry *entry = GTK_ENTRY(widget); + purple_prefs_set_string("/purple/network/turn_server", + gtk_entry_get_text(entry)); + purple_network_set_turn_server(gtk_entry_get_text(entry)); + + return FALSE; +} + static void proxy_changed_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) @@ -1471,8 +1514,16 @@ vbox = pidgin_make_frame (ret, _("IP Address")); sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - pidgin_prefs_labeled_entry(vbox,_("ST_UN server:"), - "/purple/network/stun_server", sg); + + entry = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(entry), purple_prefs_get_string( + "/purple/network/stun_server")); + g_signal_connect(G_OBJECT(entry), "focus-out-event", + G_CALLBACK(network_stun_server_changed_cb), NULL); + gtk_widget_show(entry); + + pidgin_add_widget_to_vbox(GTK_BOX(vbox), "ST_UN server:", + sg, entry, TRUE, NULL); hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); gtk_container_add(GTK_CONTAINER(vbox), hbox); @@ -1550,6 +1601,29 @@ g_signal_connect(G_OBJECT(ports_checkbox), "clicked", G_CALLBACK(pidgin_toggle_sensitive), spin_button); + g_object_unref(sg); + + /* TURN server */ + vbox = pidgin_make_frame(ret, _("Relay Server (TURN)")); + sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + entry = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(entry), purple_prefs_get_string( + "/purple/network/turn_server")); + g_signal_connect(G_OBJECT(entry), "focus-out-event", + G_CALLBACK(network_turn_server_changed_cb), NULL); + gtk_widget_show(entry); + + hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), "_TURN server:", + sg, entry, TRUE, NULL); + + pidgin_prefs_labeled_spin_button(hbox, _("_Port:"), + "/purple/network/turn_port", 0, 65535, NULL); + hbox = pidgin_prefs_labeled_entry(vbox, "_Username:", + "/purple/network/turn_username", sg); + pidgin_prefs_labeled_password(hbox, "_Password:", + "/purple/network/turn_password", NULL); + if (purple_running_gnome()) { vbox = pidgin_make_frame(ret, _("Proxy Server & Browser")); prefs_proxy_frame = gtk_vbox_new(FALSE, 0); @@ -2326,6 +2400,293 @@ return ret; } +#ifdef USE_VV + +/* get a GList of pairs name / device */ +static GList * +get_device_items(const gchar *plugin) +{ + GList *ret = NULL; + GList *devices = purple_media_get_devices(plugin); + GstElement *element = gst_element_factory_make(plugin, NULL); + + if (element == NULL) + return NULL; + + for(; devices ; devices = g_list_delete_link(devices, devices)) { + gchar *name; + g_object_set(G_OBJECT(element), "device", devices->data, NULL); + g_object_get(G_OBJECT(element), "device-name", &name, NULL); + ret = g_list_append(ret, name); + ret = g_list_append(ret, devices->data); + } + + gst_object_unref(element); + return ret; +} + +/* + * Test functions to run video preview + */ +static gboolean +preview_video_bus_call(GstBus *bus, GstMessage *msg, gpointer pipeline) +{ + switch(GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: + purple_debug_info("preview-video", "End of Stream\n"); + break; + case GST_MESSAGE_ERROR: { + gchar *debug = NULL; + GError *err = NULL; + + gst_message_parse_error(msg, &err, &debug); + + purple_debug_error("preview-video", "Error: %s\n", err->message); + g_error_free(err); + + if (debug) { + purple_debug_error("preview-video", "details: %s\n", debug); + g_free (debug); + } + break; + } + default: + return TRUE; + } + + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref(GST_PIPELINE(pipeline)); + return FALSE; +} + +static void +preview_button_clicked(GtkWidget *widget, gpointer *data) +{ + const char *plugin = purple_prefs_get_string("/purple/media/video/plugin"); + const char *device = purple_prefs_get_string("/purple/media/video/device"); + GstBus *bus; + + /* create a preview window... */ + GstElement *pipeline = NULL; + GError *p_err = NULL; + + gchar *test_pipeline_str = NULL; + + if (strlen(device) > 0) + test_pipeline_str = g_strdup_printf("%s device=\"%s\" !" \ + " ffmpegcolorspace !" \ + " autovideosink", + plugin, device); + else + test_pipeline_str = g_strdup_printf("%s ! ffmpegcolorspace !" \ + " autovideosink", plugin); + + pipeline = gst_parse_launch (test_pipeline_str, &p_err); + + g_free(test_pipeline_str); + + if (pipeline == NULL) { + purple_debug_error("gtkprefs", + "Error starting preview: %s\n", p_err->message); + g_error_free(p_err); + return; + } + + bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); + gst_bus_add_watch(bus, preview_video_bus_call, pipeline); + gst_object_unref(bus); + + gst_element_set_state(pipeline, GST_STATE_PLAYING); +} + +static void +media_plugin_changed_cb(const gchar *name, PurplePrefType type, + gconstpointer value, gpointer data) +{ + GtkWidget *hbox = data; + GtkWidget *dd = NULL; + GtkWidget *preview_button = NULL; + const char *plugin = value; + const char *device = purple_prefs_get_string("/purple/media/video/device"); + GList *video_items = get_device_items(plugin); + GList *list; + + if (video_items == NULL) { + video_items = g_list_prepend(video_items, g_strdup("")); + video_items = g_list_prepend(video_items, g_strdup("Default")); + } + + if (g_list_find(video_items, device) == NULL) + { + purple_prefs_set_string("/purple/media/video/device", + g_list_next(video_items)->data); + } + + list = gtk_container_get_children(GTK_CONTAINER(hbox)); + + while (list) { + gtk_widget_destroy(list->data); + list = g_list_delete_link(list, list); + } + + dd = pidgin_prefs_dropdown_from_list(hbox, _("_Device:"), PURPLE_PREF_STRING, + "/purple/media/video/device", + video_items); + + gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); + + preview_button = gtk_button_new_with_mnemonic(_("_Preview")); + g_signal_connect(G_OBJECT(preview_button), "clicked", + G_CALLBACK(preview_button_clicked), NULL); + + gtk_container_add(GTK_CONTAINER(hbox), preview_button); + + gtk_widget_show_all(hbox); +} + +static void +prefs_media_input_volume_changed(GtkRange *range) +{ + double val = (double)gtk_range_get_value(GTK_RANGE(range)); + GList *medias = purple_media_manager_get_media(purple_media_manager_get()); + purple_prefs_set_int("/purple/media/audio/volume/input", val); + + val /= 10.0; + for (; medias; medias = g_list_next(medias)) { + PurpleMedia *media = PURPLE_MEDIA(medias->data); + purple_media_set_input_volume(media, NULL, val); + } +} + +static void +prefs_media_output_volume_changed(GtkRange *range) +{ + double val = (double)gtk_range_get_value(GTK_RANGE(range)); + GList *medias = purple_media_manager_get_media(purple_media_manager_get()); + purple_prefs_set_int("/purple/media/audio/volume/output", val); + + val /= 10.0; + for (; medias; medias = g_list_next(medias)) { + PurpleMedia *media = PURPLE_MEDIA(medias->data); + purple_media_set_output_volume(media, NULL, NULL, val); + } +} + +static GtkWidget * +media_page() +{ + GtkWidget *ret; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *dd; + GtkWidget *preview_button; + GtkWidget *sw; + GtkSizeGroup *sg, *sg2; + const char *plugin = purple_prefs_get_string("/purple/media/video/plugin"); + const char *device = purple_prefs_get_string("/purple/media/video/device"); + GList *video_items = get_device_items(plugin); + GList *audio_items = get_device_items("alsasrc"); + + if (video_items == NULL) { + video_items = g_list_prepend(video_items, ""); + video_items = g_list_prepend(video_items, "Default"); + } + + if (g_list_find(video_items, device) == NULL) + { + purple_prefs_set_string("/purple/media/video/device", + g_list_next(video_items)->data); + } + + ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); + gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); + + sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + sg2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + vbox = pidgin_make_frame (ret, _("Video Input")); + gtk_size_group_add_widget(sg2, vbox); + + hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); + dd = pidgin_prefs_dropdown(vbox, _("_Plugin:"), PURPLE_PREF_STRING, + "/purple/media/video/plugin", + _("Default"), "gconfvideosrc", + _("Video4Linux"), "v4lsrc", + _("Video4Linux2"), "v4l2src", + _("Video Test Source"), "videotestsrc", + NULL); + + gtk_size_group_add_widget(sg, dd); + gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); + + hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); + dd = pidgin_prefs_dropdown_from_list(hbox, _("Device:"), PURPLE_PREF_STRING, + "/purple/media/video/device", + video_items); + + purple_prefs_connect_callback(prefs, "/purple/media/video/plugin", + media_plugin_changed_cb, hbox); + + g_signal_connect_swapped(hbox, "destroy", + G_CALLBACK(purple_prefs_disconnect_by_handle), hbox); + + gtk_size_group_add_widget(sg, dd); + gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); + + preview_button = gtk_button_new_with_mnemonic(_("_Preview")); + g_signal_connect(G_OBJECT(preview_button), "clicked", + G_CALLBACK(preview_button_clicked), NULL); + + gtk_container_add(GTK_CONTAINER(hbox), preview_button); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + vbox = pidgin_make_frame (ret, _("Audio Input")); + gtk_size_group_add_widget(sg2, vbox); + dd = pidgin_prefs_dropdown_from_list(vbox, _("Device:"), PURPLE_PREF_STRING, + "/purple/media/audio/device", + audio_items); + + gtk_size_group_add_widget(sg, dd); + gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); + + hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + /* Input Volume */ + sw = gtk_hscale_new_with_range(0.0, 100.0, 5.0); + gtk_range_set_increments(GTK_RANGE(sw), 5.0, 25.0); + gtk_range_set_value(GTK_RANGE(sw), + purple_prefs_get_int("/purple/media/audio/volume/input")); + g_signal_connect (G_OBJECT (sw), "format-value", + G_CALLBACK (prefs_sound_volume_format), + NULL); + g_signal_connect (G_OBJECT (sw), "value-changed", + G_CALLBACK (prefs_media_input_volume_changed), + NULL); + pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Volume:"), sg, sw, TRUE, NULL); + + vbox = pidgin_make_frame (ret, _("Audio Output")); + gtk_size_group_add_widget(sg2, vbox); + + /* Output Volume */ + sw = gtk_hscale_new_with_range(0.0, 100.0, 5.0); + gtk_range_set_increments(GTK_RANGE(sw), 5.0, 25.0); + gtk_range_set_value(GTK_RANGE(sw), + purple_prefs_get_int("/purple/media/audio/volume/output")); + g_signal_connect (G_OBJECT (sw), "format-value", + G_CALLBACK (prefs_sound_volume_format), + NULL); + g_signal_connect (G_OBJECT (sw), "value-changed", + G_CALLBACK (prefs_media_output_volume_changed), + NULL); + pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Volume:"), sg, sw, TRUE, NULL); + + gtk_widget_show_all(ret); + + return ret; +} + +#endif /* USE_VV */ static void set_idle_away(PurpleSavedStatus *status) @@ -2451,6 +2812,10 @@ prefs_notebook_add_page(_("Conversations"), conv_page(), notebook_page++); prefs_notebook_add_page(_("Smiley Themes"), theme_page(), notebook_page++); prefs_notebook_add_page(_("Sounds"), sound_page(), notebook_page++); + +#ifdef USE_VV + prefs_notebook_add_page(_("Media"), media_page(), notebook_page++); +#endif prefs_notebook_add_page(_("Network"), network_page(), notebook_page++); #ifndef _WIN32 /* We use the registered default browser in windows */ @@ -2587,6 +2952,18 @@ purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/smileys/theme", smiley_theme_pref_cb, NULL); +#ifdef USE_VV + purple_prefs_add_none("/purple/media"); + purple_prefs_add_none("/purple/media/video"); + purple_prefs_add_string("/purple/media/video/plugin", "gconfvideosrc"); + purple_prefs_add_string("/purple/media/video/device", ""); + purple_prefs_add_none("/purple/media/audio"); + purple_prefs_add_string("/purple/media/audio/device", ""); + purple_prefs_add_none("/purple/media/audio/volume"); + purple_prefs_add_int("/purple/media/audio/volume/input", 10); + purple_prefs_add_int("/purple/media/audio/volume/output", 10); +#endif /* USE_VV */ + pidgin_prefs_update_old(); }