diff options
Diffstat (limited to 'panels/sound/cc-sound-panel.c')
-rw-r--r-- | panels/sound/cc-sound-panel.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/panels/sound/cc-sound-panel.c b/panels/sound/cc-sound-panel.c new file mode 100644 index 0000000..0de1ca9 --- /dev/null +++ b/panels/sound/cc-sound-panel.c @@ -0,0 +1,318 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <libintl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include <glib/gi18n-lib.h> +#include <glib.h> +#include <gtk/gtk.h> +#include <pulse/pulseaudio.h> +#include <gvc-mixer-control.h> + +#include "cc-alert-chooser.h" +#include "cc-balance-slider.h" +#include "cc-device-combo-box.h" +#include "cc-fade-slider.h" +#include "cc-level-bar.h" +#include "cc-output-test-dialog.h" +#include "cc-profile-combo-box.h" +#include "cc-sound-panel.h" +#include "cc-sound-resources.h" +#include "cc-stream-list-box.h" +#include "cc-subwoofer-slider.h" +#include "cc-volume-slider.h" + +struct _CcSoundPanel +{ + CcPanel parent_instance; + + CcBalanceSlider *balance_slider; + GtkListBoxRow *fade_row; + CcFadeSlider *fade_slider; + CcDeviceComboBox *input_device_combo_box; + CcLevelBar *input_level_bar; + GtkListBox *input_list_box; + CcProfileComboBox *input_profile_combo_box; + GtkListBoxRow *input_profile_row; + CcVolumeSlider *input_volume_slider; + GtkSizeGroup *label_size_group; + CcDeviceComboBox *output_device_combo_box; + GtkListStore *output_device_model; + CcLevelBar *output_level_bar; + GtkListBox *output_list_box; + CcProfileComboBox *output_profile_combo_box; + GtkListBoxRow *output_profile_row; + CcVolumeSlider *output_volume_slider; + CcStreamListBox *stream_list_box; + GtkListBoxRow *subwoofer_row; + CcSubwooferSlider *subwoofer_slider; + + GvcMixerControl *mixer_control; + GSettings *sound_settings; +}; + +CC_PANEL_REGISTER (CcSoundPanel, cc_sound_panel) + +enum +{ + PROP_0, + PROP_PARAMETERS +}; + +#define KEY_SOUNDS_SCHEMA "org.gnome.desktop.sound" + +static void +allow_amplified_changed_cb (CcSoundPanel *self) +{ + cc_volume_slider_set_is_amplified (self->output_volume_slider, + g_settings_get_boolean (self->sound_settings, "allow-volume-above-100-percent")); +} + +static void +set_output_stream (CcSoundPanel *self, + GvcMixerStream *stream) +{ + GvcChannelMap *map = NULL; + gboolean can_fade = FALSE, has_lfe = FALSE; + + cc_volume_slider_set_stream (self->output_volume_slider, stream, CC_STREAM_TYPE_OUTPUT); + cc_level_bar_set_stream (self->output_level_bar, stream, CC_STREAM_TYPE_OUTPUT); + + if (stream != NULL) + { + map = (GvcChannelMap *) gvc_mixer_stream_get_channel_map (stream); + can_fade = gvc_channel_map_can_fade (map); + has_lfe = gvc_channel_map_has_lfe (map); + } + cc_fade_slider_set_channel_map (self->fade_slider, map); + cc_balance_slider_set_channel_map (self->balance_slider, map); + cc_subwoofer_slider_set_channel_map (self->subwoofer_slider, map); + + gtk_widget_set_visible (GTK_WIDGET (self->fade_row), can_fade); + gtk_widget_set_visible (GTK_WIDGET (self->subwoofer_row), has_lfe); +} + +static void +output_device_changed_cb (CcSoundPanel *self) +{ + GvcMixerUIDevice *device; + GvcMixerStream *stream = NULL; + + device = cc_device_combo_box_get_device (self->output_device_combo_box); + + if (device != NULL) + stream = gvc_mixer_control_get_stream_from_device (self->mixer_control, device); + + set_output_stream (self, stream); + + if (device != NULL) + gvc_mixer_control_change_output (self->mixer_control, device); +} + +static void +set_input_stream (CcSoundPanel *self, + GvcMixerStream *stream) +{ + cc_volume_slider_set_stream (self->input_volume_slider, stream, CC_STREAM_TYPE_INPUT); + cc_level_bar_set_stream (self->input_level_bar, stream, CC_STREAM_TYPE_INPUT); +} + +static void +input_device_changed_cb (CcSoundPanel *self) +{ + GvcMixerUIDevice *device; + GvcMixerStream *stream = NULL; + + device = cc_device_combo_box_get_device (self->input_device_combo_box); + + if (device != NULL) + stream = gvc_mixer_control_get_stream_from_device (self->mixer_control, device); + + set_input_stream (self, stream); + + if (device != NULL) + gvc_mixer_control_change_input (self->mixer_control, device); +} + +static void +output_device_update_cb (CcSoundPanel *self, + guint id) +{ + GvcMixerUIDevice *device; + gboolean has_multi_profiles; + GvcMixerStream *stream = NULL; + + device = cc_device_combo_box_get_device (self->output_device_combo_box); + cc_profile_combo_box_set_device (self->output_profile_combo_box, self->mixer_control, device); + has_multi_profiles = (cc_profile_combo_box_get_profile_count (self->output_profile_combo_box) > 1); + gtk_widget_set_visible (GTK_WIDGET (self->output_profile_row), + has_multi_profiles); + + if (cc_volume_slider_get_stream (self->output_volume_slider) == NULL) + stream = gvc_mixer_control_get_stream_from_device (self->mixer_control, device); + if (stream != NULL) + set_output_stream (self, stream); +} + +static void +input_device_update_cb (CcSoundPanel *self, + guint id) +{ + GvcMixerUIDevice *device; + gboolean has_multi_profiles; + GvcMixerStream *stream = NULL; + + device = cc_device_combo_box_get_device (self->input_device_combo_box); + cc_profile_combo_box_set_device (self->input_profile_combo_box, self->mixer_control, device); + has_multi_profiles = (cc_profile_combo_box_get_profile_count (self->input_profile_combo_box) > 1); + gtk_widget_set_visible (GTK_WIDGET (self->input_profile_row), + has_multi_profiles); + + if (cc_volume_slider_get_stream (self->input_volume_slider) == NULL) + stream = gvc_mixer_control_get_stream_from_device (self->mixer_control, device); + if (stream != NULL) + set_input_stream (self, stream); +} + +static void +test_output_configuration_button_clicked_cb (CcSoundPanel *self) +{ + GvcMixerUIDevice *device; + GvcMixerStream *stream = NULL; + CcOutputTestDialog *dialog; + GtkWidget *toplevel; + CcShell *shell; + + device = cc_device_combo_box_get_device (self->output_device_combo_box); + if (device != NULL) + stream = gvc_mixer_control_get_stream_from_device (self->mixer_control, device); + + shell = cc_panel_get_shell (CC_PANEL (self)); + toplevel = cc_shell_get_toplevel (shell); + + dialog = cc_output_test_dialog_new (device, stream); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel)); + gtk_window_present (GTK_WINDOW (dialog)); +} + +static const char * +cc_sound_panel_get_help_uri (CcPanel *panel) +{ + return "help:gnome-help/media#sound"; +} + +static void +cc_sound_panel_finalize (GObject *object) +{ + CcSoundPanel *panel = CC_SOUND_PANEL (object); + + g_clear_object (&panel->mixer_control); + g_clear_object (&panel->sound_settings); + + G_OBJECT_CLASS (cc_sound_panel_parent_class)->finalize (object); +} + +static void +cc_sound_panel_class_init (CcSoundPanelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + CcPanelClass *panel_class = CC_PANEL_CLASS (klass); + + panel_class->get_help_uri = cc_sound_panel_get_help_uri; + + object_class->finalize = cc_sound_panel_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/sound/cc-sound-panel.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, balance_slider); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, fade_row); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, fade_slider); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, input_device_combo_box); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, input_level_bar); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, input_list_box); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, input_profile_combo_box); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, input_profile_row); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, input_volume_slider); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, label_size_group); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, output_device_combo_box); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, output_level_bar); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, output_list_box); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, output_profile_combo_box); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, output_profile_row); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, output_volume_slider); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, stream_list_box); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, subwoofer_row); + gtk_widget_class_bind_template_child (widget_class, CcSoundPanel, subwoofer_slider); + + gtk_widget_class_bind_template_callback (widget_class, input_device_changed_cb); + gtk_widget_class_bind_template_callback (widget_class, output_device_changed_cb); + gtk_widget_class_bind_template_callback (widget_class, test_output_configuration_button_clicked_cb); + + g_type_ensure (CC_TYPE_ALERT_CHOOSER); + g_type_ensure (CC_TYPE_BALANCE_SLIDER); + g_type_ensure (CC_TYPE_DEVICE_COMBO_BOX); + g_type_ensure (CC_TYPE_FADE_SLIDER); + g_type_ensure (CC_TYPE_LEVEL_BAR); + g_type_ensure (CC_TYPE_PROFILE_COMBO_BOX); + g_type_ensure (CC_TYPE_STREAM_LIST_BOX); + g_type_ensure (CC_TYPE_SUBWOOFER_SLIDER); + g_type_ensure (CC_TYPE_VOLUME_SLIDER); +} + +static void +cc_sound_panel_init (CcSoundPanel *self) +{ + g_resources_register (cc_sound_get_resource ()); + + gtk_widget_init_template (GTK_WIDGET (self)); + + self->sound_settings = g_settings_new (KEY_SOUNDS_SCHEMA); + g_signal_connect_object (self->sound_settings, + "changed::allow-volume-above-100-percent", + G_CALLBACK (allow_amplified_changed_cb), + self, + G_CONNECT_SWAPPED); + allow_amplified_changed_cb (self); + + self->mixer_control = gvc_mixer_control_new ("GNOME Settings"); + gvc_mixer_control_open (self->mixer_control); + + cc_stream_list_box_set_mixer_control (self->stream_list_box, self->mixer_control); + cc_volume_slider_set_mixer_control (self->input_volume_slider, self->mixer_control); + cc_volume_slider_set_mixer_control (self->output_volume_slider, self->mixer_control); + cc_subwoofer_slider_set_mixer_control (self->subwoofer_slider, self->mixer_control); + cc_device_combo_box_set_mixer_control (self->input_device_combo_box, self->mixer_control, FALSE); + cc_device_combo_box_set_mixer_control (self->output_device_combo_box, self->mixer_control, TRUE); + g_signal_connect_object (self->mixer_control, + "active-output-update", + G_CALLBACK (output_device_update_cb), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (self->mixer_control, + "active-input-update", + G_CALLBACK (input_device_update_cb), + self, + G_CONNECT_SWAPPED); +} |