? cddb-slave2/.deps
? gnome-cd/.deps
? gnome-cd/.libs
? gnome-cd/GNOME_Media_CDDBSlave2-common.lo
? gnome-cd/GNOME_Media_CDDBSlave2-skels.lo
? gnome-cd/GNOME_Media_CDDBSlave2-stubs.lo
? gnome-cd/libgnomemedia-cddbslave2.la
? gnome-cd/access/.deps
? gnome-cd/access/.libs
? gnome-cd/access/cddisplayaccessible.lo
? gnome-cd/access/cddisplayaccessiblefactory.lo
? gnome-cd/access/factory.lo
? gnome-cd/access/libgnomecdaccess.la
? gnome-cd/access/pangoaccessible.lo
? gnome-cd/access/pangoaccessiblefactory.lo
? grecord/src/recent-files/.deps
? gst-mixer/src/.deps
? gst-mixer/src/.kdbgrc.gnome-volume-control
? gst-mixer/src/.libs
? gstreamer-properties/.deps
? po/.intltool-merge-cache
? po/stamp-it
? profiles/.deps
? profiles/glade/.deps
Index: gst-mixer/src/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/Makefile.am,v
retrieving revision 1.8
diff -p -u -r1.8 Makefile.am
--- gst-mixer/src/Makefile.am	16 Sep 2004 20:20:11 -0000	1.8
+++ gst-mixer/src/Makefile.am	1 Jun 2006 15:00:28 -0000
@@ -13,7 +13,8 @@ gnome_volume_control_SOURCES = \
 	preferences.c \
 	track.c \
 	volume.c \
-	window.c
+	window.c \
+	misc.c
 
 noinst_HEADERS = \
 	button.h \
@@ -23,7 +24,8 @@ noinst_HEADERS = \
 	stock.h \
 	track.h \
 	volume.h \
-	window.h
+	window.h \
+	misc.h
 
 gnome_volume_control_LDFLAGS = \
 	$(GSTMIXER_LIBS)
Index: gst-mixer/src/element.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/element.c,v
retrieving revision 1.7
diff -p -u -r1.7 element.c
--- gst-mixer/src/element.c	19 Jan 2006 23:52:21 -0000	1.7
+++ gst-mixer/src/element.c	1 Jun 2006 15:00:28 -0000
@@ -30,6 +30,7 @@
 #include "keys.h"
 #include "preferences.h"
 #include "track.h"
+#include "misc.h"
 
 static void	gnome_volume_control_element_class_init	(GnomeVolumeControlElementClass *klass);
 static void	gnome_volume_control_element_init	(GnomeVolumeControlElement *el);
@@ -166,19 +167,6 @@ gnome_volume_control_element_whitelist (
  * Hide/show notebook page.
  */
 
-static gint
-get_page_num (GstMixerTrack *track)
-{
-  if (GST_IS_MIXER_OPTIONS (track))
-    return 3;
-  else if (track->num_channels == 0)
-    return 2;
-  else if (track->flags & GST_MIXER_TRACK_INPUT)
-    return 1;
-  else
-    return 0;
-}
-
 static void
 update_tab_visibility (GnomeVolumeControlElement *el, gint page)
 {
@@ -298,7 +286,7 @@ gnome_volume_control_element_change (Gno
 
     /* visible? */
     active = gnome_volume_control_element_whitelist (track, list);
-    key = get_gconf_key (el->mixer, track->label);
+    key = get_gconf_key (el->mixer, track);
     if ((value = gconf_client_get (el->client, key, NULL)) != NULL &&
         value->type == GCONF_VALUE_BOOL) {
       active = gconf_value_get_bool (value);
@@ -390,7 +378,7 @@ cb_gconf (GConfClient *client,
 	  gpointer     data)
 {
   GnomeVolumeControlElement *el = GNOME_VOLUME_CONTROL_ELEMENT (data);
-  gchar *keybase = get_gconf_key (el->mixer, "");
+  gchar *keybase = get_gconf_key (el->mixer, NULL);
 
   if (!strncmp (gconf_entry_get_key (entry),
 		keybase, strlen (keybase))) {
@@ -401,7 +389,7 @@ cb_gconf (GConfClient *client,
       GstMixerTrack *track = item->data;
       GnomeVolumeControlTrack *trkw =
 	g_object_get_data (G_OBJECT (track), "gnome-volume-control-trkw");
-      gchar *key = get_gconf_key (el->mixer, track->label);
+      gchar *key = get_gconf_key (el->mixer, track);
 
       if (!strcmp (gconf_entry_get_key (entry), key)) {
         GConfValue *value = gconf_entry_get_value (entry);
Index: gst-mixer/src/misc.c
===================================================================
RCS file: gst-mixer/src/misc.c
diff -N gst-mixer/src/misc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gst-mixer/src/misc.c	1 Jun 2006 15:00:28 -0000
@@ -0,0 +1,48 @@
+#include <gst/interfaces/mixer.h>
+#include <gst/interfaces/mixertrack.h>
+#include <gst/interfaces/mixeroptions.h>
+
+#include <glib.h>
+
+#define _(String) gettext((String))
+
+gint get_page_num (GstMixerTrack *track)
+{
+	/* GstMixerOptions derives from GstMixerTrack */
+	if (GST_IS_MIXER_OPTIONS (track)) {
+		return 3;
+	} else {
+		/* present tracks without channels as toggle switches */
+		if (track->num_channels == 0)
+			return 2;
+		else {
+			/* is it possible to have a track that does input and output? */
+			g_assert (! (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_INPUT)
+			            && GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_OUTPUT)));
+
+			if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_INPUT))
+				return 1;
+			else if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_OUTPUT))
+				return 0;
+		}
+	}
+	
+	g_assert_not_reached ();
+}
+
+gchar *get_page_description (gint n)
+{
+	/* needs i18n work */
+	switch (n) {
+	case 0:
+		return _("Playback");
+	case 1:
+		return _("Capture");
+	case 2:
+		return _("Switch");
+	case 3:
+		return _("Option");
+	}
+
+	g_assert_not_reached ();
+}
Index: gst-mixer/src/misc.h
===================================================================
RCS file: gst-mixer/src/misc.h
diff -N gst-mixer/src/misc.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gst-mixer/src/misc.h	1 Jun 2006 15:00:28 -0000
@@ -0,0 +1,6 @@
+#include <glib.h>
+#include <gst/interfaces/mixertrack.h>
+
+gint get_page_num (GstMixerTrack *track);
+
+gchar *get_page_description (gint n);
Index: gst-mixer/src/preferences.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/preferences.c,v
retrieving revision 1.5
diff -p -u -r1.5 preferences.c
--- gst-mixer/src/preferences.c	19 Jan 2006 23:52:21 -0000	1.5
+++ gst-mixer/src/preferences.c	1 Jun 2006 15:00:28 -0000
@@ -30,11 +30,13 @@
 #include "preferences.h"
 #include "keys.h"
 #include "track.h"
+#include "misc.h"
 
 enum {
   COL_ACTIVE,
   COL_LABEL,
   COL_TRACK,
+  COL_TYPE,
   NUM_COLS
 };
 
@@ -122,7 +124,7 @@ gnome_volume_control_preferences_init (G
   gtk_widget_show (label);
 
   store = gtk_list_store_new (NUM_COLS, G_TYPE_BOOLEAN,
-			      G_TYPE_STRING, G_TYPE_POINTER);
+			      G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING);
   prefs->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (prefs->treeview), FALSE);
   gtk_label_set_mnemonic_widget (GTK_LABEL(label), GTK_WIDGET (prefs->treeview));
@@ -133,7 +135,7 @@ gnome_volume_control_preferences_init (G
 				  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view),
 				       GTK_SHADOW_IN);
-  gtk_widget_set_usize (view, -1, 150);
+  gtk_widget_set_size_request (view, -1, 250);
 
   gtk_container_add (GTK_CONTAINER (view), prefs->treeview);
   gtk_box_pack_start (GTK_BOX (box), view, TRUE, TRUE, 0);
@@ -160,6 +162,12 @@ gnome_volume_control_preferences_init (G
 						  NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (prefs->treeview), col);
 
+  render = gtk_cell_renderer_text_new ();
+  col = gtk_tree_view_column_new_with_attributes ("Type", render,
+                          "text", COL_TYPE,
+						  NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (prefs->treeview), col);
+
   gtk_tree_view_set_search_column (GTK_TREE_VIEW (prefs->treeview), COL_LABEL);
 
   /* and show */
@@ -230,29 +238,34 @@ gnome_volume_control_preferences_respons
 
 gchar *
 get_gconf_key (GstMixer *mixer,
-	       gchar    *track_label)
+           GstMixerTrack *track)
 {
-  gchar *res;
-  const gchar *dev = g_object_get_data (G_OBJECT (mixer),
-					"gnome-volume-control-name");
-  gint i, pos;
-
-  pos = strlen (GNOME_VOLUME_CONTROL_KEY_DIR) + 1;
-  res = g_new (gchar, pos + strlen (dev) + 1 + strlen (track_label) + 1);
-  strcpy (res, GNOME_VOLUME_CONTROL_KEY_DIR "/");
-
-  for (i = 0; dev[i] != '\0'; i++) {
-    if (g_ascii_isalnum (dev[i]))
-      res[pos++] = dev[i];
+  GString *key = g_string_sized_new (90);
+
+  g_string_append_printf (key, "%s/", GNOME_VOLUME_CONTROL_KEY_DIR);
+
+  gchar *device = g_object_get_data (G_OBJECT (mixer),
+                                  "gnome-volume-control-name");
+  gint i;
+  for (i = 0; device[i] != '\0'; i++) {
+    if (g_ascii_isalnum (device[i]))
+      g_string_append_c (key, device[i]);
   }
-  res[pos] = '/';
-  for (i = 0; track_label[i] != '\0'; i++) {
-    if (g_ascii_isalnum (track_label[i]))
-      res[pos++] = track_label[i];
+ 
+  if (track != NULL) {
+    g_string_append_c (key, '-');
+ 
+    for (i = 0; track->label[i] != '\0'; i++) {
+      if (g_ascii_isalnum (track->label[i]))
+        g_string_append_c (key, track->label[i]);
+    }
+
+    g_string_append_printf (key, "-%d", get_page_num (track));
   }
-  res[pos] = '\0';
 
-  return res;
+  gchar *result = g_strdup (key->str);
+  g_string_free (key, TRUE);
+  return result;
 }
 
 /*
@@ -277,6 +290,7 @@ gnome_volume_control_preferences_change 
   /* remove old */
   while (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
     gtk_list_store_remove (store, &iter);
+	/* does this free COL_TYPE? */
   }
 
   /* take/put reference */
@@ -286,21 +300,24 @@ gnome_volume_control_preferences_change 
   for (item = gst_mixer_list_tracks (mixer);
        item != NULL; item = item->next) {
     GstMixerTrack *track = item->data;
-    gchar *key = get_gconf_key (mixer, track->label);
+    gchar *key = get_gconf_key (mixer, track);
     GConfValue *value;
+    gchar *type;
     gboolean active = gnome_volume_control_element_whitelist (track, list);
-
     if ((value = gconf_client_get (prefs->client, key, NULL)) != NULL &&
         value->type == GCONF_VALUE_BOOL) {
       active = gconf_value_get_bool (value);
     }
     g_free (key);
 
+	type = get_page_description (get_page_num (track));
+
     gtk_list_store_append (store, &iter);
     gtk_list_store_set (store, &iter,
 			COL_ACTIVE, active,
 			COL_LABEL, track->label,
 			COL_TRACK, track,
+			COL_TYPE, type,
 			-1);
   }
 }
@@ -335,7 +352,7 @@ cb_toggle (GtkCellRendererToggle *cell,
 		      -1);
   gtk_tree_path_free (path);
 
-  key = get_gconf_key (prefs->mixer, track->label);
+  key = get_gconf_key (prefs->mixer, track);
   value = gconf_value_new (GCONF_VALUE_BOOL);
   gconf_value_set_bool (value, active);
   gconf_client_set (prefs->client, key, value, NULL);
Index: gst-mixer/src/preferences.h
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/preferences.h,v
retrieving revision 1.2
diff -p -u -r1.2 preferences.h
--- gst-mixer/src/preferences.h	19 Jan 2006 23:52:21 -0000	1.2
+++ gst-mixer/src/preferences.h	1 Jun 2006 15:00:28 -0000
@@ -69,7 +69,7 @@ void	gnome_volume_control_preferences_ch
  * GConf thingy. Escapes spaces and such.
  */
 gchar *	get_gconf_key	(GstMixer *mixer,
-			 gchar    *track_label);
+			 GstMixerTrack *track);
 
 
 G_END_DECLS
Index: gst-mixer/src/track.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/track.c,v
retrieving revision 1.8
diff -p -u -r1.8 track.c
--- gst-mixer/src/track.c	15 Apr 2005 12:59:37 -0000	1.8
+++ gst-mixer/src/track.c	1 Jun 2006 15:00:28 -0000
@@ -24,6 +24,7 @@
 #endif
 
 #include <gnome.h>
+#include <string.h>
 
 #include "button.h"
 #include "stock.h"
@@ -74,14 +75,29 @@ cb_record_toggled (GnomeVolumeControlBut
 		        gnome_volume_control_button_get_active (button));
 }
 
+/* Tells us whether toggling a switch should change the corresponding
+ * GstMixerTrack's MUTE or RECORD flag.
+ */
+static gboolean
+should_toggle_record_switch (const GstMixerTrack *track)
+{
+  return GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_INPUT);
+}
+ 
+
 static void
 cb_toggle_changed (GtkToggleButton *button,
 		   gpointer         data)
 {
   GnomeVolumeControlTrack *ctrl = data;
 
-  gst_mixer_set_mute (ctrl->mixer, ctrl->track,
-		      !gtk_toggle_button_get_active (button));
+  if (should_toggle_record_switch (ctrl->track)) {
+    gst_mixer_set_record (ctrl->mixer, ctrl->track,
+      gtk_toggle_button_get_active (button));
+  } else {
+    gst_mixer_set_mute (ctrl->mixer, ctrl->track,
+      !gtk_toggle_button_get_active (button));
+  }
 }
 
 static void
@@ -109,6 +125,14 @@ static gboolean
 cb_check (gpointer data)
 {
   GnomeVolumeControlTrack *trkw = data;
+
+  /* trigger an update of the mixer state */
+  if (! GST_IS_MIXER_OPTIONS (trkw->track)) {
+    gint *dummy = g_new (gint, 1);
+    gst_mixer_get_volume (trkw->mixer, GST_MIXER_TRACK (trkw->track), dummy);
+    g_free (dummy);
+  }
+  
   gboolean mute = GST_MIXER_TRACK_HAS_FLAG (trkw->track,
 				GST_MIXER_TRACK_MUTE) ? TRUE : FALSE,
            record = GST_MIXER_TRACK_HAS_FLAG (trkw->track,
@@ -136,20 +160,20 @@ cb_check (gpointer data)
   }
 
   if (trkw->toggle) {
-    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (trkw->toggle)) ==
-            mute) {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (trkw->toggle), !mute);
+    if (should_toggle_record_switch (trkw->track)) {
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (trkw->toggle),
+        GST_MIXER_TRACK_HAS_FLAG (trkw->track, GST_MIXER_TRACK_RECORD));
+    } else {
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (trkw->toggle),
+        !GST_MIXER_TRACK_HAS_FLAG (trkw->track, GST_MIXER_TRACK_MUTE));
     }
   }
 
   /* FIXME:
    * - options.
-   * - we cannot check flags! We need a _get_*() function in the
-   *     mixer interface, because flags don't change if other
-   *     apps change device state.
    */
 
-  return (trkw->mute || trkw->record);
+  return TRUE;
 }
 
 /*
@@ -180,7 +204,7 @@ gnome_volume_control_track_add_title (Gt
   ctrl->visible = TRUE;
   ctrl->table = table;
   ctrl->pos = tab_pos;
-  ctrl->id = g_timeout_add (100, cb_check, ctrl);
+  ctrl->id = g_timeout_add (200, cb_check, ctrl);
 
   /* image (optional) */
   for (i = 0; !found && pix[i].label != NULL; i++) {
@@ -398,9 +422,13 @@ gnome_volume_control_track_add_switch (G
 					       GTK_ORIENTATION_HORIZONTAL,
 					       mixer, track, l_sep, r_sep);
   ctrl->toggle = gtk_check_button_new ();
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ctrl->toggle),
-				!GST_MIXER_TRACK_HAS_FLAG (ctrl->track,
-					GST_MIXER_TRACK_MUTE));
+  if (should_toggle_record_switch (ctrl->track)) {
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ctrl->toggle),
+      GST_MIXER_TRACK_HAS_FLAG (ctrl->track, GST_MIXER_TRACK_RECORD));
+  } else {
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ctrl->toggle),
+      !GST_MIXER_TRACK_HAS_FLAG (ctrl->track, GST_MIXER_TRACK_MUTE));
+  }
 
   /* attach'n'show */
   gtk_table_attach (GTK_TABLE (table), ctrl->toggle,
