summaryrefslogtreecommitdiff
path: root/mate-volume-control/src/gvc-mixer-dialog.c
diff options
context:
space:
mode:
authorMichal Ratajsky <[email protected]>2014-11-08 15:14:10 +0100
committerMichal Ratajsky <[email protected]>2014-11-08 15:14:10 +0100
commit93332554c235c7de59c64d0733f791a3be9f1775 (patch)
tree98dcd2e71920dde5426eafbaa4c0e69e559b14d3 /mate-volume-control/src/gvc-mixer-dialog.c
parentd71e47bc5279e1af152c9e65f589020280306a7f (diff)
downloadmate-media-93332554c235c7de59c64d0733f791a3be9f1775.tar.bz2
mate-media-93332554c235c7de59c64d0733f791a3be9f1775.tar.xz
Move some files and directories to better locations
- mate-volume-control/data changed to /data - mate-volume-control/src/* moved to mate-volume-control - sound-theme/sounds changed to /data/sounds - sound-theme/*.{c,h} moved to mate-volume-control - Removed AUTHORS and ChangeLog.pre-2-26 from mate-volume-control
Diffstat (limited to 'mate-volume-control/src/gvc-mixer-dialog.c')
-rw-r--r--mate-volume-control/src/gvc-mixer-dialog.c2606
1 files changed, 0 insertions, 2606 deletions
diff --git a/mate-volume-control/src/gvc-mixer-dialog.c b/mate-volume-control/src/gvc-mixer-dialog.c
deleted file mode 100644
index b6525fb..0000000
--- a/mate-volume-control/src/gvc-mixer-dialog.c
+++ /dev/null
@@ -1,2606 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2008 William Jon McCann
- * Copyright (C) 2014 Michal Ratajsky <[email protected]>
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib-object.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <libmatemixer/matemixer.h>
-
-#include "gvc-channel-bar.h"
-#include "gvc-balance-bar.h"
-#include "gvc-combo-box.h"
-#include "gvc-mixer-dialog.h"
-#include "gvc-sound-theme-chooser.h"
-#include "gvc-level-bar.h"
-#include "gvc-speaker-test.h"
-#include "gvc-utils.h"
-
-#define GVC_MIXER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_DIALOG, GvcMixerDialogPrivate))
-
-struct _GvcMixerDialogPrivate
-{
- MateMixerContext *context;
- GHashTable *bars;
- GtkWidget *notebook;
- GtkWidget *output_bar;
- GtkWidget *input_bar;
- GtkWidget *input_level_bar;
- GtkWidget *effects_bar;
- GtkWidget *output_stream_box;
- GtkWidget *sound_effects_box;
- GtkWidget *hw_box;
- GtkWidget *hw_treeview;
- GtkWidget *hw_settings_box;
- GtkWidget *hw_profile_combo;
- GtkWidget *input_box;
- GtkWidget *output_box;
- GtkWidget *applications_box;
- GtkWidget *applications_window;
- GtkWidget *no_apps_label;
- GtkWidget *output_treeview;
- GtkWidget *output_settings_frame;
- GtkWidget *output_settings_box;
- GtkWidget *output_balance_bar;
- GtkWidget *output_fade_bar;
- GtkWidget *output_lfe_bar;
- GtkWidget *output_port_combo;
- GtkWidget *input_treeview;
- GtkWidget *input_port_combo;
- GtkWidget *input_settings_box;
- GtkWidget *sound_theme_chooser;
- GtkSizeGroup *size_group;
- gdouble last_input_peak;
- guint num_apps;
-};
-
-enum {
- ICON_COLUMN,
- NAME_COLUMN,
- LABEL_COLUMN,
- ACTIVE_COLUMN,
- SPEAKERS_COLUMN,
- NUM_COLUMNS
-};
-
-enum {
- HW_ICON_COLUMN,
- HW_NAME_COLUMN,
- HW_LABEL_COLUMN,
- HW_STATUS_COLUMN,
- HW_PROFILE_COLUMN,
- HW_NUM_COLUMNS
-};
-
-enum {
- PAGE_EFFECTS,
- PAGE_HARDWARE,
- PAGE_INPUT,
- PAGE_OUTPUT,
- PAGE_APPLICATIONS
-};
-
-enum {
- PROP_0,
- PROP_CONTEXT
-};
-
-static const guint tab_accel_keys[] = {
- GDK_KEY_1, GDK_KEY_2, GDK_KEY_3, GDK_KEY_4, GDK_KEY_5
-};
-
-static void gvc_mixer_dialog_class_init (GvcMixerDialogClass *klass);
-static void gvc_mixer_dialog_init (GvcMixerDialog *dialog);
-static void gvc_mixer_dialog_finalize (GObject *object);
-
-static void add_stream (GvcMixerDialog *dialog,
- MateMixerStream *stream);
-static void add_application_control (GvcMixerDialog *dialog,
- MateMixerStreamControl *control);
-static void add_effects_control (GvcMixerDialog *dialog,
- MateMixerStreamControl *control);
-
-static void remove_stream (GvcMixerDialog *dialog,
- const gchar *name);
-static void remove_application_control (GvcMixerDialog *dialog,
- const gchar *name);
-
-static void bar_set_stream (GvcMixerDialog *dialog,
- GtkWidget *bar,
- MateMixerStream *stream);
-static void bar_set_stream_control (GvcMixerDialog *dialog,
- GtkWidget *bar,
- MateMixerStreamControl *control);
-
-G_DEFINE_TYPE (GvcMixerDialog, gvc_mixer_dialog, GTK_TYPE_DIALOG)
-
-static MateMixerSwitch *
-find_stream_port_switch (MateMixerStream *stream)
-{
- const GList *switches;
-
- switches = mate_mixer_stream_list_switches (stream);
- while (switches != NULL) {
- MateMixerSwitch *swtch = MATE_MIXER_SWITCH (switches->data);
- MateMixerSwitchFlags flags;
-
- flags = mate_mixer_switch_get_flags (swtch);
- if ((flags & MATE_MIXER_SWITCH_TOGGLE) == 0 &&
- mate_mixer_switch_get_role (swtch) == MATE_MIXER_SWITCH_ROLE_PORT)
- return swtch;
-
- switches = switches->next;
- }
- return NULL;
-}
-
-static MateMixerSwitch *
-find_device_profile_switch (MateMixerDevice *device)
-{
- const GList *switches;
-
- switches = mate_mixer_device_list_switches (device);
- while (switches != NULL) {
- MateMixerSwitch *swtch = MATE_MIXER_SWITCH (switches->data);
-
- if (mate_mixer_switch_get_role (swtch) == MATE_MIXER_SWITCH_ROLE_DEVICE_PROFILE)
- return swtch;
-
- switches = switches->next;
- }
- return NULL;
-}
-
-static MateMixerStream *
-find_device_test_stream (GvcMixerDialog *dialog, MateMixerDevice *device)
-{
- const GList *streams;
-
- streams = mate_mixer_device_list_streams (device);
- while (streams != NULL) {
- MateMixerStream *stream;
- MateMixerDirection direction;
-
- stream = MATE_MIXER_STREAM (streams->data);
- direction = mate_mixer_stream_get_direction (stream);
-
- if (direction == MATE_MIXER_DIRECTION_OUTPUT) {
- MateMixerStreamControl *control;
-
- control = mate_mixer_stream_get_default_control (stream);
- if (mate_mixer_stream_control_get_num_channels (control) > 0)
- return stream;
- }
- streams = streams->next;
- }
- return FALSE;
-}
-
-static gboolean
-find_tree_item_by_name (GtkTreeModel *model,
- const gchar *name,
- guint column,
- GtkTreeIter *iter)
-{
- gboolean found = FALSE;
-
- if (!gtk_tree_model_get_iter_first (model, iter))
- return FALSE;
-
- do {
- gchar *n;
- gtk_tree_model_get (model, iter, column, &n, -1);
-
- if (!g_strcmp0 (name, n))
- found = TRUE;
-
- g_free (n);
- } while (!found && gtk_tree_model_iter_next (model, iter));
-
- return found;
-}
-
-static void
-update_default_tree_item (GvcMixerDialog *dialog,
- GtkTreeModel *model,
- MateMixerStream *stream)
-{
- GtkTreeIter iter;
- const gchar *name = NULL;
-
- if (gtk_tree_model_get_iter_first (model, &iter) == FALSE)
- return;
-
- /* The supplied stream is the default, or the selected item. Traverse
- * the item list and mark each item as being selected or not. Also do not
- * presume some known stream is selected and allow NULL here. */
- if (stream != NULL)
- name = mate_mixer_stream_get_name (stream);
-
- do {
- gchar *n;
- gtk_tree_model_get (model, &iter,
- NAME_COLUMN, &n,
- -1);
- gtk_list_store_set (GTK_LIST_STORE (model),
- &iter,
- ACTIVE_COLUMN, !g_strcmp0 (name, n),
- -1);
- g_free (n);
- } while (gtk_tree_model_iter_next (model, &iter));
-}
-
-static void
-on_combobox_option_changed (GvcComboBox *combo,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- MateMixerSwitch *swtch;
- MateMixerSwitchOption *option;
- const GList *options;
-
- swtch = g_object_get_data (G_OBJECT (combo), "switch");
- if (G_UNLIKELY (swtch == NULL)) {
- g_warn_if_reached ();
- return;
- }
-
- options = mate_mixer_switch_list_options (swtch);
- while (options != NULL) {
- option = MATE_MIXER_SWITCH_OPTION (options->data);
-
- if (g_strcmp0 (mate_mixer_switch_option_get_name (option), name) == 0)
- break;
-
- option = NULL;
- options = options->next;
- }
-
- if (G_UNLIKELY (option == NULL)) {
- g_warn_if_reached ();
- return;
- }
-
- mate_mixer_switch_set_active_option (swtch, option);
-}
-
-static GtkWidget *
-create_port_combo_box (GvcMixerDialog *dialog,
- MateMixerSwitch *swtch,
- const gchar *name,
- const GList *items,
- const gchar *active)
-{
- GtkWidget *combobox;
-
- combobox = gvc_combo_box_new (name);
-
- gvc_combo_box_set_options (GVC_COMBO_BOX (combobox), items);
- gvc_combo_box_set_active (GVC_COMBO_BOX (combobox), active);
-
- gvc_combo_box_set_size_group (GVC_COMBO_BOX (combobox),
- dialog->priv->size_group,
- FALSE);
-
- g_object_set_data_full (G_OBJECT (combobox),
- "switch",
- g_object_ref (swtch),
- g_object_unref);
-
- g_signal_connect (G_OBJECT (combobox),
- "changed",
- G_CALLBACK (on_combobox_option_changed),
- dialog);
- return combobox;
-}
-
-static void
-update_output_settings (GvcMixerDialog *dialog)
-{
- MateMixerStream *stream;
- MateMixerStreamControl *control;
- MateMixerStreamControlFlags flags;
- MateMixerSwitch *port_switch;
- gboolean has_settings = FALSE;
-
- g_debug ("Updating output settings");
-
- if (dialog->priv->output_balance_bar != NULL) {
- gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box),
- dialog->priv->output_balance_bar);
-
- dialog->priv->output_balance_bar = NULL;
- }
- if (dialog->priv->output_fade_bar != NULL) {
- gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box),
- dialog->priv->output_fade_bar);
-
- dialog->priv->output_fade_bar = NULL;
- }
- if (dialog->priv->output_lfe_bar != NULL) {
- gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box),
- dialog->priv->output_lfe_bar);
-
- dialog->priv->output_lfe_bar = NULL;
- }
- if (dialog->priv->output_port_combo != NULL) {
- gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box),
- dialog->priv->output_port_combo);
-
- dialog->priv->output_port_combo = NULL;
- }
-
- /* Get the control currently associated with the output slider */
- control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->output_bar));
- if (control == NULL) {
- g_debug ("There is no control for the default output stream");
- gtk_widget_hide (dialog->priv->output_settings_frame);
- return;
- }
- flags = mate_mixer_stream_control_get_flags (control);
-
- /* Enable balance bar if it is available */
- if (flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) {
- dialog->priv->output_balance_bar =
- gvc_balance_bar_new (control, BALANCE_TYPE_RL);
-
- gvc_balance_bar_set_size_group (GVC_BALANCE_BAR (dialog->priv->output_balance_bar),
- dialog->priv->size_group,
- TRUE);
-
- gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box),
- dialog->priv->output_balance_bar,
- FALSE, FALSE, 6);
-
- gtk_widget_show (dialog->priv->output_balance_bar);
- has_settings = TRUE;
- }
-
- /* Enable fade bar if it is available */
- if (flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) {
- dialog->priv->output_fade_bar =
- gvc_balance_bar_new (control, BALANCE_TYPE_FR);
-
- gvc_balance_bar_set_size_group (GVC_BALANCE_BAR (dialog->priv->output_fade_bar),
- dialog->priv->size_group,
- TRUE);
-
- gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box),
- dialog->priv->output_fade_bar,
- FALSE, FALSE, 6);
-
- gtk_widget_show (dialog->priv->output_fade_bar);
- has_settings = TRUE;
- }
-
- /* Enable subwoofer volume bar if subwoofer is available */
- if (mate_mixer_stream_control_has_channel_position (control, MATE_MIXER_CHANNEL_LFE)) {
- dialog->priv->output_lfe_bar =
- gvc_balance_bar_new (control, BALANCE_TYPE_LFE);
-
- gvc_balance_bar_set_size_group (GVC_BALANCE_BAR (dialog->priv->output_lfe_bar),
- dialog->priv->size_group,
- TRUE);
-
- gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box),
- dialog->priv->output_lfe_bar,
- FALSE, FALSE, 6);
-
- gtk_widget_show (dialog->priv->output_lfe_bar);
- has_settings = TRUE;
- }
-
- /* Get owning stream of the control */
- stream = mate_mixer_stream_control_get_stream (control);
- if (G_UNLIKELY (stream == NULL))
- return;
-
- /* Enable the port selector if the stream has one */
- port_switch = find_stream_port_switch (stream);
- if (port_switch != NULL) {
- const GList *options;
- const gchar *active_name = NULL;
- MateMixerSwitchOption *active;
-
- options = mate_mixer_switch_list_options (port_switch);
- active = mate_mixer_switch_get_active_option (port_switch);
- if (active != NULL)
- active_name = mate_mixer_switch_option_get_name (active);
-
- dialog->priv->output_port_combo =
- create_port_combo_box (dialog,
- port_switch,
- _("Co_nnector:"),
- options,
- active_name);
-
- gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box),
- dialog->priv->output_port_combo,
- TRUE, FALSE, 6);
-
- gtk_widget_show (dialog->priv->output_port_combo);
- has_settings = TRUE;
- }
-
- if (has_settings == TRUE)
- gtk_widget_show (dialog->priv->output_settings_frame);
- else
- gtk_widget_hide (dialog->priv->output_settings_frame);
-}
-
-static void
-set_output_stream (GvcMixerDialog *dialog, MateMixerStream *stream)
-{
- GtkTreeModel *model;
- MateMixerSwitch *swtch;
- MateMixerStreamControl *control;
-
- control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->output_bar));
- if (control != NULL) {
- /* Disconnect port switch of the previous stream */
- if (dialog->priv->output_port_combo != NULL) {
- swtch = g_object_get_data (G_OBJECT (dialog->priv->output_port_combo),
- "switch");
- if (swtch != NULL)
- g_signal_handlers_disconnect_by_data (G_OBJECT (swtch),
- dialog);
- }
- }
-
- bar_set_stream (dialog, dialog->priv->output_bar, stream);
-
- if (stream != NULL) {
- const GList *controls;
-
- controls = mate_mixer_context_list_stored_controls (dialog->priv->context);
-
- /* Move all stored controls to the newly selected default stream */
- while (controls != NULL) {
- MateMixerStream *parent;
- MateMixerStreamControl *control;
-
- control = MATE_MIXER_STREAM_CONTROL (controls->data);
- parent = mate_mixer_stream_control_get_stream (control);
-
- /* Prefer streamless controls to stay the way they are, forcing them to
- * a particular owning stream would be wrong for eg. event controls */
- if (parent != NULL && parent != stream) {
- MateMixerDirection direction =
- mate_mixer_stream_get_direction (parent);
-
- if (direction == MATE_MIXER_DIRECTION_OUTPUT)
- mate_mixer_stream_control_set_stream (control, stream);
- }
- controls = controls->next;
- }
- }
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview));
- update_default_tree_item (dialog, model, stream);
-
- update_output_settings (dialog);
-}
-
-static void
-on_context_default_output_stream_notify (MateMixerContext *context,
- GParamSpec *pspec,
- GvcMixerDialog *dialog)
-{
- MateMixerStream *stream;
-
- stream = mate_mixer_context_get_default_output_stream (context);
-
- set_output_stream (dialog, stream);
-}
-
-#define DECAY_STEP .15
-
-static void
-on_stream_control_monitor_value (MateMixerStream *stream,
- gdouble value,
- GvcMixerDialog *dialog)
-{
- GtkAdjustment *adj;
-
- if (dialog->priv->last_input_peak >= DECAY_STEP) {
- if (value < dialog->priv->last_input_peak - DECAY_STEP) {
- value = dialog->priv->last_input_peak - DECAY_STEP;
- }
- }
-
- dialog->priv->last_input_peak = value;
-
- adj = gvc_level_bar_get_peak_adjustment (GVC_LEVEL_BAR (dialog->priv->input_level_bar));
- if (value >= 0)
- gtk_adjustment_set_value (adj, value);
- else
- gtk_adjustment_set_value (adj, 0.0);
-}
-
-static void
-update_input_settings (GvcMixerDialog *dialog)
-{
- MateMixerStream *stream;
- MateMixerStreamControl *control;
- MateMixerStreamControlFlags flags;
- MateMixerSwitch *port_switch;
-
- g_debug ("Updating input settings");
-
- if (dialog->priv->input_port_combo != NULL) {
- gtk_container_remove (GTK_CONTAINER (dialog->priv->input_settings_box),
- dialog->priv->input_port_combo);
-
- dialog->priv->input_port_combo = NULL;
- }
-
- /* Get the control currently associated with the input slider */
- control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar));
- if (control == NULL)
- return;
-
- flags = mate_mixer_stream_control_get_flags (control);
-
- /* Enable level bar only if supported by the control */
- if (flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR)
- g_signal_connect (G_OBJECT (control),
- "monitor-value",
- G_CALLBACK (on_stream_control_monitor_value),
- dialog);
-
- /* Get owning stream of the control */
- stream = mate_mixer_stream_control_get_stream (control);
- if (G_UNLIKELY (stream == NULL))
- return;
-
- /* Enable the port selector if the stream has one */
- port_switch = find_stream_port_switch (stream);
- if (port_switch != NULL) {
- const GList *options;
- const gchar *active_name = NULL;
- MateMixerSwitchOption *active;
-
- options = mate_mixer_switch_list_options (port_switch);
- active = mate_mixer_switch_get_active_option (port_switch);
- if (active != NULL)
- active_name = mate_mixer_switch_option_get_name (active);
-
- dialog->priv->input_port_combo =
- create_port_combo_box (dialog,
- port_switch,
- _("Co_nnector:"),
- options,
- active_name);
-
- gtk_box_pack_start (GTK_BOX (dialog->priv->input_settings_box),
- dialog->priv->input_port_combo,
- TRUE, TRUE, 0);
-
- gtk_widget_show (dialog->priv->input_port_combo);
- }
-}
-
-static void
-on_stream_control_mute_notify (MateMixerStreamControl *control,
- GParamSpec *pspec,
- GvcMixerDialog *dialog)
-{
- /* Stop monitoring the input stream when it gets muted */
- if (mate_mixer_stream_control_get_mute (control) == TRUE)
- mate_mixer_stream_control_set_monitor_enabled (control, FALSE);
- else
- mate_mixer_stream_control_set_monitor_enabled (control, TRUE);
-}
-
-static void
-set_input_stream (GvcMixerDialog *dialog, MateMixerStream *stream)
-{
- GtkTreeModel *model;
- MateMixerSwitch *swtch;
- MateMixerStreamControl *control;
-
- control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar));
- if (control != NULL) {
- /* Disconnect port switch of the previous stream */
- if (dialog->priv->input_port_combo != NULL) {
- swtch = g_object_get_data (G_OBJECT (dialog->priv->input_port_combo),
- "switch");
- if (swtch != NULL)
- g_signal_handlers_disconnect_by_data (G_OBJECT (swtch),
- dialog);
- }
-
- /* Disable monitoring of the previous control */
- g_signal_handlers_disconnect_by_func (G_OBJECT (control),
- G_CALLBACK (on_stream_control_monitor_value),
- dialog);
-
- mate_mixer_stream_control_set_monitor_enabled (control, FALSE);
- }
-
- bar_set_stream (dialog, dialog->priv->input_bar, stream);
-
- if (stream != NULL) {
- const GList *controls;
- guint page = gtk_notebook_get_current_page (GTK_NOTEBOOK (dialog->priv->notebook));
-
- controls = mate_mixer_context_list_stored_controls (dialog->priv->context);
-
- /* Move all stored controls to the newly selected default stream */
- while (controls != NULL) {
- MateMixerStream *parent;
-
- control = MATE_MIXER_STREAM_CONTROL (controls->data);
- parent = mate_mixer_stream_control_get_stream (control);
-
- /* Prefer streamless controls to stay the way they are, forcing them to
- * a particular owning stream would be wrong for eg. event controls */
- if (parent != NULL && parent != stream) {
- MateMixerDirection direction =
- mate_mixer_stream_get_direction (parent);
-
- if (direction == MATE_MIXER_DIRECTION_INPUT)
- mate_mixer_stream_control_set_stream (control, stream);
- }
- controls = controls->next;
- }
-
- if (page == PAGE_INPUT) {
- MateMixerStreamControl *control =
- gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar));
-
- if (G_LIKELY (control != NULL))
- mate_mixer_stream_control_set_monitor_enabled (control, TRUE);
- }
-
- /* Enable/disable the peak level monitor according to mute state */
- g_signal_connect (G_OBJECT (stream),
- "notify::mute",
- G_CALLBACK (on_stream_control_mute_notify),
- dialog);
- }
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview));
- update_default_tree_item (dialog, model, stream);
-
- update_input_settings (dialog);
-}
-
-static void
-on_context_default_input_stream_notify (MateMixerContext *context,
- GParamSpec *pspec,
- GvcMixerDialog *dialog)
-{
- MateMixerStream *stream;
-
- g_debug ("Default input stream has changed");
-
- stream = mate_mixer_context_get_default_input_stream (context);
-
- set_input_stream (dialog, stream);
-}
-
-static GvcComboBox *
-find_combo_box_by_switch (GvcMixerDialog *dialog, MateMixerSwitch *swtch)
-{
- MateMixerSwitch *combo_switch;
-
- if (dialog->priv->output_port_combo != NULL) {
- combo_switch = g_object_get_data (G_OBJECT (dialog->priv->output_port_combo),
- "switch");
- if (combo_switch == swtch)
- return GVC_COMBO_BOX (dialog->priv->output_port_combo);
- }
-
- if (dialog->priv->input_port_combo != NULL) {
- combo_switch = g_object_get_data (G_OBJECT (dialog->priv->input_port_combo),
- "switch");
- if (combo_switch == swtch)
- return GVC_COMBO_BOX (dialog->priv->input_port_combo);
- }
- return NULL;
-}
-
-static void
-on_switch_option_notify (MateMixerSwitch *swtch,
- GParamSpec *pspec,
- GvcMixerDialog *dialog)
-{
- GvcComboBox *combobox;
- MateMixerSwitchOption *port;
-
- combobox = find_combo_box_by_switch (dialog, swtch);
- if (G_UNLIKELY (combobox == NULL)) {
- g_warn_if_reached ();
- return;
- }
-
- g_signal_handlers_block_by_func (G_OBJECT (combobox),
- on_combobox_option_changed,
- dialog);
-
- port = mate_mixer_switch_get_active_option (swtch);
- if (G_LIKELY (port != NULL))
- gvc_combo_box_set_active (GVC_COMBO_BOX (combobox),
- mate_mixer_switch_option_get_name (port));
-
- g_signal_handlers_unblock_by_func (G_OBJECT (combobox),
- on_combobox_option_changed,
- dialog);
-}
-
-static GtkWidget *
-create_bar (GvcMixerDialog *dialog, gboolean use_size_group, gboolean symmetric)
-{
- GtkWidget *bar;
-
- bar = gvc_channel_bar_new (NULL);
-
- if (use_size_group == TRUE)
- gvc_channel_bar_set_size_group (GVC_CHANNEL_BAR (bar),
- dialog->priv->size_group,
- symmetric);
-
- g_object_set (G_OBJECT (bar),
- "orientation", GTK_ORIENTATION_HORIZONTAL,
- "show-mute", TRUE,
- "show-icons", TRUE,
- "show-marks", TRUE,
- "extended", TRUE, NULL);
- return bar;
-}
-
-static void
-bar_set_stream (GvcMixerDialog *dialog,
- GtkWidget *bar,
- MateMixerStream *stream)
-{
- MateMixerStreamControl *control = NULL;
-
- if (stream != NULL) {
- MateMixerSwitch *port_switch;
-
- control = mate_mixer_stream_get_default_control (stream);
-
- port_switch = find_stream_port_switch (stream);
- if (port_switch != NULL)
- g_signal_connect (G_OBJECT (port_switch),
- "notify::active-option",
- G_CALLBACK (on_switch_option_notify),
- dialog);
- }
-
- bar_set_stream_control (dialog, bar, control);
-}
-
-static void
-bar_set_stream_control (GvcMixerDialog *dialog,
- GtkWidget *bar,
- MateMixerStreamControl *control)
-{
- MateMixerStreamControl *previous;
-
- previous = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (bar));
- if (previous != NULL) {
- const gchar *name = mate_mixer_stream_control_get_name (previous);
-
- g_debug ("Disconnecting old stream control %s", name);
-
- g_signal_handlers_disconnect_by_data (G_OBJECT (previous), dialog);
-
- /* This may not do anything because we no longer have the information
- * about the owning stream, in case it was an input stream, make
- * sure to disconnected from the peak level monitor */
- mate_mixer_stream_control_set_monitor_enabled (previous, FALSE);
-
- g_hash_table_remove (dialog->priv->bars, name);
- }
-
- gvc_channel_bar_set_control (GVC_CHANNEL_BAR (bar), control);
-
- if (control != NULL) {
- const gchar *name = mate_mixer_stream_control_get_name (control);
-
- g_hash_table_insert (dialog->priv->bars,
- (gpointer) name,
- bar);
-
- gtk_widget_set_sensitive (GTK_WIDGET (bar), TRUE);
- } else
- gtk_widget_set_sensitive (GTK_WIDGET (bar), TRUE);
-}
-
-static void
-add_application_control (GvcMixerDialog *dialog, MateMixerStreamControl *control)
-{
- MateMixerStream *stream;
- MateMixerStreamControlMediaRole media_role;
- MateMixerAppInfo *info;
- MateMixerDirection direction = MATE_MIXER_DIRECTION_UNKNOWN;
- GtkWidget *bar;
- const gchar *app_id;
- const gchar *app_name;
- const gchar *app_icon;
-
- media_role = mate_mixer_stream_control_get_media_role (control);
-
- /* Add stream to the applications page, but make sure the stream qualifies
- * for the inclusion */
- info = mate_mixer_stream_control_get_app_info (control);
- if (info == NULL)
- return;
-
- /* Skip streams with roles we don't care about */
- if (media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT ||
- media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_TEST ||
- media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_ABSTRACT ||
- media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_FILTER)
- return;
-
- app_id = mate_mixer_app_info_get_id (info);
-
- /* These applications may have associated streams because they do peak
- * level monitoring, skip these too */
- if (!g_strcmp0 (app_id, "org.mate.VolumeControl") ||
- !g_strcmp0 (app_id, "org.gnome.VolumeControl") ||
- !g_strcmp0 (app_id, "org.PulseAudio.pavucontrol"))
- return;
-
- app_name = mate_mixer_app_info_get_name (info);
- if (app_name == NULL)
- app_name = mate_mixer_stream_control_get_label (control);
- if (app_name == NULL)
- app_name = mate_mixer_stream_control_get_name (control);
- if (G_UNLIKELY (app_name == NULL))
- return;
-
- bar = create_bar (dialog, FALSE, FALSE);
-
- g_object_set (G_OBJECT (bar),
- "show-marks", FALSE,
- "extended", FALSE,
- NULL);
-
- /* By default channel bars use speaker icons, use microphone icons
- * instead for recording applications */
- stream = mate_mixer_stream_control_get_stream (control);
- if (stream != NULL)
- direction = mate_mixer_stream_get_direction (stream);
-
- if (direction == MATE_MIXER_DIRECTION_INPUT)
- g_object_set (G_OBJECT (bar),
- "low-icon-name", "audio-input-microphone-low",
- "high-icon-name", "audio-input-microphone-high",
- NULL);
-
- app_icon = mate_mixer_app_info_get_icon (info);
- if (app_icon == NULL) {
- if (direction == MATE_MIXER_DIRECTION_INPUT)
- app_icon = "audio-input-microphone";
- else
- app_icon = "applications-multimedia";
- }
-
- gvc_channel_bar_set_name (GVC_CHANNEL_BAR (bar), app_name);
- gvc_channel_bar_set_icon_name (GVC_CHANNEL_BAR (bar), app_icon);
-
- gtk_box_pack_start (GTK_BOX (dialog->priv->applications_box),
- bar,
- FALSE, FALSE, 12);
-
- bar_set_stream_control (dialog, bar, control);
- dialog->priv->num_apps++;
-
- gtk_widget_hide (dialog->priv->no_apps_label);
- gtk_widget_show (bar);
-}
-
-static void
-add_effects_control (GvcMixerDialog *dialog, MateMixerStreamControl *control)
-{
- MateMixerStreamControl *previous;
- const gchar *name;
-
- /* We use a stored event control for the effects volume slider,
- * because regular streams are only created when an event sound
- * is played and then immediately destroyed.
- * The stored event control should exist all the time. */
- previous = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->effects_bar));
- if (previous != NULL) {
- name = mate_mixer_stream_control_get_name (previous);
-
- g_signal_handlers_disconnect_by_data (G_OBJECT (previous), dialog);
- g_hash_table_remove (dialog->priv->bars, name);
- }
-
- gvc_channel_bar_set_control (GVC_CHANNEL_BAR (dialog->priv->effects_bar), control);
-
- if (control != NULL) {
- name = mate_mixer_stream_control_get_name (control);
- g_hash_table_insert (dialog->priv->bars,
- (gpointer) name,
- dialog->priv->effects_bar);
-
- gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->effects_bar), TRUE);
- } else
- gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->effects_bar), FALSE);
-}
-
-static void
-on_stream_control_added (MateMixerStream *stream,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- MateMixerStreamControl *control;
- MateMixerStreamControlRole role;
-
- control = mate_mixer_stream_get_control (stream, name);
- if G_UNLIKELY (control == NULL)
- return;
-
- role = mate_mixer_stream_control_get_role (control);
-
- if (role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION)
- add_application_control (dialog, control);
-}
-
-static void
-on_stream_control_removed (MateMixerStream *stream,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- MateMixerStreamControl *control;
-
- control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar));
- if (control != NULL) {
- const gchar *input_name = mate_mixer_stream_control_get_name (control);
-
- if (strcmp (name, input_name) == 0) {
- // XXX probably can't even happen, but handle it somehow
- return;
- }
- }
-
- control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->output_bar));
- if (control != NULL) {
- const gchar *input_name = mate_mixer_stream_control_get_name (control);
-
- if (strcmp (name, input_name) == 0) {
- // XXX probably can't even happen, but handle it somehow
- return;
- }
- }
-
- /* No way to be sure that it is an application control, but we don't have
- * any other than application bars that could match the name */
- remove_application_control (dialog, name);
-}
-
-static void
-add_stream (GvcMixerDialog *dialog, MateMixerStream *stream)
-{
- GtkTreeModel *model = NULL;
- GtkTreeIter iter;
- const gchar *speakers = NULL;
- const GList *controls;
- gboolean is_default = FALSE;
- MateMixerDirection direction;
-
- direction = mate_mixer_stream_get_direction (stream);
-
- if (direction == MATE_MIXER_DIRECTION_INPUT) {
- MateMixerStream *input;
-
- input = mate_mixer_context_get_default_input_stream (dialog->priv->context);
- if (stream == input) {
- bar_set_stream (dialog, dialog->priv->input_bar, stream);
-
- update_input_settings (dialog);
- is_default = TRUE;
- }
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview));
- }
- else if (direction == MATE_MIXER_DIRECTION_OUTPUT) {
- MateMixerStream *output;
- MateMixerStreamControl *control;
-
- output = mate_mixer_context_get_default_output_stream (dialog->priv->context);
- if (stream == output) {
- bar_set_stream (dialog, dialog->priv->output_bar, stream);
-
- update_output_settings (dialog);
- is_default = TRUE;
- }
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview));
-
- control = mate_mixer_stream_get_default_control (stream);
- if (G_LIKELY (control != NULL))
- speakers = gvc_channel_map_to_pretty_string (control);
- }
-
- controls = mate_mixer_stream_list_controls (stream);
- while (controls != NULL) {
- MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (controls->data);
- MateMixerStreamControlRole role;
-
- role = mate_mixer_stream_control_get_role (control);
-
- if (role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION)
- add_application_control (dialog, control);
-
- controls = controls->next;
- }
-
- if (model != NULL) {
- const gchar *name;
- const gchar *label;
-
- name = mate_mixer_stream_get_name (stream);
- label = mate_mixer_stream_get_label (stream);
-
- gtk_list_store_append (GTK_LIST_STORE (model), &iter);
- gtk_list_store_set (GTK_LIST_STORE (model),
- &iter,
- NAME_COLUMN, name,
- LABEL_COLUMN, label,
- ACTIVE_COLUMN, is_default,
- SPEAKERS_COLUMN, speakers,
- -1);
- }
-
- // XXX find a way to disconnect when removed
- g_signal_connect (G_OBJECT (stream),
- "control-added",
- G_CALLBACK (on_stream_control_added),
- dialog);
- g_signal_connect (G_OBJECT (stream),
- "control-removed",
- G_CALLBACK (on_stream_control_removed),
- dialog);
-}
-
-static void
-update_device_test_visibility (GvcMixerDialog *dialog)
-{
- MateMixerDevice *device;
- MateMixerStream *stream;
-
- device = g_object_get_data (G_OBJECT (dialog->priv->hw_profile_combo), "device");
- if (G_UNLIKELY (device == NULL)) {
- return;
- }
-
- stream = find_device_test_stream (dialog, device);
-
- g_object_set (G_OBJECT (dialog->priv->hw_profile_combo),
- "show-button", (stream != NULL),
- NULL);
-}
-
-static void
-on_context_stream_added (MateMixerContext *context,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- MateMixerStream *stream;
- MateMixerDirection direction;
- GtkWidget *bar;
-
- stream = mate_mixer_context_get_stream (context, name);
- if (G_UNLIKELY (stream == NULL))
- return;
-
- direction = mate_mixer_stream_get_direction (stream);
-
- /* If the newly added stream belongs to the currently selected device and
- * the test button is hidden, this stream may be the one to allow the
- * sound test and therefore we may need to enable the button */
- if (dialog->priv->hw_profile_combo != NULL && direction == MATE_MIXER_DIRECTION_OUTPUT) {
- MateMixerDevice *device1;
- MateMixerDevice *device2;
-
- device1 = mate_mixer_stream_get_device (stream);
- device2 = g_object_get_data (G_OBJECT (dialog->priv->hw_profile_combo),
- "device");
-
- if (device1 == device2) {
- gboolean show_button;
-
- g_object_get (G_OBJECT (dialog->priv->hw_profile_combo),
- "show-button", &show_button,
- NULL);
-
- if (show_button == FALSE)
- update_device_test_visibility (dialog);
- }
- }
-
- bar = g_hash_table_lookup (dialog->priv->bars, name);
- if (G_UNLIKELY (bar != NULL))
- return;
-
- add_stream (dialog, stream);
-}
-
-static void
-remove_stream (GvcMixerDialog *dialog, const gchar *name)
-{
- GtkWidget *bar;
- GtkTreeIter iter;
- GtkTreeModel *model;
-
- bar = g_hash_table_lookup (dialog->priv->bars, name);
-
- if (bar != NULL) {
- g_debug ("Removing stream %s from bar %s",
- name,
- gvc_channel_bar_get_name (GVC_CHANNEL_BAR (bar)));
-
- bar_set_stream (dialog, bar, NULL);
- }
-
- /* Remove from any models */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview));
- if (find_tree_item_by_name (GTK_TREE_MODEL (model),
- name,
- NAME_COLUMN,
- &iter) == TRUE)
- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview));
- if (find_tree_item_by_name (GTK_TREE_MODEL (model),
- name,
- NAME_COLUMN,
- &iter) == TRUE)
- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-}
-
-static void
-remove_application_control (GvcMixerDialog *dialog, const gchar *name)
-{
- GtkWidget *bar;
-
- bar = g_hash_table_lookup (dialog->priv->bars, name);
- if (G_UNLIKELY (bar == NULL))
- return;
-
- g_debug ("Removing application stream %s", name);
-
- /* We could call bar_set_stream_control here, but that would pointlessly
- * invalidate the channel bar, so just remove it ourselves */
- g_hash_table_remove (dialog->priv->bars, name);
-
- gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (bar)), bar);
-
- if (G_UNLIKELY (dialog->priv->num_apps <= 0)) {
- g_warn_if_reached ();
- dialog->priv->num_apps = 1;
- }
-
- dialog->priv->num_apps--;
-
- if (dialog->priv->num_apps == 0)
- gtk_widget_show (dialog->priv->no_apps_label);
-}
-
-static void
-on_context_stream_removed (MateMixerContext *context,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- if (dialog->priv->hw_profile_combo != NULL) {
- gboolean show_button;
-
- g_object_get (G_OBJECT (dialog->priv->hw_profile_combo),
- "show-button", &show_button,
- NULL);
-
- if (show_button == TRUE)
- update_device_test_visibility (dialog);
- }
-
- remove_stream (dialog, name);
-}
-
-static void
-on_context_stored_control_added (MateMixerContext *context,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- MateMixerStreamControl *control;
- MateMixerStreamControlMediaRole media_role;
-
- control = MATE_MIXER_STREAM_CONTROL (mate_mixer_context_get_stored_control (context, name));
- if (G_UNLIKELY (control == NULL))
- return;
-
- media_role = mate_mixer_stream_control_get_media_role (control);
-
- if (media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT)
- add_effects_control (dialog, control);
-}
-
-static void
-on_context_stored_control_removed (MateMixerContext *context,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- GtkWidget *bar;
-
- bar = g_hash_table_lookup (dialog->priv->bars, name);
-
- if (bar != NULL) {
- /* We only use a stored control in the effects bar */
- if (G_UNLIKELY (bar != dialog->priv->effects_bar)) {
- g_warn_if_reached ();
- return;
- }
-
- bar_set_stream (dialog, bar, NULL);
- }
-}
-
-static gchar *
-device_status (MateMixerDevice *device)
-{
- guint inputs = 0;
- guint outputs = 0;
- gchar *inputs_str = NULL;
- gchar *outputs_str = NULL;
- const GList *streams;
-
- /* Get number of input and output streams in the device */
- streams = mate_mixer_device_list_streams (device);
- while (streams != NULL) {
- MateMixerStream *stream = MATE_MIXER_STREAM (streams->data);
- MateMixerDirection direction;
-
- direction = mate_mixer_stream_get_direction (stream);
-
- if (direction == MATE_MIXER_DIRECTION_INPUT)
- inputs++;
- else if (direction == MATE_MIXER_DIRECTION_OUTPUT)
- outputs++;
-
- streams = streams->next;
- }
-
- if (inputs == 0 && outputs == 0) {
- /* translators:
- * The device has been disabled */
- return g_strdup (_("Disabled"));
- }
-
- if (outputs > 0) {
- /* translators:
- * The number of sound outputs on a particular device */
- outputs_str = g_strdup_printf (ngettext ("%u Output",
- "%u Outputs",
- outputs),
- outputs);
- }
-
- if (inputs > 0) {
- /* translators:
- * The number of sound inputs on a particular device */
- inputs_str = g_strdup_printf (ngettext ("%u Input",
- "%u Inputs",
- inputs),
- inputs);
- }
-
- if (inputs_str != NULL && outputs_str != NULL) {
- gchar *ret = g_strdup_printf ("%s / %s",
- outputs_str,
- inputs_str);
- g_free (outputs_str);
- g_free (inputs_str);
- return ret;
- }
-
- if (inputs_str != NULL)
- return inputs_str;
-
- return outputs_str;
-}
-
-static void
-update_device_info (GvcMixerDialog *dialog, MateMixerDevice *device)
-{
- GtkTreeModel *model = NULL;
- GtkTreeIter iter;
- const gchar *label;
- const gchar *profile_label = NULL;
- gchar *status;
- MateMixerSwitch *profile_switch;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview));
-
- if (find_tree_item_by_name (model,
- mate_mixer_device_get_name (device),
- HW_NAME_COLUMN,
- &iter) == FALSE)
- return;
-
- label = mate_mixer_device_get_label (device);
-
- profile_switch = find_device_profile_switch (device);
- if (profile_switch != NULL) {
- MateMixerSwitchOption *active;
-
- active = mate_mixer_switch_get_active_option (profile_switch);
- if (G_LIKELY (active != NULL))
- profile_label = mate_mixer_switch_option_get_label (active);
- }
-
- status = device_status (device);
-
- gtk_list_store_set (GTK_LIST_STORE (model),
- &iter,
- HW_LABEL_COLUMN, label,
- HW_PROFILE_COLUMN, profile_label,
- HW_STATUS_COLUMN, status,
- -1);
- g_free (status);
-}
-
-static void
-on_device_profile_notify (MateMixerSwitch *swtch,
- GParamSpec *pspec,
- GvcMixerDialog *dialog)
-{
- MateMixerSwitchOption *active;
-
- g_signal_handlers_block_by_func (G_OBJECT (dialog->priv->hw_profile_combo),
- G_CALLBACK (on_combobox_option_changed),
- dialog);
-
- active = mate_mixer_switch_get_active_option (swtch);
- if (G_LIKELY (active != NULL)) {
- const gchar *name = mate_mixer_switch_option_get_name (active);
-
- gvc_combo_box_set_active (GVC_COMBO_BOX (dialog->priv->hw_profile_combo),
- name);
- }
-
- g_signal_handlers_unblock_by_func (G_OBJECT (dialog->priv->hw_profile_combo),
- G_CALLBACK (on_combobox_option_changed),
- dialog);
-
- // XXX find device
- // update_device_info (dialog, device);
-}
-
-static void
-add_device (GvcMixerDialog *dialog, MateMixerDevice *device)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GIcon *icon;
- const gchar *name;
- const gchar *label;
- gchar *status;
- const gchar *profile_label = NULL;
- MateMixerSwitch *profile_switch;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview));
-
- name = mate_mixer_device_get_name (device);
- label = mate_mixer_device_get_label (device);
-
- if (find_tree_item_by_name (GTK_TREE_MODEL (model),
- name,
- HW_NAME_COLUMN,
- &iter) == FALSE)
- gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-
- icon = g_themed_icon_new_with_default_fallbacks (mate_mixer_device_get_icon (device));
-
- profile_switch = find_device_profile_switch (device);
- if (profile_switch != NULL) {
- MateMixerSwitchOption *active;
-
- active = mate_mixer_switch_get_active_option (profile_switch);
- if (G_LIKELY (active != NULL))
- profile_label = mate_mixer_switch_option_get_label (active);
-
- g_signal_connect (G_OBJECT (device),
- "notify::active-option",
- G_CALLBACK (on_device_profile_notify),
- dialog);
- }
-
- status = device_status (device);
-
- gtk_list_store_set (GTK_LIST_STORE (model),
- &iter,
- HW_NAME_COLUMN, name,
- HW_LABEL_COLUMN, label,
- HW_ICON_COLUMN, icon,
- HW_PROFILE_COLUMN, profile_label,
- HW_STATUS_COLUMN, status,
- -1);
- g_free (status);
-
-}
-
-static void
-on_context_device_added (MateMixerContext *context, const gchar *name, GvcMixerDialog *dialog)
-{
- MateMixerDevice *device;
-
- device = mate_mixer_context_get_device (context, name);
- if (G_UNLIKELY (device == NULL))
- return;
-
- add_device (dialog, device);
-}
-
-static void
-on_context_device_removed (MateMixerContext *context,
- const gchar *name,
- GvcMixerDialog *dialog)
-{
- GtkTreeIter iter;
- GtkTreeModel *model;
-
- /* Remove from the device model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview));
-
- if (find_tree_item_by_name (GTK_TREE_MODEL (model),
- name,
- HW_NAME_COLUMN,
- &iter) == TRUE)
- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-}
-
-static void
-make_label_bold (GtkLabel *label)
-{
- PangoFontDescription *font_desc;
-
- font_desc = pango_font_description_new ();
-
- pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
-
- /* This will only affect the weight of the font, the rest is
- * from the current state of the widget, which comes from the
- * theme or user prefs, since the font desc only has the
- * weight flag turned on. */
-#if GTK_CHECK_VERSION (3, 0, 0)
- gtk_widget_override_font (GTK_WIDGET (label), font_desc);
-#else
- gtk_widget_modify_font (GTK_WIDGET (label), font_desc);
-#endif
- pango_font_description_free (font_desc);
-}
-
-static void
-on_input_radio_toggled (GtkCellRendererToggle *renderer,
- gchar *path_str,
- GvcMixerDialog *dialog)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreePath *path;
- gboolean toggled = FALSE;
- gchar *name = NULL;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview));
- path = gtk_tree_path_new_from_string (path_str);
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
-
- gtk_tree_model_get (model, &iter,
- NAME_COLUMN, &name,
- ACTIVE_COLUMN, &toggled,
- -1);
- if (toggled ^ 1) {
- MateMixerStream *stream;
- MateMixerBackendFlags flags;
-
- stream = mate_mixer_context_get_stream (dialog->priv->context, name);
- if (G_UNLIKELY (stream == NULL)) {
- g_warn_if_reached ();
- g_free (name);
- return;
- }
-
- g_debug ("Default input stream selection changed to %s", name);
-
- // XXX cache this
- flags = mate_mixer_context_get_backend_flags (dialog->priv->context);
-
- if (flags & MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM)
- mate_mixer_context_set_default_input_stream (dialog->priv->context, stream);
- else
- set_input_stream (dialog, stream);
- }
- g_free (name);
-}
-
-static void
-on_output_radio_toggled (GtkCellRendererToggle *renderer,
- gchar *path_str,
- GvcMixerDialog *dialog)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreePath *path;
- gboolean toggled = FALSE;
- gchar *name = NULL;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview));
- path = gtk_tree_path_new_from_string (path_str);
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
-
- gtk_tree_model_get (model, &iter,
- NAME_COLUMN, &name,
- ACTIVE_COLUMN, &toggled,
- -1);
- if (toggled ^ 1) {
- MateMixerStream *stream;
- MateMixerBackendFlags flags;
-
- stream = mate_mixer_context_get_stream (dialog->priv->context, name);
- if (G_UNLIKELY (stream == NULL)) {
- g_warn_if_reached ();
- g_free (name);
- return;
- }
-
- g_debug ("Default output stream selection changed to %s", name);
-
- // XXX cache this
- flags = mate_mixer_context_get_backend_flags (dialog->priv->context);
-
- if (flags & MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM)
- mate_mixer_context_set_default_output_stream (dialog->priv->context, stream);
- else
- set_output_stream (dialog, stream);
- }
- g_free (name);
-}
-
-static void
-stream_name_to_text (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- gchar *label;
- gchar *speakers;
-
- gtk_tree_model_get (model, iter,
- LABEL_COLUMN, &label,
- SPEAKERS_COLUMN, &speakers,
- -1);
-
- if (speakers != NULL) {
- gchar *str = g_strdup_printf ("%s\n<i>%s</i>",
- label,
- speakers);
-
- g_object_set (cell, "markup", str, NULL);
- g_free (str);
- g_free (speakers);
- } else {
- g_object_set (cell, "text", label, NULL);
- }
-
- g_free (label);
-}
-
-static gint
-compare_stream_treeview_items (GtkTreeModel *model,
- GtkTreeIter *a,
- GtkTreeIter *b,
- gpointer user_data)
-{
- gchar *desc_a = NULL;
- gchar *desc_b = NULL;
- gint result;
-
- gtk_tree_model_get (model, a,
- LABEL_COLUMN, &desc_a,
- -1);
- gtk_tree_model_get (model, b,
- LABEL_COLUMN, &desc_b,
- -1);
-
- if (desc_a == NULL) {
- g_free (desc_b);
- return -1;
- }
- if (desc_b == NULL) {
- g_free (desc_a);
- return 1;
- }
-
- result = g_ascii_strcasecmp (desc_a, desc_b);
-
- g_free (desc_a);
- g_free (desc_b);
- return result;
-}
-
-static GtkWidget *
-create_stream_treeview (GvcMixerDialog *dialog, GCallback on_toggled)
-{
- GtkWidget *treeview;
- GtkListStore *store;
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
-
- treeview = gtk_tree_view_new ();
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
-
- store = gtk_list_store_new (NUM_COLUMNS,
- G_TYPE_ICON,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_STRING);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
- GTK_TREE_MODEL (store));
-
- renderer = gtk_cell_renderer_toggle_new ();
- gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer), TRUE);
-
- column = gtk_tree_view_column_new_with_attributes (NULL,
- renderer,
- "active", ACTIVE_COLUMN,
- NULL);
-
- gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-
- g_signal_connect (G_OBJECT (renderer),
- "toggled",
- G_CALLBACK (on_toggled),
- dialog);
-
- gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), -1,
- _("Name"),
- gtk_cell_renderer_text_new (),
- stream_name_to_text,
- NULL, NULL);
-
- /* Keep the list of streams sorted by the name */
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
- LABEL_COLUMN,
- GTK_SORT_ASCENDING);
-
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
- LABEL_COLUMN,
- compare_stream_treeview_items,
- NULL, NULL);
- return treeview;
-}
-
-static void
-on_test_speakers_clicked (GvcComboBox *widget, GvcMixerDialog *dialog)
-{
- GtkWidget *d,
- *test,
- *container;
- gchar *title;
- MateMixerDevice *device;
- MateMixerStream *stream;
-
- device = g_object_get_data (G_OBJECT (widget), "device");
- if (G_UNLIKELY (device == NULL)) {
- g_warn_if_reached ();
- return;
- }
-
- stream = find_device_test_stream (dialog, device);
- if (G_UNLIKELY (stream == NULL)) {
- g_warn_if_reached ();
- return;
- }
-
- title = g_strdup_printf (_("Speaker Testing for %s"),
- mate_mixer_device_get_label (device));
-
- d = gtk_dialog_new_with_buttons (title,
- GTK_WINDOW (dialog),
- GTK_DIALOG_MODAL |
- GTK_DIALOG_DESTROY_WITH_PARENT,
- "gtk-close",
- GTK_RESPONSE_CLOSE,
- NULL);
- g_free (title);
-
- gtk_window_set_resizable (GTK_WINDOW (d), FALSE);
-
- test = gvc_speaker_test_new (stream);
- gtk_widget_show (test);
-
- container = gtk_dialog_get_content_area (GTK_DIALOG (d));
- gtk_container_add (GTK_CONTAINER (container), test);
-
- gtk_dialog_run (GTK_DIALOG (d));
- gtk_widget_destroy (d);
-}
-
-static GtkWidget *
-create_profile_combo_box (GvcMixerDialog *dialog,
- MateMixerSwitch *swtch,
- const gchar *name,
- const GList *items,
- const gchar *active)
-{
- GtkWidget *combobox;
-
- combobox = gvc_combo_box_new (name);
-
- gvc_combo_box_set_options (GVC_COMBO_BOX (combobox), items);
- gvc_combo_box_set_active (GVC_COMBO_BOX (combobox), active);
-
- gvc_combo_box_set_size_group (GVC_COMBO_BOX (combobox),
- dialog->priv->size_group,
- FALSE);
-
- g_object_set (G_OBJECT (combobox),
- "button-label", _("Test Speakers"),
- NULL);
-
- g_object_set_data_full (G_OBJECT (combobox),
- "switch",
- g_object_ref (swtch),
- g_object_unref);
-
- g_signal_connect (G_OBJECT (combobox),
- "changed",
- G_CALLBACK (on_combobox_option_changed),
- dialog);
-
- g_signal_connect (G_OBJECT (combobox),
- "button-clicked",
- G_CALLBACK (on_test_speakers_clicked),
- dialog);
-
- return combobox;
-}
-
-static void
-on_device_selection_changed (GtkTreeSelection *selection, GvcMixerDialog *dialog)
-{
- GtkTreeIter iter;
- gchar *name;
- MateMixerDevice *device;
- MateMixerSwitch *profile_switch;
-
- g_debug ("Device selection changed");
-
- if (dialog->priv->hw_profile_combo != NULL) {
- gtk_container_remove (GTK_CONTAINER (dialog->priv->hw_settings_box),
- dialog->priv->hw_profile_combo);
-
- dialog->priv->hw_profile_combo = NULL;
- }
-
- if (gtk_tree_selection_get_selected (selection, NULL, &iter) == FALSE)
- return;
-
- gtk_tree_model_get (gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview)),
- &iter,
- HW_NAME_COLUMN, &name,
- -1);
-
- device = mate_mixer_context_get_device (dialog->priv->context, name);
- if (G_UNLIKELY (device == NULL)) {
- g_warn_if_reached ();
- g_free (name);
- return;
- }
- g_free (name);
-
- /* Profile/speaker test combo */
- profile_switch = find_device_profile_switch (device);
- if (profile_switch != NULL) {
- const GList *options;
- const gchar *active_name = NULL;
- MateMixerSwitchOption *active;
-
- options = mate_mixer_switch_list_options (profile_switch);
- active = mate_mixer_switch_get_active_option (profile_switch);
- if (active != NULL)
- active_name = mate_mixer_switch_option_get_name (active);
-
- dialog->priv->hw_profile_combo =
- create_profile_combo_box (dialog,
- profile_switch,
- _("_Profile:"),
- options,
- active_name);
-
- g_object_set_data_full (G_OBJECT (dialog->priv->hw_profile_combo),
- "device",
- g_object_ref (device),
- g_object_unref);
-
- gtk_box_pack_start (GTK_BOX (dialog->priv->hw_settings_box),
- dialog->priv->hw_profile_combo,
- TRUE, TRUE, 6);
-
- /* Enable the speaker test button if the selected device
- * is capable of sound output */
- update_device_test_visibility (dialog);
-
- gtk_widget_show (dialog->priv->hw_profile_combo);
- }
-}
-
-static void
-on_notebook_switch_page (GtkNotebook *notebook,
- GtkWidget *page,
- guint page_num,
- GvcMixerDialog *dialog)
-{
- MateMixerStreamControl *control;
-
- // XXX because this is called too early in constructor
- if (G_UNLIKELY (dialog->priv->input_bar == NULL))
- return;
-
- control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar));
- if (control == NULL)
- return;
-
- if (page_num == PAGE_INPUT)
- mate_mixer_stream_control_set_monitor_enabled (control, TRUE);
- else
- mate_mixer_stream_control_set_monitor_enabled (control, FALSE);
-}
-
-static void
-device_name_to_text (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- gchar *label = NULL;
- gchar *profile = NULL;
- gchar *status = NULL;
-
- gtk_tree_model_get (model, iter,
- HW_LABEL_COLUMN, &label,
- HW_PROFILE_COLUMN, &profile,
- HW_STATUS_COLUMN, &status,
- -1);
-
- if (G_LIKELY (status != NULL)) {
- gchar *str;
-
- if (profile != NULL)
- str = g_strdup_printf ("%s\n<i>%s</i>\n<i>%s</i>",
- label,
- status,
- profile);
- else
- str = g_strdup_printf ("%s\n<i>%s</i>",
- label,
- status);
-
- g_object_set (cell, "markup", str, NULL);
- g_free (str);
- g_free (profile);
- g_free (status);
- } else
- g_object_set (cell, "text", label, NULL);
-
- g_free (label);
-}
-
-static gint
-compare_device_treeview_items (GtkTreeModel *model,
- GtkTreeIter *a,
- GtkTreeIter *b,
- gpointer user_data)
-{
- gchar *desc_a = NULL;
- gchar *desc_b = NULL;
- gint result;
-
- gtk_tree_model_get (model, a,
- HW_LABEL_COLUMN, &desc_a,
- -1);
- gtk_tree_model_get (model, b,
- HW_LABEL_COLUMN, &desc_b,
- -1);
-
- result = g_ascii_strcasecmp (desc_a, desc_b);
-
- g_free (desc_a);
- g_free (desc_b);
- return result;
-}
-
-static GtkWidget *
-create_device_treeview (GvcMixerDialog *dialog, GCallback on_changed)
-{
- GtkWidget *treeview;
- GtkListStore *store;
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
- GtkTreeSelection *selection;
-
- treeview = gtk_tree_view_new ();
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
- g_signal_connect (G_OBJECT (selection),
- "changed",
- on_changed,
- dialog);
-
- store = gtk_list_store_new (HW_NUM_COLUMNS,
- G_TYPE_ICON,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
- GTK_TREE_MODEL (store));
-
- renderer = gtk_cell_renderer_pixbuf_new ();
- g_object_set (G_OBJECT (renderer),
- "stock-size",
- GTK_ICON_SIZE_DIALOG,
- NULL);
-
- column = gtk_tree_view_column_new_with_attributes (NULL,
- renderer,
- "gicon", HW_ICON_COLUMN,
- NULL);
-
- gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
- gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), -1,
- _("Name"),
- gtk_cell_renderer_text_new (),
- device_name_to_text,
- NULL, NULL);
-
- /* Keep the list of streams sorted by the name */
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
- HW_LABEL_COLUMN,
- GTK_SORT_ASCENDING);
-
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
- HW_LABEL_COLUMN,
- compare_device_treeview_items,
- NULL, NULL);
- return treeview;
-}
-
-static void
-dialog_accel_cb (GtkAccelGroup *accelgroup,
- GObject *object,
- guint key,
- GdkModifierType mod,
- GvcMixerDialog *self)
-{
- gint num = -1;
- gint i;
-
- for (i = 0; i < G_N_ELEMENTS (tab_accel_keys); i++) {
- if (tab_accel_keys[i] == key) {
- num = i;
- break;
- }
- }
-
- if (num != -1)
- gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook), num);
-}
-
-static GObject *
-gvc_mixer_dialog_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_params)
-{
- GObject *object;
- GvcMixerDialog *self;
- GtkWidget *main_vbox;
- GtkWidget *label;
- GtkWidget *alignment;
- GtkWidget *box;
- GtkWidget *sbox;
- GtkWidget *ebox;
- GtkTreeSelection *selection;
- GtkAccelGroup *accel_group;
- GClosure *closure;
- GtkTreeIter iter;
- gint i;
- const GList *list;
-
- object = G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->constructor (type,
- n_construct_properties,
- construct_params);
-
- self = GVC_MIXER_DIALOG (object);
-
- gtk_dialog_add_button (GTK_DIALOG (self), "gtk-close", GTK_RESPONSE_OK);
-
- main_vbox = gtk_dialog_get_content_area (GTK_DIALOG (self));
- gtk_box_set_spacing (GTK_BOX (main_vbox), 2);
-
- gtk_container_set_border_width (GTK_CONTAINER (self), 6);
-
-#if GTK_CHECK_VERSION (3, 0, 0)
- self->priv->output_stream_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-#else
- self->priv->output_stream_box = gtk_hbox_new (FALSE, 12);
-#endif
-
- alignment = gtk_alignment_new (0, 0, 1, 1);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 0, 0, 0);
- gtk_container_add (GTK_CONTAINER (alignment), self->priv->output_stream_box);
- gtk_box_pack_start (GTK_BOX (main_vbox),
- alignment,
- FALSE, FALSE, 0);
-
- self->priv->output_bar = create_bar (self, TRUE, TRUE);
- gvc_channel_bar_set_name (GVC_CHANNEL_BAR (self->priv->output_bar),
- _("_Output volume: "));
-
- gtk_widget_show (self->priv->output_bar);
- gtk_widget_set_sensitive (self->priv->output_bar, FALSE);
-
- gtk_box_pack_start (GTK_BOX (self->priv->output_stream_box),
- self->priv->output_bar, TRUE, TRUE, 12);
-
- self->priv->notebook = gtk_notebook_new ();
- gtk_box_pack_start (GTK_BOX (main_vbox),
- self->priv->notebook,
- TRUE, TRUE, 0);
-
- g_signal_connect (G_OBJECT (self->priv->notebook),
- "switch-page",
- G_CALLBACK (on_notebook_switch_page),
- self);
-
- gtk_container_set_border_width (GTK_CONTAINER (self->priv->notebook), 5);
-
- /* Set up accels (borrowed from Empathy) */
- accel_group = gtk_accel_group_new ();
- gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
-
- for (i = 0; i < G_N_ELEMENTS (tab_accel_keys); i++) {
- closure = g_cclosure_new (G_CALLBACK (dialog_accel_cb),
- self,
- NULL);
- gtk_accel_group_connect (accel_group,
- tab_accel_keys[i],
- GDK_MOD1_MASK,
- 0,
- closure);
- }
-
- g_object_unref (accel_group);
-
- /* Create notebook pages */
-#if GTK_CHECK_VERSION (3, 0, 0)
- self->priv->sound_effects_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-#else
- self->priv->sound_effects_box = gtk_vbox_new (FALSE, 6);
-#endif
- gtk_container_set_border_width (GTK_CONTAINER (self->priv->sound_effects_box), 12);
-
- label = gtk_label_new (_("Sound Effects"));
- gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
- self->priv->sound_effects_box,
- label);
-
- self->priv->effects_bar = create_bar (self, TRUE, TRUE);
- gtk_box_pack_start (GTK_BOX (self->priv->sound_effects_box),
- self->priv->effects_bar, FALSE, FALSE, 0);
-
- gvc_channel_bar_set_show_marks (GVC_CHANNEL_BAR (self->priv->effects_bar), FALSE);
- gvc_channel_bar_set_extended (GVC_CHANNEL_BAR (self->priv->effects_bar), FALSE);
-
- gvc_channel_bar_set_name (GVC_CHANNEL_BAR (self->priv->effects_bar),
- _("_Alert volume: "));
-
- gtk_widget_show (self->priv->effects_bar);
- gtk_widget_set_sensitive (self->priv->effects_bar, FALSE);
-
- self->priv->sound_theme_chooser = gvc_sound_theme_chooser_new ();
-
- gtk_box_pack_start (GTK_BOX (self->priv->sound_effects_box),
- self->priv->sound_theme_chooser,
- TRUE, TRUE, 6);
-
-#if GTK_CHECK_VERSION (3, 0, 0)
- self->priv->hw_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-#else
- self->priv->hw_box = gtk_vbox_new (FALSE, 12);
-#endif
- gtk_container_set_border_width (GTK_CONTAINER (self->priv->hw_box), 12);
-
- label = gtk_label_new (_("Hardware"));
- gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
- self->priv->hw_box,
- label);
-
- box = gtk_frame_new (_("C_hoose a device to configure:"));
- label = gtk_frame_get_label_widget (GTK_FRAME (box));
- make_label_bold (GTK_LABEL (label));
- gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
- gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
- gtk_box_pack_start (GTK_BOX (self->priv->hw_box), box, TRUE, TRUE, 0);
-
- alignment = gtk_alignment_new (0, 0, 1, 1);
- gtk_container_add (GTK_CONTAINER (box), alignment);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
-
- self->priv->hw_treeview = create_device_treeview (self,
- G_CALLBACK (on_device_selection_changed));
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->priv->hw_treeview);
-
- box = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box),
- GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (box), self->priv->hw_treeview);
- gtk_container_add (GTK_CONTAINER (alignment), box);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->hw_treeview));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-
- box = gtk_frame_new (_("Settings for the selected device:"));
- label = gtk_frame_get_label_widget (GTK_FRAME (box));
- make_label_bold (GTK_LABEL (label));
- gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
- gtk_box_pack_start (GTK_BOX (self->priv->hw_box), box, FALSE, TRUE, 12);
-
-#if GTK_CHECK_VERSION (3, 0, 0)
- self->priv->hw_settings_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-#else
- self->priv->hw_settings_box = gtk_vbox_new (FALSE, 12);
-#endif
-
- gtk_container_add (GTK_CONTAINER (box), self->priv->hw_settings_box);
-
-#if GTK_CHECK_VERSION (3, 0, 0)
- self->priv->input_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-#else
- self->priv->input_box = gtk_vbox_new (FALSE, 12);
-#endif
-
- gtk_container_set_border_width (GTK_CONTAINER (self->priv->input_box), 12);
-
- label = gtk_label_new (_("Input"));
- gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
- self->priv->input_box,
- label);
-
- self->priv->input_bar = create_bar (self, TRUE, TRUE);
-
- gvc_channel_bar_set_name (GVC_CHANNEL_BAR (self->priv->input_bar),
- _("_Input volume: "));
-
- gvc_channel_bar_set_low_icon_name (GVC_CHANNEL_BAR (self->priv->input_bar),
- "audio-input-microphone-low");
- gvc_channel_bar_set_high_icon_name (GVC_CHANNEL_BAR (self->priv->input_bar),
- "audio-input-microphone-high");
-
- gtk_widget_show (self->priv->input_bar);
- gtk_widget_set_sensitive (self->priv->input_bar, FALSE);
-
- alignment = gtk_alignment_new (0, 0, 1, 1);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
- gtk_container_add (GTK_CONTAINER (alignment), self->priv->input_bar);
- gtk_box_pack_start (GTK_BOX (self->priv->input_box),
- alignment,
- FALSE, FALSE, 0);
-
-#if GTK_CHECK_VERSION (3, 0, 0)
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- sbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- ebox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-#else
- box = gtk_hbox_new (FALSE, 6);
- sbox = gtk_hbox_new (FALSE, 6);
- ebox = gtk_hbox_new (FALSE, 6);
-#endif
-
- gtk_box_pack_start (GTK_BOX (self->priv->input_box),
- box,
- FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (box),
- sbox,
- FALSE, FALSE, 0);
-
- label = gtk_label_new (_("Input level:"));
- gtk_box_pack_start (GTK_BOX (sbox),
- label,
- FALSE, FALSE, 0);
- gtk_size_group_add_widget (self->priv->size_group, sbox);
-
- self->priv->input_level_bar = gvc_level_bar_new ();
- gvc_level_bar_set_orientation (GVC_LEVEL_BAR (self->priv->input_level_bar),
- GTK_ORIENTATION_HORIZONTAL);
- gvc_level_bar_set_scale (GVC_LEVEL_BAR (self->priv->input_level_bar),
- GVC_LEVEL_SCALE_LINEAR);
- gtk_box_pack_start (GTK_BOX (box),
- self->priv->input_level_bar,
- TRUE, TRUE, 6);
-
- gtk_box_pack_start (GTK_BOX (box),
- ebox,
- FALSE, FALSE, 0);
- gtk_size_group_add_widget (self->priv->size_group, ebox);
-
-#if GTK_CHECK_VERSION (3, 0, 0)
- self->priv->input_settings_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-#else
- self->priv->input_settings_box = gtk_hbox_new (FALSE, 6);
-#endif
- gtk_box_pack_start (GTK_BOX (self->priv->input_box),
- self->priv->input_settings_box,
- FALSE, FALSE, 0);
-
- box = gtk_frame_new (_("C_hoose a device for sound input:"));
- label = gtk_frame_get_label_widget (GTK_FRAME (box));
- make_label_bold (GTK_LABEL (label));
- gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
- gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
- gtk_box_pack_start (GTK_BOX (self->priv->input_box), box, TRUE, TRUE, 0);
-
- alignment = gtk_alignment_new (0, 0, 1, 1);
- gtk_container_add (GTK_CONTAINER (box), alignment);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
-
- self->priv->input_treeview =
- create_stream_treeview (self, G_CALLBACK (on_input_radio_toggled));
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->priv->input_treeview);
-
- box = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box),
- GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (box), self->priv->input_treeview);
- gtk_container_add (GTK_CONTAINER (alignment), box);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->input_treeview));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-
- /* Output page */
- self->priv->output_box = gtk_vbox_new (FALSE, 12);
- gtk_container_set_border_width (GTK_CONTAINER (self->priv->output_box), 12);
- label = gtk_label_new (_("Output"));
- gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
- self->priv->output_box,
- label);
-
- box = gtk_frame_new (_("C_hoose a device for sound output:"));
- label = gtk_frame_get_label_widget (GTK_FRAME (box));
- make_label_bold (GTK_LABEL (label));
- gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
- gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
- gtk_box_pack_start (GTK_BOX (self->priv->output_box), box, TRUE, TRUE, 0);
-
- alignment = gtk_alignment_new (0, 0, 1, 1);
- gtk_container_add (GTK_CONTAINER (box), alignment);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
-
- self->priv->output_treeview = create_stream_treeview (self,
- G_CALLBACK (on_output_radio_toggled));
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->priv->output_treeview);
-
- box = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box),
- GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (box), self->priv->output_treeview);
- gtk_container_add (GTK_CONTAINER (alignment), box);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->output_treeview));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-
- box = gtk_frame_new (_("Settings for the selected device:"));
- label = gtk_frame_get_label_widget (GTK_FRAME (box));
- make_label_bold (GTK_LABEL (label));
- gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
- gtk_box_pack_start (GTK_BOX (self->priv->output_box), box, FALSE, FALSE, 12);
- self->priv->output_settings_box = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (box), self->priv->output_settings_box);
-
- self->priv->output_settings_frame = box;
-
- /* Applications */
- self->priv->applications_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->priv->applications_window),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
-
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self->priv->applications_window),
- GTK_SHADOW_IN);
-
-#if GTK_CHECK_VERSION (3, 0, 0)
- self->priv->applications_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-#else
- self->priv->applications_box = gtk_vbox_new (FALSE, 12);
-#endif
- gtk_container_set_border_width (GTK_CONTAINER (self->priv->applications_box), 12);
-
-#if GTK_CHECK_VERSION (3, 8, 0)
- gtk_container_add (GTK_CONTAINER (self->priv->applications_window),
- self->priv->applications_box);
-#else
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (self->priv->applications_window),
- self->priv->applications_box);
-#endif
-
- label = gtk_label_new (_("Applications"));
- gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
- self->priv->applications_window,
- label);
-
- self->priv->no_apps_label = gtk_label_new (_("No application is currently playing or recording audio."));
- gtk_box_pack_start (GTK_BOX (self->priv->applications_box),
- self->priv->no_apps_label,
- TRUE, TRUE, 0);
-
- gtk_widget_show_all (main_vbox);
-
- list = mate_mixer_context_list_streams (self->priv->context);
- while (list != NULL) {
- add_stream (self, MATE_MIXER_STREAM (list->data));
- list = list->next;
- }
-
- list = mate_mixer_context_list_devices (self->priv->context);
- while (list != NULL) {
- add_device (self, MATE_MIXER_DEVICE (list->data));
- list = list->next;
- }
-
- /* Find an event role stream */
- list = mate_mixer_context_list_stored_controls (self->priv->context);
- while (list != NULL) {
- MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data);
- MateMixerStreamControlMediaRole media_role;
-
- media_role = mate_mixer_stream_control_get_media_role (control);
-
- if (media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT) {
- add_effects_control (self, control);
- break;
- }
- list = list->next;
- }
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->hw_treeview));
-
- /* Select the first device in the list */
- // XXX handle no devices
- if (gtk_tree_selection_get_selected (selection, NULL, NULL) == FALSE) {
- GtkTreeModel *model =
- gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->hw_treeview));
-
- if (gtk_tree_model_get_iter_first (model, &iter))
- gtk_tree_selection_select_iter (selection, &iter);
- }
-
- return object;
-}
-
-static MateMixerContext *
-gvc_mixer_dialog_get_context (GvcMixerDialog *dialog)
-{
- return dialog->priv->context;
-}
-
-static void
-gvc_mixer_dialog_set_context (GvcMixerDialog *dialog, MateMixerContext *context)
-{
- dialog->priv->context = g_object_ref (context);
-
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "stream-added",
- G_CALLBACK (on_context_stream_added),
- dialog);
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "stream-removed",
- G_CALLBACK (on_context_stream_removed),
- dialog);
-
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "device-added",
- G_CALLBACK (on_context_device_added),
- dialog);
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "device-removed",
- G_CALLBACK (on_context_device_removed),
- dialog);
-
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "notify::default-input-stream",
- G_CALLBACK (on_context_default_input_stream_notify),
- dialog);
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "notify::default-output-stream",
- G_CALLBACK (on_context_default_output_stream_notify),
- dialog);
-
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "stored-control-added",
- G_CALLBACK (on_context_stored_control_added),
- dialog);
- g_signal_connect (G_OBJECT (dialog->priv->context),
- "stored-control-removed",
- G_CALLBACK (on_context_stored_control_removed),
- dialog);
-
- g_object_notify (G_OBJECT (dialog), "context");
-}
-
-static void
-gvc_mixer_dialog_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GvcMixerDialog *self = GVC_MIXER_DIALOG (object);
-
- switch (prop_id) {
- case PROP_CONTEXT:
- gvc_mixer_dialog_set_context (self, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gvc_mixer_dialog_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GvcMixerDialog *self = GVC_MIXER_DIALOG (object);
-
- switch (prop_id) {
- case PROP_CONTEXT:
- g_value_set_object (value, gvc_mixer_dialog_get_context (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gvc_mixer_dialog_dispose (GObject *object)
-{
- GvcMixerDialog *dialog = GVC_MIXER_DIALOG (object);
-
- if (dialog->priv->context != NULL) {
- g_signal_handlers_disconnect_by_data (G_OBJECT (dialog->priv->context),
- dialog);
-
- g_clear_object (&dialog->priv->context);
- }
-
- G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->dispose (object);
-}
-
-static void
-gvc_mixer_dialog_class_init (GvcMixerDialogClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->constructor = gvc_mixer_dialog_constructor;
- object_class->dispose = gvc_mixer_dialog_dispose;
- object_class->finalize = gvc_mixer_dialog_finalize;
- object_class->set_property = gvc_mixer_dialog_set_property;
- object_class->get_property = gvc_mixer_dialog_get_property;
-
- g_object_class_install_property (object_class,
- PROP_CONTEXT,
- g_param_spec_object ("context",
- "Context",
- "MateMixer context",
- MATE_MIXER_TYPE_CONTEXT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_type_class_add_private (klass, sizeof (GvcMixerDialogPrivate));
-}
-
-static void
-gvc_mixer_dialog_init (GvcMixerDialog *dialog)
-{
- dialog->priv = GVC_MIXER_DIALOG_GET_PRIVATE (dialog);
-
- dialog->priv->bars = g_hash_table_new (g_str_hash, g_str_equal);
- dialog->priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-}
-
-static void
-gvc_mixer_dialog_finalize (GObject *object)
-{
- GvcMixerDialog *dialog;
-
- dialog = GVC_MIXER_DIALOG (object);
-
- g_hash_table_destroy (dialog->priv->bars);
-
- G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->finalize (object);
-}
-
-GvcMixerDialog *
-gvc_mixer_dialog_new (MateMixerContext *context)
-{
- return g_object_new (GVC_TYPE_MIXER_DIALOG,
- "icon-name", "multimedia-volume-control",
- "title", _("Sound Preferences"),
- "context", context,
- NULL);
-}
-
-gboolean
-gvc_mixer_dialog_set_page (GvcMixerDialog *self, const gchar *page)
-{
- guint num = 0;
-
- g_return_val_if_fail (GVC_IS_MIXER_DIALOG (self), FALSE);
-
- if (page != NULL) {
- if (g_str_equal (page, "effects"))
- num = PAGE_EFFECTS;
- else if (g_str_equal (page, "hardware"))
- num = PAGE_HARDWARE;
- else if (g_str_equal (page, "input"))
- num = PAGE_INPUT;
- else if (g_str_equal (page, "output"))
- num = PAGE_OUTPUT;
- else if (g_str_equal (page, "applications"))
- num = PAGE_APPLICATIONS;
- }
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook), num);
-
- return TRUE;
-}