Updating branch refs/heads/master to 46d08678f7a1cbeb3970c03b5a91e55ec284a1ec (commit) from 3e0def60db29746e501586d36d33ea305540a2e8 (commit)
commit 46d08678f7a1cbeb3970c03b5a91e55ec284a1ec Author: Guido Berhoerster <guido+x...@berhoerster.name> Date: Thu Sep 27 16:31:08 2012 +0200 Keep the sound card and controls in sync between the mixer and xfconf Also apply changes in the controls dialog instantly to the mixer window. NEWS | 1 + configure.ac.in | 1 + libxfce4mixer/Makefile.am | 2 + libxfce4mixer/libxfce4mixer.c | 19 ++ libxfce4mixer/libxfce4mixer.h | 5 + libxfce4mixer/xfce-mixer-preferences.c | 308 ++++++++++++++---------------- libxfce4mixer/xfce-mixer-preferences.h | 12 +- xfce4-mixer/xfce-mixer-controls-dialog.c | 181 ++++++++++-------- xfce4-mixer/xfce-mixer-controls-dialog.h | 6 +- xfce4-mixer/xfce-mixer-window.c | 189 ++++++++++++++----- xfce4-mixer/xfce-mixer.c | 24 ++- 11 files changed, 443 insertions(+), 305 deletions(-) diff --git a/NEWS b/NEWS index 59ff72e..f2e2825 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ - Add global keyboard shortcuts for raising and lowering the volume as well as muting (bug #5314). - Set the main window to normal rather than dialog type (bug #7623). +- Keep the sound card and controls in sync between the mixer and xfconf. 4.8.0 diff --git a/configure.ac.in b/configure.ac.in index d4b86d7..4baffdb 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -95,6 +95,7 @@ dnl *** Check for required packages *** dnl *********************************** XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.24.0]) XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.24.0]) +XDT_CHECK_PACKAGE([DBUS_GLIB], [dbus-glib-1], [0.84]) XDT_CHECK_PACKAGE([GST_PLUGINS_BASE], [gstreamer-plugins-base-0.10], [0.10.23]) XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.20.0]) XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.10.0]) diff --git a/libxfce4mixer/Makefile.am b/libxfce4mixer/Makefile.am index 399bb2d..8f44cd4 100644 --- a/libxfce4mixer/Makefile.am +++ b/libxfce4mixer/Makefile.am @@ -30,6 +30,7 @@ libxfce4mixer_la_CFLAGS = \ $(LIBXFCE4UTIL_CFLAGS) \ $(LIBXFCE4UI_CFLAGS) \ $(XFCONF_CFLAGS) \ + $(DBUS_GLIB_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) libxfce4mixer_la_LDFLAGS = \ @@ -42,6 +43,7 @@ libxfce4mixer_la_LIBADD = \ $(LIBXFCE4UTIL_LIBS) \ $(LIBXFCE4UI_LIBS) \ $(XFCONF_LIBS) \ + $(DBUS_GLIB_LIBS) \ $(GST_PLUGINS_BASE_LIBS) \ -lgstaudio-0.10 \ -lgstinterfaces-0.10 diff --git a/libxfce4mixer/libxfce4mixer.c b/libxfce4mixer/libxfce4mixer.c index b25ecc5..7bb9293 100644 --- a/libxfce4mixer/libxfce4mixer.c +++ b/libxfce4mixer/libxfce4mixer.c @@ -25,6 +25,8 @@ #include <glib.h> +#include <dbus/dbus-glib.h> + #include <gst/audio/mixerutils.h> #include <gst/interfaces/mixer.h> @@ -350,3 +352,20 @@ xfce_mixer_utf8_cmp (const gchar *s1, const gchar *s2) return g_utf8_collate (s1, s2); } + + +GType +xfce_mixer_value_array_get_type (void) +{ + static volatile gsize type__volatile = 0; + GType type; + + if (g_once_init_enter (&type__volatile)) + { + type = dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE); + g_once_init_leave (&type__volatile, type); + } + + return type__volatile; +} + diff --git a/libxfce4mixer/libxfce4mixer.h b/libxfce4mixer/libxfce4mixer.h index 41f5816..187db3f 100644 --- a/libxfce4mixer/libxfce4mixer.h +++ b/libxfce4mixer/libxfce4mixer.h @@ -24,6 +24,8 @@ #include <glib.h> +#include <dbus/dbus-glib.h> + #include <gst/interfaces/mixer.h> #include "xfce-mixer-preferences.h" @@ -31,6 +33,8 @@ #include "xfce-mixer-track-combo.h" #include "xfce-mixer-track-type.h" +#define XFCE_MIXER_TYPE_VALUE_ARRAY (xfce_mixer_value_array_get_type ()) + G_BEGIN_DECLS; void xfce_mixer_init (void); @@ -52,6 +56,7 @@ gint xfce_mixer_get_max_volume (gint *volumes, gint num_channels); int xfce_mixer_utf8_cmp (const gchar *s1, const gchar *s2); +GType xfce_mixer_value_array_get_type (void); G_END_DECLS; diff --git a/libxfce4mixer/xfce-mixer-preferences.c b/libxfce4mixer/xfce-mixer-preferences.c index 04aef50..2cb7edb 100644 --- a/libxfce4mixer/xfce-mixer-preferences.c +++ b/libxfce4mixer/xfce-mixer-preferences.c @@ -1,6 +1,7 @@ /* vi:set expandtab sw=2 sts=2: */ /*- * Copyright (c) 2008 Jannis Pohlmann <jan...@xfce.org> + * Copyright (c) 2012 Guido Berhoerster <guido+x...@berhoerster.name> * * 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 @@ -31,13 +32,13 @@ #include "xfce-mixer-preferences.h" - enum { PROP_0, PROP_WINDOW_WIDTH, PROP_WINDOW_HEIGHT, PROP_SOUND_CARD, + PROP_CONTROLS, N_PROPERTIES, }; @@ -54,8 +55,6 @@ static void xfce_mixer_preferences_set_property (GObject guint prop_id, const GValue *value, GParamSpec *pspec); -static void xfce_mixer_preferences_load (XfceMixerPreferences *preferences); -static void xfce_mixer_preferences_store (XfceMixerPreferences *preferences); @@ -69,9 +68,15 @@ struct _XfceMixerPreferences GObject __parent__; XfconfChannel *channel; - GHashTable *controls; - GValue values[N_PROPERTIES]; + gint window_width; + gint window_height; + + gchar *sound_card; + + GPtrArray *controls; + + gulong sound_cards_property_bind_id; }; @@ -145,6 +150,14 @@ xfce_mixer_preferences_class_init (XfceMixerPreferencesClass *klass) "sound-card", NULL, G_PARAM_READABLE | G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, + PROP_CONTROLS, + g_param_spec_boxed ("controls", + "controls", + "controls", + XFCE_MIXER_TYPE_VALUE_ARRAY, + G_PARAM_READABLE | G_PARAM_WRITABLE)); } @@ -152,14 +165,20 @@ xfce_mixer_preferences_class_init (XfceMixerPreferencesClass *klass) static void xfce_mixer_preferences_init (XfceMixerPreferences *preferences) { - preferences->channel = xfconf_channel_get ("xfce4-mixer"); - preferences->controls = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev); + preferences->channel = xfconf_channel_get ("xfce4-mixer"); - xfconf_g_property_bind (preferences->channel, "/window-width", G_TYPE_INT, G_OBJECT (preferences), "window-width"); - xfconf_g_property_bind (preferences->channel, "/window-height", G_TYPE_INT, G_OBJECT (preferences), "window-height"); - xfconf_g_property_bind (preferences->channel, "/sound-card", G_TYPE_STRING, G_OBJECT (preferences), "sound-card"); + preferences->window_width = 1; + preferences->window_height = 1; - xfce_mixer_preferences_load (preferences); + preferences->sound_card = NULL; + + preferences->controls = g_ptr_array_new (); + + preferences->sound_cards_property_bind_id = 0UL; + + xfconf_g_property_bind (preferences->channel, "/window-width", G_TYPE_INT, G_OBJECT (preferences), "window-width"); + xfconf_g_property_bind (preferences->channel, "/window-height", G_TYPE_INT, G_OBJECT (preferences), "window-height"); + xfconf_g_property_bind (preferences->channel, "/sound-card", G_TYPE_STRING, G_OBJECT (preferences), "sound-card"); } @@ -169,7 +188,17 @@ xfce_mixer_preferences_finalize (GObject *object) { XfceMixerPreferences *preferences = XFCE_MIXER_PREFERENCES (object); - g_hash_table_unref (preferences->controls); + if (preferences->sound_card != NULL) + { + g_free (preferences->sound_card); + preferences->sound_card = NULL; + } + + if (preferences->controls != NULL) + { + xfconf_array_free (preferences->controls); + preferences->controls = NULL; + } (*G_OBJECT_CLASS (xfce_mixer_preferences_parent_class)->finalize) (object); } @@ -183,14 +212,25 @@ xfce_mixer_preferences_get_property (GObject *object, GParamSpec *pspec) { XfceMixerPreferences *preferences = XFCE_MIXER_PREFERENCES (object); - GValue *src; - src = preferences->values + prop_id; - - if (G_LIKELY (G_IS_VALUE (src))) - g_value_copy (src, value); - else - g_param_value_set_default (pspec, value); + switch (prop_id) + { + case PROP_WINDOW_WIDTH: + g_value_set_int (value, preferences->window_width); + break; + case PROP_WINDOW_HEIGHT: + g_value_set_int (value, preferences->window_height); + break; + case PROP_SOUND_CARD: + g_value_set_string (value, preferences->sound_card); + break; + case PROP_CONTROLS: + g_value_set_boxed (value, preferences->controls); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } @@ -202,18 +242,75 @@ xfce_mixer_preferences_set_property (GObject *object, GParamSpec *pspec) { XfceMixerPreferences *preferences = XFCE_MIXER_PREFERENCES (object); - GValue *dest; - - dest = preferences->values + prop_id; + gchar *sound_cards_property_name; + GPtrArray *controls; + guint i; + GValue *element; + GValue *control; - if (G_UNLIKELY (!G_IS_VALUE (dest))) + switch (prop_id) { - g_value_init (dest, pspec->value_type); - g_param_value_set_default (pspec, dest); - } + case PROP_WINDOW_WIDTH: + preferences->window_width = g_value_get_int (value); + break; + case PROP_WINDOW_HEIGHT: + preferences->window_height = g_value_get_int (value); + break; + case PROP_SOUND_CARD: + /* Freeze "notify" signals since the "controls" property is also manipulated */ + g_object_freeze_notify (object); + + g_free (preferences->sound_card); + preferences->sound_card = g_value_dup_string (value); + + /* Remove the previous binding */ + if (preferences->sound_cards_property_bind_id > 0) + { + xfconf_g_property_unbind (preferences->sound_cards_property_bind_id); + preferences->sound_cards_property_bind_id = 0UL; + } + + /* Make sure the "controls" property is reset */ + g_object_set (object, "controls", NULL, NULL); - if (G_LIKELY (g_param_values_cmp (pspec, value, dest) != 0)) - g_value_copy (value, dest); + if (preferences->sound_card != NULL) + { + /* Bind to the property corresponding to the new sound card */ + sound_cards_property_name = g_strdup_printf ("/sound-cards/%s", preferences->sound_card); + preferences->sound_cards_property_bind_id = xfconf_g_property_bind (preferences->channel, sound_cards_property_name, XFCE_MIXER_TYPE_VALUE_ARRAY, G_OBJECT (preferences), "controls"); + g_free (sound_cards_property_name); + } + + g_object_thaw_notify (object); + break; + case PROP_CONTROLS: + if (preferences->controls != NULL) + xfconf_array_free (preferences->controls); + + controls = g_value_get_boxed (value); + if (controls != NULL) + { + preferences->controls = g_ptr_array_sized_new (controls->len); + for (i = 0; i < controls->len; ++i) + { + element = (GValue *) g_ptr_array_index (controls, i); + + /* Filter out invalid value types */ + if (G_VALUE_HOLDS_STRING (element)) + { + control = g_value_init (g_new0 (GValue, 1), G_TYPE_STRING); + g_value_copy (element, control); + g_ptr_array_add (preferences->controls, control); + } + } + } + else + preferences->controls = g_ptr_array_new (); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } @@ -236,166 +333,51 @@ xfce_mixer_preferences_get (void) -static void -xfce_mixer_preferences_load_controls (const gchar *property_name, - const GValue *value, - XfceMixerPreferences *preferences) -{ - gchar **controls; - gchar *card_name; - - g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences)); - g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel)); - - if (G_UNLIKELY ((card_name = g_strrstr (property_name, "/")) == NULL)) - return; - - /* Remove the leading slash */ - card_name = card_name + 1; - - /* Read controls for this card */ - controls = xfconf_channel_get_string_list (preferences->channel, property_name); - - if (G_LIKELY (controls != NULL)) - { - /* Store controls in the hash table */ - g_hash_table_insert (preferences->controls, g_strdup (card_name), controls); - } -} - - - -static void -xfce_mixer_preferences_load (XfceMixerPreferences *preferences) -{ - GHashTable *properties; - - g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences)); - g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel)); - - properties = xfconf_channel_get_properties (preferences->channel, "/sound-cards"); - - if (G_LIKELY (properties != NULL)) - g_hash_table_foreach (properties, (GHFunc) xfce_mixer_preferences_load_controls, preferences); -} - - - -static void -xfce_mixer_preferences_store_controls (const gchar *card_name, - gchar * const *controls, - XfceMixerPreferences *preferences) -{ - gchar *property_name; - - g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences)); - g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel)); - - property_name = g_strdup_printf ("/sound-cards/%s", card_name); - - if (G_UNLIKELY (controls != NULL)) - xfconf_channel_set_string_list (preferences->channel, property_name, (const gchar * const *) controls); - else - xfconf_channel_reset_property (preferences->channel, property_name, TRUE); - - g_free (property_name); -} - - - -static void -xfce_mixer_preferences_update_controls (const gchar *property_name, - const GValue *value, - XfceMixerPreferences *preferences) -{ - g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences)); - g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel)); - - xfconf_channel_reset_property (preferences->channel, property_name, TRUE); -} - - - -static void -xfce_mixer_preferences_store (XfceMixerPreferences *preferences) +void +xfce_mixer_preferences_set_controls (XfceMixerPreferences *preferences, + GPtrArray *controls) { - GHashTable *properties; - g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences)); - g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel)); - - properties = xfconf_channel_get_properties (preferences->channel, "/sound-cards"); - - if (G_LIKELY (properties != NULL)) - g_hash_table_foreach (properties, (GHFunc) xfce_mixer_preferences_update_controls, preferences); + g_return_if_fail (controls != NULL); - g_hash_table_foreach (preferences->controls, (GHFunc) xfce_mixer_preferences_store_controls, preferences); + g_object_set (G_OBJECT (preferences), "controls", controls, NULL); } -gchar * const * -xfce_mixer_preferences_get_visible_controls (XfceMixerPreferences *preferences, - GstElement *card) +GPtrArray * +xfce_mixer_preferences_get_controls (XfceMixerPreferences *preferences) { - const gchar *card_name; + GPtrArray *controls; g_return_val_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences), NULL); - g_return_val_if_fail (GST_IS_MIXER (card), NULL); - - card_name = xfce_mixer_get_card_internal_name (card); - return (gchar * const *) g_hash_table_lookup (preferences->controls, card_name); -} + g_object_get (G_OBJECT (preferences), "controls", &controls, NULL); - -void -xfce_mixer_preferences_set_visible_controls (XfceMixerPreferences *preferences, - GstElement *card, - gchar * const *controls) -{ - const gchar *card_name; - g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences)); - g_return_if_fail (GST_IS_MIXER (card)); - - card_name = xfce_mixer_get_card_internal_name (card); - g_hash_table_insert (preferences->controls, g_strdup (card_name), g_strdupv ((gchar **) controls)); - xfce_mixer_preferences_store (preferences); + return controls; } gboolean xfce_mixer_preferences_get_control_visible (XfceMixerPreferences *preferences, - GstElement *card, - GstMixerTrack *track) + const gchar *track_label) { - gchar * const *controls; - const gchar *card_name; gboolean visible = FALSE; - gchar *label; - gint i; + guint i; g_return_val_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences), FALSE); - g_return_val_if_fail (GST_IS_MIXER (card), FALSE); - g_return_val_if_fail (GST_IS_MIXER_TRACK (track), FALSE); + g_return_val_if_fail (preferences->controls != NULL, FALSE); - g_object_get (track, "label", &label, NULL); - - card_name = xfce_mixer_get_card_internal_name (card); - controls = g_hash_table_lookup (preferences->controls, card_name); - - if (G_LIKELY (controls != NULL)) + for (i = 0; i < preferences->controls->len; ++i) { - for (i = 0; controls != NULL && controls[i] != NULL; ++i) - if (g_utf8_collate (controls[i], label) == 0) - { - visible = TRUE; - break; - } + if (xfce_mixer_utf8_cmp (g_value_get_string (g_ptr_array_index (preferences->controls, i)), track_label) == 0) + { + visible = TRUE; + break; + } } - g_free (label); - return visible; } + diff --git a/libxfce4mixer/xfce-mixer-preferences.h b/libxfce4mixer/xfce-mixer-preferences.h index 70ff50e..c4aa5c8 100644 --- a/libxfce4mixer/xfce-mixer-preferences.h +++ b/libxfce4mixer/xfce-mixer-preferences.h @@ -1,6 +1,7 @@ /* vi:set expandtab sw=2 sts=2: */ /*- * Copyright (c) 2008 Jannis Pohlmann <jan...@xfce.org> + * Copyright (c) 2012 Guido Berhoerster <guido+x...@berhoerster.name> * * 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 @@ -41,14 +42,11 @@ typedef struct _XfceMixerPreferences XfceMixerPreferences; GType xfce_mixer_preferences_get_type (void) G_GNUC_CONST; XfceMixerPreferences *xfce_mixer_preferences_get (void); -gchar * const *xfce_mixer_preferences_get_visible_controls (XfceMixerPreferences *preferences, - GstElement *card); -void xfce_mixer_preferences_set_visible_controls (XfceMixerPreferences *preferences, - GstElement *card, - gchar * const *controls); +void xfce_mixer_preferences_set_controls (XfceMixerPreferences *preferences, + GPtrArray *controls); +GPtrArray *xfce_mixer_preferences_get_controls (XfceMixerPreferences *preferences); gboolean xfce_mixer_preferences_get_control_visible (XfceMixerPreferences *preferences, - GstElement *card, - GstMixerTrack *track); + const gchar *track_label); G_END_DECLS; diff --git a/xfce4-mixer/xfce-mixer-controls-dialog.c b/xfce4-mixer/xfce-mixer-controls-dialog.c index b9b851b..baa5c38 100644 --- a/xfce4-mixer/xfce-mixer-controls-dialog.c +++ b/xfce4-mixer/xfce-mixer-controls-dialog.c @@ -1,6 +1,7 @@ /* vi:set expandtab sw=2 sts=2: */ /*- * Copyright (c) 2008 Jannis Pohlmann <jan...@xfce.org> + * Copyright (c) 2012 Guido Berhoerster <guido+x...@berhoerster.name> * * 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 @@ -27,6 +28,7 @@ #include <libxfce4util/libxfce4util.h> #include <libxfce4ui/libxfce4ui.h> +#include <xfconf/xfconf.h> #include "libxfce4mixer/libxfce4mixer.h" @@ -47,6 +49,7 @@ static void xfce_mixer_controls_dialog_finalize (GObject static void xfce_mixer_controls_dialog_response (GtkDialog *dialog, gint response_id); static void xfce_mixer_controls_dialog_create_contents (XfceMixerControlsDialog *dialog); +static void xfce_mixer_controls_dialog_update_preferences (XfceMixerControlsDialog *dialog); static void xfce_mixer_controls_dialog_control_toggled (GtkCellRendererToggle *renderer, gchar *path, XfceMixerControlsDialog *dialog); @@ -66,6 +69,7 @@ struct _XfceMixerControlsDialog XfceMixerPreferences *preferences; GstElement *card; + GtkWidget *frame; GtkListStore *store; }; @@ -130,6 +134,10 @@ xfce_mixer_controls_dialog_init (XfceMixerControlsDialog *dialog) dialog->preferences = xfce_mixer_preferences_get (); + dialog->card = NULL; + + dialog->frame = NULL; + gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 350); gtk_window_set_icon_name (GTK_WINDOW (dialog), "preferences-desktop"); gtk_window_set_title (GTK_WINDOW (dialog), _("Select Controls")); @@ -163,59 +171,11 @@ xfce_mixer_controls_dialog_finalize (GObject *object) -static gboolean -xfce_mixer_controls_dialog_collect_visible_controls (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - GList **controls) -{ - gboolean visible; - gchar *name; - - gtk_tree_model_get (model, iter, VISIBLE_COLUMN, &visible, NAME_COLUMN, &name, -1); - - if (G_LIKELY (visible && name != NULL)) - *controls = g_list_append (*controls, name); - - return FALSE; -} - - - static void xfce_mixer_controls_dialog_response (GtkDialog *dialog, gint response_id) { - XfceMixerControlsDialog *mixer_dialog = XFCE_MIXER_CONTROLS_DIALOG (dialog); - XfceMixerPreferences *preferences; - GList *visible_controls = NULL; - gchar **controls; - guint i; - - gtk_tree_model_foreach (GTK_TREE_MODEL (mixer_dialog->store), - (GtkTreeModelForeachFunc) xfce_mixer_controls_dialog_collect_visible_controls, - &visible_controls); - - preferences = xfce_mixer_preferences_get (); - - if (G_LIKELY (g_list_length (visible_controls) > 0)) - { - controls = g_new0 (gchar *, g_list_length (visible_controls) + 1); - controls[g_list_length (visible_controls)] = NULL; - - for (i = 0; i < g_list_length (visible_controls); ++i) - controls[i] = (gchar *) g_list_nth (visible_controls, i)->data; - - xfce_mixer_preferences_set_visible_controls (preferences, mixer_dialog->card, controls); - - g_strfreev (controls); - } - else - xfce_mixer_preferences_set_visible_controls (preferences, mixer_dialog->card, NULL); - - g_object_unref (preferences); - - g_list_free (visible_controls); + xfce_mixer_controls_dialog_update_preferences (XFCE_MIXER_CONTROLS_DIALOG (dialog)); } @@ -227,6 +187,7 @@ xfce_mixer_controls_dialog_new (XfceMixerWindow *window) dialog = g_object_new (TYPE_XFCE_MIXER_CONTROLS_DIALOG, NULL); dialog->parent = window; + dialog->card = xfce_mixer_window_get_active_card (window); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (dialog->parent)); @@ -241,30 +202,23 @@ xfce_mixer_controls_dialog_new (XfceMixerWindow *window) static void xfce_mixer_controls_dialog_create_contents (XfceMixerControlsDialog *dialog) { - XfceMixerPreferences *preferences; GtkTreeViewColumn *column; GtkCellRenderer *renderer; - GstElement *card; - const GList *iter; - GtkTreeIter tree_iter; GtkWidget *view; - GtkWidget *frame; GtkWidget *scrollwin; - gchar *label; - gboolean visible; dialog->store = gtk_list_store_new (2, G_TYPE_BOOLEAN, G_TYPE_STRING); - frame = gtk_frame_new (NULL); - gtk_container_set_border_width (GTK_CONTAINER (frame), 6); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), frame); - gtk_widget_show (frame); + dialog->frame = gtk_frame_new (NULL); + gtk_container_set_border_width (GTK_CONTAINER (dialog->frame), 6); + gtk_frame_set_shadow_type (GTK_FRAME (dialog->frame), GTK_SHADOW_NONE); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog->frame); + gtk_widget_show (dialog->frame); scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (frame), scrollwin); + gtk_container_add (GTK_CONTAINER (dialog->frame), scrollwin); gtk_widget_show (scrollwin); view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog->store)); @@ -282,29 +236,85 @@ xfce_mixer_controls_dialog_create_contents (XfceMixerControlsDialog *dialog) column = gtk_tree_view_column_new_with_attributes ("Control", renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + xfce_mixer_controls_dialog_update_dialog (dialog); +} + + + +void +xfce_mixer_controls_dialog_update_dialog (XfceMixerControlsDialog *dialog) +{ + XfceMixerPreferences *preferences; + const GList *iter; + gchar *track_label; + gboolean visible; + GtkTreeIter tree_iter; + + /* Clear the list before recreating it below */ + gtk_list_store_clear (dialog->store); + + if (G_UNLIKELY (!GST_IS_MIXER (dialog->card))) + return; + preferences = xfce_mixer_preferences_get (); - card = xfce_mixer_window_get_active_card (dialog->parent); - if (G_LIKELY (card != NULL)) + for (iter = gst_mixer_list_tracks (GST_MIXER (dialog->card)); + iter != NULL; + iter = g_list_next (iter)) { - for (iter = gst_mixer_list_tracks (GST_MIXER (dialog->card)); - iter != NULL; - iter = g_list_next (iter)) - { - visible = xfce_mixer_preferences_get_control_visible (preferences, dialog->card, iter->data); + g_object_get (GST_MIXER_TRACK (iter->data), "label", &track_label, NULL); + + visible = xfce_mixer_preferences_get_control_visible (preferences, track_label); + + gtk_list_store_append (dialog->store, &tree_iter); + gtk_list_store_set (dialog->store, &tree_iter, + VISIBLE_COLUMN, visible, + NAME_COLUMN, track_label, + -1); + + g_free (track_label); + } + + g_object_unref (preferences); +} + + - g_object_get (GST_MIXER_TRACK (iter->data), "label", &label, NULL, NULL); +static void +xfce_mixer_controls_dialog_update_preferences (XfceMixerControlsDialog *dialog) +{ + XfceMixerPreferences *preferences; + GPtrArray *controls; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean visible; + GValue *name; - gtk_list_store_append (dialog->store, &tree_iter); - gtk_list_store_set (dialog->store, &tree_iter, - VISIBLE_COLUMN, visible, - NAME_COLUMN, label, - -1); + preferences = xfce_mixer_preferences_get (); - g_free (label); + controls = g_ptr_array_new (); + + model = GTK_TREE_MODEL (dialog->store); + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + gtk_tree_model_get (model, &iter, VISIBLE_COLUMN, &visible, -1); + + if (visible) + { + name = g_new0 (GValue, 1); + gtk_tree_model_get_value (model, &iter, NAME_COLUMN, name); + g_ptr_array_add (controls, name); + } } + while (gtk_tree_model_iter_next(model, &iter)); } + xfce_mixer_preferences_set_controls (preferences, controls); + + xfconf_array_free (controls); + g_object_unref (preferences); } @@ -328,5 +338,24 @@ xfce_mixer_controls_dialog_control_toggled (GtkCellRendererToggle *renderer, else gtk_list_store_set (dialog->store, &iter, VISIBLE_COLUMN, FALSE, -1); + xfce_mixer_controls_dialog_update_preferences (dialog); + g_free (name); } + + + +void +xfce_mixer_controls_dialog_set_soundcard (XfceMixerControlsDialog *dialog, + GstElement *card) +{ + g_return_if_fail (IS_XFCE_MIXER_CONTROLS_DIALOG (dialog)); + g_return_if_fail (GST_IS_MIXER (card)); + + dialog->card = card; + + /* Recreate contents corresponding to the new card */ + gtk_widget_destroy (dialog->frame); + xfce_mixer_controls_dialog_create_contents (dialog); +} + diff --git a/xfce4-mixer/xfce-mixer-controls-dialog.h b/xfce4-mixer/xfce-mixer-controls-dialog.h index 11b1130..739e95a 100644 --- a/xfce4-mixer/xfce-mixer-controls-dialog.h +++ b/xfce4-mixer/xfce-mixer-controls-dialog.h @@ -1,6 +1,7 @@ /* vi:set expandtab sw=2 sts=2: */ /*- * Copyright (c) 2008 Jannis Pohlmann <jan...@xfce.org> + * Copyright (c) 2012 Guido Berhoerster <guido+x...@berhoerster.name> * * 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 @@ -37,7 +38,10 @@ typedef struct _XfceMixerControlsDialog XfceMixerControlsDialog; GType xfce_mixer_controls_dialog_get_type (void) G_GNUC_CONST; -GtkWidget *xfce_mixer_controls_dialog_new (XfceMixerWindow *parent); +GtkWidget *xfce_mixer_controls_dialog_new (XfceMixerWindow *parent); +void xfce_mixer_controls_dialog_set_soundcard (XfceMixerControlsDialog *dialog, + GstElement *card); +void xfce_mixer_controls_dialog_update_dialog (XfceMixerControlsDialog *dialog); G_END_DECLS; diff --git a/xfce4-mixer/xfce-mixer-window.c b/xfce4-mixer/xfce-mixer-window.c index 11ecf1d..b1b04eb 100644 --- a/xfce4-mixer/xfce-mixer-window.c +++ b/xfce4-mixer/xfce-mixer-window.c @@ -1,6 +1,7 @@ /* vi:set expandtab sw=2 sts=2: */ /*- * Copyright (c) 2008 Jannis Pohlmann <jan...@xfce.org> + * Copyright (c) 2012 Guido Berhoerster <guido+x...@berhoerster.name> * * 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 @@ -37,21 +38,27 @@ -static void xfce_mixer_window_class_init (XfceMixerWindowClass *klass); -static void xfce_mixer_window_init (XfceMixerWindow *window); -static void xfce_mixer_window_dispose (GObject *object); -static void xfce_mixer_window_finalize (GObject *object); -static void xfce_mixer_window_soundcard_changed (XfceMixerCardCombo *combo, - GstElement *card, - XfceMixerWindow *window); -static void xfce_mixer_window_action_select_controls (GtkAction *action, - XfceMixerWindow *window); -static void xfce_mixer_window_close (GtkAction *action, - XfceMixerWindow *window); -static gboolean xfce_mixer_window_closed (GtkWidget *window, - GdkEvent *event, - XfceMixerWindow *mixer_window); -static void xfce_mixer_window_update_contents (XfceMixerWindow *window); +static void xfce_mixer_window_class_init (XfceMixerWindowClass *klass); +static void xfce_mixer_window_init (XfceMixerWindow *window); +static void xfce_mixer_window_dispose (GObject *object); +static void xfce_mixer_window_finalize (GObject *object); +static void xfce_mixer_window_soundcard_changed (XfceMixerCardCombo *combo, + GstElement *card, + XfceMixerWindow *window); +static void xfce_mixer_window_soundcard_property_changed (XfceMixerWindow *window, + GParamSpec *pspec, + GObject *object); +static void xfce_mixer_window_action_select_controls (GtkAction *action, + XfceMixerWindow *window); +static void xfce_mixer_window_controls_property_changed (XfceMixerWindow *window, + GParamSpec *pspec, + GObject *object); +static void xfce_mixer_window_close (GtkAction *action, + XfceMixerWindow *window); +static gboolean xfce_mixer_window_closed (GtkWidget *window, + GdkEvent *event, + XfceMixerWindow *mixer_window); +static void xfce_mixer_window_update_contents (XfceMixerWindow *window); @@ -75,6 +82,8 @@ struct _XfceMixerWindow GtkWidget *mixer; GtkWidget *select_controls_button; + + GtkWidget *controls_dialog; }; @@ -152,15 +161,30 @@ xfce_mixer_window_init (XfceMixerWindow *window) GtkWidget *vbox; GtkWidget *hbox; GtkWidget *bbox; - gchar *active_card = NULL; + gchar *card_name; + GstElement *card; gchar *title; guint i; gint width; gint height; + window->mixer = NULL; + + window->controls_dialog = NULL; + window->preferences = xfce_mixer_preferences_get (); - g_object_get (window->preferences, "window-width", &width, "window-height", &height, "sound-card", &active_card, NULL); + g_object_get (window->preferences, "window-width", &width, "window-height", &height, "sound-card", &card_name, NULL); + if (card_name != NULL) + card = xfce_mixer_get_card (card_name); + else + { + card = xfce_mixer_get_default_card (); + + if (GST_IS_MIXER (card)) + g_object_set (window->preferences, "sound-card", xfce_mixer_get_card_internal_name (card), NULL); + } + g_free (card_name); /* Configure the main window */ gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL); @@ -207,8 +231,8 @@ xfce_mixer_window_init (XfceMixerWindow *window) gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_widget_show (label); - window->soundcard_combo = xfce_mixer_card_combo_new (xfce_mixer_get_card (active_card)); - g_signal_connect (window->soundcard_combo, "soundcard-changed", G_CALLBACK (xfce_mixer_window_soundcard_changed), window); + window->soundcard_combo = xfce_mixer_card_combo_new (card); + g_signal_connect (G_OBJECT (window->soundcard_combo), "soundcard-changed", G_CALLBACK (xfce_mixer_window_soundcard_changed), window); gtk_container_add (GTK_CONTAINER (hbox), window->soundcard_combo); gtk_widget_show (window->soundcard_combo); @@ -238,10 +262,12 @@ xfce_mixer_window_init (XfceMixerWindow *window) gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, TRUE, 0); gtk_widget_show (button); + g_signal_connect_swapped (G_OBJECT (window->preferences), "notify::sound-card", G_CALLBACK (xfce_mixer_window_soundcard_property_changed), window); + + g_signal_connect_swapped (G_OBJECT (window->preferences), "notify::controls", G_CALLBACK (xfce_mixer_window_controls_property_changed), window); + /* Re-generate mixer controls for the active sound card */ xfce_mixer_window_update_contents (window); - - g_free (active_card); } @@ -279,36 +305,70 @@ xfce_mixer_window_soundcard_changed (XfceMixerCardCombo *combo, GstElement *card, XfceMixerWindow *window) { - gchar *title; - g_return_if_fail (IS_XFCE_MIXER_CARD_COMBO (combo)); g_return_if_fail (IS_XFCE_MIXER_WINDOW (window)); g_return_if_fail (GST_IS_MIXER (card)); - title = g_strdup_printf ("%s - %s", _("Audio Mixer"), xfce_mixer_get_card_display_name (card)); - gtk_window_set_title (GTK_WINDOW (window), title); - g_free (title); + /* Remember the card for next time */ + g_signal_handlers_block_by_func (G_OBJECT (window->preferences), xfce_mixer_window_soundcard_property_changed, window); + g_object_set (G_OBJECT (window->preferences), "sound-card", xfce_mixer_get_card_internal_name (card), NULL); + g_signal_handlers_unblock_by_func (G_OBJECT (window->preferences), xfce_mixer_window_soundcard_property_changed, window); - /* Destroy the current mixer */ - if (G_LIKELY (window->mixer != NULL)) - gtk_widget_destroy (gtk_bin_get_child (GTK_BIN (window->mixer_frame))); + /* Re-generate mixer controls for the active sound card */ + xfce_mixer_window_update_contents (window); - DBG ("card = %s", xfce_mixer_get_card_internal_name (card)); + /* Update the controls dialog */ + if (window->controls_dialog != NULL) + xfce_mixer_controls_dialog_set_soundcard (XFCE_MIXER_CONTROLS_DIALOG (window->controls_dialog), card); +} - xfce_mixer_select_card (card); - /* Create a new XfceMixer for the active sound card */ - window->mixer = xfce_mixer_new (card); - /* Add the XfceMixer to the window */ - gtk_container_add (GTK_CONTAINER (window->mixer_frame), window->mixer); - gtk_widget_show (window->mixer); +static void +xfce_mixer_window_soundcard_property_changed (XfceMixerWindow *window, + GParamSpec *pspec, + GObject *object) +{ + gchar *new_card_name; + GstElement *new_card = NULL; + GstElement *old_card; - /* Make the "Select Controls..." button sensitive */ - gtk_widget_set_sensitive (window->select_controls_button, TRUE); + g_return_if_fail (IS_XFCE_MIXER_WINDOW (window)); + g_return_if_fail (G_IS_OBJECT (object)); - /* Remember the card for next time */ - g_object_set (G_OBJECT (window->preferences), "sound-card", xfce_mixer_get_card_internal_name (card), NULL); + g_object_get (object, "sound-card", &new_card_name, NULL); + if (new_card_name != NULL) + new_card = xfce_mixer_get_card (new_card_name); + g_free (new_card_name); + + /* If the new card is not valid reset it to the default */ + if (!GST_IS_MIXER (new_card)) + { + new_card = xfce_mixer_get_default_card (); + + if (GST_IS_MIXER (new_card)) + g_object_set (object, "sound-card", xfce_mixer_get_card_internal_name (new_card), NULL); + + return; + } + + old_card = xfce_mixer_card_combo_get_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo)); + + /* Only update if different from the active card */ + if (new_card != old_card) + { + /* Update the combobox */ + g_signal_handlers_block_by_func (G_OBJECT (window->soundcard_combo), xfce_mixer_window_soundcard_changed, window); + xfce_mixer_card_combo_set_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo), new_card); + g_signal_handlers_unblock_by_func (G_OBJECT (window->soundcard_combo), xfce_mixer_window_soundcard_changed, window); + + /* Re-generate mixer controls for the active sound card */ + xfce_mixer_window_update_contents (window); + + /* Update the controls dialog */ + if (window->controls_dialog != NULL) + xfce_mixer_controls_dialog_set_soundcard (XFCE_MIXER_CONTROLS_DIALOG (window->controls_dialog), new_card); + } } @@ -317,14 +377,27 @@ static void xfce_mixer_window_action_select_controls (GtkAction *action, XfceMixerWindow *window) { - GtkWidget *dialog; + g_return_if_fail (window->controls_dialog == NULL); - dialog = xfce_mixer_controls_dialog_new (window); + window->controls_dialog = xfce_mixer_controls_dialog_new (window); + + gtk_dialog_run (GTK_DIALOG (window->controls_dialog)); + gtk_widget_destroy (window->controls_dialog); + window->controls_dialog = NULL; +} - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); + +static void +xfce_mixer_window_controls_property_changed (XfceMixerWindow *window, + GParamSpec *pspec, + GObject *object) +{ xfce_mixer_window_update_contents (window); + + /* Update the controls dialog */ + if (window->controls_dialog != NULL) + xfce_mixer_controls_dialog_update_dialog (XFCE_MIXER_CONTROLS_DIALOG (window->controls_dialog)); } @@ -369,13 +442,33 @@ xfce_mixer_window_get_active_card (XfceMixerWindow *window) static void xfce_mixer_window_update_contents (XfceMixerWindow *window) { - GstElement *card; + gchar *title; + GstElement *card; g_return_if_fail (IS_XFCE_MIXER_WINDOW (window)); card = xfce_mixer_card_combo_get_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo)); - /* Kind of a hack to regenerate the mixer controls */ - if (G_LIKELY (GST_IS_MIXER (card))) - xfce_mixer_window_soundcard_changed (XFCE_MIXER_CARD_COMBO (window->soundcard_combo), card, window); + if (G_UNLIKELY (!GST_IS_MIXER (card))) + return; + + title = g_strdup_printf ("%s - %s", _("Audio Mixer"), xfce_mixer_get_card_display_name (card)); + gtk_window_set_title (GTK_WINDOW (window), title); + g_free (title); + + /* Destroy the current mixer */ + if (G_LIKELY (window->mixer != NULL)) + gtk_widget_destroy (window->mixer); + + xfce_mixer_select_card (card); + + /* Create a new XfceMixer for the active sound card */ + window->mixer = xfce_mixer_new (card); + + /* Add the XfceMixer to the window */ + gtk_container_add (GTK_CONTAINER (window->mixer_frame), window->mixer); + gtk_widget_show (window->mixer); + + /* Make the "Select Controls..." button sensitive */ + gtk_widget_set_sensitive (window->select_controls_button, TRUE); } diff --git a/xfce4-mixer/xfce-mixer.c b/xfce4-mixer/xfce-mixer.c index 26cb625..f61a87e 100644 --- a/xfce4-mixer/xfce-mixer.c +++ b/xfce4-mixer/xfce-mixer.c @@ -1,6 +1,7 @@ /* vi:set expandtab sw=2 sts=2: */ /*- * Copyright (c) 2008 Jannis Pohlmann <jan...@xfce.org> + * Copyright (c) 2012 Guido Berhoerster <guido+x...@berhoerster.name> * * 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 @@ -165,7 +166,7 @@ xfce_mixer_constructed (GObject *object) GtkWidget *last_separator[4] = { NULL, NULL, NULL, NULL }; GtkWidget *label1; GtkWidget *label2; - gchar *label; + gchar *track_label; guint num_children[4] = { 0, 0, 0, 0 }; gint i; @@ -203,14 +204,17 @@ xfce_mixer_constructed (GObject *object) { track = iter->data; - if (!xfce_mixer_preferences_get_control_visible (preferences, mixer->card, track)) - continue; + g_object_get (GST_MIXER_TRACK (track), "label", &track_label, NULL); + + if (!xfce_mixer_preferences_get_control_visible (preferences, track_label)) + { + g_free (track_label); + continue; + } /* Determine the type of the mixer track */ type = xfce_mixer_track_type_new (track); - g_object_get (GST_MIXER_TRACK (track), "label", &label, NULL); - switch (type) { case XFCE_MIXER_TRACK_TYPE_PLAYBACK: @@ -229,7 +233,7 @@ xfce_mixer_constructed (GObject *object) num_children[0]++; /* Add the track to the hash table */ - g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget); + g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget); break; case XFCE_MIXER_TRACK_TYPE_CAPTURE: @@ -248,7 +252,7 @@ xfce_mixer_constructed (GObject *object) num_children[1]++; /* Add the track to the hash table */ - g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget); + g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget); break; case XFCE_MIXER_TRACK_TYPE_SWITCH: @@ -258,7 +262,7 @@ xfce_mixer_constructed (GObject *object) num_children[2]++; /* Add the track to the hash table */ - g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget); + g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget); break; case XFCE_MIXER_TRACK_TYPE_OPTIONS: @@ -268,11 +272,11 @@ xfce_mixer_constructed (GObject *object) num_children[3]++; /* Add the track to the hash table */ - g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget); + g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget); break; } - g_free (label); + g_free (track_label); } /* Append tab or destroy all its widgets - depending on the contents of each tab */ _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org https://mail.xfce.org/mailman/listinfo/xfce4-commits