[Xfce4-commits] r27092 - in xfce4-mixer/trunk: . libxfce4mixer panel-plugin xfce4-mixer

Jannis Pohlmann jannis at xfce.org
Sat Jun 21 02:10:07 CEST 2008


Author: jannis
Date: 2008-06-21 00:10:07 +0000 (Sat, 21 Jun 2008)
New Revision: 27092

Added:
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.c
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.h
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.c
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.h
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.c
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.h
   xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.c
   xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.h
Modified:
   xfce4-mixer/trunk/ChangeLog
   xfce4-mixer/trunk/libxfce4mixer/Makefile.am
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.c
   xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.h
   xfce4-mixer/trunk/panel-plugin/Makefile.am
   xfce4-mixer/trunk/panel-plugin/xfce-mixer-plugin.c
   xfce4-mixer/trunk/panel-plugin/xfce-volume-button.c
   xfce4-mixer/trunk/panel-plugin/xfce-volume-button.h
   xfce4-mixer/trunk/xfce4-mixer/xfce-mixer-window.c
Log:
	* libxfce4mixer/Makefile.am,
	  libxfce4mixer/xfce-mixer-card-combo.{c,h},
	  libxfce4mixer/xfce-mixer-track-combo.{c,h},
	  libxfce4mixer/xfce-mixer-utilities.{c,h}:
	  Add subclasses of GtkComboBox for unified selection of
	  sound cards and mixer tracks. Add convenience functions for
	  getting a list of available sound cards and getting sound
	  cards by name.
	* panel-plugin/Makefile.am,
	  panel-plugin/xfce-mixer-plugin.{c,h},
	  panel-plugin/xfce-plugin-dialog.{c,h},
	  panel-plugin/xfce-volume-button.{c,h}:
	  Implement the properties dialog of the plugin. By now it
	  makes it possible to select which sound card and mixer track
	  to use. Also connect the plugin to GStreamer, so it actually
	  does something. Add support for reading/writing the plugin
	  configuration to the rc file. The volume button itself has
	  some focus grabbing problems: sometimes other windows don't
	  receive the focus even when the pointer leaves the button.
	* xfce4-mixer/xfce-mixer-window.c: Move the _load_soundcards
	  method to the libxfce4mixer. Make use of the new
	  XfceMixerCardCombo in XfceMixerWindow.


Modified: xfce4-mixer/trunk/ChangeLog
===================================================================
--- xfce4-mixer/trunk/ChangeLog	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/ChangeLog	2008-06-21 00:10:07 UTC (rev 27092)
@@ -1,3 +1,28 @@
+2008-06-21	Jannis Pohlmann <jannis at xfce.org>
+
+	* libxfce4mixer/Makefile.am, 
+	  libxfce4mixer/xfce-mixer-card-combo.{c,h},
+	  libxfce4mixer/xfce-mixer-track-combo.{c,h}, 
+	  libxfce4mixer/xfce-mixer-utilities.{c,h}:
+	  Add subclasses of GtkComboBox for unified selection of 
+	  sound cards and mixer tracks. Add convenience functions for
+	  getting a list of available sound cards and getting sound
+	  cards by name. 
+	* panel-plugin/Makefile.am,
+	  panel-plugin/xfce-mixer-plugin.{c,h},
+	  panel-plugin/xfce-plugin-dialog.{c,h},
+	  panel-plugin/xfce-volume-button.{c,h}:
+	  Implement the properties dialog of the plugin. By now it 
+	  makes it possible to select which sound card and mixer track
+	  to use. Also connect the plugin to GStreamer, so it actually 
+	  does something. Add support for reading/writing the plugin 
+	  configuration to the rc file. The volume button itself has
+	  some focus grabbing problems: sometimes other windows don't
+	  receive the focus even when the pointer leaves the button.
+	* xfce4-mixer/xfce-mixer-window.c: Move the _load_soundcards 
+	  method to the libxfce4mixer. Make use of the new 
+	  XfceMixerCardCombo in XfceMixerWindow.
+
 2008-06-19	Jannis Pohlmann <jannis at xfce.org>
 
 	* panel-plugin/xfce-mixer-plugin.c: Try to start "xfce4-mixer" 

Modified: xfce4-mixer/trunk/libxfce4mixer/Makefile.am
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/Makefile.am	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/libxfce4mixer/Makefile.am	2008-06-21 00:10:07 UTC (rev 27092)
@@ -6,12 +6,18 @@
 	libxfce4mixer.la
 
 libxfce4mixer_la_SOURCES =						\
+	xfce-mixer-card-combo.h						\
+	xfce-mixer-card-combo.c						\
+	xfce-mixer-track-combo.h					\
+	xfce-mixer-track-combo.c					\
 	xfce-mixer-card.h						\
 	xfce-mixer-card.c						\
 	xfce-mixer-stock.h						\
 	xfce-mixer-stock.c						\
 	xfce-mixer-track-type.h						\
 	xfce-mixer-track-type.c						\
+	xfce-mixer-utilities.h						\
+	xfce-mixer-utilities.c						\
 	xfce-mixer-preferences.h					\
 	xfce-mixer-preferences.c
 
@@ -29,7 +35,7 @@
 	-no-undefined
 
 libxfce4mixer_la_LIBADD =						\
-	$(PLATFORM_LDFLAGS)
+	$(PLATFORM_LDFLAGS)						\
 	$(GLIB_LIBS)							\
 	$(GTK_FLAGS)							\
 	$(LIBXFCE4UTIL_LIBS)						\

Added: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.c
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.c	                        (rev 0)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,267 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <gst/gst.h>
+
+#include "xfce-mixer-card.h"
+#include "xfce-mixer-card-combo.h"
+
+
+
+#define NAME_COLUMN 0
+#define CARD_COLUMN 1
+
+
+
+enum
+{
+  SOUNDCARD_CHANGED,
+  LAST_SIGNAL,
+};
+
+
+
+static guint combo_signals[LAST_SIGNAL];
+
+
+
+static void xfce_mixer_card_combo_class_init        (XfceMixerCardComboClass *klass);
+static void xfce_mixer_card_combo_init              (XfceMixerCardCombo      *combo);
+static void xfce_mixer_card_combo_dispose           (GObject                 *object);
+static void xfce_mixer_card_combo_finalize          (GObject                 *object);
+static void xfce_mixer_card_combo_load_soundcards   (XfceMixerCardCombo      *combo,
+                                                     const gchar             *card_name);
+static void xfce_mixer_card_combo_soundcard_changed (XfceMixerCardCombo      *combo,
+                                                     XfceMixerCard           *card);
+static void xfce_mixer_card_combo_changed           (XfceMixerCardCombo      *combo);
+
+
+
+struct _XfceMixerCardComboClass
+{
+  GtkComboBoxClass __parent__;
+
+  /* Signals */
+  void (*soundcard_changed) (XfceMixerCardCombo *combo,
+                             XfceMixerCard      *card);
+};
+
+struct _XfceMixerCardCombo
+{
+  GtkComboBox __parent__;
+
+  GtkListStore *model;
+
+  GList        *cards;
+};
+
+
+
+static GObjectClass *xfce_mixer_card_combo_parent_class = NULL;
+
+
+
+GType
+xfce_mixer_card_combo_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info = 
+        {
+          sizeof (XfceMixerCardComboClass),
+          NULL,
+          NULL,
+          (GClassInitFunc) xfce_mixer_card_combo_class_init,
+          NULL,
+          NULL,
+          sizeof (XfceMixerCardCombo),
+          0,
+          (GInstanceInitFunc) xfce_mixer_card_combo_init,
+          NULL,
+        };
+
+      type = g_type_register_static (GTK_TYPE_COMBO_BOX, "XfceMixerCardCombo", &info, 0);
+    }
+  
+  return type;
+}
+
+
+
+static void
+xfce_mixer_card_combo_class_init (XfceMixerCardComboClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine parent type class */
+  xfce_mixer_card_combo_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = xfce_mixer_card_combo_dispose;
+  gobject_class->finalize = xfce_mixer_card_combo_finalize;
+
+  klass->soundcard_changed = xfce_mixer_card_combo_soundcard_changed;
+
+  combo_signals[SOUNDCARD_CHANGED] = g_signal_new ("soundcard-changed",
+                                                   G_TYPE_FROM_CLASS (klass),
+                                                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                                   G_STRUCT_OFFSET (XfceMixerCardComboClass, soundcard_changed),
+                                                   NULL,
+                                                   NULL,
+                                                   g_cclosure_marshal_VOID__OBJECT,
+                                                   G_TYPE_NONE,
+                                                   1,
+                                                   TYPE_XFCE_MIXER_CARD);
+}
+
+
+
+static void
+xfce_mixer_card_combo_init (XfceMixerCardCombo *combo)
+{
+  GtkCellRenderer *renderer;
+
+  combo->model = gtk_list_store_new (2, G_TYPE_STRING, TYPE_XFCE_MIXER_CARD);
+  gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (combo->model));
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+  gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", NAME_COLUMN);
+
+  combo->cards = xfce_mixer_utilities_get_cards ();
+
+  g_signal_connect_swapped (combo, "changed", G_CALLBACK (xfce_mixer_card_combo_changed), combo);
+}
+
+
+
+static void
+xfce_mixer_card_combo_dispose (GObject *object)
+{
+  (*G_OBJECT_CLASS (xfce_mixer_card_combo_parent_class)->dispose) (object);
+}
+
+
+
+static void
+xfce_mixer_card_combo_finalize (GObject *object)
+{
+  XfceMixerCardCombo *combo = XFCE_MIXER_CARD_COMBO (object);
+
+  gtk_list_store_clear (combo->model);
+  g_object_unref (G_OBJECT (combo->model));
+
+  g_list_foreach (combo->cards, (GFunc) g_object_unref, NULL);
+  g_list_free (combo->cards);
+
+  (*G_OBJECT_CLASS (xfce_mixer_card_combo_parent_class)->finalize) (object);
+}
+
+
+
+GtkWidget*
+xfce_mixer_card_combo_new (const gchar *card_name)
+{
+  XfceMixerCardCombo *combo;
+  
+  combo = XFCE_MIXER_CARD_COMBO (g_object_new (TYPE_XFCE_MIXER_CARD_COMBO, NULL));
+
+  xfce_mixer_card_combo_load_soundcards (combo, card_name);
+
+  return GTK_WIDGET (combo);
+}
+
+
+
+static void 
+xfce_mixer_card_combo_load_soundcards (XfceMixerCardCombo *combo,
+                                       const gchar        *card_name)
+{
+  XfceMixerCard *card;
+  GtkTreeIter    iter;
+  GList         *citer;
+  gint           counter;
+  gint           active_index = 0;
+
+  for (citer = g_list_first (combo->cards), counter = 0; citer != NULL; citer = g_list_next (citer), ++counter)
+    {
+      card = XFCE_MIXER_CARD (citer->data);
+
+      g_debug ("Adding sound card: %s", xfce_mixer_card_get_display_name (card));
+
+      gtk_list_store_append (combo->model, &iter);
+      gtk_list_store_set (combo->model, &iter, NAME_COLUMN, xfce_mixer_card_get_display_name (card), CARD_COLUMN, card, -1);
+
+      if (G_UNLIKELY (card_name != NULL && g_utf8_collate (xfce_mixer_card_get_display_name (card), card_name) == 0))
+        active_index = counter;
+    }
+
+  gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active_index);
+}
+
+
+
+static void
+xfce_mixer_card_combo_soundcard_changed (XfceMixerCardCombo *combo,
+                                         XfceMixerCard      *card)
+{
+}
+
+
+
+static void
+xfce_mixer_card_combo_changed (XfceMixerCardCombo *combo)
+{
+  XfceMixerCard *card;
+  GtkTreeIter    iter;
+
+  if (G_LIKELY (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)))
+    {
+      gtk_tree_model_get (GTK_TREE_MODEL (combo->model), &iter, CARD_COLUMN, &card, -1);
+
+      xfce_mixer_card_set_ready (card);
+
+      g_signal_emit_by_name (combo, "soundcard-changed", card);
+    }
+}
+
+
+
+XfceMixerCard*
+xfce_mixer_card_combo_get_active_card (XfceMixerCardCombo *combo)
+{
+  XfceMixerCard *card;
+  GtkTreeIter    iter;
+
+  g_return_val_if_fail (IS_XFCE_MIXER_CARD_COMBO (combo), NULL);
+  
+  if (G_LIKELY (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)))
+    gtk_tree_model_get (GTK_TREE_MODEL (combo->model), &iter, CARD_COLUMN, &card, -1);
+
+  return card;
+}

Added: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.h
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.h	                        (rev 0)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card-combo.h	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,46 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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 __XFCE_MIXER_CARD_COMBO_H__
+#define __XFCE_MIXER_CARD_COMBO_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _XfceMixerCardComboClass XfceMixerCardComboClass;
+typedef struct _XfceMixerCardCombo      XfceMixerCardCombo;
+
+#define TYPE_XFCE_MIXER_CARD_COMBO            (xfce_mixer_card_combo_get_type ())
+#define XFCE_MIXER_CARD_COMBO(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_XFCE_MIXER_CARD_COMBO, XfceMixerCardCombo))
+#define XFCE_MIXER_CARD_COMBO_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_XFCE_MIXER_CARD_COMBO, XfceMixerCardComboClass))
+#define IS_XFCE_MIXER_CARD_COMBO(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_XFCE_MIXER_CARD_COMBO))
+#define IS_XFCE_MIXER_CARD_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_XFCE_MIXER_CARD_COMBO))
+#define XFCE_MIXER_CARD_COMBO_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_XFCE_MIXER_CARD_COMBO, XfceMixerCardComboClass))
+
+GType          xfce_mixer_card_combo_get_type        (void) G_GNUC_CONST;
+
+GtkWidget      *xfce_mixer_card_combo_new            (const gchar        *card_name);
+
+XfceMixerCard *xfce_mixer_card_combo_get_active_card (XfceMixerCardCombo *combo);
+
+G_END_DECLS;
+
+#endif /* !__XFCE_MIXER_CARD_COMBO_H__ */

Modified: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.c
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.c	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -151,7 +151,8 @@
   XfceMixerCard *card;
 
   card = g_object_new (TYPE_XFCE_MIXER_CARD, NULL);
-  card->element = gst_object_ref (element);
+//  card->element = gst_object_ref (element);
+  card->element = element;
   card->display_name = g_strdup (g_object_get_data (G_OBJECT (card->element), "xfce-mixer-control-name"));
 
   return card;
@@ -227,6 +228,31 @@
 
 
 
+GstMixerTrack*
+xfce_mixer_card_get_track_by_name (XfceMixerCard *card,
+                                   const gchar   *track_name)
+{
+  GstMixerTrack *track = NULL;
+  const GList   *tracks;
+  const GList   *iter;
+
+  g_return_val_if_fail (IS_XFCE_MIXER_CARD (card), NULL);
+  g_return_val_if_fail (track_name != NULL, NULL);
+
+  tracks = gst_mixer_list_tracks (GST_MIXER (card->element));
+
+  for (iter = g_list_first (tracks); iter != NULL; iter = g_list_next (iter))
+    if (G_UNLIKELY (g_utf8_collate (GST_MIXER_TRACK (iter->data)->label, track_name) == 0))
+      {
+        track = GST_MIXER_TRACK (iter->data);
+        break;
+      }
+
+  return track;
+}
+
+
+
 void
 xfce_mixer_card_set_control_visible (XfceMixerCard *card,
                                      const gchar   *control,

Modified: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.h
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.h	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-card.h	2008-06-21 00:10:07 UTC (rev 27092)
@@ -45,12 +45,17 @@
 void           xfce_mixer_card_set_ready            (XfceMixerCard *card);
 GList         *xfce_mixer_card_get_visible_controls (XfceMixerCard *card);
 const GList   *xfce_mixer_card_get_tracks           (XfceMixerCard *card);
+GstMixerTrack *xfce_mixer_card_get_track_by_name    (XfceMixerCard *card,
+                                                     const gchar   *track_name);
 void           xfce_mixer_card_set_control_visible  (XfceMixerCard *card,
                                                      const gchar   *control,
                                                      gboolean       visible);
 void           xfce_mixer_card_get_track_volume     (XfceMixerCard *card,
                                                      GstMixerTrack *track,
                                                      gint          *volumes);
+void          xfce_mixer_card_set_track_volume      (XfceMixerCard *card,
+                                                     GstMixerTrack *track,
+                                                     gint          *volumes);
 void           xfce_mixer_card_set_track_muted      (XfceMixerCard *card,
                                                      GstMixerTrack *track,
                                                      gboolean       muted);

Added: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.c
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.c	                        (rev 0)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,307 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "xfce-mixer-track-type.h"
+#include "xfce-mixer-track-combo.h"
+
+
+
+#define NAME_COLUMN  0
+#define TRACK_COLUMN 1
+
+
+
+enum 
+{
+  TRACK_CHANGED,
+  LAST_SIGNAL,
+};
+
+
+
+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_dispose       (GObject                  *object);
+static void xfce_mixer_track_combo_finalize      (GObject                  *object);
+static void xfce_mixer_track_combo_changed       (XfceMixerTrackCombo      *combo);
+static void xfce_mixer_track_combo_track_changed (XfceMixerTrackCombo      *combo,
+                                                  GstMixerTrack            *track);
+
+
+
+struct _XfceMixerTrackComboClass
+{
+  GtkComboBoxClass __parent__;
+
+  /* Signals */
+  void (*track_changed) (XfceMixerTrackCombo *combo,
+                         GstMixerTrack       *track);
+};
+
+struct _XfceMixerTrackCombo
+{
+  GtkComboBox __parent__;
+
+  GtkListStore  *model;
+
+  XfceMixerCard *card;
+
+  gchar         *track_name;
+};
+
+
+
+static GObjectClass *xfce_mixer_track_combo_parent_class = NULL;
+
+
+
+GType
+xfce_mixer_track_combo_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info = 
+        {
+          sizeof (XfceMixerTrackComboClass),
+          NULL,
+          NULL,
+          (GClassInitFunc) xfce_mixer_track_combo_class_init,
+          NULL,
+          NULL,
+          sizeof (XfceMixerTrackCombo),
+          0,
+          (GInstanceInitFunc) xfce_mixer_track_combo_init,
+          NULL,
+        };
+
+      type = g_type_register_static (GTK_TYPE_COMBO_BOX, "XfceMixerTrackCombo", &info, 0);
+    }
+  
+  return type;
+}
+
+
+
+static void
+xfce_mixer_track_combo_class_init (XfceMixerTrackComboClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine parent type class */
+  xfce_mixer_track_combo_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = xfce_mixer_track_combo_dispose;
+  gobject_class->finalize = xfce_mixer_track_combo_finalize;
+
+  klass->track_changed = xfce_mixer_track_combo_track_changed;
+
+  combo_signals[TRACK_CHANGED] = g_signal_new ("track-changed",
+                                               G_TYPE_FROM_CLASS (klass),
+                                               G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                               G_STRUCT_OFFSET (XfceMixerTrackComboClass, track_changed),
+                                               NULL,
+                                               NULL,
+                                               g_cclosure_marshal_VOID__OBJECT,
+                                               G_TYPE_NONE,
+                                               1,
+                                               GST_TYPE_MIXER_TRACK);
+}
+
+
+
+static void
+xfce_mixer_track_combo_init (XfceMixerTrackCombo *combo)
+{
+  GtkCellRenderer *renderer;
+
+  combo->card = NULL;
+  combo->track_name = NULL;
+
+  combo->model = gtk_list_store_new (2, G_TYPE_STRING, GST_TYPE_MIXER_TRACK);
+  gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (combo->model));
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+  gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", NAME_COLUMN);
+
+  g_signal_connect_swapped (combo, "changed", G_CALLBACK (xfce_mixer_track_combo_changed), combo);
+}
+
+
+
+static void
+xfce_mixer_track_combo_dispose (GObject *object)
+{
+  (*G_OBJECT_CLASS (xfce_mixer_track_combo_parent_class)->dispose) (object);
+}
+
+
+
+static void
+xfce_mixer_track_combo_finalize (GObject *object)
+{
+  XfceMixerTrackCombo *combo = XFCE_MIXER_TRACK_COMBO (object);
+
+  gtk_list_store_clear (combo->model);
+  g_object_unref (G_OBJECT (combo->model));
+
+  (*G_OBJECT_CLASS (xfce_mixer_track_combo_parent_class)->finalize) (object);
+}
+
+
+
+GtkWidget*
+xfce_mixer_track_combo_new (XfceMixerCard *card,
+                            const gchar   *track_name)
+{
+  XfceMixerTrackCombo *combo;
+
+  combo = XFCE_MIXER_TRACK_COMBO (g_object_new (TYPE_XFCE_MIXER_TRACK_COMBO, NULL));
+
+  xfce_mixer_track_combo_set_track (combo,track_name);
+  xfce_mixer_track_combo_set_soundcard (combo, card);
+
+  return GTK_WIDGET (combo);
+}
+
+
+
+void
+xfce_mixer_track_combo_set_soundcard (XfceMixerTrackCombo *combo,
+                                      XfceMixerCard       *card)
+{
+  XfceMixerTrackType type;
+  GList             *cards;
+  const GList       *titer;
+  GtkTreeIter        iter;
+  gint               counter;
+  gint               active_index = 0;
+
+  g_return_if_fail (IS_XFCE_MIXER_TRACK_COMBO (combo));
+
+  if (G_LIKELY (combo->card != NULL))
+    g_object_unref (G_OBJECT (combo->card));
+
+  if (IS_XFCE_MIXER_CARD (card))
+    combo->card = XFCE_MIXER_CARD (g_object_ref (G_OBJECT (card)));
+  else
+    {
+      cards = xfce_mixer_utilities_get_cards ();
+      
+      combo->card = XFCE_MIXER_CARD (g_object_ref (G_OBJECT ( (g_list_first (cards)->data))));
+      xfce_mixer_card_set_ready (combo->card);
+
+      g_list_foreach (cards, (GFunc) g_object_unref, NULL);
+      g_list_free (cards);
+    }
+
+  gtk_list_store_clear (combo->model);
+
+  for (titer = xfce_mixer_card_get_tracks (combo->card), counter = 0; titer != NULL; titer = g_list_next (titer), ++counter)
+    {
+      type = xfce_mixer_track_type_new (titer->data);
+
+      if (type == XFCE_MIXER_TRACK_TYPE_PLAYBACK || type == XFCE_MIXER_TRACK_TYPE_CAPTURE)
+        {
+          gtk_list_store_append (combo->model, &iter);
+          gtk_list_store_set (combo->model, &iter, 
+                              NAME_COLUMN, GST_MIXER_TRACK (titer->data)->label, 
+                              TRACK_COLUMN, GST_MIXER_TRACK (titer->data), -1);
+
+          if (G_UNLIKELY (combo->track_name != NULL && g_utf8_collate (GST_MIXER_TRACK (titer->data)->label, combo->track_name) == 0))
+            active_index = counter;
+        }
+    }
+
+  gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active_index);
+}
+
+
+
+void
+xfce_mixer_track_combo_set_track (XfceMixerTrackCombo *combo,
+                                  const gchar         *track_name)
+{
+  g_return_if_fail (IS_XFCE_MIXER_TRACK_COMBO (combo));
+
+  g_free (combo->track_name);
+
+  if (G_UNLIKELY (track_name == NULL))
+    {
+      combo->track_name = g_strdup (track_name);
+      
+      /* TODO: Reset the active iter */
+    }
+}
+
+
+
+static void
+xfce_mixer_track_combo_changed (XfceMixerTrackCombo *combo)
+{
+  GstMixerTrack *track;
+  GtkTreeIter    iter;
+
+  g_return_if_fail (IS_XFCE_MIXER_TRACK_COMBO (combo));
+
+  if (G_LIKELY (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)))
+    {
+      gtk_tree_model_get (GTK_TREE_MODEL (combo->model), &iter, TRACK_COLUMN, &track, -1);
+
+      g_signal_emit_by_name (combo, "track-changed", track);
+    }
+}
+
+
+
+static void 
+xfce_mixer_track_combo_track_changed (XfceMixerTrackCombo *combo,
+                                      GstMixerTrack       *track)
+{
+}
+
+
+
+GstMixerTrack*
+xfce_mixer_track_combo_get_active_track (XfceMixerTrackCombo *combo)
+{
+  GstMixerTrack *track = NULL;
+  GtkTreeIter    iter;
+
+  g_return_val_if_fail (IS_XFCE_MIXER_TRACK_COMBO (combo), NULL);
+
+  if (G_LIKELY (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)))
+    gtk_tree_model_get (GTK_TREE_MODEL (combo->model), &iter, TRACK_COLUMN, &track, -1);
+
+  return track;
+}

Added: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.h
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.h	                        (rev 0)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-track-combo.h	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,53 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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 __XFCE_MIXER_TRACK_COMBO_H__
+#define __XFCE_MIXER_TRACK_COMBO_H__
+
+#include <gtk/gtk.h>
+
+#include "xfce-mixer-card.h"
+
+G_BEGIN_DECLS;
+
+typedef struct _XfceMixerTrackComboClass XfceMixerTrackComboClass;
+typedef struct _XfceMixerTrackCombo      XfceMixerTrackCombo;
+
+#define TYPE_XFCE_MIXER_TRACK_COMBO            (xfce_mixer_track_combo_get_type ())
+#define XFCE_MIXER_TRACK_COMBO(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_XFCE_MIXER_TRACK_COMBO, XfceMixerTrackCombo))
+#define XFCE_MIXER_TRACK_COMBO_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_XFCE_MIXER_TRACK_COMBO, XfceMixerTrackComboClass))
+#define IS_XFCE_MIXER_TRACK_COMBO(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_XFCE_MIXER_TRACK_COMBO))
+#define IS_XFCE_MIXER_TRACK_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_XFCE_MIXER_TRACK_COMBO))
+#define XFCE_MIXER_TRACK_COMBO_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_XFCE_MIXER_TRACK_COMBO, XfceMixerTrackComboClass))
+
+GType          xfce_mixer_track_combo_get_type      (void) G_GNUC_CONST;
+
+GtkWidget     *xfce_mixer_track_combo_new           (XfceMixerCard       *card,
+                                                     const gchar         *track_name);
+
+void           xfce_mixer_track_combo_set_soundcard (XfceMixerTrackCombo *combo,
+                                                     XfceMixerCard       *card);
+void           xfce_mixer_track_combo_set_track     (XfceMixerTrackCombo *combo,
+                                                     const gchar         *track_name);
+GstMixerTrack *xfce_mixer_track_get_active_track    (XfceMixerTrackCombo *combo);
+
+G_END_DECLS;
+
+#endif /* !__XFCE_MIXER_TRACK_COMBO_H__ */

Added: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.c
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.c	                        (rev 0)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,127 @@
+/* $Id$ */
+/* vim:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+#include <gst/gst.h>
+#include <gst/audio/mixerutils.h>
+#include <gst/interfaces/mixer.h>
+
+#include "xfce-mixer-card.h"
+
+
+
+static gboolean xfce_mixer_utilities_filter_mixer (GstMixer *mixer,
+                                                   gpointer  user_data);
+
+
+
+GList*
+xfce_mixer_utilities_get_cards (void)
+{
+  GList *cards = NULL;
+  GList *mixers = NULL;
+  GList *iter;
+  guint  counter = 0;
+
+  /* Get list of all available sound cards */
+  mixers = gst_audio_default_registry_mixer_filter (xfce_mixer_utilities_filter_mixer, FALSE, &counter);
+
+  for (iter = g_list_first (mixers); iter != NULL; iter = g_list_next (iter))
+    cards = g_list_append (cards, xfce_mixer_card_new (iter->data));
+
+  g_list_free (mixers);
+
+  return cards;
+}
+
+
+
+static gboolean
+xfce_mixer_utilities_filter_mixer (GstMixer *mixer,
+                                   gpointer  user_data)
+{
+  GstElementFactory *factory;
+  const gchar       *long_name;
+  gchar             *device_name = NULL;
+  gchar             *name;
+  gchar             *title;
+  guint             *counter = (guint *) user_data;
+
+  /* Get long name of the mixer element */
+  factory = gst_element_get_factory (GST_ELEMENT (mixer));
+  long_name = gst_element_factory_get_longname (factory);
+
+  /* Get device name of the mixer element */
+  g_object_get (G_OBJECT (mixer), "device-name", &device_name, NULL);
+
+  /* Build full name for this element */
+  if (G_LIKELY (device_name != NULL))
+    {
+      name = g_strdup_printf ("%s (%s)", device_name, long_name);
+      g_free (device_name);
+    }
+  else
+    {
+      title = g_strdup_printf (gettext ("Unknown Volume Control %d"), (*counter)++);
+      name = g_strdup_printf ("%s (%s)", title, long_name);
+      g_free (title);
+    }
+
+  /* Set name to be used in xfce4-mixer */
+  g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-control-name", name, (GDestroyNotify) g_free);
+
+  gst_element_set_state (GST_ELEMENT (mixer), GST_STATE_NULL);
+
+  return TRUE;
+}
+
+
+
+XfceMixerCard*
+xfce_mixer_utilities_get_card_by_name (const gchar *card_name)
+{
+  XfceMixerCard *card = NULL;
+  GList         *cards;
+  GList         *iter;
+
+  g_return_val_if_fail (card_name != NULL, NULL);
+
+  cards = xfce_mixer_utilities_get_cards ();
+
+  for (iter = g_list_first (cards); iter != NULL; iter = g_list_next (iter))
+    if (G_UNLIKELY (g_utf8_collate (xfce_mixer_card_get_display_name (XFCE_MIXER_CARD (iter->data)), card_name) == 0))
+      {
+        card = XFCE_MIXER_CARD (g_object_ref (G_OBJECT (iter->data)));
+        break;
+      }
+
+  g_list_foreach (cards, (GFunc) g_object_unref, NULL);
+  g_list_free (cards);
+
+  xfce_mixer_card_set_ready (card);
+
+  return card;
+}

Added: xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.h
===================================================================
--- xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.h	                        (rev 0)
+++ xfce4-mixer/trunk/libxfce4mixer/xfce-mixer-utilities.h	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,30 @@
+/* $Id$ */
+/* vim:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __XFCE_MIXER_UTILITIES_H__
+#define __XFCE_MIXER_UTILITIES_H__
+
+
+GList         *xfce_mixer_utilities_get_cards        (void);
+XfceMixerCard *xfce_mixer_utilities_get_card_by_name (const gchar *card_name);
+
+
+#endif /* !__XFCE_MIXER_UTILITIES_H__ */

Modified: xfce4-mixer/trunk/panel-plugin/Makefile.am
===================================================================
--- xfce4-mixer/trunk/panel-plugin/Makefile.am	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/panel-plugin/Makefile.am	2008-06-21 00:10:07 UTC (rev 27092)
@@ -8,6 +8,8 @@
 	xfce4-mixer-plugin
 
 xfce4_mixer_plugin_SOURCES =						\
+	xfce-plugin-dialog.h						\
+	xfce-plugin-dialog.c						\
 	xfce-volume-button.h						\
 	xfce-volume-button.c						\
 	xfce-mixer-plugin.c

Modified: xfce4-mixer/trunk/panel-plugin/xfce-mixer-plugin.c
===================================================================
--- xfce4-mixer/trunk/panel-plugin/xfce-mixer-plugin.c	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/panel-plugin/xfce-mixer-plugin.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -25,11 +25,17 @@
 
 #include <gtk/gtk.h>
 
+#include <gst/gst.h>
+
 #include <libxfce4util/libxfce4util.h>
 #include <libxfcegui4/libxfcegui4.h>
 #include <libxfce4panel/xfce-panel-plugin.h>
 
+#include "libxfce4mixer/xfce-mixer-stock.h"
+#include "libxfce4mixer/xfce-mixer-card.h"
+
 #include "xfce-volume-button.h"
+#include "xfce-plugin-dialog.h"
 
 
 
@@ -42,6 +48,12 @@
 {
   XfcePanelPlugin *plugin;
 
+  gchar           *card_name;
+  gchar           *track_name;
+
+  XfceMixerCard   *card;
+  GstMixerTrack   *track;
+
   GtkWidget       *hvbox;
   GtkWidget       *button;
 };
@@ -59,6 +71,12 @@
                                                           gdouble           volume);
 static void             xfce_mixer_plugin_configure      (XfceMixerPlugin  *mixer_plugin);
 static void             xfce_mixer_plugin_clicked        (XfceMixerPlugin  *mixer_plugin);
+static void             xfce_mixer_plugin_read_config    (XfceMixerPlugin  *mixer_plugin);
+static void             xfce_mixer_plugin_write_config   (XfceMixerPlugin  *mixer_plugin);
+static void             xfce_mixer_plugin_update_track   (XfceMixerPlugin  *mixer_plugin);
+static void             xfce_mixer_plugin_replace_values (XfceMixerPlugin  *mixer_plugin, 
+                                                          const gchar      *card_name,
+                                                          const gchar      *track_name);
 
 
 
@@ -79,24 +97,21 @@
   /* Store pointer to the panel plugin */
   mixer_plugin->plugin = plugin;
 
+  mixer_plugin->card = NULL;
+  mixer_plugin->track = NULL;
+
   mixer_plugin->hvbox = GTK_WIDGET (xfce_hvbox_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0));
   xfce_panel_plugin_add_action_widget (plugin, mixer_plugin->hvbox);
   gtk_container_add (GTK_CONTAINER (plugin), mixer_plugin->hvbox);
   gtk_widget_show (mixer_plugin->hvbox);
 
   mixer_plugin->button = xfce_volume_button_new ();
-  g_signal_connect (G_OBJECT (mixer_plugin->button), "volume-changed", G_CALLBACK (xfce_mixer_plugin_volume_changed), mixer_plugin);
+  xfce_panel_plugin_add_action_widget (plugin, mixer_plugin->button);
+  g_signal_connect_swapped (G_OBJECT (mixer_plugin->button), "volume-changed", G_CALLBACK (xfce_mixer_plugin_volume_changed), mixer_plugin);
   g_signal_connect_swapped (G_OBJECT (mixer_plugin->button), "clicked", G_CALLBACK (xfce_mixer_plugin_clicked), mixer_plugin);
   gtk_container_add (GTK_CONTAINER (mixer_plugin->hvbox), mixer_plugin->button);
   gtk_widget_show (mixer_plugin->button);
 
-  xfce_panel_plugin_menu_show_configure (plugin);
-
-  /* Connect to plugin signals */
-  g_signal_connect_swapped (G_OBJECT (plugin), "free-data", G_CALLBACK (xfce_mixer_plugin_free), mixer_plugin);
-  g_signal_connect_swapped (G_OBJECT (plugin), "size-changed", G_CALLBACK (xfce_mixer_plugin_size_changed), mixer_plugin);
-  g_signal_connect_swapped (G_OBJECT (plugin), "configure", G_CALLBACK (xfce_mixer_plugin_configure), mixer_plugin);
-
   return mixer_plugin;
 }
 
@@ -106,6 +121,9 @@
 xfce_mixer_plugin_free (XfcePanelPlugin *plugin,
                         XfceMixerPlugin *mixer_plugin)
 {
+  g_free (mixer_plugin->card_name);
+  g_free (mixer_plugin->track_name);
+
   panel_slice_free (XfceMixerPlugin, mixer_plugin);
 }
 
@@ -119,8 +137,30 @@
   /* Set up translation domain */
   xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
 
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  /* Initialize GStreamer */
+  gst_init (NULL, NULL);
+
+  /* Initialize our own stock icon set */
+  xfce_mixer_stock_init ();
+
   /* Create the plugin */
   mixer_plugin = xfce_mixer_plugin_new (plugin);
+
+  xfce_panel_plugin_menu_show_configure (plugin);
+
+  /* Connect to plugin signals */
+  g_signal_connect_swapped (G_OBJECT (plugin), "free-data", G_CALLBACK (xfce_mixer_plugin_free), mixer_plugin);
+  g_signal_connect_swapped (G_OBJECT (plugin), "size-changed", G_CALLBACK (xfce_mixer_plugin_size_changed), mixer_plugin);
+  g_signal_connect_swapped (G_OBJECT (plugin), "configure-plugin", G_CALLBACK (xfce_mixer_plugin_configure), mixer_plugin);
+
+  /* Read config file */
+  xfce_mixer_plugin_read_config (mixer_plugin);
+
+  /* Update the plugin */
+  xfce_mixer_plugin_update_track (mixer_plugin);
 }
 
 
@@ -153,7 +193,26 @@
 xfce_mixer_plugin_volume_changed (XfceMixerPlugin  *mixer_plugin,
                                   gdouble           volume)
 {
-  g_message ("volume changed to %f", volume);
+  gint *volumes;
+  gint  volume_range;
+  gint  new_volume;
+  gint  i;
+
+  g_return_if_fail (mixer_plugin != NULL);
+  g_return_if_fail (IS_XFCE_MIXER_CARD (mixer_plugin->card));
+  g_return_if_fail (GST_IS_MIXER_TRACK (mixer_plugin->track));
+
+  volumes = g_new (gint, mixer_plugin->track->num_channels);
+
+  volume_range = mixer_plugin->track->max_volume - mixer_plugin->track->min_volume;
+  new_volume = mixer_plugin->track->min_volume + (volume * volume_range);
+
+  for (i = 0; i < mixer_plugin->track->num_channels; ++i)
+    volumes[i] = new_volume;
+
+  xfce_mixer_card_set_track_volume (mixer_plugin->card, mixer_plugin->track, volumes);
+
+  g_free (volumes);
 }
 
 
@@ -172,7 +231,157 @@
 static void
 xfce_mixer_plugin_configure (XfceMixerPlugin *mixer_plugin)
 {
+  XfceMixerCard *card;
+  GstMixerTrack *track;
+  GtkWidget     *dialog;
+
   g_return_if_fail (mixer_plugin != NULL);
 
   xfce_panel_plugin_block_menu (mixer_plugin->plugin);
+
+  dialog = xfce_plugin_dialog_new (mixer_plugin->card_name, mixer_plugin->track_name);
+
+  gtk_dialog_run (GTK_DIALOG (dialog));
+
+  xfce_plugin_dialog_get_data (XFCE_PLUGIN_DIALOG (dialog), &card, &track);
+
+  gtk_widget_destroy (dialog);
+
+  g_message ("Changed to card %s and track %s", xfce_mixer_card_get_display_name (card), GST_MIXER_TRACK (track)->label);
+
+  xfce_mixer_plugin_replace_values (mixer_plugin, xfce_mixer_card_get_display_name (card), GST_MIXER_TRACK (track)->label);
+
+  xfce_mixer_plugin_write_config (mixer_plugin);
+
+  xfce_mixer_plugin_update_track (mixer_plugin);
+
+  xfce_panel_plugin_unblock_menu (mixer_plugin->plugin);
 }
+
+
+
+static void
+xfce_mixer_plugin_read_config (XfceMixerPlugin *mixer_plugin)
+{
+  XfceRc      *rc;
+  const gchar *card = NULL;
+  const gchar *track = NULL;
+  gchar       *filename;
+
+  g_return_if_fail (mixer_plugin != NULL);
+
+  /* Search for the config file */
+  filename = xfce_panel_plugin_lookup_rc_file (mixer_plugin->plugin);
+
+  /* Abort if file cannot be found */
+  if (G_UNLIKELY (filename == NULL))
+    {
+      mixer_plugin->card_name = g_strdup (card);
+      mixer_plugin->track_name = g_strdup (track);
+      return;
+    }
+
+  /* Open rc handle */
+  rc = xfce_rc_simple_open (filename, TRUE);
+
+  /* Only read config if rc handle could be opened */
+  if (G_LIKELY (rc != NULL))
+    {
+      /* Read card value */
+      card = xfce_rc_read_entry (rc, "card", card);
+      
+      /* Read track value */
+      track = xfce_rc_read_entry (rc, "track", track);
+
+      /* Update plugin values */
+      xfce_mixer_plugin_replace_values (mixer_plugin, card, track);
+
+      /* Close rc handle */
+      xfce_rc_close (rc);
+    }
+
+  /* Free filename string */
+  g_free (filename);
+}
+
+
+
+static void
+xfce_mixer_plugin_write_config (XfceMixerPlugin *mixer_plugin)
+{
+  XfceRc *rc;
+  gchar  *filename;
+
+  g_return_if_fail (mixer_plugin != NULL);
+
+  /* Search for the config file */
+  filename = xfce_panel_plugin_save_location (mixer_plugin->plugin, TRUE);
+
+  /* Abort saving if the file does not exist and could not be created */
+  if (G_UNLIKELY (filename == NULL))
+    return;
+
+  /* Open rc handle */
+  rc = xfce_rc_simple_open (filename, FALSE);
+
+  if (G_LIKELY (rc != NULL))
+    {
+      xfce_rc_write_entry (rc, "card", mixer_plugin->card_name);
+      xfce_rc_write_entry (rc, "track", mixer_plugin->track_name);
+
+      xfce_rc_close (rc);
+    }
+
+  g_free (filename);
+}
+
+
+
+static void
+xfce_mixer_plugin_update_track (XfceMixerPlugin *mixer_plugin)
+{
+  gint   *volumes;
+  gdouble volume;
+
+  g_return_if_fail (mixer_plugin != NULL);
+
+  if (mixer_plugin->card_name == NULL || mixer_plugin->track_name == NULL)
+    return;
+
+  if (IS_XFCE_MIXER_CARD (mixer_plugin->card))
+    g_object_unref (G_OBJECT (mixer_plugin->card));
+
+  if (GST_IS_MIXER_TRACK (mixer_plugin->track))
+    g_object_unref (G_OBJECT (mixer_plugin->track));
+
+  mixer_plugin->card = XFCE_MIXER_CARD (xfce_mixer_utilities_get_card_by_name (mixer_plugin->card_name));
+  mixer_plugin->track = xfce_mixer_card_get_track_by_name (mixer_plugin->card, mixer_plugin->track_name);
+
+  volumes = g_new (gint, mixer_plugin->track->num_channels);
+  xfce_mixer_card_get_track_volume (mixer_plugin->card, mixer_plugin->track, volumes);
+  volume = ((gdouble) volumes[0]) / mixer_plugin->track->max_volume;
+
+  g_message ("volume (int) = %i, volume (double) = %f", volumes[0], volume);
+
+  xfce_volume_button_set_volume (XFCE_VOLUME_BUTTON (mixer_plugin->button), volume);
+
+  g_free (volumes);
+}
+
+
+
+static void
+xfce_mixer_plugin_replace_values (XfceMixerPlugin *mixer_plugin, 
+                                  const gchar     *card_name,
+                                  const gchar     *track_name)
+{
+  g_return_if_fail (mixer_plugin != NULL);
+  g_return_if_fail (card_name != NULL);
+  g_return_if_fail (track_name != NULL);
+
+  g_free (mixer_plugin->card_name);
+  g_free (mixer_plugin->track_name);
+
+  mixer_plugin->card_name = g_strdup (card_name);
+  mixer_plugin->track_name = g_strdup (track_name);
+}

Added: xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.c
===================================================================
--- xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.c	                        (rev 0)
+++ xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,267 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "libxfce4mixer/xfce-mixer-card.h"
+#include "libxfce4mixer/xfce-mixer-card-combo.h"
+#include "libxfce4mixer/xfce-mixer-track-combo.h"
+#include "libxfce4mixer/xfce-mixer-utilities.h"
+#include "libxfce4mixer/xfce-mixer-track-type.h"
+
+#include "xfce-plugin-dialog.h"
+
+
+
+static void xfce_plugin_dialog_class_init        (XfcePluginDialogClass *klass);
+static void xfce_plugin_dialog_init              (XfcePluginDialog      *dialog);
+static void xfce_plugin_dialog_dispose           (GObject               *object);
+static void xfce_plugin_dialog_finalize          (GObject               *object);
+static void xfce_plugin_dialog_create_contents   (XfcePluginDialog      *dialog,
+                                                  const gchar           *card_name,
+                                                  const gchar           *track_name);
+static void xfce_plugin_dialog_soundcard_changed (XfceMixerCardCombo    *combo,
+                                                  XfceMixerCard         *card,
+                                                  XfcePluginDialog      *dialog);
+static void xfce_plugin_dialog_update_tracks     (XfcePluginDialog      *dialog,
+                                                  XfceMixerCard         *card);
+static void xfce_plugin_dialog_track_changed     (XfceMixerTrackCombo   *combo,
+                                                  GstMixerTrack         *track,
+                                                  XfcePluginDialog      *dialog);
+
+
+
+struct _XfcePluginDialogClass
+{
+  XfceTitledDialogClass __parent__;
+};
+
+struct _XfcePluginDialog
+{
+  XfceTitledDialog __parent__;
+
+  GtkWidget    *card_combo;
+  GtkWidget    *track_combo;
+};
+
+
+
+static GObjectClass *xfce_plugin_dialog_parent_class = NULL;
+
+
+
+GType
+xfce_plugin_dialog_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info = 
+        {
+          sizeof (XfcePluginDialogClass),
+          NULL,
+          NULL,
+          (GClassInitFunc) xfce_plugin_dialog_class_init,
+          NULL,
+          NULL,
+          sizeof (XfcePluginDialog),
+          0,
+          (GInstanceInitFunc) xfce_plugin_dialog_init,
+          NULL,
+        };
+
+      type = g_type_register_static (XFCE_TYPE_TITLED_DIALOG, "XfcePluginDialog", &info, 0);
+    }
+  
+  return type;
+}
+
+
+
+static void
+xfce_plugin_dialog_class_init (XfcePluginDialogClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine parent type class */
+  xfce_plugin_dialog_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = xfce_plugin_dialog_dispose;
+  gobject_class->finalize = xfce_plugin_dialog_finalize;
+}
+
+
+
+static void
+xfce_plugin_dialog_init (XfcePluginDialog *dialog)
+{
+}
+
+
+
+static void
+xfce_plugin_dialog_dispose (GObject *object)
+{
+  (*G_OBJECT_CLASS (xfce_plugin_dialog_parent_class)->dispose) (object);
+}
+
+
+
+static void
+xfce_plugin_dialog_finalize (GObject *object)
+{
+  XfcePluginDialog *dialog = XFCE_PLUGIN_DIALOG (object);
+
+  (*G_OBJECT_CLASS (xfce_plugin_dialog_parent_class)->finalize) (object);
+}
+
+
+
+GtkWidget*
+xfce_plugin_dialog_new (const gchar *card_name,
+                        const gchar *track_name)
+{
+  XfcePluginDialog *dialog;
+  
+  dialog = XFCE_PLUGIN_DIALOG (g_object_new (TYPE_XFCE_PLUGIN_DIALOG, NULL));
+
+  xfce_plugin_dialog_create_contents (dialog, card_name, track_name);
+
+  return GTK_WIDGET (dialog);
+}
+
+
+
+static void 
+xfce_plugin_dialog_soundcard_changed (XfceMixerCardCombo *combo,
+                                      XfceMixerCard      *card,
+                                      XfcePluginDialog *dialog)
+{
+  xfce_plugin_dialog_update_tracks (dialog, card);
+}
+
+
+
+static void 
+xfce_plugin_dialog_update_tracks (XfcePluginDialog *dialog,
+                                  XfceMixerCard    *card)
+{
+  xfce_mixer_track_combo_set_soundcard (XFCE_MIXER_TRACK_COMBO (dialog->track_combo), card);
+}
+
+
+
+void
+xfce_plugin_dialog_get_data (XfcePluginDialog *dialog,
+                             XfceMixerCard   **card,
+                             GstMixerTrack   **track)
+{
+  g_return_if_fail (IS_XFCE_PLUGIN_DIALOG (dialog));
+
+  *card = XFCE_MIXER_CARD (g_object_ref (G_OBJECT (xfce_mixer_card_combo_get_active_card (XFCE_MIXER_CARD_COMBO (dialog->card_combo)))));
+  *track = GST_MIXER_TRACK (g_object_ref (G_OBJECT (xfce_mixer_track_combo_get_active_track (XFCE_MIXER_TRACK_COMBO (dialog->track_combo)))));
+}
+
+
+
+static void 
+xfce_plugin_dialog_track_changed (XfceMixerTrackCombo *combo,
+                                  GstMixerTrack       *track,
+                                  XfcePluginDialog    *dialog)
+{
+  g_debug ("track changed to: %s", GST_MIXER_TRACK (track)->label);
+}
+
+
+
+static void
+xfce_plugin_dialog_create_contents (XfcePluginDialog *dialog,
+                                    const gchar      *card_name,
+                                    const gchar      *track_name)
+{
+  GtkCellRenderer *renderer;
+  XfceMixerCard   *card = NULL;
+  GtkWidget       *vbox;
+  GtkWidget       *button;
+  GtkWidget       *label;
+  GtkWidget       *card_frame;
+  GtkWidget       *track_frame;
+  gchar           *title;
+
+  gtk_window_set_icon_name (GTK_WINDOW (dialog), "xfce4-mixer");
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Mixer Plugin Settings"));
+
+  xfce_titled_dialog_set_subtitle (XFCE_TITLED_DIALOG (dialog), _("Please select which mixer track should be used by the plugin"));
+  
+  button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CLOSE);
+  gtk_widget_show (button);
+
+  vbox = gtk_vbox_new (FALSE, 6);
+  gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
+  gtk_widget_show (vbox);
+
+  label = gtk_label_new (NULL);
+  title = g_strdup_printf ("<span weight='bold'>%s</span>", _("Sound card"));
+  gtk_label_set_markup (GTK_LABEL (label), title);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+  g_free (title);
+
+  card_frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (card_frame), GTK_SHADOW_NONE);
+  gtk_box_pack_start (GTK_BOX (vbox), card_frame, FALSE, TRUE, 0);
+  gtk_widget_show (card_frame);
+
+  dialog->card_combo = xfce_mixer_card_combo_new (card_name);
+  g_signal_connect (G_OBJECT (dialog->card_combo), "soundcard-changed", G_CALLBACK (xfce_plugin_dialog_soundcard_changed), dialog);
+  gtk_container_add (GTK_CONTAINER (card_frame), dialog->card_combo);
+  gtk_widget_show (dialog->card_combo);
+
+  label = gtk_label_new (NULL);
+  title = g_strdup_printf ("<span weight='bold'>%s</span>", _("Mixer track"));
+  gtk_label_set_markup (GTK_LABEL (label), title);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+  g_free (title);
+
+  track_frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (track_frame), GTK_SHADOW_NONE);
+  gtk_box_pack_start (GTK_BOX (vbox), track_frame, FALSE, TRUE, 0);
+  gtk_widget_show (track_frame);
+
+  card = card_name == NULL ? NULL : xfce_mixer_utilities_get_card_by_name (card_name);
+
+  dialog->track_combo = xfce_mixer_track_combo_new (card, track_name);
+  g_signal_connect (G_OBJECT (dialog->track_combo), "track-changed", G_CALLBACK (xfce_plugin_dialog_track_changed), dialog);
+  gtk_container_add (GTK_CONTAINER (track_frame), dialog->track_combo);
+  gtk_widget_show (dialog->track_combo);
+}

Added: xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.h
===================================================================
--- xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.h	                        (rev 0)
+++ xfce4-mixer/trunk/panel-plugin/xfce-plugin-dialog.h	2008-06-21 00:10:07 UTC (rev 27092)
@@ -0,0 +1,49 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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 __XFCE_PLUGIN_DIALOG_H__
+#define __XFCE_PLUGIN_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _XfcePluginDialogClass XfcePluginDialogClass;
+typedef struct _XfcePluginDialog      XfcePluginDialog;
+
+#define TYPE_XFCE_PLUGIN_DIALOG            (xfce_plugin_dialog_get_type ())
+#define XFCE_PLUGIN_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_XFCE_PLUGIN_DIALOG, XfcePluginDialog))
+#define XFCE_PLUGIN_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_XFCE_PLUGIN_DIALOG, XfcePluginDialogClass))
+#define IS_XFCE_PLUGIN_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_XFCE_PLUGIN_DIALOG))
+#define IS_XFCE_PLUGIN_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_XFCE_PLUGIN_DIALOG))
+#define XFCE_PLUGIN_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_XFCE_PLUGIN_DIALOG, XfcePluginDialogClass))
+
+GType     xfce_plugin_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget *xfce_plugin_dialog_new     (const gchar *active_card,
+                                       const gchar *active_track);
+
+void       xce_plugin_dialog_get_data (XfcePluginDialog *dialog,
+                                       XfceMixerCard   **card,
+                                       GstMixerTrack   **track);
+
+G_END_DECLS;
+
+#endif /* !__XFCE_PLUGIN_DIALOG_H__ */

Modified: xfce4-mixer/trunk/panel-plugin/xfce-volume-button.c
===================================================================
--- xfce4-mixer/trunk/panel-plugin/xfce-volume-button.c	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/panel-plugin/xfce-volume-button.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -247,11 +247,13 @@
 
   if (!GTK_WIDGET_HAS_FOCUS (widget))
     {
+#if 1
       gtk_widget_grab_focus (widget);
       gtk_grab_add (widget);
       gdk_pointer_grab (widget->window, TRUE, GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_POINTER_MOTION_MASK|GDK_SCROLL_MASK, NULL, NULL, GDK_CURRENT_TIME);
       gdk_keyboard_grab (widget->window, TRUE, GDK_CURRENT_TIME);
       gtk_widget_set_state (widget, GTK_STATE_SELECTED);
+#endif
     }
 }
 
@@ -265,10 +267,12 @@
 
   if (GTK_WIDGET_HAS_FOCUS (widget))
     {
+#if 1
       gtk_widget_set_state (widget, GTK_STATE_NORMAL);
       gdk_keyboard_ungrab (GDK_CURRENT_TIME);
       gdk_pointer_ungrab (GDK_CURRENT_TIME);
       gtk_grab_remove (widget);
+#endif
     }
 }
 
@@ -361,3 +365,14 @@
                                    gdouble           volume)
 {
 }
+
+
+
+void 
+xfce_volume_button_set_volume (XfceVolumeButton *button,
+                               gdouble           volume)
+{
+  g_return_if_fail (IS_XFCE_VOLUME_BUTTON (button));
+  gtk_adjustment_set_value (GTK_ADJUSTMENT (button->adjustment), volume);
+  xfce_volume_button_update (button);
+}

Modified: xfce4-mixer/trunk/panel-plugin/xfce-volume-button.h
===================================================================
--- xfce4-mixer/trunk/panel-plugin/xfce-volume-button.h	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/panel-plugin/xfce-volume-button.h	2008-06-21 00:10:07 UTC (rev 27092)
@@ -41,6 +41,8 @@
 
 void       xfce_volume_button_set_icon_size (XfceVolumeButton *button,
                                              gint              size);
+void       xfce_volume_button_set_volume    (XfceVolumeButton *button,
+                                             gdouble           volume);
 
 G_END_DECLS;
 

Modified: xfce4-mixer/trunk/xfce4-mixer/xfce-mixer-window.c
===================================================================
--- xfce4-mixer/trunk/xfce4-mixer/xfce-mixer-window.c	2008-06-20 19:27:55 UTC (rev 27091)
+++ xfce4-mixer/trunk/xfce4-mixer/xfce-mixer-window.c	2008-06-21 00:10:07 UTC (rev 27092)
@@ -33,32 +33,30 @@
 #include "xfce-mixer-window.h"
 #include "xfce-mixer.h"
 #include "xfce-mixer-controls-dialog.h"
+
 #include "libxfce4mixer/xfce-mixer-card.h"
+#include "libxfce4mixer/xfce-mixer-card-combo.h"
 #include "libxfce4mixer/xfce-mixer-preferences.h"
+#include "libxfce4mixer/xfce-mixer-utilities.h"
 
 
 
-#define NAME_COLUMN 0
-#define CARD_COLUMN 1
-
-
-
 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_load_soundcards        (XfceMixerWindow      *window);
-static void     xfce_mixer_window_soundcard_changed      (GtkComboBox          *widget,
+static void     xfce_mixer_window_soundcard_changed      (XfceMixerCardCombo   *combo,
+                                                          XfceMixerCard        *card,
                                                           XfceMixerWindow      *window);
 static void     xfce_mixer_window_action_select_controls (GtkAction            *action,
                                                           XfceMixerWindow      *window);
-static gboolean xfce_mixer_window_filter_mixer           (GstMixer             *mixer,
-                                                          gpointer              user_data);
 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,7 +73,6 @@
 
   GtkActionGroup       *action_group;
 
-  GtkListStore         *soundcard_model;
   GtkWidget            *soundcard_combo;
 
   /* List of available sound cards */
@@ -166,6 +163,7 @@
   GtkCellRenderer *renderer;
   GtkAction       *action;
   GtkListStore    *model;
+  gchar           *active_card;
   gchar           *title;
   gint             width;
   gint             height;
@@ -219,17 +217,13 @@
   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
   gtk_widget_show (label);
 
-  window->soundcard_model = gtk_list_store_new (2, G_TYPE_STRING, TYPE_XFCE_MIXER_CARD);
+  g_object_get (G_OBJECT (window->preferences), "sound-card", &active_card, NULL);
 
-  window->soundcard_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (window->soundcard_model));
-  g_signal_connect (G_OBJECT (window->soundcard_combo), "changed", G_CALLBACK (xfce_mixer_window_soundcard_changed), window);
+  window->soundcard_combo = xfce_mixer_card_combo_new (active_card);
+  g_signal_connect (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);
 
-  renderer = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (window->soundcard_combo), renderer, TRUE);
-  gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (window->soundcard_combo), renderer, "text", 0);
-
   window->mixer_frame = gtk_frame_new (NULL);
   gtk_frame_set_shadow_type (GTK_FRAME (window->mixer_frame), GTK_SHADOW_NONE);
   gtk_container_set_border_width (GTK_CONTAINER (window->mixer_frame), 6);
@@ -257,8 +251,7 @@
   gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, TRUE, 0);
   gtk_widget_show (button);
 
-  /* Load available sound cards */
-  xfce_mixer_window_load_soundcards (window);
+  xfce_mixer_window_update_contents (window);
 }
 
 
@@ -295,168 +288,55 @@
 
 
 static void
-xfce_mixer_window_load_soundcards (XfceMixerWindow *window)
+xfce_mixer_window_soundcard_changed (XfceMixerCardCombo *combo,
+                                     XfceMixerCard      *card,
+                                     XfceMixerWindow    *window)
 {
-  XfceMixerCard *card;
-  GtkTreeIter    iter;
-  GList         *mixers = NULL;
-  GList         *miter;
-  guint          counter = 0;
-  gchar         *active_card;
-  guint          active_index = 0;
+  gchar *title;
 
-  /* Prepare sound card list */
-  window->cards = NULL;
+  g_return_if_fail (IS_XFCE_MIXER_CARD_COMBO (combo));
+  g_return_if_fail (IS_XFCE_MIXER_CARD (card));
+  g_return_if_fail (IS_XFCE_MIXER_WINDOW (window));
 
-  /* Get list of all available sound cards */
-  mixers = gst_audio_default_registry_mixer_filter (xfce_mixer_window_filter_mixer, FALSE, &counter);
+  title = g_strdup_printf ("%s - %s", _("Xfce Mixer"), xfce_mixer_card_get_display_name (card));
+  gtk_window_set_title (GTK_WINDOW (window), title);
+  g_free (title);
 
-  if (G_UNLIKELY (g_list_length (mixers) == 0))
-    xfce_err (_("No sound cards could be found. You may have to install additional gstreamer packages for ALSA or OSS support."));
+  /* Destroy the current mixer */
+  if (G_LIKELY (window->mixer != NULL))
+    gtk_widget_destroy (gtk_bin_get_child (GTK_BIN (window->mixer_frame)));
 
-  /* Get sound card used last time */
-  g_object_get (G_OBJECT (window->preferences), "sound-card", &active_card, NULL);
+  xfce_mixer_card_set_ready (card);
 
-  for (miter = g_list_first (mixers), counter = 0; miter != NULL; miter = g_list_next (miter), ++counter)
-    {
-      /* Create new sound card object */
-      card = xfce_mixer_card_new (miter->data);
+  /* Create a new XfceMixer for the active sound card */
+  window->mixer = xfce_mixer_new (card);
 
-      /* Add sound card to the list */
-      window->cards = g_list_append (window->cards, card);
+  /* Add the XfceMixer to the window */
+  gtk_container_add (GTK_CONTAINER (window->mixer_frame), window->mixer);
+  gtk_widget_show (window->mixer);
 
-      g_debug ("Adding sound card: %s", xfce_mixer_card_get_display_name (card));
-
-      /* Insert sound card into the main combo box */
-      gtk_list_store_append (window->soundcard_model, &iter);
-      gtk_list_store_set (window->soundcard_model, &iter, 
-                          NAME_COLUMN, xfce_mixer_card_get_display_name (card), 
-                          CARD_COLUMN, card, -1);
-
-      /* Check if the sound card was the last active one */
-      if (G_UNLIKELY (active_card != NULL && g_utf8_collate (xfce_mixer_card_get_display_name (card), active_card) == 0))
-        active_index = counter;
-    }
-
-  if (G_LIKELY (active_card != NULL))
-    g_free (active_card);
-
-  g_list_free (mixers);
-
-  /* Select the sound card which was selected the last time */
-  gtk_combo_box_set_active (GTK_COMBO_BOX (window->soundcard_combo), active_index);
+  /* Make the "Select Controls..." button sensitive */
+  gtk_widget_set_sensitive (window->select_controls_button, TRUE);
 }
 
 
 
 static void
-xfce_mixer_window_soundcard_changed (GtkComboBox     *widget,
-                                     XfceMixerWindow *window)
-{
-  XfceMixerCard *card;
-  GtkTreeIter    iter;
-  const gchar   *name;
-  gchar         *title;
-
-  /* Determine selected sound card */
-  if (G_LIKELY (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)))
-    {
-      /* Get the active sound card */
-      gtk_tree_model_get (GTK_TREE_MODEL (window->soundcard_model), &iter, CARD_COLUMN, &card, -1);
-
-      /* Update window title */
-      if (G_LIKELY (card != NULL))
-        {
-          title = g_strdup_printf ("%s - %s", _("Xfce Mixer"), xfce_mixer_card_get_display_name (card));
-          gtk_window_set_title (GTK_WINDOW (window), title);
-          g_free (title);
-        }
-      else
-        gtk_window_set_title (GTK_WINDOW (window), _("Xfce Mixer"));
-
-      /* Destroy current mixer controls */
-      if (G_LIKELY (window->mixer != NULL))
-        gtk_widget_destroy (gtk_bin_get_child (GTK_BIN (window->mixer_frame)));
-
-      xfce_mixer_card_set_ready (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);
-    }
-  else
-    {
-      /* Make the "Select Controls..." button insensitive */
-      gtk_widget_set_sensitive (window->select_controls_button, FALSE);
-    }
-}
-
-
-
-static void
 xfce_mixer_window_action_select_controls (GtkAction       *action,
                                           XfceMixerWindow *window)
 {
-  GtkWidget *dialog;
+  GtkWidget     *dialog;
 
   dialog = xfce_mixer_controls_dialog_new (window);
 
   gtk_dialog_run (GTK_DIALOG (dialog));
   gtk_widget_destroy (dialog);
 
-  /* Again, kind of a hack, this time to regenerate the mixer controls */
-  xfce_mixer_window_soundcard_changed (GTK_COMBO_BOX (window->soundcard_combo), window);
+  xfce_mixer_window_update_contents (window);
 }
 
 
 
-static gboolean
-xfce_mixer_window_filter_mixer (GstMixer *mixer,
-                                gpointer user_data)
-{
-  GstElementFactory *factory;
-  const gchar       *long_name;
-  gchar             *device_name = NULL;
-  gchar             *name;
-  gchar             *title;
-  guint             *counter = (guint *) user_data;
-
-  /* Get long name of the mixer element */
-  factory = gst_element_get_factory (GST_ELEMENT (mixer));
-  long_name = gst_element_factory_get_longname (factory);
-
-  /* Get device name of the mixer element */
-  g_object_get (G_OBJECT (mixer), "device-name", &device_name, NULL);
-
-  /* Build full name for this element */
-  if (G_LIKELY (device_name != NULL))
-    {
-      name = g_strdup_printf ("%s (%s)", device_name, long_name);
-      g_free (device_name);
-    }
-  else
-    {
-      title = g_strdup_printf (_("Unknown Volume Control %d"), (*counter)++);
-      name = g_strdup_printf ("%s (%s)", title, long_name);
-      g_free (title);
-    }
-
-  /* Set name to be used in xfce4-mixer */
-  g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-control-name", name, (GDestroyNotify) g_free);
-
-  gst_element_set_state (GST_ELEMENT (mixer), GST_STATE_NULL);
-
-  return TRUE;
-}
-
-
-
 static void
 xfce_mixer_window_close (GtkAction       *action,
                          XfceMixerWindow *window)
@@ -496,11 +376,20 @@
 XfceMixerCard*
 xfce_mixer_window_get_active_card (XfceMixerWindow *window)
 {
-  XfceMixerCard *card = NULL;
-  GtkTreeIter    iter;
+  return xfce_mixer_card_combo_get_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo));
+}
 
-  if (G_LIKELY (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (window->soundcard_combo), &iter)))
-    gtk_tree_model_get (GTK_TREE_MODEL (window->soundcard_model), &iter, CARD_COLUMN, &card, -1);
 
-  return card;
+
+static void
+xfce_mixer_window_update_contents (XfceMixerWindow *window)
+{
+  XfceMixerCard *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));
+
+  /* Again, kind of a hack, this time to regenerate the mixer controls */
+  xfce_mixer_window_soundcard_changed (XFCE_MIXER_CARD_COMBO (window->soundcard_combo), card, window);
 }



More information about the Xfce4-commits mailing list