diff options
author | Giovanni Campagna <gcampagna@src.gnome.org> | 2012-10-22 21:52:29 +0200 |
---|---|---|
committer | Giovanni Campagna <gcampagna@src.gnome.org> | 2012-10-22 22:03:35 +0200 |
commit | f3df56c399279f52b141b4a2fa3df0b08bdcec55 (patch) | |
tree | bb742b9029e8300852d78ed763d7ba0af4e7da17 | |
parent | 96e9f84a2b41ebb3c63933b14f59fd8380f70699 (diff) | |
download | libgnome-volume-control-f3df56c399279f52b141b4a2fa3df0b08bdcec55.tar.gz |
Remove Gtk dependency
It is undesirable in gnome-settings-daemon
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | gvc-channel-bar.c | 980 | ||||
-rw-r--r-- | gvc-channel-bar.h | 90 | ||||
-rw-r--r-- | gvc-mixer-dialog.c | 1977 | ||||
-rw-r--r-- | gvc-mixer-dialog.h | 56 |
5 files changed, 1 insertions, 3106 deletions
diff --git a/Makefile.am b/Makefile.am index 08ea266..54bf7c6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,8 +31,6 @@ libgvc_la_gir_sources = \ gvc-mixer-event-role.c \ gvc-mixer-control.h \ gvc-mixer-control.c \ - gvc-channel-bar.h \ - gvc-channel-bar.c \ $(NULL) libgvc_la_SOURCES = \ @@ -52,7 +50,7 @@ if HAVE_INTROSPECTION include $(INTROSPECTION_MAKEFILE) Gvc-1.0.gir: libgvc.la -Gvc_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 Gtk-3.0 +Gvc_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 Gvc_1_0_gir_CFLAGS = $(INCLUDES) -I$(srcdir)/gvc -DWITH_INTROSPECTION Gvc_1_0_gir_LIBS = libgvc.la Gvc_1_0_gir_FILES = $(addprefix $(srcdir)/,$(libgvc_la_gir_sources)) diff --git a/gvc-channel-bar.c b/gvc-channel-bar.c deleted file mode 100644 index b9d4a6c..0000000 --- a/gvc-channel-bar.c +++ /dev/null @@ -1,980 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> - -#include <pulse/pulseaudio.h> - -#include <glib.h> -#include <glib/gi18n-lib.h> -#include <gtk/gtk.h> -#include <canberra-gtk.h> - -#include "gvc-channel-bar.h" -#include "gvc-mixer-control.h" - -#define SCALE_SIZE 128 -#define ADJUSTMENT_MAX_NORMAL gvc_mixer_control_get_vol_max_norm(NULL) -#define ADJUSTMENT_MAX_AMPLIFIED gvc_mixer_control_get_vol_max_amplified(NULL) -#define ADJUSTMENT_MAX (bar->priv->is_amplified ? ADJUSTMENT_MAX_AMPLIFIED : ADJUSTMENT_MAX_NORMAL) -#define SCROLLSTEP (ADJUSTMENT_MAX / 100.0 * 5.0) - -#define GVC_CHANNEL_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_CHANNEL_BAR, GvcChannelBarPrivate)) - -struct GvcChannelBarPrivate -{ - GtkOrientation orientation; - GtkWidget *scale_box; - GtkWidget *start_box; - GtkWidget *end_box; - GtkWidget *image; - GtkWidget *label; - GtkWidget *low_image; - GtkWidget *scale; - GtkWidget *high_image; - GtkWidget *mute_box; - GtkWidget *mute_switch; - GtkAdjustment *adjustment; - GtkAdjustment *zero_adjustment; - gboolean show_mute; - gboolean is_muted; - char *name; - char *icon_name; - char *low_icon_name; - char *high_icon_name; - GtkSizeGroup *size_group; - gboolean symmetric; - gboolean click_lock; - gboolean is_amplified; - guint32 base_volume; -}; - -enum -{ - PROP_0, - PROP_ORIENTATION, - PROP_SHOW_MUTE, - PROP_IS_MUTED, - PROP_ADJUSTMENT, - PROP_NAME, - PROP_ICON_NAME, - PROP_LOW_ICON_NAME, - PROP_HIGH_ICON_NAME, - PROP_IS_AMPLIFIED, - PROP_ELLIPSIZE -}; - -static void gvc_channel_bar_class_init (GvcChannelBarClass *klass); -static void gvc_channel_bar_init (GvcChannelBar *channel_bar); -static void gvc_channel_bar_finalize (GObject *object); - -static gboolean on_scale_button_press_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar); -static gboolean on_scale_button_release_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar); -static gboolean on_scale_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - GvcChannelBar *bar); - -G_DEFINE_TYPE (GvcChannelBar, gvc_channel_bar, GTK_TYPE_HBOX) - -static GtkWidget * -_scale_box_new (GvcChannelBar *bar) -{ - GvcChannelBarPrivate *priv = bar->priv; - GtkWidget *box; - GtkWidget *sbox; - GtkWidget *ebox; - - if (priv->orientation == GTK_ORIENTATION_VERTICAL) { - bar->priv->scale_box = box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - - priv->scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, priv->adjustment); - - gtk_widget_set_size_request (priv->scale, -1, SCALE_SIZE); - gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE); - - bar->priv->start_box = sbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (box), sbox, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (sbox), priv->image, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (sbox), priv->label, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (sbox), priv->high_image, FALSE, FALSE, 0); - gtk_widget_hide (priv->high_image); - gtk_box_pack_start (GTK_BOX (box), priv->scale, TRUE, TRUE, 0); - - bar->priv->end_box = ebox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (box), ebox, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (ebox), priv->low_image, FALSE, FALSE, 0); - gtk_widget_hide (priv->low_image); - - gtk_box_pack_start (GTK_BOX (ebox), priv->mute_box, FALSE, FALSE, 0); - } else { - bar->priv->scale_box = box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0); - - priv->scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, priv->adjustment); - - gtk_widget_set_size_request (priv->scale, SCALE_SIZE, -1); - - bar->priv->start_box = sbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (box), sbox, FALSE, FALSE, 0); - - gtk_box_pack_end (GTK_BOX (sbox), priv->low_image, FALSE, FALSE, 0); - gtk_widget_show (priv->low_image); - - gtk_box_pack_start (GTK_BOX (sbox), priv->label, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (box), priv->scale, TRUE, TRUE, 0); - - bar->priv->end_box = ebox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (box), ebox, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (ebox), priv->high_image, FALSE, FALSE, 0); - gtk_widget_show (priv->high_image); - gtk_box_pack_start (GTK_BOX (ebox), priv->mute_box, FALSE, FALSE, 0); - } - - ca_gtk_widget_disable_sounds (bar->priv->scale, FALSE); - gtk_widget_add_events (bar->priv->scale, GDK_SCROLL_MASK); - - g_signal_connect (G_OBJECT (bar->priv->scale), "button-press-event", - G_CALLBACK (on_scale_button_press_event), bar); - g_signal_connect (G_OBJECT (bar->priv->scale), "button-release-event", - G_CALLBACK (on_scale_button_release_event), bar); - g_signal_connect (G_OBJECT (bar->priv->scale), "scroll-event", - G_CALLBACK (on_scale_scroll_event), bar); - - if (bar->priv->size_group != NULL) { - gtk_size_group_add_widget (bar->priv->size_group, sbox); - - if (bar->priv->symmetric) { - gtk_size_group_add_widget (bar->priv->size_group, ebox); - } - } - - gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE); - - return box; -} - -static void -update_image (GvcChannelBar *bar) -{ - gtk_image_set_from_icon_name (GTK_IMAGE (bar->priv->image), - bar->priv->icon_name, - GTK_ICON_SIZE_DIALOG); - - if (bar->priv->icon_name != NULL) { - gtk_widget_show (bar->priv->image); - } else { - gtk_widget_hide (bar->priv->image); - } -} - -static void -update_label (GvcChannelBar *bar) -{ - if (bar->priv->name != NULL) { - gtk_label_set_text_with_mnemonic (GTK_LABEL (bar->priv->label), - bar->priv->name); - gtk_label_set_mnemonic_widget (GTK_LABEL (bar->priv->label), - bar->priv->scale); - gtk_widget_show (bar->priv->label); - } else { - gtk_label_set_text (GTK_LABEL (bar->priv->label), NULL); - gtk_widget_hide (bar->priv->label); - } -} - -static void -update_layout (GvcChannelBar *bar) -{ - GtkWidget *box; - GtkWidget *frame; - - if (bar->priv->scale == NULL) { - return; - } - - box = bar->priv->scale_box; - frame = gtk_widget_get_parent (box); - - g_object_ref (bar->priv->image); - g_object_ref (bar->priv->label); - g_object_ref (bar->priv->mute_box); - g_object_ref (bar->priv->low_image); - g_object_ref (bar->priv->high_image); - - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), bar->priv->image); - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), bar->priv->label); - gtk_container_remove (GTK_CONTAINER (bar->priv->end_box), bar->priv->mute_box); - - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), bar->priv->low_image); - gtk_container_remove (GTK_CONTAINER (bar->priv->end_box), bar->priv->high_image); - } else { - gtk_container_remove (GTK_CONTAINER (bar->priv->end_box), bar->priv->low_image); - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), bar->priv->high_image); - } - - gtk_container_remove (GTK_CONTAINER (box), bar->priv->start_box); - gtk_container_remove (GTK_CONTAINER (box), bar->priv->scale); - gtk_container_remove (GTK_CONTAINER (box), bar->priv->end_box); - gtk_container_remove (GTK_CONTAINER (frame), box); - - bar->priv->scale_box = _scale_box_new (bar); - gtk_container_add (GTK_CONTAINER (frame), bar->priv->scale_box); - - g_object_unref (bar->priv->image); - g_object_unref (bar->priv->label); - g_object_unref (bar->priv->mute_box); - g_object_unref (bar->priv->low_image); - g_object_unref (bar->priv->high_image); - - gtk_widget_show_all (frame); -} - -void -gvc_channel_bar_set_size_group (GvcChannelBar *bar, - GtkSizeGroup *group, - gboolean symmetric) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - bar->priv->size_group = group; - bar->priv->symmetric = symmetric; - - if (bar->priv->size_group != NULL) { - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->start_box); - - if (bar->priv->symmetric) { - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->end_box); - } - } - gtk_widget_queue_draw (GTK_WIDGET (bar)); -} - -void -gvc_channel_bar_set_name (GvcChannelBar *bar, - const char *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - g_free (bar->priv->name); - bar->priv->name = g_strdup (name); - update_label (bar); - g_object_notify (G_OBJECT (bar), "name"); -} - -void -gvc_channel_bar_set_icon_name (GvcChannelBar *bar, - const char *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - g_free (bar->priv->icon_name); - bar->priv->icon_name = g_strdup (name); - update_image (bar); - g_object_notify (G_OBJECT (bar), "icon-name"); -} - -void -gvc_channel_bar_set_low_icon_name (GvcChannelBar *bar, - const char *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (name != NULL && strcmp (bar->priv->low_icon_name, name) != 0) { - g_free (bar->priv->low_icon_name); - bar->priv->low_icon_name = g_strdup (name); - gtk_image_set_from_icon_name (GTK_IMAGE (bar->priv->low_image), - bar->priv->low_icon_name, - GTK_ICON_SIZE_MENU); - g_object_notify (G_OBJECT (bar), "low-icon-name"); - } -} - -void -gvc_channel_bar_set_high_icon_name (GvcChannelBar *bar, - const char *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (name != NULL && strcmp (bar->priv->high_icon_name, name) != 0) { - g_free (bar->priv->high_icon_name); - bar->priv->high_icon_name = g_strdup (name); - gtk_image_set_from_icon_name (GTK_IMAGE (bar->priv->high_image), - bar->priv->high_icon_name, - GTK_ICON_SIZE_MENU); - g_object_notify (G_OBJECT (bar), "high-icon-name"); - } -} - -void -gvc_channel_bar_set_orientation (GvcChannelBar *bar, - GtkOrientation orientation) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (orientation != bar->priv->orientation) { - bar->priv->orientation = orientation; - update_layout (bar); - g_object_notify (G_OBJECT (bar), "orientation"); - } -} - -static void -gvc_channel_bar_set_adjustment (GvcChannelBar *bar, - GtkAdjustment *adjustment) -{ - g_return_if_fail (GVC_CHANNEL_BAR (bar)); - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - - if (bar->priv->adjustment != NULL) { - g_object_unref (bar->priv->adjustment); - } - bar->priv->adjustment = g_object_ref_sink (adjustment); - - if (bar->priv->scale != NULL) { - gtk_range_set_adjustment (GTK_RANGE (bar->priv->scale), adjustment); - } - - g_object_notify (G_OBJECT (bar), "adjustment"); -} - -/** - * gvc_channel_bar_get_adjustment: - * @bar: - * - * Returns: (transfer none): - */ -GtkAdjustment * -gvc_channel_bar_get_adjustment (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), NULL); - - return bar->priv->adjustment; -} - -static gboolean -on_scale_button_press_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar) -{ - bar->priv->click_lock = TRUE; - - return FALSE; -} - -static gboolean -on_scale_button_release_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar) -{ - GtkAdjustment *adj; - gdouble value; - - bar->priv->click_lock = FALSE; - - adj = gtk_range_get_adjustment (GTK_RANGE (widget)); - - value = gtk_adjustment_get_value (adj); - - /* this means the adjustment moved away from zero and - * therefore we should unmute and set the volume. */ - gvc_channel_bar_set_is_muted (bar, (value == 0.0)); - - /* Play a sound! */ - ca_gtk_play_for_widget (GTK_WIDGET (bar), 0, - CA_PROP_EVENT_ID, "audio-volume-change", - CA_PROP_EVENT_DESCRIPTION, "foobar event happened", - CA_PROP_APPLICATION_ID, "org.gnome.VolumeControl", - NULL); - - return FALSE; -} - -gboolean -gvc_channel_bar_scroll (GvcChannelBar *bar, GdkEventScroll *event) -{ - GtkAdjustment *adj; - gdouble value; - GdkScrollDirection direction; - gdouble dx, dy; - - g_return_val_if_fail (bar != NULL, FALSE); - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - - direction = event->direction; - - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - if (direction == GDK_SCROLL_LEFT || direction == GDK_SCROLL_RIGHT) - return FALSE; - } else { - /* Switch direction for RTL */ - if (gtk_widget_get_direction (GTK_WIDGET (bar)) == GTK_TEXT_DIR_RTL) { - if (direction == GDK_SCROLL_RIGHT) - direction = GDK_SCROLL_LEFT; - else if (direction == GDK_SCROLL_LEFT) - direction = GDK_SCROLL_RIGHT; - } - /* Switch side scroll to vertical */ - if (direction == GDK_SCROLL_RIGHT) - direction = GDK_SCROLL_UP; - else if (direction == GDK_SCROLL_LEFT) - direction = GDK_SCROLL_DOWN; - } - - if (!gdk_event_get_scroll_deltas ((GdkEvent*)event, &dx, &dy)) { - dx = 0.0; - dy = 0.0; - - switch (direction) { - case GDK_SCROLL_UP: - case GDK_SCROLL_LEFT: - dy = 1.0; - break; - case GDK_SCROLL_DOWN: - case GDK_SCROLL_RIGHT: - dy = -1.0; - break; - default: - ; - } - } - - adj = gtk_range_get_adjustment (GTK_RANGE (bar->priv->scale)); - if (adj == bar->priv->zero_adjustment) { - if (dy > 0) - gvc_channel_bar_set_is_muted (bar, FALSE); - return TRUE; - } - - value = gtk_adjustment_get_value (adj); - - if (dy > 0) { - if (value + dy * SCROLLSTEP > ADJUSTMENT_MAX) - value = ADJUSTMENT_MAX; - else - value = value + dy * SCROLLSTEP; - } else if (dy < 0) { - if (value + dy * SCROLLSTEP < 0) - value = 0.0; - else - value = value + dy * SCROLLSTEP; - } - - gvc_channel_bar_set_is_muted (bar, (value == 0.0)); - adj = gtk_range_get_adjustment (GTK_RANGE (bar->priv->scale)); - gtk_adjustment_set_value (adj, value); - - return TRUE; -} - -static gboolean -on_scale_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - GvcChannelBar *bar) -{ - return gvc_channel_bar_scroll (bar, event); -} - -static void -on_zero_adjustment_value_changed (GtkAdjustment *adjustment, - GvcChannelBar *bar) -{ - gdouble value; - - if (bar->priv->click_lock != FALSE) { - return; - } - - value = gtk_adjustment_get_value (bar->priv->zero_adjustment); - gtk_adjustment_set_value (bar->priv->adjustment, value); - - - if (bar->priv->show_mute == FALSE) { - /* this means the adjustment moved away from zero and - * therefore we should unmute and set the volume. */ - gvc_channel_bar_set_is_muted (bar, value > 0.0); - } -} - -static void -update_mute_switch (GvcChannelBar *bar) -{ - if (bar->priv->show_mute) { - gtk_widget_show (bar->priv->mute_switch); - gtk_switch_set_active (GTK_SWITCH (bar->priv->mute_switch), - !bar->priv->is_muted); - } else { - gtk_widget_hide (bar->priv->mute_switch); - } - - if (bar->priv->is_muted) { - /* If we aren't showing the mute button then - * move slider to the zero. But we don't want to - * change the adjustment. */ - g_signal_handlers_block_by_func (bar->priv->zero_adjustment, - on_zero_adjustment_value_changed, - bar); - gtk_adjustment_set_value (bar->priv->zero_adjustment, 0); - g_signal_handlers_unblock_by_func (bar->priv->zero_adjustment, - on_zero_adjustment_value_changed, - bar); - gtk_range_set_adjustment (GTK_RANGE (bar->priv->scale), - bar->priv->zero_adjustment); - } else { - /* no longer muted so restore the original adjustment - * and tell the front-end that the value changed */ - gtk_range_set_adjustment (GTK_RANGE (bar->priv->scale), - bar->priv->adjustment); - gtk_adjustment_value_changed (bar->priv->adjustment); - } -} - -void -gvc_channel_bar_set_is_muted (GvcChannelBar *bar, - gboolean is_muted) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (is_muted != bar->priv->is_muted) { - /* Update our internal state before telling the - * front-end about our changes */ - bar->priv->is_muted = is_muted; - update_mute_switch (bar); - g_object_notify (G_OBJECT (bar), "is-muted"); - } -} - -gboolean -gvc_channel_bar_get_is_muted (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - return bar->priv->is_muted; -} - -void -gvc_channel_bar_set_show_mute (GvcChannelBar *bar, - gboolean show_mute) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (show_mute != bar->priv->show_mute) { - bar->priv->show_mute = show_mute; - g_object_notify (G_OBJECT (bar), "show-mute"); - update_mute_switch (bar); - } -} - -gboolean -gvc_channel_bar_get_show_mute (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - return bar->priv->show_mute; -} - -void -gvc_channel_bar_set_is_amplified (GvcChannelBar *bar, gboolean amplified) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - bar->priv->is_amplified = amplified; - gtk_adjustment_set_upper (bar->priv->adjustment, ADJUSTMENT_MAX); - gtk_adjustment_set_upper (bar->priv->zero_adjustment, ADJUSTMENT_MAX); - gtk_scale_clear_marks (GTK_SCALE (bar->priv->scale)); - - if (amplified) { - char *str; - - if (bar->priv->base_volume == ADJUSTMENT_MAX_NORMAL) { - str = g_strdup_printf ("<small>%s</small>", C_("volume", "100%")); - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), ADJUSTMENT_MAX_NORMAL, - GTK_POS_BOTTOM, str); - } else { - str = g_strdup_printf ("<small>%s</small>", C_("volume", "Unamplified")); - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), bar->priv->base_volume, - GTK_POS_BOTTOM, str); - /* Only show 100% if it's higher than the base volume */ - if (bar->priv->base_volume < ADJUSTMENT_MAX_NORMAL) { - str = g_strdup_printf ("<small>%s</small>", C_("volume", "100%")); - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), ADJUSTMENT_MAX_NORMAL, - GTK_POS_BOTTOM, str); - } - } - - g_free (str); - gtk_alignment_set (GTK_ALIGNMENT (bar->priv->mute_box), 0.5, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (bar->priv->low_image), 0.5, 0.15); - gtk_misc_set_alignment (GTK_MISC (bar->priv->high_image), 0.5, 0.15); - gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0, 0); - } else { - gtk_alignment_set (GTK_ALIGNMENT (bar->priv->mute_box), 0.5, 0.5, 0, 0); - gtk_misc_set_alignment (GTK_MISC (bar->priv->low_image), 0.5, 0.5); - gtk_misc_set_alignment (GTK_MISC (bar->priv->high_image), 0.5, 0.5); - gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0, 0.5); - } -} - -gboolean -gvc_channel_bar_get_ellipsize (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - - return gtk_label_get_ellipsize (GTK_LABEL (bar->priv->label)) != PANGO_ELLIPSIZE_NONE; -} - -void -gvc_channel_bar_set_ellipsize (GvcChannelBar *bar, - gboolean ellipsized) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (ellipsized) - gtk_label_set_ellipsize (GTK_LABEL (bar->priv->label), PANGO_ELLIPSIZE_END); - else - gtk_label_set_ellipsize (GTK_LABEL (bar->priv->label), PANGO_ELLIPSIZE_NONE); -} - -void -gvc_channel_bar_set_base_volume (GvcChannelBar *bar, - pa_volume_t base_volume) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (base_volume == 0) { - bar->priv->base_volume = ADJUSTMENT_MAX_NORMAL; - return; - } - - /* Note that you need to call _is_amplified() afterwards to update the marks */ - bar->priv->base_volume = base_volume; -} - -static void -gvc_channel_bar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcChannelBar *self = GVC_CHANNEL_BAR (object); - - switch (prop_id) { - case PROP_ORIENTATION: - gvc_channel_bar_set_orientation (self, g_value_get_enum (value)); - break; - case PROP_IS_MUTED: - gvc_channel_bar_set_is_muted (self, g_value_get_boolean (value)); - break; - case PROP_SHOW_MUTE: - gvc_channel_bar_set_show_mute (self, g_value_get_boolean (value)); - break; - case PROP_NAME: - gvc_channel_bar_set_name (self, g_value_get_string (value)); - break; - case PROP_ICON_NAME: - gvc_channel_bar_set_icon_name (self, g_value_get_string (value)); - break; - case PROP_LOW_ICON_NAME: - gvc_channel_bar_set_low_icon_name (self, g_value_get_string (value)); - break; - case PROP_HIGH_ICON_NAME: - gvc_channel_bar_set_high_icon_name (self, g_value_get_string (value)); - break; - case PROP_ADJUSTMENT: - gvc_channel_bar_set_adjustment (self, g_value_get_object (value)); - break; - case PROP_IS_AMPLIFIED: - gvc_channel_bar_set_is_amplified (self, g_value_get_boolean (value)); - break; - case PROP_ELLIPSIZE: - gvc_channel_bar_set_ellipsize (self, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_channel_bar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcChannelBar *self = GVC_CHANNEL_BAR (object); - GvcChannelBarPrivate *priv = self->priv; - - switch (prop_id) { - case PROP_ORIENTATION: - g_value_set_enum (value, priv->orientation); - break; - case PROP_IS_MUTED: - g_value_set_boolean (value, priv->is_muted); - break; - case PROP_SHOW_MUTE: - g_value_set_boolean (value, priv->show_mute); - break; - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - case PROP_ICON_NAME: - g_value_set_string (value, priv->icon_name); - break; - case PROP_LOW_ICON_NAME: - g_value_set_string (value, priv->low_icon_name); - break; - case PROP_HIGH_ICON_NAME: - g_value_set_string (value, priv->high_icon_name); - break; - case PROP_ADJUSTMENT: - g_value_set_object (value, gvc_channel_bar_get_adjustment (self)); - break; - case PROP_IS_AMPLIFIED: - g_value_set_boolean (value, priv->is_amplified); - break; - case PROP_ELLIPSIZE: - g_value_set_boolean (value, gvc_channel_bar_get_ellipsize (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GObject * -gvc_channel_bar_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_params) -{ - GObject *object; - GvcChannelBar *self; - - object = G_OBJECT_CLASS (gvc_channel_bar_parent_class)->constructor (type, n_construct_properties, construct_params); - - self = GVC_CHANNEL_BAR (object); - - update_mute_switch (self); - - return object; -} - -static void -gvc_channel_bar_class_init (GvcChannelBarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructor = gvc_channel_bar_constructor; - object_class->finalize = gvc_channel_bar_finalize; - object_class->set_property = gvc_channel_bar_set_property; - object_class->get_property = gvc_channel_bar_get_property; - - g_object_class_install_property (object_class, - PROP_ORIENTATION, - g_param_spec_enum ("orientation", - "Orientation", - "The orientation of the scale", - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_VERTICAL, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_IS_MUTED, - g_param_spec_boolean ("is-muted", - "is muted", - "Whether stream is muted", - FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_SHOW_MUTE, - g_param_spec_boolean ("show-mute", - "show mute", - "Whether stream is muted", - FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - - g_object_class_install_property (object_class, - PROP_ADJUSTMENT, - g_param_spec_object ("adjustment", - "Adjustment", - "The GtkAdjustment that contains the current value of this scale button object", - GTK_TYPE_ADJUSTMENT, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_NAME, - g_param_spec_string ("name", - "Name", - "Name to display for this stream", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_ICON_NAME, - g_param_spec_string ("icon-name", - "Icon Name", - "Name of icon to display for this stream", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_LOW_ICON_NAME, - g_param_spec_string ("low-icon-name", - "Icon Name", - "Name of icon to display for this stream", - "audio-volume-low-symbolic", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_HIGH_ICON_NAME, - g_param_spec_string ("high-icon-name", - "Icon Name", - "Name of icon to display for this stream", - "audio-volume-high-symbolic", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_IS_AMPLIFIED, - g_param_spec_boolean ("is-amplified", - "Is amplified", - "Whether the stream is digitally amplified", - FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_ELLIPSIZE, - g_param_spec_boolean ("ellipsize", - "Label is ellipsized", - "Whether the label is ellipsized", - FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - g_type_class_add_private (klass, sizeof (GvcChannelBarPrivate)); -} - -static void -on_mute_switch_toggled (GtkSwitch *sw, - GParamSpec *pspec, - GvcChannelBar *bar) -{ - gboolean is_muted; - is_muted = gtk_switch_get_active (sw); - gvc_channel_bar_set_is_muted (bar, !is_muted); -} - -static void -gvc_channel_bar_init (GvcChannelBar *bar) -{ - GtkWidget *frame; - - bar->priv = GVC_CHANNEL_BAR_GET_PRIVATE (bar); - - bar->priv->base_volume = ADJUSTMENT_MAX_NORMAL; - bar->priv->low_icon_name = g_strdup ("audio-volume-low-symbolic"); - bar->priv->high_icon_name = g_strdup ("audio-volume-high-symbolic"); - - bar->priv->orientation = GTK_ORIENTATION_VERTICAL; - bar->priv->adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, - 0.0, - ADJUSTMENT_MAX_NORMAL, - ADJUSTMENT_MAX_NORMAL/100.0, - ADJUSTMENT_MAX_NORMAL/10.0, - 0.0)); - g_object_ref_sink (bar->priv->adjustment); - - bar->priv->zero_adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, - 0.0, - ADJUSTMENT_MAX_NORMAL, - ADJUSTMENT_MAX_NORMAL/100.0, - ADJUSTMENT_MAX_NORMAL/10.0, - 0.0)); - g_object_ref_sink (bar->priv->zero_adjustment); - - g_signal_connect (bar->priv->zero_adjustment, - "value-changed", - G_CALLBACK (on_zero_adjustment_value_changed), - bar); - - bar->priv->mute_switch = gtk_switch_new (); - gtk_widget_set_no_show_all (bar->priv->mute_switch, TRUE); - g_signal_connect (bar->priv->mute_switch, - "notify::active", - G_CALLBACK (on_mute_switch_toggled), - bar); - bar->priv->mute_box = gtk_alignment_new (0.5, 0.5, 0, 0); - gtk_container_add (GTK_CONTAINER (bar->priv->mute_box), bar->priv->mute_switch); - - bar->priv->low_image = gtk_image_new_from_icon_name ("audio-volume-low-symbolic", - GTK_ICON_SIZE_MENU); - gtk_widget_set_no_show_all (bar->priv->low_image, TRUE); - bar->priv->high_image = gtk_image_new_from_icon_name ("audio-volume-high-symbolic", - GTK_ICON_SIZE_MENU); - gtk_widget_set_no_show_all (bar->priv->high_image, TRUE); - - bar->priv->image = gtk_image_new (); - gtk_widget_set_no_show_all (bar->priv->image, TRUE); - - bar->priv->label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0.0, 0.5); - gtk_widget_set_no_show_all (bar->priv->label, TRUE); - - /* frame */ - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (bar), frame); - gtk_widget_show_all (frame); - - /* box with scale */ - bar->priv->scale_box = _scale_box_new (bar); - - gtk_container_add (GTK_CONTAINER (frame), bar->priv->scale_box); -} - -static void -gvc_channel_bar_finalize (GObject *object) -{ - GvcChannelBar *channel_bar; - - g_return_if_fail (object != NULL); - g_return_if_fail (GVC_IS_CHANNEL_BAR (object)); - - channel_bar = GVC_CHANNEL_BAR (object); - - g_return_if_fail (channel_bar->priv != NULL); - - g_free (channel_bar->priv->name); - g_free (channel_bar->priv->icon_name); - g_free (channel_bar->priv->low_icon_name); - g_free (channel_bar->priv->high_icon_name); - - G_OBJECT_CLASS (gvc_channel_bar_parent_class)->finalize (object); -} - -GtkWidget * -gvc_channel_bar_new (void) -{ - GObject *bar; - bar = g_object_new (GVC_TYPE_CHANNEL_BAR, - NULL); - return GTK_WIDGET (bar); -} diff --git a/gvc-channel-bar.h b/gvc-channel-bar.h deleted file mode 100644 index 5d036f2..0000000 --- a/gvc-channel-bar.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef __GVC_CHANNEL_BAR_H -#define __GVC_CHANNEL_BAR_H - -#include <glib-object.h> -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define GVC_TYPE_CHANNEL_BAR (gvc_channel_bar_get_type ()) -#define GVC_CHANNEL_BAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_CHANNEL_BAR, GvcChannelBar)) -#define GVC_CHANNEL_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_CHANNEL_BAR, GvcChannelBarClass)) -#define GVC_IS_CHANNEL_BAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_CHANNEL_BAR)) -#define GVC_IS_CHANNEL_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_CHANNEL_BAR)) -#define GVC_CHANNEL_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_CHANNEL_BAR, GvcChannelBarClass)) - -typedef struct GvcChannelBarPrivate GvcChannelBarPrivate; - -typedef struct -{ - GtkHBox parent; - GvcChannelBarPrivate *priv; -} GvcChannelBar; - -typedef struct -{ - GtkHBoxClass parent_class; -} GvcChannelBarClass; - -GType gvc_channel_bar_get_type (void); - -GtkWidget * gvc_channel_bar_new (void); - -void gvc_channel_bar_set_name (GvcChannelBar *bar, - const char *name); -void gvc_channel_bar_set_icon_name (GvcChannelBar *bar, - const char *icon_name); -void gvc_channel_bar_set_low_icon_name (GvcChannelBar *bar, - const char *icon_name); -void gvc_channel_bar_set_high_icon_name (GvcChannelBar *bar, - const char *icon_name); - -void gvc_channel_bar_set_orientation (GvcChannelBar *bar, - GtkOrientation orientation); -GtkOrientation gvc_channel_bar_get_orientation (GvcChannelBar *bar); - -GtkAdjustment * gvc_channel_bar_get_adjustment (GvcChannelBar *bar); - -gboolean gvc_channel_bar_get_is_muted (GvcChannelBar *bar); -void gvc_channel_bar_set_is_muted (GvcChannelBar *bar, - gboolean is_muted); -gboolean gvc_channel_bar_get_show_mute (GvcChannelBar *bar); -void gvc_channel_bar_set_show_mute (GvcChannelBar *bar, - gboolean show_mute); -void gvc_channel_bar_set_size_group (GvcChannelBar *bar, - GtkSizeGroup *group, - gboolean symmetric); -void gvc_channel_bar_set_is_amplified (GvcChannelBar *bar, - gboolean amplified); -void gvc_channel_bar_set_base_volume (GvcChannelBar *bar, - guint32 base_volume); -gboolean gvc_channel_bar_get_ellipsize (GvcChannelBar *bar); -void gvc_channel_bar_set_ellipsize (GvcChannelBar *bar, - gboolean ellipsized); - -gboolean gvc_channel_bar_scroll (GvcChannelBar *bar, - GdkEventScroll *event); - -G_END_DECLS - -#endif /* __GVC_CHANNEL_BAR_H */ diff --git a/gvc-mixer-dialog.c b/gvc-mixer-dialog.c deleted file mode 100644 index ea95825..0000000 --- a/gvc-mixer-dialog.c +++ /dev/null @@ -1,1977 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <math.h> - -#include <glib.h> -#include <glib/gi18n-lib.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <pulse/pulseaudio.h> - -#include "gvc-channel-bar.h" -#include "gvc-balance-bar.h" -#include "gvc-combo-box.h" -#include "gvc-mixer-control.h" -#include "gvc-mixer-card.h" -#include "gvc-mixer-sink.h" -#include "gvc-mixer-source.h" -#include "gvc-mixer-source-output.h" -#include "gvc-mixer-dialog.h" -#include "gvc-sound-theme-chooser.h" -#include "gvc-level-bar.h" -#include "gvc-speaker-test.h" -#include "gvc-mixer-control-private.h" - -#define SCALE_SIZE 128 - -#define GVC_MIXER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_DIALOG, GvcMixerDialogPrivate)) - -struct GvcMixerDialogPrivate -{ - GvcMixerControl *mixer_control; - GHashTable *bars; /* Application and event bars only */ - GtkWidget *notebook; - GtkWidget *output_bar; - GtkWidget *input_bar; - GtkWidget *input_level_bar; - GtkWidget *effects_bar; - GtkWidget *output_stream_box; - GtkWidget *sound_effects_box; - GtkWidget *input_box; - GtkWidget *output_box; - GtkWidget *applications_box; - GtkWidget *no_apps_label; - GtkWidget *output_treeview; - GtkWidget *output_settings_box; - GtkWidget *output_balance_bar; - GtkWidget *output_fade_bar; - GtkWidget *output_lfe_bar; - GtkWidget *output_profile_combo; - GtkWidget *input_treeview; - GtkWidget *input_profile_combo; - GtkWidget *input_settings_box; - GtkWidget *sound_theme_chooser; - GtkWidget *click_feedback_button; - GtkWidget *audible_bell_button; - GtkSizeGroup *size_group; - - gdouble last_input_peak; - guint num_apps; -}; - -enum { - NAME_COLUMN, - DEVICE_COLUMN, - ACTIVE_COLUMN, - ID_COLUMN, - ICON_COLUMN, - NUM_COLUMNS -}; - -enum { - HW_ID_COLUMN, - HW_ICON_COLUMN, - HW_NAME_COLUMN, - HW_STATUS_COLUMN, - HW_PROFILE_COLUMN, - HW_PROFILE_HUMAN_COLUMN, - HW_SENSITIVE_COLUMN, - HW_NUM_COLUMNS -}; - -enum -{ - PROP_0, - PROP_MIXER_CONTROL -}; - -static void gvc_mixer_dialog_class_init (GvcMixerDialogClass *klass); -static void gvc_mixer_dialog_init (GvcMixerDialog *mixer_dialog); -static void gvc_mixer_dialog_finalize (GObject *object); - -static void bar_set_stream (GvcMixerDialog *dialog, - GtkWidget *bar, - GvcMixerStream *stream); - -static void on_adjustment_value_changed (GtkAdjustment *adjustment, - GvcMixerDialog *dialog); -static void on_control_active_output_update (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog); - -static void on_control_active_input_update (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog); - -static void on_test_speakers_clicked (GvcComboBox *widget, - gpointer user_data); - - -G_DEFINE_TYPE (GvcMixerDialog, gvc_mixer_dialog, GTK_TYPE_VBOX) - -static void -profile_selection_changed (GvcComboBox *combo_box, - const char *profile, - GvcMixerDialog *dialog) -{ - GvcMixerUIDevice *output; - - g_debug ("profile_selection_changed() to %s", profile); - - output = g_object_get_data (G_OBJECT (combo_box), "uidevice"); - - if (output == NULL) { - g_warning ("Could not find Output for profile combo box"); - return; - } - - g_debug ("on profile selection changed on output '%s' (origin: %s, id: %i)", - gvc_mixer_ui_device_get_description (output), - gvc_mixer_ui_device_get_origin (output), - gvc_mixer_ui_device_get_id (output)); - - if (gvc_mixer_control_change_profile_on_selected_device (dialog->priv->mixer_control, output, profile) == FALSE) { - g_warning ("Could not change profile on device %s", - gvc_mixer_ui_device_get_description (output)); - } -} - -static void -update_output_settings (GvcMixerDialog *dialog, - GvcMixerUIDevice *device) -{ - GvcMixerStream *stream; - const GvcChannelMap *map; - const GList *profiles; - GtkAdjustment *adj; - - 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_profile_combo != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box), - dialog->priv->output_profile_combo); - dialog->priv->output_profile_combo = NULL; - } - - stream = gvc_mixer_control_get_stream_from_device (dialog->priv->mixer_control, - device); - if (stream == NULL) { - g_warning ("Default sink stream not found"); - return; - } - - gvc_channel_bar_set_base_volume (GVC_CHANNEL_BAR (dialog->priv->output_bar), - gvc_mixer_stream_get_base_volume (stream)); - gvc_channel_bar_set_is_amplified (GVC_CHANNEL_BAR (dialog->priv->output_bar), - gvc_mixer_stream_get_can_decibel (stream)); - - /* Update the adjustment in case the previous bar wasn't decibel - * capable, and we clipped it */ - adj = GTK_ADJUSTMENT (gvc_channel_bar_get_adjustment (GVC_CHANNEL_BAR (dialog->priv->output_bar))); - gtk_adjustment_set_value (adj, - gvc_mixer_stream_get_volume (stream)); - - map = gvc_mixer_stream_get_channel_map (stream); - if (map == NULL) { - g_warning ("Default sink stream has no channel map"); - return; - } - - dialog->priv->output_balance_bar = gvc_balance_bar_new (map, BALANCE_TYPE_RL); - if (dialog->priv->size_group != NULL) { - 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); - - if (gvc_channel_map_can_fade (map)) { - dialog->priv->output_fade_bar = gvc_balance_bar_new (map, BALANCE_TYPE_FR); - if (dialog->priv->size_group != NULL) { - 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); - } - - if (gvc_channel_map_has_lfe (map)) { - dialog->priv->output_lfe_bar = gvc_balance_bar_new (map, BALANCE_TYPE_LFE); - if (dialog->priv->size_group != NULL) { - 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); - } - - profiles = gvc_mixer_ui_device_get_profiles (device); - /* FIXME: How do we make sure the "Test speakers" button is shown - * even when there are no profiles to choose between? */ - if (TRUE /*g_list_length((GList *) profiles) >= 2 */) { - const gchar *active_profile; - - dialog->priv->output_profile_combo = gvc_combo_box_new (_("_Profile:")); - - g_object_set (G_OBJECT (dialog->priv->output_profile_combo), "button-label", _("_Test Speakers"), NULL); - g_object_set (G_OBJECT (dialog->priv->output_profile_combo), - "show-button", TRUE, NULL); - g_signal_connect (G_OBJECT (dialog->priv->output_profile_combo), "button-clicked", - G_CALLBACK (on_test_speakers_clicked), dialog); - - if (profiles) - gvc_combo_box_set_profiles (GVC_COMBO_BOX (dialog->priv->output_profile_combo), - profiles); - gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box), - dialog->priv->output_profile_combo, - TRUE, FALSE, 6); - - if (dialog->priv->size_group != NULL) { - gvc_combo_box_set_size_group (GVC_COMBO_BOX (dialog->priv->output_profile_combo), - dialog->priv->size_group, FALSE); - } - - active_profile = gvc_mixer_ui_device_get_active_profile (device); - if (active_profile) - gvc_combo_box_set_active (GVC_COMBO_BOX (dialog->priv->output_profile_combo), active_profile); - - g_object_set_data (G_OBJECT (dialog->priv->output_profile_combo), - "uidevice", - device); - if (g_list_length((GList *) profiles)) - g_signal_connect (G_OBJECT (dialog->priv->output_profile_combo), "changed", - G_CALLBACK (profile_selection_changed), dialog); - - gtk_widget_show (dialog->priv->output_profile_combo); - } - - /* FIXME: We could make this into a "No settings" label instead */ - gtk_widget_set_sensitive (dialog->priv->output_balance_bar, gvc_channel_map_can_balance (map)); -} - -#define DECAY_STEP .15 - -static void -update_input_peak (GvcMixerDialog *dialog, - gdouble v) -{ - GtkAdjustment *adj; - - if (dialog->priv->last_input_peak >= DECAY_STEP) { - if (v < dialog->priv->last_input_peak - DECAY_STEP) { - v = dialog->priv->last_input_peak - DECAY_STEP; - } - } - - dialog->priv->last_input_peak = v; - - adj = gvc_level_bar_get_peak_adjustment (GVC_LEVEL_BAR (dialog->priv->input_level_bar)); - if (v >= 0) { - gtk_adjustment_set_value (adj, v); - } else { - gtk_adjustment_set_value (adj, 0.0); - } -} - -static void -update_input_meter (GvcMixerDialog *dialog, - uint32_t source_index, - uint32_t sink_input_idx, - double v) -{ - update_input_peak (dialog, v); -} - -static void -on_monitor_suspended_callback (pa_stream *s, - void *userdata) -{ - GvcMixerDialog *dialog; - - dialog = userdata; - - if (pa_stream_is_suspended (s)) { - g_debug ("Stream suspended"); - update_input_meter (dialog, - pa_stream_get_device_index (s), - PA_INVALID_INDEX, - -1); - } -} - -static void -on_monitor_read_callback (pa_stream *s, - size_t length, - void *userdata) -{ - GvcMixerDialog *dialog; - const void *data; - double v; - - dialog = userdata; - - if (pa_stream_peek (s, &data, &length) < 0) { - g_warning ("Failed to read data from stream"); - return; - } - - assert (length > 0); - assert (length % sizeof (float) == 0); - - v = ((const float *) data)[length / sizeof (float) -1]; - - pa_stream_drop (s); - - if (v < 0) { - v = 0; - } - if (v > 1) { - v = 1; - } - - update_input_meter (dialog, - pa_stream_get_device_index (s), - pa_stream_get_monitor_stream (s), - v); -} - -static void -create_monitor_stream_for_source (GvcMixerDialog *dialog, - GvcMixerStream *stream) -{ - pa_stream *s; - char t[16]; - pa_buffer_attr attr; - pa_sample_spec ss; - pa_context *context; - int res; - pa_proplist *proplist; - gboolean has_monitor; - - if (stream == NULL) { - return; - } - has_monitor = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (stream), "has-monitor")); - if (has_monitor != FALSE) { - return; - } - - g_debug ("Create monitor for %u", - gvc_mixer_stream_get_index (stream)); - - context = gvc_mixer_control_get_pa_context (dialog->priv->mixer_control); - - if (pa_context_get_server_protocol_version (context) < 13) { - return; - } - - ss.channels = 1; - ss.format = PA_SAMPLE_FLOAT32; - ss.rate = 25; - - memset (&attr, 0, sizeof (attr)); - attr.fragsize = sizeof (float); - attr.maxlength = (uint32_t) -1; - - snprintf (t, sizeof (t), "%u", gvc_mixer_stream_get_index (stream)); - - proplist = pa_proplist_new (); - pa_proplist_sets (proplist, PA_PROP_APPLICATION_ID, "org.gnome.VolumeControl"); - s = pa_stream_new_with_proplist (context, _("Peak detect"), &ss, NULL, proplist); - pa_proplist_free (proplist); - if (s == NULL) { - g_warning ("Failed to create monitoring stream"); - return; - } - - pa_stream_set_read_callback (s, on_monitor_read_callback, dialog); - pa_stream_set_suspended_callback (s, on_monitor_suspended_callback, dialog); - - res = pa_stream_connect_record (s, - t, - &attr, - (pa_stream_flags_t) (PA_STREAM_DONT_MOVE - |PA_STREAM_PEAK_DETECT - |PA_STREAM_ADJUST_LATENCY)); - if (res < 0) { - g_warning ("Failed to connect monitoring stream"); - pa_stream_unref (s); - } else { - g_object_set_data (G_OBJECT (stream), "has-monitor", GINT_TO_POINTER (TRUE)); - g_object_set_data (G_OBJECT (dialog->priv->input_level_bar), "pa_stream", s); - g_object_set_data (G_OBJECT (dialog->priv->input_level_bar), "stream", stream); - } -} - -static void -stop_monitor_stream_for_source (GvcMixerDialog *dialog) -{ - pa_stream *s; - pa_context *context; - int res; - GvcMixerStream *stream; - - s = g_object_get_data (G_OBJECT (dialog->priv->input_level_bar), "pa_stream"); - if (s == NULL) - return; - stream = g_object_get_data (G_OBJECT (dialog->priv->input_level_bar), "stream"); - g_assert (stream != NULL); - - g_debug ("Stopping monitor for %u", pa_stream_get_index (s)); - - context = gvc_mixer_control_get_pa_context (dialog->priv->mixer_control); - - if (pa_context_get_server_protocol_version (context) < 13) { - return; - } - - res = pa_stream_disconnect (s); - if (res == 0) - g_object_set_data (G_OBJECT (stream), "has-monitor", GINT_TO_POINTER (FALSE)); - g_object_set_data (G_OBJECT (dialog->priv->input_level_bar), "pa_stream", NULL); - g_object_set_data (G_OBJECT (dialog->priv->input_level_bar), "stream", NULL); -} - -static void -update_input_settings (GvcMixerDialog *dialog, - GvcMixerUIDevice *device) -{ - GvcMixerStream *stream; - const GList *profiles; - GtkAdjustment *adj; - - g_debug ("Updating input settings"); - - stop_monitor_stream_for_source (dialog); - - if (dialog->priv->input_profile_combo != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->input_settings_box), - dialog->priv->input_profile_combo); - dialog->priv->input_profile_combo = NULL; - } - - stream = gvc_mixer_control_get_stream_from_device (dialog->priv->mixer_control, - device); - if (stream == NULL) { - g_debug ("Default source stream not found"); - return; - } - - gvc_channel_bar_set_base_volume (GVC_CHANNEL_BAR (dialog->priv->input_bar), - gvc_mixer_stream_get_base_volume (stream)); - gvc_channel_bar_set_is_amplified (GVC_CHANNEL_BAR (dialog->priv->input_bar), - gvc_mixer_stream_get_can_decibel (stream)); - - /* Update the adjustment in case the previous bar wasn't decibel - * capable, and we clipped it */ - adj = GTK_ADJUSTMENT (gvc_channel_bar_get_adjustment (GVC_CHANNEL_BAR (dialog->priv->input_bar))); - gtk_adjustment_set_value (adj, - gvc_mixer_stream_get_volume (stream)); - - profiles = gvc_mixer_ui_device_get_profiles (device); - if (g_list_length ((GList *) profiles) >= 2) { - const gchar *active_profile; - - dialog->priv->input_profile_combo = gvc_combo_box_new (_("_Profile:")); - gvc_combo_box_set_profiles (GVC_COMBO_BOX (dialog->priv->input_profile_combo), - profiles); - - gtk_box_pack_start (GTK_BOX (dialog->priv->input_settings_box), - dialog->priv->input_profile_combo, - TRUE, TRUE, 0); - - if (dialog->priv->size_group != NULL) { - gvc_combo_box_set_size_group (GVC_COMBO_BOX (dialog->priv->input_profile_combo), - dialog->priv->size_group, FALSE); - } - - active_profile = gvc_mixer_ui_device_get_active_profile (device); - if (active_profile) - gvc_combo_box_set_active (GVC_COMBO_BOX (dialog->priv->input_profile_combo), active_profile); - - g_object_set_data (G_OBJECT (dialog->priv->input_profile_combo), - "uidevice", - device); - g_signal_connect (G_OBJECT (dialog->priv->input_profile_combo), "changed", - G_CALLBACK (profile_selection_changed), dialog); - - gtk_widget_show (dialog->priv->input_profile_combo); - } - - create_monitor_stream_for_source (dialog, stream); -} - -static void -gvc_mixer_dialog_set_mixer_control (GvcMixerDialog *dialog, - GvcMixerControl *control) -{ - g_return_if_fail (GVC_MIXER_DIALOG (dialog)); - g_return_if_fail (GVC_IS_MIXER_CONTROL (control)); - - g_object_ref (control); - - if (dialog->priv->mixer_control != NULL) { - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - G_CALLBACK (on_control_active_input_update), - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - G_CALLBACK (on_control_active_output_update), - dialog); - g_object_unref (dialog->priv->mixer_control); - } - - dialog->priv->mixer_control = control; - - /* FIXME: Why are some mixer_control signals connected here, - * and others in the dialog constructor? (And similar for disconnect) */ - g_signal_connect (dialog->priv->mixer_control, - "active-input-update", - G_CALLBACK (on_control_active_input_update), - dialog); - g_signal_connect (dialog->priv->mixer_control, - "active-output-update", - G_CALLBACK (on_control_active_output_update), - dialog); - - g_object_notify (G_OBJECT (dialog), "mixer-control"); -} - -static GvcMixerControl * -gvc_mixer_dialog_get_mixer_control (GvcMixerDialog *dialog) -{ - g_return_val_if_fail (GVC_IS_MIXER_DIALOG (dialog), NULL); - - return dialog->priv->mixer_control; -} - -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_MIXER_CONTROL: - gvc_mixer_dialog_set_mixer_control (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_MIXER_CONTROL: - g_value_set_object (value, gvc_mixer_dialog_get_mixer_control (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -on_adjustment_value_changed (GtkAdjustment *adjustment, - GvcMixerDialog *dialog) -{ - GvcMixerStream *stream; - - stream = g_object_get_data (G_OBJECT (adjustment), "gvc-mixer-dialog-stream"); - if (stream != NULL) { - GObject *bar; - gdouble volume, rounded; - char *name; - - volume = gtk_adjustment_get_value (adjustment); - rounded = round (volume); - - bar = g_object_get_data (G_OBJECT (adjustment), "gvc-mixer-dialog-bar"); - g_object_get (bar, "name", &name, NULL); - g_debug ("Setting stream volume %lf (rounded: %lf) for bar '%s'", volume, rounded, name); - g_free (name); - - /* FIXME would need to do that in the balance bar really... */ - /* Make sure we do not unmute muted streams, there's a button for that */ - if (volume == 0.0) - gvc_mixer_stream_set_is_muted (stream, TRUE); - /* Only push the volume if it's actually changed */ - if (gvc_mixer_stream_set_volume (stream, (pa_volume_t) rounded) != FALSE) - gvc_mixer_stream_push_volume (stream); - } -} - -static void -on_bar_is_muted_notify (GObject *object, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - gboolean is_muted; - GvcMixerStream *stream; - - is_muted = gvc_channel_bar_get_is_muted (GVC_CHANNEL_BAR (object)); - - stream = g_object_get_data (object, "gvc-mixer-dialog-stream"); - if (stream != NULL) { - gvc_mixer_stream_change_is_muted (stream, is_muted); - } else { - char *name; - g_object_get (object, "name", &name, NULL); - g_warning ("Unable to find stream for bar '%s'", name); - g_free (name); - } -} - -static GtkWidget * -lookup_bar_for_stream (GvcMixerDialog *dialog, - GvcMixerStream *stream) -{ - GtkWidget *bar; - - bar = g_hash_table_lookup (dialog->priv->bars, GUINT_TO_POINTER (gvc_mixer_stream_get_id (stream))); - - return bar; -} - -static void -on_stream_volume_notify (GObject *object, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - GvcMixerStream *stream; - GtkWidget *bar; - GtkAdjustment *adj; - - stream = GVC_MIXER_STREAM (object); - - bar = lookup_bar_for_stream (dialog, stream); - - if (bar == NULL) { - g_warning ("Unable to find bar for stream %s in on_stream_volume_notify()", - gvc_mixer_stream_get_name (stream)); - return; - } - - adj = GTK_ADJUSTMENT (gvc_channel_bar_get_adjustment (GVC_CHANNEL_BAR (bar))); - - g_signal_handlers_block_by_func (adj, - on_adjustment_value_changed, - dialog); - - gtk_adjustment_set_value (adj, - gvc_mixer_stream_get_volume (stream)); - - g_signal_handlers_unblock_by_func (adj, - on_adjustment_value_changed, - dialog); -} - -static void -on_stream_is_muted_notify (GObject *object, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - GvcMixerStream *stream; - GtkWidget *bar; - gboolean is_muted; - - stream = GVC_MIXER_STREAM (object); - bar = lookup_bar_for_stream (dialog, stream); - - if (bar == NULL) { - g_warning ("Unable to find bar for stream %s in on_stream_is_muted_notify()", - gvc_mixer_stream_get_name (stream)); - return; - } - - is_muted = gvc_mixer_stream_get_is_muted (stream); - gvc_channel_bar_set_is_muted (GVC_CHANNEL_BAR (bar), - is_muted); - - if (stream == gvc_mixer_control_get_default_sink (dialog->priv->mixer_control)) { - gtk_widget_set_sensitive (dialog->priv->applications_box, - !is_muted); - } - -} - -static void -save_bar_for_stream (GvcMixerDialog *dialog, - GvcMixerStream *stream, - GtkWidget *bar) -{ - g_hash_table_insert (dialog->priv->bars, - GUINT_TO_POINTER (gvc_mixer_stream_get_id (stream)), - bar); -} - -static GtkWidget * -create_bar (GvcMixerDialog *dialog, - gboolean add_to_size_group, - gboolean symmetric) -{ - GtkWidget *bar; - - bar = gvc_channel_bar_new (); - gtk_widget_set_sensitive (bar, FALSE); - if (add_to_size_group && dialog->priv->size_group != NULL) { - gvc_channel_bar_set_size_group (GVC_CHANNEL_BAR (bar), - dialog->priv->size_group, - symmetric); - } - gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (bar), - GTK_ORIENTATION_HORIZONTAL); - gvc_channel_bar_set_show_mute (GVC_CHANNEL_BAR (bar), - TRUE); - g_signal_connect (bar, - "notify::is-muted", - G_CALLBACK (on_bar_is_muted_notify), - dialog); - return bar; -} - -static GtkWidget * -create_app_bar (GvcMixerDialog *dialog, - const char *name, - const char *icon_name) -{ - GtkWidget *bar; - - bar = create_bar (dialog, FALSE, FALSE); - gvc_channel_bar_set_ellipsize (GVC_CHANNEL_BAR (bar), TRUE); - gvc_channel_bar_set_icon_name (GVC_CHANNEL_BAR (bar), icon_name); - if (name == NULL || strchr (name, '_') == NULL) { - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (bar), name); - } else { - char **tokens, *escaped; - - tokens = g_strsplit (name, "_", -1); - escaped = g_strjoinv ("__", tokens); - g_strfreev (tokens); - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (bar), escaped); - g_free (escaped); - } - - return bar; -} - -/* active_input_update - * Handle input update change from the backend (control). - * Trust the backend whole-heartedly to deliver the correct input. */ -static void -active_input_update (GvcMixerDialog *dialog, - GvcMixerUIDevice *active_input) -{ - /* First make sure the correct UI device is selected. */ - GtkTreeModel *model; - GtkTreeIter iter; - GvcMixerStream *stream; - - g_debug ("active_input_update device id = %i", - gvc_mixer_ui_device_get_id (active_input)); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - - if (gtk_tree_model_get_iter_first (model, &iter) == FALSE) { - g_warning ("No devices in the tree, so cannot set the active output"); - return; - } - - do { - gboolean is_selected = FALSE; - gint id; - - gtk_tree_model_get (model, &iter, - ID_COLUMN, &id, - -1); - - is_selected = id == gvc_mixer_ui_device_get_id (active_input); - - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - ACTIVE_COLUMN, is_selected, - -1); - - if (is_selected) { - GtkTreeSelection *selection; - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->input_treeview)); - gtk_tree_selection_select_iter (selection, &iter); - } - } while (gtk_tree_model_iter_next (model, &iter)); - - stream = gvc_mixer_control_get_stream_from_device (dialog->priv->mixer_control, - active_input); - if (stream == NULL) { - g_warning ("Couldn't find a stream from the active input"); - gtk_widget_set_sensitive (dialog->priv->input_bar, FALSE); - return; - } - - bar_set_stream (dialog, dialog->priv->input_bar, stream); - update_input_settings (dialog, active_input); - -} - -/* active_output_update - * Handle output update change from the backend (control). - * Trust the backend whole heartedly to deliver the correct output. */ -static void -active_output_update (GvcMixerDialog *dialog, - GvcMixerUIDevice *active_output) -{ - /* First make sure the correct UI device is selected. */ - GvcMixerStream *stream; - GtkTreeModel *model; - GtkTreeIter iter; - - g_debug ("active output update device id = %i", - gvc_mixer_ui_device_get_id (active_output)); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - - if (gtk_tree_model_get_iter_first (model, &iter) == FALSE){ - g_warning ("No devices in the tree, so cannot set the active output"); - return; - } - - do { - gboolean is_selected; - gint id; - - gtk_tree_model_get (model, &iter, - ID_COLUMN, &id, - ACTIVE_COLUMN, &is_selected, - -1); - - if (is_selected && id == gvc_mixer_ui_device_get_id (active_output)) { - /* XXX: profile change on the same device? */ - g_debug ("Unneccessary active output update"); - } - - is_selected = id == gvc_mixer_ui_device_get_id (active_output); - - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - ACTIVE_COLUMN, is_selected, - -1); - - if (is_selected) { - GtkTreeSelection *selection; - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->output_treeview)); - gtk_tree_selection_select_iter (selection, &iter); - } - } while (gtk_tree_model_iter_next (model, &iter)); - - stream = gvc_mixer_control_get_stream_from_device (dialog->priv->mixer_control, - active_output); - if (stream == NULL) { - g_warning ("Couldn't find a stream from the active output"); - return; - } - - bar_set_stream (dialog, dialog->priv->output_bar, stream); - update_output_settings (dialog, active_output); -} - -static void -bar_set_stream (GvcMixerDialog *dialog, - GtkWidget *bar, - GvcMixerStream *stream) -{ - GtkAdjustment *adj; - GvcMixerStream *old_stream; - - g_assert (bar != NULL); - - old_stream = g_object_get_data (G_OBJECT (bar), "gvc-mixer-dialog-stream"); - if (old_stream != NULL) { - char *name; - - g_object_get (bar, "name", &name, NULL); - g_debug ("Disconnecting old stream '%s' from bar '%s'", - gvc_mixer_stream_get_name (old_stream), name); - g_free (name); - - g_signal_handlers_disconnect_by_func (old_stream, on_stream_is_muted_notify, dialog); - g_signal_handlers_disconnect_by_func (old_stream, on_stream_volume_notify, dialog); - g_hash_table_remove (dialog->priv->bars, GUINT_TO_POINTER (gvc_mixer_stream_get_id (old_stream))); - } - - gtk_widget_set_sensitive (bar, (stream != NULL)); - - adj = GTK_ADJUSTMENT (gvc_channel_bar_get_adjustment (GVC_CHANNEL_BAR (bar))); - - g_signal_handlers_disconnect_by_func (adj, on_adjustment_value_changed, dialog); - - g_object_set_data (G_OBJECT (bar), "gvc-mixer-dialog-stream", stream); - g_object_set_data (G_OBJECT (bar), "gvc-mixer-dialog-stream-id", - GUINT_TO_POINTER (gvc_mixer_stream_get_id (stream))); - g_object_set_data (G_OBJECT (adj), "gvc-mixer-dialog-stream", stream); - g_object_set_data (G_OBJECT (adj), "gvc-mixer-dialog-bar", bar); - - if (stream != NULL) { - gboolean is_muted; - - is_muted = gvc_mixer_stream_get_is_muted (stream); - gvc_channel_bar_set_is_muted (GVC_CHANNEL_BAR (bar), is_muted); - - gtk_adjustment_set_value (adj, - gvc_mixer_stream_get_volume (stream)); - - g_signal_connect (stream, - "notify::is-muted", - G_CALLBACK (on_stream_is_muted_notify), - dialog); - g_signal_connect (stream, - "notify::volume", - G_CALLBACK (on_stream_volume_notify), - dialog); - g_signal_connect (adj, - "value-changed", - G_CALLBACK (on_adjustment_value_changed), - dialog); - } -} - -static void -add_stream (GvcMixerDialog *dialog, - GvcMixerStream *stream) -{ - GtkWidget *bar; - GvcMixerStream *old_stream; - - bar = NULL; - - if (GVC_IS_MIXER_SOURCE (stream) || GVC_IS_MIXER_SINK (stream)) - return; - else if (stream == gvc_mixer_control_get_event_sink_input (dialog->priv->mixer_control)) { - bar = dialog->priv->effects_bar; - g_debug ("Adding effects stream"); - } else { - /* Must be an application stream */ - const char *name; - name = gvc_mixer_stream_get_name (stream); - g_debug ("Add bar for application stream : %s", name); - - bar = create_app_bar (dialog, name, - gvc_mixer_stream_get_icon_name (stream)); - gtk_box_pack_start (GTK_BOX (dialog->priv->applications_box), bar, FALSE, FALSE, 12); - dialog->priv->num_apps++; - gtk_widget_hide (dialog->priv->no_apps_label); - } - - /* We should have a bar by now. */ - g_assert (bar != NULL); - - if (bar != NULL) { - old_stream = g_object_get_data (G_OBJECT (bar), "gvc-mixer-dialog-stream"); - if (old_stream != NULL) { - char *name; - - g_object_get (bar, "name", &name, NULL); - g_debug ("Disconnecting old stream '%s' from bar '%s'", - gvc_mixer_stream_get_name (old_stream), name); - g_free (name); - - g_signal_handlers_disconnect_by_func (old_stream, on_stream_is_muted_notify, dialog); - g_signal_handlers_disconnect_by_func (old_stream, on_stream_volume_notify, dialog); - g_hash_table_remove (dialog->priv->bars, GUINT_TO_POINTER (gvc_mixer_stream_get_id (old_stream))); - } - save_bar_for_stream (dialog, stream, bar); - bar_set_stream (dialog, bar, stream); - gtk_widget_show (bar); - } -} - -static void -on_control_stream_added (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - GvcMixerStream *stream; - const char *app_id; - - stream = gvc_mixer_control_lookup_stream_id (control, id); - if (stream == NULL) - return; - - app_id = gvc_mixer_stream_get_application_id (stream); - - if (stream == gvc_mixer_control_get_event_sink_input (dialog->priv->mixer_control) || - (GVC_IS_MIXER_SOURCE (stream) == FALSE && - GVC_IS_MIXER_SINK (stream) == FALSE && - gvc_mixer_stream_is_virtual (stream) == FALSE && - g_strcmp0 (app_id, "org.gnome.VolumeControl") != 0 && - g_strcmp0 (app_id, "org.PulseAudio.pavucontrol") != 0)) { - GtkWidget *bar; - - bar = g_hash_table_lookup (dialog->priv->bars, GUINT_TO_POINTER (id)); - if (bar != NULL) { - g_debug ("GvcMixerDialog: Stream %u already added", id); - return; - } - add_stream (dialog, stream); - } -} - -static gboolean -find_item_by_id (GtkTreeModel *model, - guint id, - guint column, - GtkTreeIter *iter) -{ - gboolean found_item; - - found_item = FALSE; - - if (!gtk_tree_model_get_iter_first (model, iter)) { - return FALSE; - } - - do { - guint t_id; - - gtk_tree_model_get (model, iter, - column, &t_id, -1); - - if (id == t_id) { - found_item = TRUE; - } - } while (!found_item && gtk_tree_model_iter_next (model, iter)); - - return found_item; -} - -static void -add_input_ui_entry (GvcMixerDialog *dialog, - GvcMixerUIDevice *input) -{ - gchar *final_name; - gchar *port_name; - gchar *origin; - gchar *description; - gboolean available; - gint stream_id; - GtkTreeModel *model; - GtkTreeIter iter; - GIcon *icon; - GvcMixerCard *card; - - g_debug ("Add input ui entry with id :%u", - gvc_mixer_ui_device_get_id (input)); - - g_object_get (G_OBJECT (input), - "stream-id", &stream_id, - "card", &card, - "origin", &origin, - "description", &description, - "port-name", &port_name, - "port-available", &available, - NULL); - - if (origin && origin[0] != '\0') - final_name = g_strdup_printf ("%s - %s", description, origin); - else - final_name = g_strdup (description); - - g_free (port_name); - g_free (origin); - g_free (description); - - if (card == NULL) { - GvcMixerStream *stream; - g_debug ("just detected a network source"); - stream = gvc_mixer_control_get_stream_from_device (dialog->priv->mixer_control, input); - if (stream == NULL) { - g_warning ("tried to add the network source but the stream was null - fail ?!"); - g_free (final_name); - return; - } - icon = gvc_mixer_stream_get_gicon (stream); - } else - icon = gvc_mixer_card_get_gicon (card); - - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - NAME_COLUMN, final_name, - DEVICE_COLUMN, "", - ACTIVE_COLUMN, FALSE, - ICON_COLUMN, icon, - ID_COLUMN, gvc_mixer_ui_device_get_id (input), - -1); - - if (icon != NULL) - g_object_unref (icon); - g_free (final_name); -} - -static void -add_output_ui_entry (GvcMixerDialog *dialog, - GvcMixerUIDevice *output) -{ - gchar *sink_port_name; - gchar *origin; - gchar *description; - gchar *final_name; - gboolean available; - gint sink_stream_id; - GtkTreeModel *model; - GtkTreeIter iter; - GIcon *icon; - GvcMixerCard *card; - - g_debug ("Add output ui entry with id :%u", - gvc_mixer_ui_device_get_id (output)); - - g_object_get (G_OBJECT (output), - "stream-id", &sink_stream_id, - "card", &card, - "origin", &origin, - "description", &description, - "port-name", &sink_port_name, - "port-available", &available, - NULL); - - if (origin && origin[0] != '\0') - final_name = g_strdup_printf ("%s - %s", description, origin); - else - final_name = g_strdup (description); - - g_free (sink_port_name); - g_free (origin); - g_free (description); - - if (card == NULL) { - GvcMixerStream *stream; - - g_debug ("just detected a network sink"); - stream = gvc_mixer_control_get_stream_from_device (dialog->priv->mixer_control, output); - - if (stream == NULL) { - g_warning ("tried to add the network sink but the stream was null - fail ?!"); - g_free (final_name); - return; - } - icon = gvc_mixer_stream_get_gicon (stream); - } else - icon = gvc_mixer_card_get_gicon (card); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - NAME_COLUMN, final_name, - DEVICE_COLUMN, "", - ACTIVE_COLUMN, FALSE, - ICON_COLUMN, icon, - ID_COLUMN, gvc_mixer_ui_device_get_id (output), - -1); - - if (icon != NULL) - g_object_unref (icon); - g_free (final_name); -} - - -static void -on_control_active_input_update (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - GvcMixerUIDevice* in = NULL; - in = gvc_mixer_control_lookup_input_id (control, id); - - if (in == NULL) { - g_warning ("on_control_active_input_update - tried to fetch an input of id %u but got nothing", id); - return; - } - active_input_update (dialog, in); -} - -static void -on_control_active_output_update (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - GvcMixerUIDevice* out = NULL; - out = gvc_mixer_control_lookup_output_id (control, id); - - if (out == NULL) { - g_warning ("on_control_active_output_update - tried to fetch an output of id %u but got nothing", id); - return; - } - active_output_update (dialog, out); -} - -static void -on_control_input_added (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - GvcMixerUIDevice* in = NULL; - in = gvc_mixer_control_lookup_input_id (control, id); - - if (in == NULL) { - g_warning ("on_control_input_added - tried to fetch an input of id %u but got nothing", id); - return; - } - add_input_ui_entry (dialog, in); -} - -static void -on_control_input_removed (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - gboolean found; - GtkTreeIter iter; - GtkTreeModel *model; - gint stream_id; - GvcMixerUIDevice *in; - - in = gvc_mixer_control_lookup_input_id (control, id); - - g_object_get (G_OBJECT (in), - "stream-id", &stream_id, - NULL); - - g_debug ("Remove input from dialog, id: %u, stream id: %i", - id, - stream_id); - - /* remove from any models */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - found = find_item_by_id (GTK_TREE_MODEL (model), id, ID_COLUMN, &iter); - if (found) { - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - } -} - -static void -on_control_output_added (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - GvcMixerUIDevice* out = NULL; - out = gvc_mixer_control_lookup_output_id (control, id); - - if (out == NULL) { - g_warning ("on_control_output_added - tried to fetch an output of id %u but got nothing", id); - return; - } - - add_output_ui_entry (dialog, out); -} - -static void -on_control_output_removed (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - gboolean found; - GtkTreeIter iter; - GtkTreeModel *model; - gint sink_stream_id; - - GvcMixerUIDevice* out = NULL; - out = gvc_mixer_control_lookup_output_id (control, id); - - g_object_get (G_OBJECT (out), - "stream-id", &sink_stream_id, - NULL); - - g_debug ("Remove output from dialog \n id : %u \n sink stream id : %i \n", - id, - sink_stream_id); - - /* remove from any models */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - found = find_item_by_id (GTK_TREE_MODEL (model), id, ID_COLUMN, &iter); - if (found) { - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - } -} - -static void -remove_stream (GvcMixerDialog *dialog, - guint id) -{ - GtkWidget *bar; - guint output_id, input_id; - - bar = g_hash_table_lookup (dialog->priv->bars, GUINT_TO_POINTER (id)); - if (bar != NULL) { - g_hash_table_remove (dialog->priv->bars, GUINT_TO_POINTER (id)); - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (bar)), - bar); - dialog->priv->num_apps--; - if (dialog->priv->num_apps == 0) { - gtk_widget_show (dialog->priv->no_apps_label); - } - return; - } - - output_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (dialog->priv->output_bar), "gvc-mixer-dialog-stream-id")); - input_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (dialog->priv->input_bar), "gvc-mixer-dialog-stream-id")); - - if (output_id == id) - bar = dialog->priv->output_bar; - else if (input_id == id) - bar = dialog->priv->input_bar; - else - return; - - g_object_set_data (G_OBJECT (bar), "gvc-mixer-dialog-stream-id", NULL); - g_object_set_data (G_OBJECT (bar), "gvc-mixer-dialog-stream", NULL); -} - -static void -on_control_stream_removed (GvcMixerControl *control, - guint id, - GvcMixerDialog *dialog) -{ - remove_stream (dialog, id); -} - -static void -_gtk_label_make_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. - */ - gtk_widget_modify_font (GTK_WIDGET (label), font_desc); - - pango_font_description_free (font_desc); -} - -static void -on_input_selection_changed (GtkTreeSelection *selection, - GvcMixerDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean active; - guint id; - GvcMixerUIDevice *input; - - if (gtk_tree_selection_get_selected (selection, &model, &iter) == FALSE) { - g_debug ("Could not get default input from selection"); - return; - } - - gtk_tree_model_get (model, &iter, - ID_COLUMN, &id, - ACTIVE_COLUMN, &active, - -1); - - input = gvc_mixer_control_lookup_input_id (dialog->priv->mixer_control, id); - - if (input == NULL) { - g_warning ("on_input_selection_changed - Unable to find input with id: %u", id); - return; - } - - gvc_mixer_control_change_input (dialog->priv->mixer_control, input); -} - -static void -on_output_selection_changed (GtkTreeSelection *selection, - GvcMixerDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean active; - guint id; - GvcMixerUIDevice *output; - - if (gtk_tree_selection_get_selected (selection, &model, &iter) == FALSE) { - g_debug ("Could not get default output from selection"); - return; - } - - gtk_tree_model_get (model, &iter, - ID_COLUMN, &id, - ACTIVE_COLUMN, &active, - -1); - - g_debug ("on_output_selection_changed() stream id: %u, active %i", id, active); - if (active) - return; - - output = gvc_mixer_control_lookup_output_id (dialog->priv->mixer_control, id); - - if (output == NULL) { - g_warning ("Unable to find output with id: %u", id); - return; - } - - gvc_mixer_control_change_output (dialog->priv->mixer_control, output); -} - -static GtkWidget * -create_ui_device_treeview (GvcMixerDialog *dialog, - GCallback on_selection_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); - - store = gtk_list_store_new (NUM_COLUMNS, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_BOOLEAN, - G_TYPE_UINT, - G_TYPE_ICON); - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), - GTK_TREE_MODEL (store)); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Name")); - renderer = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - g_object_set (G_OBJECT (renderer), "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); - gtk_tree_view_column_set_attributes (column, renderer, - "gicon", ICON_COLUMN, - NULL); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_set_attributes (column, renderer, - "text", NAME_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - g_signal_connect (G_OBJECT (selection), "changed", - on_selection_changed, dialog); -#if 0 - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Device"), - renderer, - "text", DEVICE_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); -#endif - return treeview; -} - -static void -on_test_speakers_clicked (GvcComboBox *widget, - gpointer user_data) -{ - GvcMixerDialog *dialog = GVC_MIXER_DIALOG (user_data); - GtkTreeModel *model; - GtkTreeIter iter; - gint stream_id; - gint active_output = GVC_MIXER_UI_DEVICE_INVALID; - GvcMixerUIDevice *output; - GvcMixerStream *stream; - GtkWidget *d, *speaker_test, *container; - char *title; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - - if (gtk_tree_model_get_iter_first (model, &iter) == FALSE) { - g_warning ("The tree is empty => we have no device to test speakers with return"); - return; - } - - do { - gboolean is_selected = FALSE; - gint id; - - gtk_tree_model_get (model, &iter, - ID_COLUMN, &id, - ACTIVE_COLUMN, &is_selected, - -1); - - if (is_selected) { - active_output = id; - break; - } - } while (gtk_tree_model_iter_next (model, &iter)); - - if (active_output == GVC_MIXER_UI_DEVICE_INVALID) { - g_warning ("Can't find the active output from the UI"); - return; - } - - output = gvc_mixer_control_lookup_output_id (dialog->priv->mixer_control, (guint)active_output); - stream_id = gvc_mixer_ui_device_get_stream_id (output); - - if (stream_id == GVC_MIXER_UI_DEVICE_INVALID) - return; - - g_debug ("Test speakers on '%s'", gvc_mixer_ui_device_get_description (output)); - - stream = gvc_mixer_control_lookup_stream_id (dialog->priv->mixer_control, stream_id); - if (stream == NULL) { - g_debug ("Stream/sink not found"); - return; - } - title = g_strdup_printf (_("Speaker Testing for %s"), gvc_mixer_ui_device_get_description (output)); - d = gtk_dialog_new_with_buttons (title, - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget))), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - gtk_window_set_has_resize_grip (GTK_WINDOW (d), FALSE); - - g_free (title); - speaker_test = gvc_speaker_test_new (dialog->priv->mixer_control, - stream); - gtk_widget_show (speaker_test); - container = gtk_dialog_get_content_area (GTK_DIALOG (d)); - gtk_container_add (GTK_CONTAINER (container), speaker_test); - - gtk_dialog_run (GTK_DIALOG (d)); - gtk_widget_destroy (d); -} - -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; - GSList *streams; - GSList *l; - GvcMixerStream *stream; - - object = G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->constructor (type, n_construct_properties, construct_params); - - self = GVC_MIXER_DIALOG (object); - - main_vbox = GTK_WIDGET (self); - gtk_box_set_spacing (GTK_BOX (main_vbox), 2); - - gtk_container_set_border_width (GTK_CONTAINER (self), 6); - - self->priv->output_stream_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - 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_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); - gtk_container_set_border_width (GTK_CONTAINER (self->priv->notebook), 5); - - /* Output page */ - self->priv->output_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 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)); - _gtk_label_make_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_ui_device_treeview (self, - G_CALLBACK (on_output_selection_changed)); - 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_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (box), 150); - gtk_container_add (GTK_CONTAINER (alignment), box); - - box = gtk_frame_new (_("Settings for the selected device:")); - label = gtk_frame_get_label_widget (GTK_FRAME (box)); - _gtk_label_make_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_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add (GTK_CONTAINER (box), self->priv->output_settings_box); - - /* Input page */ - self->priv->input_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); - 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-symbolic"); - gvc_channel_bar_set_high_icon_name (GVC_CHANNEL_BAR (self->priv->input_bar), - "audio-input-microphone-high-symbolic"); - 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); - - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (self->priv->input_box), - box, - FALSE, FALSE, 6); - - sbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 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); - if (self->priv->size_group != NULL) - 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); - - ebox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (box), - ebox, - FALSE, FALSE, 0); - if (self->priv->size_group != NULL) - gtk_size_group_add_widget (self->priv->size_group, ebox); - - self->priv->input_settings_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - 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)); - _gtk_label_make_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_ui_device_treeview (self, - G_CALLBACK (on_input_selection_changed)); - 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); - - /* Effects page */ - self->priv->sound_effects_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - 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); - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (self->priv->effects_bar), - _("_Alert volume:")); - gtk_widget_set_sensitive (self->priv->effects_bar, FALSE); - gtk_box_pack_start (GTK_BOX (self->priv->sound_effects_box), - self->priv->effects_bar, FALSE, FALSE, 0); - - 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); - - /* Applications */ - self->priv->applications_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); - gtk_container_set_border_width (GTK_CONTAINER (self->priv->applications_box), 12); - label = gtk_label_new (_("Applications")); - gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook), - self->priv->applications_box, - 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); - - g_signal_connect (self->priv->mixer_control, - "output-added", - G_CALLBACK (on_control_output_added), - self); - g_signal_connect (self->priv->mixer_control, - "output-removed", - G_CALLBACK (on_control_output_removed), - self); - g_signal_connect (self->priv->mixer_control, - "input-added", - G_CALLBACK (on_control_input_added), - self); - g_signal_connect (self->priv->mixer_control, - "input-removed", - G_CALLBACK (on_control_input_removed), - self); - - g_signal_connect (self->priv->mixer_control, - "stream-added", - G_CALLBACK (on_control_stream_added), - self); - g_signal_connect (self->priv->mixer_control, - "stream-removed", - G_CALLBACK (on_control_stream_removed), - self); - - gtk_widget_show_all (main_vbox); - - streams = gvc_mixer_control_get_streams (self->priv->mixer_control); - for (l = streams; l != NULL; l = l->next) { - stream = l->data; - add_stream (self, stream); - } - g_slist_free (streams); - - return object; -} - -static void -gvc_mixer_dialog_dispose (GObject *object) -{ - GvcMixerDialog *dialog = GVC_MIXER_DIALOG (object); - - if (dialog->priv->mixer_control != NULL) { - - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_output_added, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_output_removed, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_input_added, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_input_removed, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_active_input_update, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_active_output_update, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_stream_added, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->mixer_control, - on_control_stream_removed, - dialog); - - g_object_unref (dialog->priv->mixer_control); - dialog->priv->mixer_control = NULL; - } - - if (dialog->priv->bars != NULL) { - g_hash_table_destroy (dialog->priv->bars); - dialog->priv->bars = NULL; - } - - 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_MIXER_CONTROL, - g_param_spec_object ("mixer-control", - "mixer control", - "mixer control", - GVC_TYPE_MIXER_CONTROL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); - - 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 (NULL, NULL); - dialog->priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); -} - -static void -gvc_mixer_dialog_finalize (GObject *object) -{ - GvcMixerDialog *mixer_dialog; - - g_return_if_fail (object != NULL); - g_return_if_fail (GVC_IS_MIXER_DIALOG (object)); - - mixer_dialog = GVC_MIXER_DIALOG (object); - - g_return_if_fail (mixer_dialog->priv != NULL); - G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->finalize (object); -} - -GvcMixerDialog * -gvc_mixer_dialog_new (GvcMixerControl *control) -{ - GObject *dialog; - dialog = g_object_new (GVC_TYPE_MIXER_DIALOG, - "mixer-control", control, - NULL); - return GVC_MIXER_DIALOG (dialog); -} - -enum { - PAGE_OUTPUT, - PAGE_INPUT, - PAGE_EVENTS, - PAGE_APPLICATIONS -}; - -gboolean -gvc_mixer_dialog_set_page (GvcMixerDialog *self, - const char *page) -{ - guint num; - - g_return_val_if_fail (self != NULL, FALSE); - - num = PAGE_OUTPUT; - - if (g_str_equal (page, "effects")) - num = PAGE_EVENTS; - 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; -} diff --git a/gvc-mixer-dialog.h b/gvc-mixer-dialog.h deleted file mode 100644 index e95a7c7..0000000 --- a/gvc-mixer-dialog.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef __GVC_MIXER_DIALOG_H -#define __GVC_MIXER_DIALOG_H - -#include <glib-object.h> -#include "gvc-mixer-control.h" - -G_BEGIN_DECLS - -#define GVC_TYPE_MIXER_DIALOG (gvc_mixer_dialog_get_type ()) -#define GVC_MIXER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_DIALOG, GvcMixerDialog)) -#define GVC_MIXER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_DIALOG, GvcMixerDialogClass)) -#define GVC_IS_MIXER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_DIALOG)) -#define GVC_IS_MIXER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_DIALOG)) -#define GVC_MIXER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_DIALOG, GvcMixerDialogClass)) - -typedef struct GvcMixerDialogPrivate GvcMixerDialogPrivate; - -typedef struct -{ - GtkVBox parent; - GvcMixerDialogPrivate *priv; -} GvcMixerDialog; - -typedef struct -{ - GtkVBoxClass parent_class; -} GvcMixerDialogClass; - -GType gvc_mixer_dialog_get_type (void); - -GvcMixerDialog * gvc_mixer_dialog_new (GvcMixerControl *control); -gboolean gvc_mixer_dialog_set_page (GvcMixerDialog *dialog, const gchar* page); - -G_END_DECLS - -#endif /* __GVC_MIXER_DIALOG_H */ |