[Xfce4-commits] <xfce4-mixer:gber/improvements> Handle GST_MIXER_MESSAGE_MIXER_CHANGED messages
Guido Berhoerster
noreply at xfce.org
Fri Sep 21 17:18:32 CEST 2012
Updating branch refs/heads/gber/improvements
to fb97549cd34ed3fdc3f8a9d5b1d58a0e9facf65e (commit)
from 1cc5a806d513be3e3424ea270342ed72e0a18739 (commit)
commit fb97549cd34ed3fdc3f8a9d5b1d58a0e9facf65e
Author: Guido Berhoerster <guido+xfce at berhoerster.name>
Date: Fri Sep 21 12:00:36 2012 +0200
Handle GST_MIXER_MESSAGE_MIXER_CHANGED messages
Connect every mixer to a GstBus in libxfce4mixer and add a signal handler for messages that handles GST_MIXER_MESSAGE_MIXER_CHANGED messages for every card and adds labels to all tracks.
Refactor XfceMixer in order to allow updating itself in case the tracks have changed, preserving the currently active tab if possible; handle GST_MIXER_MESSAGE_MIXER_CHANGED messages accordingly and allow the card property to be changed.
Make XfceMixerTrackCombo and XfceMixerControlsDialog listen to the bus and handle GST_MIXER_MESSAGE_MIXER_CHANGED messages for the current sound card by rebuilding the track list.
Let XfceMixerPlugin refresh the track and attemt to retain the currently selected one when receiving a GST_MIXER_MESSAGE_MIXER_CHANGED for the currently selected card.
NEWS | 2 +
libxfce4mixer/libxfce4mixer.c | 57 ++++-
libxfce4mixer/xfce-mixer-track-combo.c | 78 ++++--
panel-plugin/xfce-mixer-plugin.c | 17 +-
xfce4-mixer/xfce-mixer-controls-dialog.c | 40 +++-
xfce4-mixer/xfce-mixer-window.c | 51 ++--
xfce4-mixer/xfce-mixer.c | 432 +++++++++++++++++-------------
xfce4-mixer/xfce-mixer.h | 4 +-
8 files changed, 430 insertions(+), 251 deletions(-)
diff --git a/NEWS b/NEWS
index 9798e77..eedf761 100644
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,8 @@
- Handle tracks which are marked read-only by GStreamer or which have no mute
or record functionality by making the corresponding widgets insensitive.
Prevent read-only tracks from being selected in the panel-plugin.
+- Handle mixer changed messages which indicate that the tracks of a mixer have
+ changed.
4.8.0
diff --git a/libxfce4mixer/libxfce4mixer.c b/libxfce4mixer/libxfce4mixer.c
index 451e1d8..244196c 100644
--- a/libxfce4mixer/libxfce4mixer.c
+++ b/libxfce4mixer/libxfce4mixer.c
@@ -40,11 +40,16 @@
-static gboolean _xfce_mixer_filter_mixer (GstMixer *mixer,
- gpointer user_data);
-static void _xfce_mixer_add_track_labels (gpointer data,
- gpointer user_data);
-static void _xfce_mixer_destroy_mixer (GstMixer *mixer);
+static gboolean _xfce_mixer_filter_mixer (GstMixer *mixer,
+ gpointer user_data);
+static void _xfce_mixer_add_track_labels (gpointer data,
+ gpointer user_data);
+static void _xfce_mixer_init_mixer (gpointer data,
+ gpointer user_data);
+static void _xfce_mixer_destroy_mixer (GstMixer *mixer);
+static void _xfce_mixer_bus_message (GstBus *bus,
+ GstMessage *message,
+ gpointer user_data);
@@ -85,12 +90,16 @@ xfce_mixer_init (void)
/* Get list of all available mixer devices */
mixers = gst_audio_default_registry_mixer_filter (_xfce_mixer_filter_mixer, FALSE, &counter);
- /* Add custom labels to all tracks of all mixers */
- g_list_foreach (mixers, (GFunc) _xfce_mixer_add_track_labels, NULL);
-
/* Create a GstBus for notifications */
bus = gst_bus_new ();
gst_bus_add_signal_watch (bus);
+
+ /*
+ * Add custom labels to all tracks of all mixers and create a GstBus for
+ * each mixer device and connect an internal signal handler to receive
+ * notifications about track list changes
+ */
+ g_list_foreach (mixers, (GFunc) _xfce_mixer_init_mixer, NULL);
}
}
@@ -188,7 +197,6 @@ xfce_mixer_select_card (GstElement *card)
{
g_return_if_fail (GST_IS_MIXER (card));
- gst_element_set_bus (card, bus);
selected_card = card;
}
@@ -361,6 +369,7 @@ void
xfce_mixer_bus_disconnect (guint signal_handler_id)
{
g_return_if_fail (refcount > 0);
+
if (signal_handler_id != 0)
g_signal_handler_disconnect (bus, signal_handler_id);
}
@@ -478,14 +487,44 @@ _xfce_mixer_add_track_labels (gpointer data,
static void
+_xfce_mixer_init_mixer (gpointer data,
+ gpointer user_data)
+{
+ GstMixer *card = GST_MIXER (data);
+
+ /* Add custom labels to all tracks */
+ _xfce_mixer_add_track_labels (card, NULL);
+
+ /* Add bus to every card and connect to internal signal handler */
+ gst_element_set_bus (GST_ELEMENT (card), bus);
+ g_signal_connect (bus, "message::element", G_CALLBACK (_xfce_mixer_bus_message), NULL);
+}
+
+
+
+static void
_xfce_mixer_destroy_mixer (GstMixer *mixer)
{
+ g_signal_handlers_disconnect_by_func (bus, _xfce_mixer_bus_message, NULL);
+
gst_element_set_state (GST_ELEMENT (mixer), GST_STATE_NULL);
gst_object_unref (GST_OBJECT (mixer));
}
+static void
+_xfce_mixer_bus_message (GstBus *bus,
+ GstMessage *message,
+ gpointer user_data)
+{
+ /* Add labels in case the tracks have changed */
+ if (gst_mixer_message_get_type (message) == GST_MIXER_MESSAGE_MIXER_CHANGED)
+ _xfce_mixer_add_track_labels (GST_MIXER (GST_MESSAGE_SRC (message)), NULL);
+}
+
+
+
int
xfce_mixer_utf8_cmp (const gchar *s1, const gchar *s2)
{
diff --git a/libxfce4mixer/xfce-mixer-track-combo.c b/libxfce4mixer/xfce-mixer-track-combo.c
index 15fafcc..d0c52d1 100644
--- a/libxfce4mixer/xfce-mixer-track-combo.c
+++ b/libxfce4mixer/xfce-mixer-track-combo.c
@@ -53,10 +53,14 @@ static guint combo_signals[LAST_SIGNAL];
-static void xfce_mixer_track_combo_class_init (XfceMixerTrackComboClass *klass);
-static void xfce_mixer_track_combo_init (XfceMixerTrackCombo *combo);
-static void xfce_mixer_track_combo_finalize (GObject *object);
-static void xfce_mixer_track_combo_changed (XfceMixerTrackCombo *combo);
+static void xfce_mixer_track_combo_class_init (XfceMixerTrackComboClass *klass);
+static void xfce_mixer_track_combo_init (XfceMixerTrackCombo *combo);
+static void xfce_mixer_track_combo_finalize (GObject *object);
+static void xfce_mixer_track_combo_update_track_list (XfceMixerTrackCombo *combo);
+static void xfce_mixer_track_combo_bus_message (GstBus *bus,
+ GstMessage *message,
+ XfceMixerTrackCombo *combo);
+static void xfce_mixer_track_combo_changed (XfceMixerTrackCombo *combo);
@@ -73,6 +77,7 @@ struct _XfceMixerTrackCombo
GstElement *card;
GstMixerTrack *track;
+ guint signal_handler_id;
};
@@ -140,6 +145,8 @@ xfce_mixer_track_combo_init (XfceMixerTrackCombo *combo)
{
GtkCellRenderer *renderer;
+ combo->signal_handler_id = xfce_mixer_bus_connect (G_CALLBACK (xfce_mixer_track_combo_bus_message), combo);
+
combo->card = NULL;
combo->list_store = gtk_list_store_new (2, G_TYPE_STRING, GST_TYPE_MIXER_TRACK);
@@ -159,6 +166,12 @@ xfce_mixer_track_combo_finalize (GObject *object)
{
XfceMixerTrackCombo *combo = XFCE_MIXER_TRACK_COMBO (object);
+ if (combo->signal_handler_id > 0)
+ {
+ xfce_mixer_bus_disconnect (combo->signal_handler_id);
+ combo->signal_handler_id = 0;
+ }
+
gtk_list_store_clear (combo->list_store);
g_object_unref (combo->list_store);
@@ -185,9 +198,8 @@ xfce_mixer_track_combo_new (GstElement *card,
-void
-xfce_mixer_track_combo_set_soundcard (XfceMixerTrackCombo *combo,
- GstElement *card)
+static void
+xfce_mixer_track_combo_update_track_list (XfceMixerTrackCombo *combo)
{
XfceMixerTrackType type;
GtkTreeIter tree_iter;
@@ -197,18 +209,7 @@ xfce_mixer_track_combo_set_soundcard (XfceMixerTrackCombo *combo,
GstMixerTrack *track;
GstMixerTrack *track_new;
- g_return_if_fail (IS_XFCE_MIXER_TRACK_COMBO (combo));
-
- /* Remember card. If the card is invalid, use the first one available */
- if (GST_IS_MIXER (card))
- combo->card = card;
- else
- {
- card = xfce_mixer_get_default_card ();
-
- if (GST_IS_MIXER (card))
- combo->card = card;
- }
+ g_return_if_fail (GST_IS_MIXER (combo->card));
/* Try to re-use the current track */
track = xfce_mixer_track_combo_get_active_track (combo);
@@ -244,6 +245,30 @@ xfce_mixer_track_combo_set_soundcard (XfceMixerTrackCombo *combo,
+void
+xfce_mixer_track_combo_set_soundcard (XfceMixerTrackCombo *combo,
+ GstElement *card)
+{
+ g_return_if_fail (IS_XFCE_MIXER_TRACK_COMBO (combo));
+
+ /* Remember card. If the card is invalid, use the first one available */
+ if (GST_IS_MIXER (card))
+ combo->card = card;
+ else
+ {
+ card = xfce_mixer_get_default_card ();
+
+ if (GST_IS_MIXER (card))
+ combo->card = card;
+ else
+ return;
+ }
+
+ xfce_mixer_track_combo_update_track_list (combo);
+}
+
+
+
static void
xfce_mixer_track_combo_changed (XfceMixerTrackCombo *combo)
{
@@ -308,3 +333,18 @@ xfce_mixer_track_combo_set_active_track (XfceMixerTrackCombo *combo,
else
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
}
+
+
+
+static void
+xfce_mixer_track_combo_bus_message (GstBus *bus,
+ GstMessage *message,
+ XfceMixerTrackCombo *combo)
+{
+ if (!GST_IS_MIXER (combo->card) || GST_MESSAGE_SRC (message) != GST_OBJECT (combo->card))
+ return;
+
+ /* Rebuild track list if the tracks for this card have changed */
+ if (gst_mixer_message_get_type (message) == GST_MIXER_MESSAGE_MIXER_CHANGED)
+ xfce_mixer_track_combo_update_track_list (combo);
+}
diff --git a/panel-plugin/xfce-mixer-plugin.c b/panel-plugin/xfce-mixer-plugin.c
index 5b8ee60..57b227f 100644
--- a/panel-plugin/xfce-mixer-plugin.c
+++ b/panel-plugin/xfce-mixer-plugin.c
@@ -780,10 +780,10 @@ xfce_mixer_plugin_bus_message (GstBus *bus,
GstMessage *message,
XfceMixerPlugin *mixer_plugin)
{
- GstMixerTrack *track = NULL;
- gboolean mute;
- gboolean record;
- const gchar *label;
+ GstMixerTrack *track = NULL;
+ gboolean mute;
+ gboolean record;
+ const gchar *label;
/* Don't do anything if GstBus messages are to be ignored */
if (G_UNLIKELY (mixer_plugin->ignore_bus_messages))
@@ -833,6 +833,15 @@ xfce_mixer_plugin_bus_message (GstBus *bus,
}
break;
+ case GST_MIXER_MESSAGE_MIXER_CHANGED:
+ /*
+ * If the mixer tracks have changed, try to keep the current track by
+ * selecting a track based on the current track name; if there is no
+ * track with such name any more, the property setter will handle the
+ * situation in a sane way
+ */
+ g_object_set (mixer_plugin, "track", mixer_plugin->track_label, NULL);
+ break;
default:
break;
}
diff --git a/xfce4-mixer/xfce-mixer-controls-dialog.c b/xfce4-mixer/xfce-mixer-controls-dialog.c
index 9b2fbff..716abd5 100644
--- a/xfce4-mixer/xfce-mixer-controls-dialog.c
+++ b/xfce4-mixer/xfce-mixer-controls-dialog.c
@@ -53,6 +53,9 @@ static void xfce_mixer_controls_dialog_update_preferences (XfceMixerControls
static void xfce_mixer_controls_dialog_control_toggled (GtkCellRendererToggle *renderer,
gchar *path,
XfceMixerControlsDialog *dialog);
+static void xfce_mixer_controls_dialog_bus_message (GstBus *bus,
+ GstMessage *message,
+ XfceMixerControlsDialog *dialog);
@@ -68,6 +71,7 @@ struct _XfceMixerControlsDialog
XfceMixerWindow *parent;
XfceMixerPreferences *preferences;
GstElement *card;
+ guint signal_handler_id;
GtkWidget *frame;
GtkListStore *store;
@@ -134,6 +138,8 @@ xfce_mixer_controls_dialog_init (XfceMixerControlsDialog *dialog)
dialog->preferences = xfce_mixer_preferences_get ();
+ dialog->signal_handler_id = xfce_mixer_bus_connect (G_CALLBACK (xfce_mixer_controls_dialog_bus_message), dialog);
+
dialog->card = NULL;
dialog->frame = NULL;
@@ -164,6 +170,12 @@ xfce_mixer_controls_dialog_finalize (GObject *object)
{
XfceMixerControlsDialog *dialog = XFCE_MIXER_CONTROLS_DIALOG (object);
+ if (dialog->signal_handler_id > 0)
+ {
+ xfce_mixer_bus_disconnect (dialog->signal_handler_id);
+ dialog->signal_handler_id = 0;
+ }
+
g_object_unref (G_OBJECT (dialog->preferences));
(*G_OBJECT_CLASS (xfce_mixer_controls_dialog_parent_class)->finalize) (object);
@@ -241,6 +253,17 @@ xfce_mixer_controls_dialog_create_contents (XfceMixerControlsDialog *dialog)
+static void
+xfce_mixer_controls_dialog_update_contents (XfceMixerControlsDialog *dialog)
+{
+ g_return_if_fail (IS_XFCE_MIXER_CONTROLS_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog->frame);
+ xfce_mixer_controls_dialog_create_contents (dialog);
+}
+
+
+
void
xfce_mixer_controls_dialog_update_dialog (XfceMixerControlsDialog *dialog)
{
@@ -350,7 +373,20 @@ xfce_mixer_controls_dialog_set_soundcard (XfceMixerControlsDialog *dialog,
dialog->card = card;
/* Recreate contents corresponding to the new card */
- gtk_widget_destroy (dialog->frame);
- xfce_mixer_controls_dialog_create_contents (dialog);
+ xfce_mixer_controls_dialog_update_contents (dialog);
}
+
+
+static void
+xfce_mixer_controls_dialog_bus_message (GstBus *bus,
+ GstMessage *message,
+ XfceMixerControlsDialog *dialog)
+{
+ if (!GST_IS_MIXER (dialog->card) || GST_MESSAGE_SRC (message) != GST_OBJECT (dialog->card))
+ return;
+
+ /* Rebuild track list if the tracks for this card have changed */
+ if (gst_mixer_message_get_type (message) == GST_MIXER_MESSAGE_MIXER_CHANGED)
+ xfce_mixer_controls_dialog_update_contents (dialog);
+}
diff --git a/xfce4-mixer/xfce-mixer-window.c b/xfce4-mixer/xfce-mixer-window.c
index a21afd6..f8dec5b 100644
--- a/xfce4-mixer/xfce-mixer-window.c
+++ b/xfce4-mixer/xfce-mixer-window.c
@@ -168,8 +168,6 @@ xfce_mixer_window_init (XfceMixerWindow *window)
gint width;
gint height;
- window->mixer = NULL;
-
window->controls_dialog = NULL;
window->preferences = xfce_mixer_preferences_get ();
@@ -242,6 +240,10 @@ xfce_mixer_window_init (XfceMixerWindow *window)
gtk_container_add (GTK_CONTAINER (vbox), window->mixer_frame);
gtk_widget_show (window->mixer_frame);
+ window->mixer = xfce_mixer_new (NULL);
+ gtk_container_add (GTK_CONTAINER (window->mixer_frame), window->mixer);
+ gtk_widget_show (window->mixer);
+
bbox = gtk_dialog_get_action_area (GTK_DIALOG (window));
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_EDGE);
gtk_container_set_border_width (GTK_CONTAINER (bbox), 6);
@@ -266,7 +268,7 @@ xfce_mixer_window_init (XfceMixerWindow *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 */
+ /* Update mixer controls for the active sound card */
xfce_mixer_window_update_contents (window);
}
@@ -314,7 +316,7 @@ xfce_mixer_window_soundcard_changed (XfceMixerCardCombo *combo,
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), G_CALLBACK (xfce_mixer_window_soundcard_property_changed), window);
- /* Re-generate mixer controls for the active sound card */
+ /* Update mixer controls for the active sound card */
xfce_mixer_window_update_contents (window);
/* Update the controls dialog */
@@ -362,7 +364,7 @@ xfce_mixer_window_soundcard_property_changed (XfceMixerWindow *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), G_CALLBACK (xfce_mixer_window_soundcard_changed), window);
- /* Re-generate mixer controls for the active sound card */
+ /* Update mixer controls for the active sound card */
xfce_mixer_window_update_contents (window);
/* Update the controls dialog */
@@ -393,7 +395,7 @@ xfce_mixer_window_controls_property_changed (XfceMixerWindow *window,
GParamSpec *pspec,
GObject *object)
{
- xfce_mixer_window_update_contents (window);
+ xfce_mixer_update_contents (XFCE_MIXER (window->mixer));
/* Update the controls dialog */
if (window->controls_dialog != NULL)
@@ -448,27 +450,28 @@ xfce_mixer_window_update_contents (XfceMixerWindow *window)
g_return_if_fail (IS_XFCE_MIXER_WINDOW (window));
card = xfce_mixer_card_combo_get_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo));
+ if (G_LIKELY (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);
- 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);
- xfce_mixer_select_card (card);
+ /* Update the XfceMixer containing the controls */
+ g_object_set (window->mixer, "card", card, NULL);
- /* Create a new XfceMixer for the active sound card */
- window->mixer = xfce_mixer_new (card);
+ /* Make the "Select Controls..." button sensitive */
+ gtk_widget_set_sensitive (window->select_controls_button, TRUE);
+ }
+ else
+ {
+ gtk_window_set_title (GTK_WINDOW (window), _("Audio Mixer"));
- /* Add the XfceMixer to the window */
- gtk_container_add (GTK_CONTAINER (window->mixer_frame), window->mixer);
- gtk_widget_show (window->mixer);
+ /* Update the XfceMixer containing the controls */
+ g_object_set (window->mixer, "card", NULL, NULL);
- /* Make the "Select Controls..." button sensitive */
- gtk_widget_set_sensitive (window->select_controls_button, TRUE);
+ /* Make the "Select Controls..." button insensitive */
+ gtk_widget_set_sensitive (window->select_controls_button, FALSE);
+ }
}
diff --git a/xfce4-mixer/xfce-mixer.c b/xfce4-mixer/xfce-mixer.c
index 773f27b..dd6f5f6 100644
--- a/xfce4-mixer/xfce-mixer.c
+++ b/xfce4-mixer/xfce-mixer.c
@@ -58,6 +58,7 @@ static void xfce_mixer_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
+static void xfce_mixer_create_contents (XfceMixer *mixer);
static void xfce_mixer_bus_message (GstBus *bus,
GstMessage *message,
XfceMixer *mixer);
@@ -135,8 +136,7 @@ xfce_mixer_class_init (XfceMixerClass *klass)
"card",
"card",
GST_TYPE_ELEMENT,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE));
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
}
@@ -144,6 +144,7 @@ xfce_mixer_class_init (XfceMixerClass *klass)
static void
xfce_mixer_instance_init (XfceMixer *mixer)
{
+ mixer->card = NULL;
mixer->widgets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
mixer->message_handler_id = 0;
}
@@ -153,7 +154,95 @@ xfce_mixer_instance_init (XfceMixer *mixer)
static void
xfce_mixer_constructed (GObject *object)
{
- XfceMixer *mixer = XFCE_MIXER (object);
+ XfceMixer *mixer = XFCE_MIXER (object);
+
+ /* Create the content */
+ xfce_mixer_create_contents (XFCE_MIXER (mixer));
+
+ mixer->message_handler_id = xfce_mixer_bus_connect (G_CALLBACK (xfce_mixer_bus_message), mixer);
+}
+
+
+
+static void
+xfce_mixer_finalize (GObject *object)
+{
+ XfceMixer *mixer = XFCE_MIXER (object);
+
+ xfce_mixer_bus_disconnect (mixer->message_handler_id);
+
+ g_object_unref (mixer->card);
+ g_hash_table_unref (mixer->widgets);
+
+ (*G_OBJECT_CLASS (xfce_mixer_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_mixer_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ XfceMixer *mixer = XFCE_MIXER (object);
+
+ switch (prop_id)
+ {
+ case PROP_CARD:
+ g_value_set_object (value, mixer->card);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+xfce_mixer_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ XfceMixer *mixer = XFCE_MIXER (object);
+
+ switch (prop_id)
+ {
+ case PROP_CARD:
+ if (mixer->message_handler_id != 0)
+ xfce_mixer_bus_disconnect (mixer->message_handler_id);
+ mixer->card = g_value_dup_object (value);
+ xfce_mixer_update_contents (mixer);
+ if (GST_IS_MIXER (mixer->card))
+ mixer->message_handler_id = xfce_mixer_bus_connect (G_CALLBACK (xfce_mixer_bus_message), mixer);
+ else
+ mixer->message_handler_id = 0;
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+GtkWidget *
+xfce_mixer_new (GstElement *card)
+{
+ GObject *object = NULL;
+
+ object = g_object_new (TYPE_XFCE_MIXER, "card", card, NULL);
+
+ return GTK_WIDGET (object);
+}
+
+
+
+static void
+xfce_mixer_create_contents (XfceMixer *mixer)
+{
XfceMixerPreferences *preferences;
XfceMixerTrackType type;
GstMixerTrack *track;
@@ -168,9 +257,10 @@ xfce_mixer_constructed (GObject *object)
GtkWidget *label2;
const gchar *track_label;
guint num_children[4] = { 0, 0, 0, 0 };
+ gboolean no_controls_visible = TRUE;
gint i;
- g_hash_table_remove_all (mixer->widgets);
+ g_return_if_fail (IS_XFCE_MIXER (mixer));
preferences = xfce_mixer_preferences_get ();
@@ -200,77 +290,82 @@ xfce_mixer_constructed (GObject *object)
}
/* Create controls for all mixer tracks */
- for (iter = gst_mixer_list_tracks (GST_MIXER (mixer->card)); iter != NULL; iter = g_list_next (iter))
+ if (GST_IS_MIXER (mixer->card))
{
- track = GST_MIXER_TRACK (iter->data);
-
- track_label = xfce_mixer_get_track_label (track);
-
- if (!xfce_mixer_preferences_get_control_visible (preferences, track_label))
- continue;
-
- /* Determine the type of the mixer track */
- type = xfce_mixer_track_type_new (track);
-
- switch (type)
+ for (iter = gst_mixer_list_tracks (GST_MIXER (mixer->card)); iter != NULL; iter = g_list_next (iter))
{
- case XFCE_MIXER_TRACK_TYPE_PLAYBACK:
- /* Create a regular volume control for this track */
- track_widget = xfce_mixer_track_new (mixer->card, track);
- gtk_table_attach (GTK_TABLE (views[0]), track_widget,
- num_children[0], num_children[0] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
- gtk_widget_show (track_widget);
- num_children[0]++;
-
- /* Append a separator. The last one will be destroyed later */
- last_separator[0] = gtk_vseparator_new ();
- gtk_table_attach (GTK_TABLE (views[0]), last_separator[0],
- num_children[0], num_children[0] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
- gtk_widget_show (last_separator[0]);
- num_children[0]++;
-
- /* Add the track to the hash table */
- g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
- break;
-
- case XFCE_MIXER_TRACK_TYPE_CAPTURE:
- /* Create a regular volume control for this track */
- track_widget = xfce_mixer_track_new (mixer->card, track);
- gtk_table_attach (GTK_TABLE (views[1]), track_widget,
- num_children[1], num_children[1] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
- gtk_widget_show (track_widget);
- num_children[1]++;
-
- /* Append a separator. The last one will be destroyed later */
- last_separator[1] = gtk_vseparator_new ();
- gtk_table_attach (GTK_TABLE (views[1]), last_separator[1],
- num_children[1], num_children[1] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
- gtk_widget_show (last_separator[1]);
- num_children[1]++;
-
- /* Add the track to the hash table */
- g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
- break;
-
- case XFCE_MIXER_TRACK_TYPE_SWITCH:
- track_widget = xfce_mixer_switch_new (mixer->card, track);
- gtk_box_pack_start (GTK_BOX (views[2]), track_widget, FALSE, FALSE, 0);
- gtk_widget_show (track_widget);
- num_children[2]++;
-
- /* Add the track to the hash table */
- g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
- break;
-
- case XFCE_MIXER_TRACK_TYPE_OPTIONS:
- track_widget = xfce_mixer_option_new (mixer->card, track);
- gtk_box_pack_start (GTK_BOX (views[3]), track_widget, FALSE, FALSE, 0);
- gtk_widget_show (track_widget);
- num_children[3]++;
-
- /* Add the track to the hash table */
- g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
- break;
+ track = GST_MIXER_TRACK (iter->data);
+
+ track_label = xfce_mixer_get_track_label (track);
+
+ if (!xfce_mixer_preferences_get_control_visible (preferences, track_label))
+ continue;
+
+ /* Determine the type of the mixer track */
+ type = xfce_mixer_track_type_new (track);
+
+ switch (type)
+ {
+ case XFCE_MIXER_TRACK_TYPE_PLAYBACK:
+ /* Create a regular volume control for this track */
+ track_widget = xfce_mixer_track_new (mixer->card, track);
+ gtk_table_attach (GTK_TABLE (views[0]), track_widget,
+ num_children[0], num_children[0] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_widget_show (track_widget);
+ num_children[0]++;
+
+ /* Append a separator. The last one will be destroyed later */
+ last_separator[0] = gtk_vseparator_new ();
+ gtk_table_attach (GTK_TABLE (views[0]), last_separator[0],
+ num_children[0], num_children[0] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_widget_show (last_separator[0]);
+ num_children[0]++;
+
+ /* Add the track to the hash table */
+ g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
+ break;
+
+ case XFCE_MIXER_TRACK_TYPE_CAPTURE:
+ /* Create a regular volume control for this track */
+ track_widget = xfce_mixer_track_new (mixer->card, track);
+ gtk_table_attach (GTK_TABLE (views[1]), track_widget,
+ num_children[1], num_children[1] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_widget_show (track_widget);
+ num_children[1]++;
+
+ /* Append a separator. The last one will be destroyed later */
+ last_separator[1] = gtk_vseparator_new ();
+ gtk_table_attach (GTK_TABLE (views[1]), last_separator[1],
+ num_children[1], num_children[1] + 1, 0, 1, GTK_SHRINK, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_widget_show (last_separator[1]);
+ num_children[1]++;
+
+ /* Add the track to the hash table */
+ g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
+ break;
+
+ case XFCE_MIXER_TRACK_TYPE_SWITCH:
+ track_widget = xfce_mixer_switch_new (mixer->card, track);
+ gtk_box_pack_start (GTK_BOX (views[2]), track_widget, FALSE, FALSE, 0);
+ gtk_widget_show (track_widget);
+ num_children[2]++;
+
+ /* Add the track to the hash table */
+ g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
+ break;
+
+ case XFCE_MIXER_TRACK_TYPE_OPTIONS:
+ track_widget = xfce_mixer_option_new (mixer->card, track);
+ gtk_box_pack_start (GTK_BOX (views[3]), track_widget, FALSE, FALSE, 0);
+ gtk_widget_show (track_widget);
+ num_children[3]++;
+
+ /* Add the track to the hash table */
+ g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
+ break;
+ default:
+ break;
+ }
}
}
@@ -281,21 +376,17 @@ xfce_mixer_constructed (GObject *object)
if (G_LIKELY (last_separator[i] != NULL))
gtk_widget_destroy (last_separator[i]);
- /* Check if there are controls at all for this tab */
- if (G_LIKELY (num_children[i] > 0))
- {
- /* If there are controls, create the notebook tab */
- gtk_notebook_append_page (GTK_NOTEBOOK (mixer), scrollwins[i], labels[i]);
- }
+ gtk_notebook_append_page (GTK_NOTEBOOK (mixer), scrollwins[i], labels[i]);
+
+ /* Hide tabs with no visible controls */
+ if (num_children[i] > 0)
+ no_controls_visible = FALSE;
else
- {
- /* Otherwise, destroy all created widgets */
- gtk_widget_destroy (labels[i]);
- gtk_widget_destroy (scrollwins[i]);
- }
+ gtk_widget_hide (gtk_notebook_get_nth_page (GTK_NOTEBOOK (mixer), i));
}
- if (G_UNLIKELY (gtk_notebook_get_n_pages (GTK_NOTEBOOK (mixer)) == 0))
+ /* Show informational message if no controls are visible */
+ if (G_UNLIKELY (no_controls_visible))
{
label1 = gtk_label_new (_("No controls visible"));
gtk_widget_show (label1);
@@ -308,80 +399,35 @@ xfce_mixer_constructed (GObject *object)
gtk_notebook_append_page (GTK_NOTEBOOK (mixer), label2, label1);
}
- mixer->message_handler_id = xfce_mixer_bus_connect (G_CALLBACK (xfce_mixer_bus_message), mixer);
-
g_object_unref (preferences);
}
-static void
-xfce_mixer_finalize (GObject *object)
+void
+xfce_mixer_update_contents (XfceMixer *mixer)
{
- XfceMixer *mixer = XFCE_MIXER (object);
-
- xfce_mixer_bus_disconnect (mixer->message_handler_id);
+ gint current_tab;
+ gint i;
- g_object_unref (mixer->card);
- g_hash_table_unref (mixer->widgets);
-
- (*G_OBJECT_CLASS (xfce_mixer_parent_class)->finalize) (object);
-}
-
-
-
-static void
-xfce_mixer_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- XfceMixer *mixer = XFCE_MIXER (object);
-
- switch (prop_id)
- {
- case PROP_CARD:
- g_value_set_object (value, mixer->card);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static void
-xfce_mixer_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- XfceMixer *mixer = XFCE_MIXER (object);
-
- switch (prop_id)
- {
- case PROP_CARD:
- mixer->card = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
+ g_return_if_fail (IS_XFCE_MIXER (mixer));
+ g_return_if_fail (mixer->widgets != NULL);
+ g_hash_table_remove_all (mixer->widgets);
+ /* Remember active tab */
+ current_tab = gtk_notebook_get_current_page (GTK_NOTEBOOK (mixer));
-GtkWidget *
-xfce_mixer_new (GstElement *card)
-{
- GObject *object = NULL;
+ /* Destroy all tabs */
+ for (i = gtk_notebook_get_n_pages (GTK_NOTEBOOK (mixer)); i >= 0; i--)
+ gtk_notebook_remove_page (GTK_NOTEBOOK (mixer), i);
- g_return_val_if_fail (GST_IS_MIXER (card), NULL);
-
- object = g_object_new (TYPE_XFCE_MIXER, "card", card, NULL);
+ /* Re-create contents */
+ xfce_mixer_create_contents (mixer);
- return GTK_WIDGET (object);
+ /* Restore previously active tab if possible */
+ if (current_tab > 0 && current_tab < 4)
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (mixer), current_tab);
}
@@ -391,7 +437,6 @@ xfce_mixer_bus_message (GstBus *bus,
GstMessage *message,
XfceMixer *mixer)
{
- GstMixerMessageType type;
GstMixerOptions *options = NULL;
GstMixerTrack *track = NULL;
GtkWidget *widget;
@@ -407,50 +452,53 @@ xfce_mixer_bus_message (GstBus *bus,
if (G_UNLIKELY (GST_MESSAGE_SRC (message) != GST_OBJECT (mixer->card)))
return;
- type = gst_mixer_message_get_type (message);
-
- if (type == GST_MIXER_MESSAGE_MUTE_TOGGLED)
- {
- gst_mixer_message_parse_mute_toggled (message, &track, &muted);
- label = xfce_mixer_get_track_label (track);
- xfce_mixer_debug ("Track '%s' was %s", label, muted ? "muted" : "unmuted");
- widget = g_hash_table_lookup (mixer->widgets, label);
-
- if (IS_XFCE_MIXER_TRACK (widget))
- xfce_mixer_track_update_mute (XFCE_MIXER_TRACK (widget));
- else if (IS_XFCE_MIXER_SWITCH (widget))
- xfce_mixer_switch_update (XFCE_MIXER_SWITCH (widget));
- }
- else if (type == GST_MIXER_MESSAGE_RECORD_TOGGLED)
- {
- gst_mixer_message_parse_record_toggled (message, &track, &record);
- label = xfce_mixer_get_track_label (track);
- xfce_mixer_debug ("Recording on track '%s' was %s", label, record ? "turned on" : "turned off");
- widget = g_hash_table_lookup (mixer->widgets, label);
-
- if (IS_XFCE_MIXER_TRACK (widget))
- xfce_mixer_track_update_record (XFCE_MIXER_TRACK (widget));
- else if (IS_XFCE_MIXER_SWITCH (widget))
- xfce_mixer_switch_update (XFCE_MIXER_SWITCH (widget));
- }
- else if (type == GST_MIXER_MESSAGE_VOLUME_CHANGED)
- {
- gst_mixer_message_parse_volume_changed (message, &track, &volumes, &num_channels);
- label = xfce_mixer_get_track_label (track);
- xfce_mixer_debug ("Volume on track '%s' changed to %i", label, volumes[0]);
- widget = g_hash_table_lookup (mixer->widgets, label);
-
- if (IS_XFCE_MIXER_TRACK (widget))
- xfce_mixer_track_update_volume (XFCE_MIXER_TRACK (widget));
- }
- else if (type == GST_MIXER_MESSAGE_OPTION_CHANGED)
+ switch (gst_mixer_message_get_type (message))
{
- gst_mixer_message_parse_option_changed (message, &options, &option);
- label = xfce_mixer_get_track_label (GST_MIXER_TRACK (options));
- xfce_mixer_debug ("Option '%s' was set to '%s'", label, option);
- widget = g_hash_table_lookup (mixer->widgets, label);
-
- if (IS_XFCE_MIXER_OPTION (widget))
- xfce_mixer_option_update (XFCE_MIXER_OPTION (widget));
+ case GST_MIXER_MESSAGE_MUTE_TOGGLED:
+ gst_mixer_message_parse_mute_toggled (message, &track, &muted);
+ label = xfce_mixer_get_track_label (track);
+ xfce_mixer_debug ("Track '%s' was %s", label, muted ? "muted" : "unmuted");
+ widget = g_hash_table_lookup (mixer->widgets, label);
+
+ if (IS_XFCE_MIXER_TRACK (widget))
+ xfce_mixer_track_update_mute (XFCE_MIXER_TRACK (widget));
+ else if (IS_XFCE_MIXER_SWITCH (widget))
+ xfce_mixer_switch_update (XFCE_MIXER_SWITCH (widget));
+ break;
+ case GST_MIXER_MESSAGE_RECORD_TOGGLED:
+ gst_mixer_message_parse_record_toggled (message, &track, &record);
+ label = xfce_mixer_get_track_label (track);
+ xfce_mixer_debug ("Recording on track '%s' was %s", label, record ? "turned on" : "turned off");
+ widget = g_hash_table_lookup (mixer->widgets, label);
+
+ if (IS_XFCE_MIXER_TRACK (widget))
+ xfce_mixer_track_update_record (XFCE_MIXER_TRACK (widget));
+ else if (IS_XFCE_MIXER_SWITCH (widget))
+ xfce_mixer_switch_update (XFCE_MIXER_SWITCH (widget));
+ break;
+ case GST_MIXER_MESSAGE_VOLUME_CHANGED:
+ gst_mixer_message_parse_volume_changed (message, &track, &volumes, &num_channels);
+ label = xfce_mixer_get_track_label (track);
+ xfce_mixer_debug ("Volume on track '%s' changed to %i", label, volumes[0]);
+ widget = g_hash_table_lookup (mixer->widgets, label);
+
+ if (IS_XFCE_MIXER_TRACK (widget))
+ xfce_mixer_track_update_volume (XFCE_MIXER_TRACK (widget));
+ break;
+ case GST_MIXER_MESSAGE_OPTION_CHANGED:
+ gst_mixer_message_parse_option_changed (message, &options, &option);
+ label = xfce_mixer_get_track_label (GST_MIXER_TRACK (options));
+ xfce_mixer_debug ("Option '%s' was set to '%s'", label, option);
+ widget = g_hash_table_lookup (mixer->widgets, label);
+
+ if (IS_XFCE_MIXER_OPTION (widget))
+ xfce_mixer_option_update (XFCE_MIXER_OPTION (widget));
+ break;
+ case GST_MIXER_MESSAGE_MIXER_CHANGED:
+ xfce_mixer_debug ("Mixer tracks have changed");
+ xfce_mixer_update_contents (mixer);
+ break;
+ default:
+ break;
}
}
diff --git a/xfce4-mixer/xfce-mixer.h b/xfce4-mixer/xfce-mixer.h
index 00186fa..2aeab9e 100644
--- a/xfce4-mixer/xfce-mixer.h
+++ b/xfce4-mixer/xfce-mixer.h
@@ -1,6 +1,7 @@
/* vi:set expandtab sw=2 sts=2: */
/*-
* Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012 Guido Berhoerster <guido+xfce at 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
@@ -38,7 +39,8 @@ typedef struct _XfceMixer XfceMixer;
GType xfce_mixer_get_type (void) G_GNUC_CONST;
-GtkWidget *xfce_mixer_new (GstElement *card);
+GtkWidget *xfce_mixer_new (GstElement *card);
+void xfce_mixer_update_contents (XfceMixer *mixer);
G_END_DECLS;
More information about the Xfce4-commits
mailing list