Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-media/Makefile.am,v
retrieving revision 1.51
diff -u -p -r1.51 Makefile.am
--- Makefile.am	1 Jun 2004 10:08:56 -0000	1.51
+++ Makefile.am	9 Jan 2006 12:26:10 -0000
@@ -1,8 +1,8 @@
 always_built_SUBDIRS = cddb-slave2 profiles
 
+#### gnome-cd disabled temporarily until patch is complete: @PROGRAMS_GNOME_CD@ #######
 SUBDIRS = po $(always_built_SUBDIRS) \
 	  @PROGRAMS_VUMETER@ \
-	  @PROGRAMS_GNOME_CD@ \
 	  @PROGRAMS_GSTMIXER@ \
 	  @PROGRAMS_GRECORD@ \
 	  @PROGRAMS_GSTPROPS@
Index: configure.in
===================================================================
RCS file: /cvs/gnome/gnome-media/configure.in,v
retrieving revision 1.286
diff -u -p -r1.286 configure.in
--- configure.in	28 Oct 2005 23:58:23 -0000	1.286
+++ configure.in	9 Jan 2006 12:26:11 -0000
@@ -127,15 +127,19 @@ AC_SUBST(VUMETER_LIBS)
 # Check for GStreamer stuff and GSR depds
 HAVE_GST=no
 
-GST_REQ=0.8.2
+# FIXME: change to 0.10.2 when released. Currently we need CVS
+# (for the mixerutils stuff in gst-plugins-base and cdparanoia for gnome-cd)
+GST_REQ=0.10.1.1
 PROGRAMS_GSTRECORD=""
 
-dnl start with 0.8
-GST_MAJORMINOR=0.8
+dnl start with 0.10
+GST_MAJORMINOR=0.10
+
+dnl  gstreamer-libs-$GST_MAJORMINOR >= $GST_REQ 
+dnl  gstreamer-gconf-$GST_MAJORMINOR >= $GST_REQ
+
 PKG_CHECK_MODULES(GSR, \
   gstreamer-$GST_MAJORMINOR >= $GST_REQ \
-  gstreamer-libs-$GST_MAJORMINOR >= $GST_REQ \
-  gstreamer-gconf-$GST_MAJORMINOR >= $GST_REQ \
   gtk+-2.0 >= 2.6.0 libgnomeui-2.0 >= 1.102.0 gnome-vfs-2.0,
   HAVE_GST=yes,HAVE_GST=no)
 
@@ -319,7 +323,9 @@ AC_SUBST(GAILUTIL_LIBS)
 PROGRAMS_GSTPROPS=""
 if test "x$HAVE_GST" = "xyes";
 then
-  COMMON_MODULES="gconf-2.0 libgnomeui-2.0 libglade-2.0 >= 1.99.12 gstreamer-$GST_MAJORMINOR gstreamer-libs-$GST_MAJORMINOR gstreamer-gconf-$GST_MAJORMINOR"
+  dnl gstreamer-libs-$GST_MAJORMINOR
+  dnl gstreamer-gconf-$GST_MAJORMINOR
+  COMMON_MODULES="gconf-2.0 libgnomeui-2.0 libglade-2.0 >= 1.99.12 gstreamer-$GST_MAJORMINOR"
   PKG_CHECK_MODULES(GSTPROPS, $COMMON_MODULES libxml-2.0 gnome-vfs-2.0,
   		  PROGRAMS_GSTPROPS="gstreamer-properties")
   GSTPROPS_LIBS="$GSTPROPS_LIBS"
@@ -338,16 +344,26 @@ fi
 if test "x$HAVE_GST" = "xyes";
 then
   PROGRAMS_GSTMIX=""
-  COMMON_MODULES="libgnomeui-2.0 gstreamer-$GST_MAJORMINOR gstreamer-interfaces-$GST_MAJORMINOR"
-  PKG_CHECK_MODULES(GSTMIXER, $COMMON_MODULES, [
+  dnl gstreamer-interfaces-$GST_MAJORMINOR
+  PKG_CHECK_MODULES(GSTMIXER,
+  [
+    libgnomeui-2.0
+    gstreamer-$GST_MAJORMINOR
+    gstreamer-plugins-base-$GST_MAJORMINOR
+  ],
+  [
     OLD_CPPFLAGS=$CPPFLAGS
     CPPFLAGS="$CPPFLAGS $GSTMIXER_CFLAGS"
     PROGRAMS_GSTMIXER="gst-mixer"
-    AC_CHECK_HEADER(gst/mixer/mixer.h, , PROGRAMS_GSTMIXER="")
-    if test x$PROGRAMS_GSTMIXER != x; then
-      AC_CHECK_HEADER(gst/propertyprobe/propertyprobe.h, , PROGRAMS_GSTMIXER="")
+    AC_CHECK_HEADER(gst/audio/mixerutils.h, , PROGRAMS_GSTMIXER="")
+    if test "x$PROGRAMS_GSTMIXER" != "x"; then
+      AC_CHECK_HEADER(gst/interfaces/mixer.h, , PROGRAMS_GSTMIXER="")
+    fi
+    if test "x$PROGRAMS_GSTMIXER" != "x"; then
+      AC_CHECK_HEADER(gst/interfaces/propertyprobe.h, , PROGRAMS_GSTMIXER="")
     fi
     CPPFLAGS=$OLD_CPPFLAGS
+    GSTMIXER_LIBS="$GSTMIXER_LIBS -lgstinterfaces-$GST_MAJORMINOR -lgstaudio-$GST_MAJORMINOR"
   ],
   [])
 
@@ -357,7 +373,7 @@ then
 fi
 
 # profiles
-PKG_CHECK_MODULES(GMP, gconf-2.0 libglade-2.0 libgnomeui-2.0,
+PKG_CHECK_MODULES(GMP, gconf-2.0 libglade-2.0 libgnomeui-2.0 gnome-vfs-module-2.0,
                   USE_GMP=yes, USE_GMP=no)
 AC_SUBST(GMP_CFLAGS)
 AC_SUBST(GMP_LIBS)
Index: gnome-cd/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-media/gnome-cd/Makefile.am,v
retrieving revision 1.32
diff -u -p -r1.32 Makefile.am
--- gnome-cd/Makefile.am	27 Aug 2005 16:05:24 -0000	1.32
+++ gnome-cd/Makefile.am	9 Jan 2006 12:26:11 -0000
@@ -31,6 +31,8 @@ EXTRA_DIST = \
 	bsd-cdrom.h		\
 	linux-cdrom.c		\
 	linux-cdrom.h		\
+	gst-cdrom.c	  	\
+	gst-cdrom.h		\
 	gst-cdparanoia-cdrom.c	\
 	gst-cdparanoia-cdrom.h	\
 	gnome-cd.png gnome-cd.desktop.in gnome-cd.schemas.in
@@ -52,7 +54,7 @@ noinst_LTLIBRARIES = libgnomemedia-cddbs
 nodist_libgnomemedia_cddbslave2_la_SOURCES = $(IDL_GENERATED)
 
 if HAVE_GSTREAMER
-cd_sources = gst-cdparanoia-cdrom.c
+cd_sources = gst-cdrom.c
 else
 if CDROM_HOST_BSD
 cd_sources = bsd-cdrom.c bsd-cdrom.h
Index: gnome-cd/cdrom.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gnome-cd/cdrom.c,v
retrieving revision 1.31
diff -u -p -r1.31 cdrom.c
--- gnome-cd/cdrom.c	13 Jun 2005 09:38:43 -0000	1.31
+++ gnome-cd/cdrom.c	9 Jan 2006 12:26:12 -0000
@@ -404,7 +404,7 @@ static void
 cdrom_update_cd (GnomeCDRom *cdrom)
 
 {
-	g_error ("cdrom_update_cd not implmented");
+	g_error ("cdrom_update_cd not implemented");
 }
 
 static void
Index: gnome-cd/gnome-cd.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gnome-cd/gnome-cd.c,v
retrieving revision 1.102
diff -u -p -r1.102 gnome-cd.c
--- gnome-cd/gnome-cd.c	21 Dec 2005 14:30:10 -0000	1.102
+++ gnome-cd/gnome-cd.c	9 Jan 2006 12:26:13 -0000
@@ -971,9 +971,6 @@ int 
 main (int argc, char *argv[])
 {
 	static struct poptOption cd_popt_options [] = {
-#ifdef HAVE_GST
-		{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, "GStreamer", NULL },
-#endif
 		{ "device", '\0', POPT_ARG_STRING, &cd_option_device, 0,
 		  N_("CD device to use"), NULL },
 		{ "unique", '\0', POPT_ARG_NONE, &cd_option_unique, 0,
@@ -999,29 +996,16 @@ main (int argc, char *argv[])
 	textdomain (GETTEXT_PACKAGE);
 
 #ifdef HAVE_GST
-	cd_popt_options[0].arg = (void*) gst_init_get_popt_table();
+	/* FIXME when transition to GOption is being made */
+        /* g_option_context_add_group (context, gst_init_get_goption_group()); */
+
+	gst_init (&argc, &argv); /* gst will remove its own options */
 #endif
+
 	gnome_program_init ("gnome-cd", VERSION, LIBGNOMEUI_MODULE, 
 			    argc, argv, 
 			    GNOME_PARAM_POPT_TABLE, cd_popt_options,
 			    GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
-
-#ifdef HAVE_GST
-	if (!gst_scheduler_factory_get_default_name ()) {
-		GtkWidget *dialog;
-
-		dialog = gtk_message_dialog_new (NULL,
-						 0,
-						 GTK_MESSAGE_ERROR,
-						 GTK_BUTTONS_CLOSE,
-						 _("Registry is not present or it is corrupted, please update it by running gst-register"));
-
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (dialog);
-
-		exit (1);
-	}
-#endif
 
 	register_stock_icons ();
 	client = gnome_master_client ();
Index: gnome-cd/gst-cdparanoia-cdrom.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gnome-cd/gst-cdparanoia-cdrom.c,v
retrieving revision 1.17
diff -u -p -r1.17 gst-cdparanoia-cdrom.c
--- gnome-cd/gst-cdparanoia-cdrom.c	21 Dec 2005 14:31:23 -0000	1.17
+++ gnome-cd/gst-cdparanoia-cdrom.c	9 Jan 2006 12:26:15 -0000
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2001 Iain Holmes
  * Copyright (C) 2003 Jonathan Nall
+ *
  * Authors: Iain Holmes  <iain@ximian.com>
  *          Jonathan Nall  <nall@themountaingoats.com>
  */
@@ -26,7 +27,6 @@
 #include "gst-cdparanoia-cdrom.h"
 #include "cddb.h"
 
-#include <gst/gconf/gconf.h>
 #include <gst/gst.h>
 #ifdef __linux__
 #include <linux/cdrom.h>
@@ -65,7 +65,7 @@ struct _GstCdparanoiaCDRomPrivate {
 
 	GstCdparanoiaCDRomTrackInfo *track_info;
 
-	GstElement *play_thread;
+	GstElement *pipeline;
 	GstElement *cdparanoia;
 	GstElement *audio_sink;
 	GstElement *vol_element;
@@ -207,10 +207,12 @@ add_msf (GnomeCDRomMSF * msf1, GnomeCDRo
 
 /* eos will be called when the src element has an end of stream */
 static void
-eos (GstElement * element, gpointer data)
+msg_cb_eos (GstBus * bus, GstMessage * msg, gpointer data)
 {
 	/*GstCdparanoiaCDRomPrivate *priv =
 	    (GstCdparanoiaCDRomPrivate *) data;*/
+
+	/* FIXME */
 }
 
 static gboolean
@@ -219,7 +221,7 @@ stop_playback_idle_func (gpointer data) 
 	GstCdparanoiaCDRomPrivate *priv =
 	    (GstCdparanoiaCDRomPrivate *) data;
 		    
-	gst_element_set_state (GST_ELEMENT (priv->play_thread),
+	gst_element_set_state (GST_ELEMENT (priv->pipeline),
                                GST_STATE_NULL);
 	priv->check_playtime = 0;
 							  
@@ -236,9 +238,10 @@ check_playtime (GstBin * bin, gpointer d
 	int i = 0;
 
 	/* figure out where we are in the stream */
-	ret =
-	    gst_pad_query (GST_PAD (priv->cdp_pad), GST_QUERY_POSITION,
-			   &priv->sector_format, &value);
+	ret = gst_pad_query_pad_position (priv->cdp_pad,
+	                                  &priv->sector_format,
+	                                  &value);
+
 	if (ret && priv->check_playtime && value >= priv->end_playtime) {
 		g_idle_add (stop_playback_idle_func, data);
 	} else {
@@ -254,10 +257,15 @@ check_playtime (GstBin * bin, gpointer d
 }
 
 static void
-cb_error (GstElement *el, GstElement *src,
-	  GError *err, gchar *debug, gpointer data)
+msg_cb_error (GstBus * bus, GstMessage * msg, gpointer data)
 {
-	g_warning (err->message);
+	GError *err = NULL;
+	gchar *dbg = NULL;
+
+	gst_message_parse_error (msg, &err, &dbg);
+	g_warning ("ERROR: %s", err->message);
+	g_error_free (err);
+	g_free (dbg);
 }
 
 static gboolean
@@ -267,21 +275,29 @@ build_pipeline (GstCdparanoiaCDRom * lcd
 	static int pipeline_built = 0;
 	char *sink;
 	char *sink_options_start = NULL;
-	GstElement *conv, *scale, *vol, *pthread, *queue;
+	GstElement *conv, *scale, *vol, *queue;
+        GstBus *bus;
 
 	if (pipeline_built == 1)
 		return TRUE; 
 
 	priv = lcd->priv;
 
-	priv->play_thread = gst_thread_new ("play_thread");
-	g_assert (priv->play_thread != 0);	/* TBD: GError */
+	priv->pipeline = gst_pipeline_new ("pipeline");
+	g_assert (priv->pipeline != NULL);
+
+	bus = gst_element_get_bus (priv->pipeline);
 
-	g_signal_connect (priv->play_thread, "error",
-			  G_CALLBACK (cb_error), priv);
+	gst_bus_add_signal_watch (bus);
 
-	g_signal_connect (priv->play_thread, "iterate",
+	g_signal_connect (bus, "message::error",
+			  G_CALLBACK (msg_cb_error), priv);
+
+#warning *** FIX iterate signal
+#if 0
+	g_signal_connect (priv->pipeline, "iterate",
 			  G_CALLBACK (check_playtime), priv);
+#endif
 
 	priv->cdparanoia =
 	    gst_element_factory_make ("cdparanoia", "cdparanoia");
@@ -302,34 +318,32 @@ build_pipeline (GstCdparanoiaCDRom * lcd
 				      priv->cd_device, NULL);
 		}
 	}
-	g_signal_connect (G_OBJECT (priv->cdparanoia), "eos",
-			  G_CALLBACK (eos), priv);
+	g_signal_connect (bus, "message::eos",
+			  G_CALLBACK (msg_cb_eos), priv);
 
 	priv->sector_format = gst_format_get_by_nick ("sector");
 	g_assert (priv->sector_format != 0);	/* TBD: GError */
 	priv->cdp_pad = gst_element_get_pad (priv->cdparanoia, "src");
 	g_assert (priv->cdp_pad != 0);	/* TBD: GError */
 
-	priv->audio_sink = gst_gconf_get_default_audio_sink ();
+	priv->audio_sink = gst_element_factory_make ("gconfaudiosink",
+	                                             "gconfaudiosink");
 	if (!priv->audio_sink) {
 		g_set_error (error, 0, 0,
-			     _("Failed to set up audio output; please install a GStreamer plugin for your soundcard."));
+			     _("Failed to set up audio output; please install the GStreamer gconfaudiosink plugin"));
 		return FALSE;
 	}
 
-	pthread = gst_element_factory_make ("thread", "outthr");
 	queue = gst_element_factory_make ("queue", "q");
 	conv = gst_element_factory_make ("audioconvert", "conv");
-	scale = gst_element_factory_make ("audioscale", "scale");
+	scale = gst_element_factory_make ("audioresample", "resample");
 	priv->vol_element = vol = gst_element_factory_make ("volume", "vol");
 	g_object_set (G_OBJECT (priv->vol_element), "volume",
 		      (gdouble) priv->volume / 255.0, NULL);
 
 	/* Now build the pipeline */
-	gst_bin_add_many (GST_BIN (pthread), queue, conv,
-			  scale, vol, priv->audio_sink, NULL);
-	gst_bin_add_many (GST_BIN (priv->play_thread), priv->cdparanoia,
-			  pthread, NULL);
+	gst_bin_add_many (GST_BIN (priv->pipeline), priv->cdparanoia,
+			  queue, conv, scale, vol, priv->audio_sink, NULL);
 
 	/* Link 'er up */
 	gst_element_link_many (priv->cdparanoia, queue, conv, scale, vol,
@@ -346,8 +360,8 @@ gst_cdparanoia_cdrom_finalize (GObject *
 {
 	GstCdparanoiaCDRom *cdrom = (GstCdparanoiaCDRom *) object;
 
-	if (cdrom->priv->play_thread != NULL) {
-		gst_object_unref (GST_OBJECT (cdrom->priv->play_thread));
+	if (cdrom->priv->pipeline != NULL) {
+		gst_object_unref (GST_OBJECT (cdrom->priv->pipeline));
 	}
 	if (cdrom->priv->cd_device != NULL) {
 		g_free (cdrom->priv->cd_device);
@@ -921,20 +935,20 @@ gst_cdparanoia_cdrom_play (GnomeCDRom * 
 		if (!build_pipeline (lcd, error))
 			return FALSE;
 
-		if (GST_STATE (priv->play_thread) <= GST_STATE_PAUSED) {
-			gst_element_set_state (GST_ELEMENT (priv->play_thread),
+		if (GST_STATE (priv->pipeline) <= GST_STATE_PAUSED) {
+			gst_element_set_state (GST_ELEMENT (priv->pipeline),
 					       GST_STATE_PAUSED);
 		}
 
 		frames = msf_struct_to_frames (&msf, 0);
 		ret = gst_pad_send_event (GST_PAD (priv->cdp_pad),
-			gst_event_new_seek (priv->sector_format |
-					    GST_SEEK_METHOD_SET |
+			gst_event_new_seek (1.0, priv->sector_format,
 					    GST_SEEK_FLAG_FLUSH,
-					    frames));
+					    GST_SEEK_TYPE_SET, frames,
+					    GST_SEEK_TYPE_NONE, -1));
 
 		if (status->audio != GNOME_CDROM_AUDIO_PAUSE) {
-			gst_element_set_state (GST_ELEMENT (priv->play_thread),
+			gst_element_set_state (GST_ELEMENT (priv->pipeline),
 					       GST_STATE_PLAYING);
 		}
 		priv->cur_track = start_track;
@@ -984,12 +998,12 @@ gst_cdparanoia_cdrom_pause (GnomeCDRom *
 	}
 
 	if (status->audio == GNOME_CDROM_AUDIO_PAUSE) {
-		gst_element_set_state (GST_ELEMENT (priv->play_thread),
+		gst_element_set_state (GST_ELEMENT (priv->pipeline),
 				       GST_STATE_PLAYING);
 	}
 
 	else if (status->audio == GNOME_CDROM_AUDIO_PLAY) {
-		gst_element_set_state (GST_ELEMENT (priv->play_thread),
+		gst_element_set_state (GST_ELEMENT (priv->pipeline),
 				       GST_STATE_PAUSED);
 	}
 
@@ -1026,8 +1040,8 @@ gst_cdparanoia_cdrom_stop (GnomeCDRom * 
 	}
 #endif
 
-	if (priv->play_thread)
-		gst_element_set_state (GST_ELEMENT (priv->play_thread),
+	if (priv->pipeline)
+		gst_element_set_state (GST_ELEMENT (priv->pipeline),
 				       GST_STATE_NULL);
 
 	gst_cdparanoia_cdrom_close (lcd);
@@ -1183,7 +1197,7 @@ gst_cdparanoia_cdrom_get_status (GnomeCD
 #else
 	struct cdrom_subchnl subchnl;
 #endif
-	int cur_gst_status;
+	GstState cur_gst_status;
 	int cd_status;
 	gint64 value = 0;
 	gboolean ret;
@@ -1282,8 +1296,9 @@ gst_cdparanoia_cdrom_get_status (GnomeCD
 
 	g_object_get (G_OBJECT (priv->vol_element), "volume", &vol, NULL);
 	realstatus->volume = priv->volume = rint (vol * 255.0);
-	cur_gst_status =
-	    gst_element_get_state (GST_ELEMENT (priv->play_thread));
+
+	/* FIXME: do we want current or pending state here? */
+	gst_element_get_state (priv->pipeline, &cur_gst_status, NULL, 0);
 
 	if (priv->cdp_pad == NULL
 	    || !(cur_gst_status == GST_STATE_PLAYING
@@ -1292,9 +1307,9 @@ gst_cdparanoia_cdrom_get_status (GnomeCD
 		priv->cur_rel_frame = 0;
 	} else {
 		/* figure out where we are in the stream */
-		ret =
-		    gst_pad_query (priv->cdp_pad, GST_QUERY_POSITION,
-				   &priv->sector_format, &value);
+		ret = gst_pad_query_position (priv->cdp_pad,
+		                              &priv->sector_format,
+		                              &value);
 		priv->cur_abs_frame = value;
 		priv->cur_rel_frame =
 		    value -
Index: grecord/src/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/Makefile.am,v
retrieving revision 1.16
diff -u -p -r1.16 Makefile.am
--- grecord/src/Makefile.am	8 Jun 2005 08:16:52 -0000	1.16
+++ grecord/src/Makefile.am	9 Jan 2006 12:26:17 -0000
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS = gst recent-files
+SUBDIRS = recent-files
 
 INCLUDES = \
 	-DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"	\
@@ -26,5 +26,4 @@ EXTRA_DIST = $(ui_DATA)
 gnome_sound_recorder_LDADD =					\
 	$(GSR_LIBS)						\
 	$(top_builddir)/profiles/libgnome-media-profiles.la	\
-	recent-files/librecent.la				\
-	gst/libgstrecelements.la
+	recent-files/librecent.la
Index: grecord/src/gnome-recorder.c
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gnome-recorder.c,v
retrieving revision 1.20
diff -u -p -r1.20 gnome-recorder.c
--- grecord/src/gnome-recorder.c	9 Jun 2005 14:45:05 -0000	1.20
+++ grecord/src/gnome-recorder.c	9 Jan 2006 12:26:17 -0000
@@ -126,7 +126,7 @@ gsr_add_recent (gchar *filename)
 	g_free (uri);
 }
 
-gint sample_count = 1;
+gint gsr_sample_count = 1;
 
 GtkWidget *
 gsr_open_window (const char *filename)
@@ -139,13 +139,12 @@ gsr_open_window (const char *filename)
 		 * there is no active sound sample. Any newly
 		 * recorded samples will be saved to disk with this
 		 * name as default value. */
-		if (sample_count == 1) {
+		if (gsr_sample_count == 1) {
 			name = g_strdup (_("Untitled"));
 		} else {
-			name = g_strdup_printf (_("Untitled-%d"),
-						sample_count);
+			name = g_strdup_printf (_("Untitled-%d"), gsr_sample_count);
 		}
-		sample_count++;
+		++gsr_sample_count;
 	} else {
 		name = g_strdup (filename);
 	}
@@ -170,51 +169,50 @@ main (int argc,
       char **argv)
 {
 	GnomeProgram *program;
-	poptContext pctx;
+/*
 	GValue value = {0, };
 	char **args = NULL;
-
-	static struct poptOption gsr_options[] = {
-		{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, "GStreamer", NULL },
-		{ NULL, 'p', POPT_ARG_NONE, NULL, 1, N_("Dummy option"), NULL },
-		POPT_TABLEEND
-	};
+*/
 
 	/* Init gettext */
 	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 	textdomain (GETTEXT_PACKAGE);
 
-	/* init gstreamer */
-	gsr_options[0].arg = (void *) gst_init_get_popt_table ();
+/* FIXME: remove when bumping requirements to 2.14 */
+#ifdef GNOME_PARAM_GOPTION_CONTEXT
+	if (1) {
+		GOptionContext *ctx;
+		GOptionGroup *group;
+
+		ctx = g_option_context_new ("gnome-sound-recorder");
+		g_option_context_add_group (ctx, gst_init_get_option_group ());
+
+		program = gnome_program_init ("gnome-sound-recorder", VERSION,
+		                              LIBGNOMEUI_MODULE, argc, argv,
+		                              GNOME_PARAM_GOPTION_CONTEXT, ctx,
+		                              GNOME_PARAM_HUMAN_READABLE_NAME,
+		                              "GNOME Sound Recorder",
+		                              GNOME_PARAM_APP_DATADIR, DATADIR,
+		                              NULL);
+	}
+#else /* GNOME_PARAM_GOPTION_CONTEXT */
+	gst_init (&argc, &argv);
 
-	/* Init GNOME */
 	program = gnome_program_init ("gnome-sound-recorder", VERSION,
 				      LIBGNOMEUI_MODULE,
 				      argc, argv,
-				      GNOME_PARAM_POPT_TABLE, gsr_options,
 				      GNOME_PARAM_HUMAN_READABLE_NAME,
 				      "GNOME Sound Recorder",
 				      GNOME_PARAM_APP_DATADIR, DATADIR,
 				      NULL);
+#endif /* GNOME_PARAM_GOPTION_CONTEXT */
 
 	init_recent ();
 
-	if (!gst_scheduler_factory_get_default_name ()) {
-		GtkWidget *dialog;
-
-		dialog = gtk_message_dialog_new (NULL,
-						 0,
-						 GTK_MESSAGE_ERROR,
-						 GTK_BUTTONS_CLOSE,
-						 _("Registry is not present or it is corrupted, please update it by running gst-register"));
-
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (dialog);
-
-		exit (1);
-	}
+#if 0
 	gst_rec_elements_init ();
+#endif
 
 	gtk_window_set_default_icon_name ("gnome-grecord");
 
@@ -224,6 +222,10 @@ main (int argc,
         /* init gnome-media-profiles */
         gnome_media_profiles_init (gconf_client);
 
+/////////////////////////////////////// FIXME: how to access the remaining
+/////////////////////////////////////// arguments after the option parsing
+/////////////////////////////////////// is done?
+#if 0
 	/* Get the args */
 	g_value_init (&value, G_TYPE_POINTER);
 	g_object_get_property (G_OBJECT (program),
@@ -241,11 +243,11 @@ main (int argc,
 			gsr_open_window (args[i]);
 		}
 	}
-
-	poptFreeContext (pctx);
+#else
+	gsr_open_window (NULL);
+#endif
 
 	gtk_main ();
 
 	return 0;
 }
-
Index: grecord/src/gsr-window.c
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gsr-window.c,v
retrieving revision 1.63
diff -u -p -r1.63 gsr-window.c
--- grecord/src/gsr-window.c	21 Dec 2005 14:10:00 -0000	1.63
+++ grecord/src/gsr-window.c	9 Jan 2006 12:26:19 -0000
@@ -2,6 +2,7 @@
 /*
  *  Authors: Iain Holmes <iain@prettypeople.org>
  *           Johan Dahlin <johan@gnome.org>
+ *           Tim-Philipp Müller <tim centricular net>
  *
  *  Copyright 2002 Iain Holmes
  *
@@ -21,7 +22,8 @@
  * Boston, MA 02111-1307, USA.
  *
  * 4th Februrary 2005: Christian Schaller: changed license to LGPL with
- * permission of Iain Holmes, Ronald Bultje, Leontine Binchy (SUN), Johan Dalhin * and Joe Marcus Clarke
+ * permission of Iain Holmes, Ronald Bultje, Leontine Binchy (SUN), Johan Dalhin
+ * and Joe Marcus Clarke
  *
  */
 
@@ -40,7 +42,6 @@
 #include <libgnomevfs/gnome-vfs.h>
 #include <gconf/gconf-client.h>
 #include <gst/gst.h>
-#include <gst/gconf/gconf.h>
 
 #include <profiles/gnome-media-profiles.h>
 
@@ -67,9 +68,13 @@ extern void gsr_add_recent (gchar *filen
 
 typedef struct _GSRWindowPipeline {
 	GstElement *pipeline;
+	GstState    state;     /* last seen (async) pipeline state */
+	GstBus     *bus;
 
-	GstElement *src, *sink;
-	guint32 state_change_id;
+	GstElement *src;
+	GstElement *sink;
+
+	guint       tick_id;
 } GSRWindowPipeline;
 
 enum {
@@ -100,9 +105,11 @@ struct _GSRWindowPrivate {
 	guint tip_message_cid;
 
 	/* Pipelines */
-	GSRWindowPipeline *play, *record;
-	char *filename, *record_filename;
-        char *extension;
+	GSRWindowPipeline *play;
+	GSRWindowPipeline *record;
+	char *record_filename;
+	char *filename;
+	char *extension;
 	char *working_file; /* Working file: Operations only occur on the
 			       working file. The result of that operation then
 			       becomes the new working file. */
@@ -112,44 +119,69 @@ struct _GSRWindowPrivate {
 	int len_secs; /* In seconds */
 	int get_length_attempts;
 
-	int n_channels, bitrate, samplerate;
+	/* ATOMIC access */
+	struct {
+		gint n_channels;
+		gint bitrate;
+		gint samplerate;
+	} atomic;
+
 	gboolean has_file;
 	gboolean saved;
 	gboolean dirty;
 	gboolean seek_in_progress;
 
+	gboolean quit_after_save;
+
 	guint32 tick_id; /* tick_callback timeout ID */
 	guint32 record_id; /* record idle callback timeout ID */
-	guint32 gstenc_id; /* encode idle callback iterator ID */
+
+	GstElement *ebusy_pipeline;  /* which pipeline we're trying to start */
+	guint       ebusy_timeout_id;
 };
 
 static GSRWindowPipeline * make_record_pipeline    (GSRWindow         *window);
 static GSRWindowPipeline * make_play_pipeline      (GSRWindow         *window);
 
 static void
-show_error_dialog (GtkWindow *window, gchar *error)
+show_error_dialog (GtkWindow   *window,
+                   const gchar *debug_message,
+                   const gchar *format, ...) G_GNUC_PRINTF (3,4);
+
+static void
+show_error_dialog (GtkWindow *win, const gchar *dbg, const gchar * format, ...)
 {
 	GtkWidget *dialog;
+	va_list args;
+	gchar *s;
+
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
 
-	dialog = gtk_message_dialog_new (window,
+	dialog = gtk_message_dialog_new (win,
 					 GTK_DIALOG_DESTROY_WITH_PARENT,
 					 GTK_MESSAGE_ERROR,
 					 GTK_BUTTONS_CLOSE,
-					 error);
-	
+					 s);
+
+	if (dbg != NULL) {
+		g_printerr ("ERROR: %s\nDEBUG MESSAGE: %s\n", s, dbg);
+	}
+
 	gtk_dialog_run (GTK_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
+	g_free (s);
 }
 
 static void
 shutdown_pipeline (GSRWindowPipeline *pipe)
 {
-	if (pipe->state_change_id > 0) {
-		g_signal_handler_disconnect (G_OBJECT (pipe->pipeline),
-					     pipe->state_change_id);
-	}
+	gst_bus_set_flushing (pipe->bus, TRUE);
+	gst_bus_remove_signal_watch (pipe->bus);
 	gst_element_set_state (pipe->pipeline, GST_STATE_NULL);
-	gst_object_unref (GST_OBJECT (pipe->pipeline));	
+	gst_object_unref (pipe->pipeline);	
+	gst_object_unref (pipe->bus);
 }
 
 static char *
@@ -225,6 +257,7 @@ seconds_to_full_string (guint seconds)
 	return NULL;
 }
 
+static void
 set_action_sensitive (GSRWindow  *window,
 		      const char *name,
 		      gboolean    sensitive)
@@ -242,44 +275,14 @@ file_new_cb (GtkAction *action,
 }
 
 static void
-file_chooser_open_response_cb (GtkDialog *file_chooser,
-			       int response_id,
-			       GSRWindow *window)
-{
-	char *name;
-	char *dirname;
-
-	if (response_id != GTK_RESPONSE_OK)
-		goto out;
-	
-	name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-	if (name == NULL)
-		goto out;
-		
-	dirname = g_path_get_dirname (name);
-	gconf_client_set_string (gconf_client, KEY_OPEN_DIR, dirname, NULL);
-	g_free (dirname);
-
-	if (window->priv->has_file == TRUE) {
-		/* Just open a new window with the file */
-		gsr_open_window (name);
-	} else {
-		/* Set the file in this window */
-		g_object_set (G_OBJECT (window), "location", name, NULL);
-	}
-		
-	g_free (name);
-	
- out:
-	gtk_widget_destroy (GTK_WIDGET (file_chooser));
-}
-
-static void
 file_open_cb (GtkAction *action,
 	      GSRWindow *window)
 {
 	GtkWidget *file_chooser;
-	char *directory;
+	gchar *directory;
+	gint response;
+
+	g_return_if_fail (GSR_IS_WINDOW (window));
 
 	file_chooser = gtk_file_chooser_dialog_new (_("Open a File"),
 						    GTK_WINDOW (window),
@@ -289,14 +292,39 @@ file_open_cb (GtkAction *action,
 						    NULL);
 
 	directory = gconf_client_get_string (gconf_client, KEY_OPEN_DIR, NULL);
+
 	if (directory != NULL && *directory != 0) {
-		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (file_chooser), directory);
+		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (file_chooser),
+		                                     directory);
 	}
-	g_free (directory);
 
-	g_signal_connect (G_OBJECT (file_chooser), "response",
-			  G_CALLBACK (file_chooser_open_response_cb), window);
-	gtk_widget_show (file_chooser);
+	response = gtk_dialog_run (GTK_DIALOG (file_chooser));
+
+	if (response == GTK_RESPONSE_OK) {
+		gchar *name;
+
+		name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
+		if (name) {
+			gchar *dirname;
+
+			dirname = g_path_get_dirname (name);
+			gconf_client_set_string (gconf_client, KEY_OPEN_DIR, dirname, NULL);
+			g_free (dirname);
+
+			if (window->priv->has_file == TRUE) {
+				/* Just open a new window with the file */
+				gsr_open_window (name);
+			} else {
+				/* Set the file in this window */
+				g_object_set (G_OBJECT (window), "location", name, NULL);
+			}
+		
+			g_free (name);
+		}
+    }
+
+	gtk_widget_destroy (file_chooser);
+	g_free (directory);
 }
 
 static void
@@ -351,62 +379,6 @@ file_open_recent_cb (EggRecentViewGtk *v
 	g_free (uri);
 }
 
-struct _eos_data {
-	GSRWindow *window;
-	char *location;
-	GstElement *pipeline;
-};
-
-static gboolean
-eos_done (struct _eos_data *ed)
-{
-	GSRWindow *window = ed->window;
-
- 	gst_element_set_state (ed->pipeline, GST_STATE_NULL);
-	if (window->priv->gstenc_id > 0) {
-	    g_source_remove (window->priv->gstenc_id);
-	    window->priv->gstenc_id = 0;
-	}
- 
-	g_object_set (G_OBJECT (window),
-		      "location", ed->location,
-		      NULL);
-
-
-	gdk_window_set_cursor (window->priv->main_vbox->window, NULL);
-
-	set_action_sensitive (window, "Stop", FALSE);
-	set_action_sensitive (window, "Play", TRUE);
-	set_action_sensitive (window, "Record", TRUE);
-	set_action_sensitive (window, "FileSave", FALSE);
-	set_action_sensitive (window, "FileSaveAs", TRUE);
-	gtk_widget_set_sensitive (window->priv->scale, TRUE);
-
-	gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar),
-			   window->priv->status_message_cid);
-	gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar),
-			    window->priv->status_message_cid,
-			    _("Ready"));
-
-	g_free (ed);
-
-	return FALSE;
-}
-
-static GstElement *
-gst_element_get_child (GstElement* element, const gchar *name)
-{
-	const GList *kids = GST_BIN (element)->children;
-	GstElement *sink;
-
-	while (kids && !(strcmp (gst_object_get_name (GST_OBJECT (kids->data)), name)))
-		kids = kids->next;
-	g_assert (kids);
-	sink = kids->data;
-
-	return sink;
-}
-
 #if 0
 static gboolean
 cb_iterate (GstBin  *bin,
@@ -433,81 +405,103 @@ cb_iterate (GstBin  *bin,
 #endif
 
 static gboolean
-is_set_ebusy_timeout (GSRWindow *window)
+handle_ebusy_error (GSRWindow *window)
 {
-	if (g_object_get_data (G_OBJECT (window), "ebusy_timeout"))
-		return TRUE;
+	g_return_val_if_fail (window->priv->ebusy_pipeline != NULL, FALSE);
+
+	gst_element_set_state (window->priv->ebusy_pipeline, GST_STATE_NULL);
+	gst_element_set_state (window->priv->ebusy_pipeline, GST_STATE_PLAYING);
 
+	/* Try only once */
 	return FALSE;
 }
 
-static void
-set_ebusy_timeout (GSRWindow *window, gpointer data)
+static GstElement *
+notgst_element_get_toplevel (GstElement * element)
 {
-	g_object_set_data (G_OBJECT (window), "ebusy_timeout", data);
-}
+	g_return_val_if_fail (element != NULL, NULL);
+	g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
 
-static gboolean
-handle_ebusy_error (GSRWindow *window)
-{
-	GSRWindowPrivate *priv = window->priv;
+	do {
+		GstElement *parent;
 
-	/* FIXME: which pipeline to reset state on? */
-	if (priv->play) {
-		gst_element_set_state (priv->play->pipeline, GST_STATE_NULL);
-		gst_element_set_state (priv->play->pipeline, GST_STATE_PLAYING);
-	} else if (priv->record) {
-		gst_element_set_state (priv->record->pipeline, GST_STATE_NULL);
-		gst_element_set_state (priv->record->pipeline, GST_STATE_PLAYING);
-	} else {
-		g_warning ("Don't know which pipeline to reset");
-	}
+		parent = (GstElement *) gst_element_get_parent (element);
 
-	/* Try only once */
-	return FALSE;
+		if (parent == NULL)
+			break;
+
+		gst_object_unref (parent);
+		element = parent;
+	} while (1);
+
+	return element;
 }
 
 static void
-pipeline_error_cb (GstElement *parent,
-		   GstElement *cause,
-		   GError     *error,
-		   gchar      *debug,
-		   gpointer    data)
+pipeline_error_cb (GstBus * bus, GstMessage * msg, GSRWindow * window)
 {
-	GSRWindow *window = data;
-	struct _eos_data *ed;
-	GstElement *sink;
+	GstElement *pipeline;
+	GError *error = NULL;
+	gchar *dbg = NULL;
 
-	g_return_if_fail (GTK_IS_WINDOW (window));
-	
-	if (error->code == GST_RESOURCE_ERROR_BUSY) {
-		if (! is_set_ebusy_timeout (window)) {
-			g_timeout_add (EBUSY_TRY_AGAIN, (GSourceFunc) handle_ebusy_error, window);
-			set_ebusy_timeout (window, GUINT_TO_POINTER (TRUE));
+	g_return_if_fail (GSR_IS_WINDOW (window));
 
+	gst_message_parse_error (msg, &error, &dbg);
+	g_return_if_fail (error != NULL);
+
+	pipeline = notgst_element_get_toplevel (GST_ELEMENT (msg->src));
+
+	if (error->code == GST_RESOURCE_ERROR_BUSY) {
+		if (window->priv->ebusy_timeout_id == 0) {
 			set_action_sensitive (window, "FileSave", FALSE);
 			set_action_sensitive (window, "FileSaveAs", FALSE);
 			set_action_sensitive (window, "Play", FALSE);
 			set_action_sensitive (window, "Record", FALSE);
+
+			window->priv->ebusy_pipeline = pipeline;
+
+			window->priv->ebusy_timeout_id = 
+				g_timeout_add (EBUSY_TRY_AGAIN,
+				               (GSourceFunc) handle_ebusy_error,
+				               window);
+
+			g_error_free (error);
+			g_free (dbg);
 			return;
 		}
 	}
 
-	set_ebusy_timeout (window, NULL);
+	if (window->priv->ebusy_timeout_id) {
+		g_source_remove (window->priv->ebusy_timeout_id);
+		window->priv->ebusy_timeout_id = 0;
+		window->priv->ebusy_pipeline = NULL;
+	}
+
+
+	/* set pipeline to NULL before showing error dialog to make sure
+	 * the audio device is freed, in case any accessability software
+	 * wants to make use of it to read out the error message */
+ 	gst_element_set_state (pipeline, GST_STATE_NULL);
 
-	show_error_dialog (GTK_WINDOW (window), error->message);
+	show_error_dialog (GTK_WINDOW (window), dbg, "%s", error->message);
 
-	ed = g_new (struct _eos_data, 1);
-	ed->window = window;
-	ed->pipeline = parent;
+	gdk_window_set_cursor (window->priv->main_vbox->window, NULL);
 
-	sink = gst_element_get_child (parent, "sink");
-	g_object_get (G_OBJECT (sink),
-		      "location", &ed->location,
-		      NULL);
+	set_action_sensitive (window, "Stop", FALSE);
+	set_action_sensitive (window, "Play", TRUE);
+	set_action_sensitive (window, "Record", TRUE);
+	set_action_sensitive (window, "FileSave", FALSE);
+	set_action_sensitive (window, "FileSaveAs", TRUE);
+	gtk_widget_set_sensitive (window->priv->scale, TRUE);
 
-	/*g_idle_add ((GSourceFunc) eos_done, ed);*/
-	eos_done (ed);
+	gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar),
+			   window->priv->status_message_cid);
+	gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar),
+			    window->priv->status_message_cid,
+			    _("Ready"));
+
+	g_error_free (error);
+	g_free (dbg);
 }
 
 static GtkWidget *
@@ -619,23 +613,19 @@ do_save_file (GSRWindow *window,
 			g_object_set (G_OBJECT (window), "location", name, NULL);
 			priv->dirty = FALSE;
 			window->priv->saved = TRUE;
-			if ( GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "save_quit")))
+			if (window->priv->quit_after_save == TRUE) {
 				gsr_window_close (window);
+			}
 		} else {
-			gchar *error_message;
- 
-			error_message = g_strdup_printf (_("Could not save the file \"%s\""), gnome_vfs_result_to_string (result));
-			show_error_dialog (GTK_WINDOW (window), error_message);
-			g_free (error_message);
+			show_error_dialog (GTK_WINDOW (window), NULL,
+			                   _("Could not save the file \"%s\""),
+			                   gnome_vfs_result_to_string (result));
 		}
 		gnome_vfs_uri_unref (src_uri);
 		gnome_vfs_uri_unref (dst_uri);
 	} else {
-		gchar *error_message;
-
-		error_message = g_strdup_printf (_("Could not save the file \"%s\""), name);
-		show_error_dialog (GTK_WINDOW (window), error_message);
-		g_free (error_message);
+		show_error_dialog (GTK_WINDOW (window), NULL,
+			           _("Could not save the file \"%s\""), name);
 	}
 
 	g_free (name);
@@ -643,38 +633,14 @@ do_save_file (GSRWindow *window,
 }
 
 static void
-file_chooser_save_response_cb (GtkDialog *file_chooser,
-			       int response_id,
-			       GSRWindow *window)
-{
-	char *name;
-	char *dirname;
-
-	if (response_id != GTK_RESPONSE_OK)
-		goto out;
-	
-	name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-	if (name == NULL)
-		goto out;
-
-	dirname = g_path_get_dirname (name);
-	gconf_client_set_string (gconf_client, KEY_SAVE_DIR, dirname, NULL);
-	g_free (dirname);
-	
-	do_save_file (window, name);
-	g_free (name);
-
- out:	
-	g_object_set_data (G_OBJECT (window), "save_quit", GPOINTER_TO_INT (NULL));
-	gtk_widget_destroy (GTK_WIDGET (file_chooser));
-}
-
-static void
 file_save_as_cb (GtkAction *action,
 		 GSRWindow *window)
 {
 	GtkWidget *file_chooser;
-	char *directory;
+	gchar *directory;
+	gint response;
+
+	g_return_if_fail (GSR_IS_WINDOW (window));
 
 	file_chooser = gtk_file_chooser_dialog_new (_("Save file as"),
 						    GTK_WINDOW (window),
@@ -716,11 +682,30 @@ file_save_as_cb (GtkAction *action,
 		g_free (basename);
 	}
 
-	g_signal_connect (G_OBJECT (file_chooser), "response",
-			  G_CALLBACK (file_chooser_save_response_cb), window);
-	gtk_widget_show (file_chooser);
+	response = gtk_dialog_run (GTK_DIALOG (file_chooser));
+
+	if (response == GTK_RESPONSE_OK) {
+		gchar *name;
+
+		name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
+		if (name) {
+			gchar *dirname;
+
+			dirname = g_path_get_dirname (name);
+			gconf_client_set_string (gconf_client, KEY_SAVE_DIR, dirname, NULL);
+			g_free (dirname);
+	
+			do_save_file (window, name);
+			g_free (name);
+	    }
+	}
+
+	gtk_widget_destroy (file_chooser);
+
+	window->priv->quit_after_save = FALSE;
 }
 
+
 static void
 file_save_cb (GtkAction *action,
 	      GSRWindow *window)
@@ -750,21 +735,18 @@ run_mixer_cb (GtkAction *action,
 	/* Open the mixer */
 	mixer_path = g_find_program_in_path ("gnome-volume-control");
 	if (mixer_path == NULL) {
-		char *tmp;
-		tmp = g_strdup_printf(_("%s is not installed in the path."), "gnome-volume-control");
-		show_error_dialog (GTK_WINDOW (window), tmp);
-		g_free(tmp);
+		show_error_dialog (GTK_WINDOW (window), NULL,
+		                   _("%s is not installed in the path."),
+		                   "gnome-volume-control");
 		return;
 	}
 
 	argv[0] = mixer_path;
 	ret = g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error);
 	if (ret == FALSE) {
-		char *tmp;
-		tmp = g_strdup_printf (_("There was an error starting %s: %s"),
-				       mixer_path, error->message);
-		show_error_dialog (GTK_WINDOW (window), tmp);
-		g_free(tmp);
+		show_error_dialog (GTK_WINDOW (window), NULL,
+		                   _("There was an error starting %s: %s"),
+		                   mixer_path, error->message);
 		g_error_free (error);
 	}
 
@@ -777,34 +759,13 @@ gsr_window_is_saved (GSRWindow *window)
 	return window->priv->saved;
 }
 
-static void
-handle_confirmation_response (GtkDialog *dialog, gint response_id, GSRWindow *window)
-{
-	switch (response_id) {
-		case GTK_RESPONSE_YES:
-			g_object_set_data (G_OBJECT (window), "save_quit", GINT_TO_POINTER (TRUE));
-			file_save_as_cb (NULL, window);
-				break;
-
-		case GTK_RESPONSE_NO:
-			gsr_window_close (window);
-			break;
-
-		case GTK_RESPONSE_CANCEL:
-		default: 
-			break;
-	} 
-
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-	return;
-}
-
 void 
 close_confirmation_dialog (GSRWindow *window)
 {
-	GtkDialog *confirmation_dialog;
-	char *msg;
+	GtkWidget *confirmation_dialog;
 	AtkObject *atk_obj;
+	gchar *msg;
+	gint response_id;
 
 	msg = g_strdup_printf (_("Save the changes to file \"%s\" before closing?"),
 			       window->priv->record_filename);
@@ -816,20 +777,35 @@ close_confirmation_dialog (GSRWindow *wi
 								  "<span weight=\"bold\" size=\"larger\">%s</span>",
 								  msg);
 
-	gtk_dialog_add_buttons (confirmation_dialog,
+	gtk_dialog_add_buttons (GTK_DIALOG (confirmation_dialog),
 			 	_("Close _without Saving"), GTK_RESPONSE_NO,
 				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 				GTK_STOCK_SAVE, GTK_RESPONSE_YES, NULL);
 
 	gtk_window_set_title (GTK_WINDOW (confirmation_dialog), "");
 
-	g_signal_connect (G_OBJECT (confirmation_dialog), "response",
-			  G_CALLBACK (handle_confirmation_response), window);
-
-	atk_obj = gtk_widget_get_accessible (GTK_WIDGET (confirmation_dialog));
+	atk_obj = gtk_widget_get_accessible (confirmation_dialog);
 	atk_object_set_name (atk_obj, _("Question"));
 
-	gtk_widget_show_all (GTK_WIDGET (confirmation_dialog));
+	response_id = gtk_dialog_run (GTK_DIALOG (confirmation_dialog));
+
+	switch (response_id) {
+		case GTK_RESPONSE_YES:
+			window->priv->quit_after_save = TRUE;
+			file_save_as_cb (NULL, window);
+			break;
+
+		case GTK_RESPONSE_NO:
+			gsr_window_close (window);
+			break;
+
+		case GTK_RESPONSE_CANCEL:
+		default: 
+			break;
+	} 
+
+	gtk_widget_destroy (confirmation_dialog);
+
 	g_free (msg);
 }
 
@@ -888,9 +864,10 @@ static void
 fill_in_information (GSRWindow *window,
 		     struct _file_props *fp)
 {
-	char *text;
-	char *name;
 	struct stat buf;
+	guint64 file_size = 0;
+	gchar *text, *name;
+	gint n_channels, bitrate, samplerate;
 
 	/* dirname */
 	text = g_path_get_dirname (window->priv->filename);
@@ -910,11 +887,13 @@ fill_in_information (GSRWindow *window,
 	
 	/* Size */
 	if (stat (window->priv->working_file, &buf) == 0) {
-		char *human;
-		human = gnome_vfs_format_file_size_for_display (buf.st_size);
+		gchar *human;
+
+		file_size = (guint64) buf.st_size;
+		human = gnome_vfs_format_file_size_for_display (file_size);
 
 		text = g_strdup_printf (ngettext ("%s (%llu byte)", "%s (%llu bytes)", 
-						   buf.st_size), human, buf.st_size);
+		                        file_size), human, file_size);
 		g_free (human);
 	} else {
 		text = g_strdup (_("Unknown size"));
@@ -934,25 +913,32 @@ fill_in_information (GSRWindow *window,
 	g_free (text);
 
 	/* sample rate */
-	if (window->priv->samplerate == 0) {
+	samplerate = g_atomic_int_get (&window->priv->atomic.samplerate);
+	if (samplerate == 0) {
 		text = g_strdup (_("Unknown"));
 	} else {
-		text = g_strdup_printf (_("%.1f kHz"), (float) window->priv->samplerate / 1000);
+		text = g_strdup_printf (_("%.1f kHz"), (float) samplerate / 1000);
 	}
 	gtk_label_set_text (GTK_LABEL (fp->samplerate), text);
 	g_free (text);
 
 	/* bit rate */
-	if (window->priv->bitrate == 0) {
-		text = g_strdup (_("Unknown"));
+	bitrate = g_atomic_int_get (&window->priv->atomic.bitrate);
+	if (bitrate > 0) {
+		text = g_strdup_printf (_("%.0f kb/s"), (float) bitrate / 1000);
+	} else if (window->priv->len_secs > 0 && file_size > 0) {
+		bitrate = (file_size * 8.0) / window->priv->len_secs;
+		text = g_strdup_printf (_("%.0f kb/s (Estimated)"),
+		                        (float) bitrate / 1000);
 	} else {
-		text = g_strdup_printf (_("%.0f kb/s"), (float) window->priv->bitrate / 1000);
+		text = g_strdup (_("Unknown"));
 	}
 	gtk_label_set_text (GTK_LABEL (fp->bitrate), text);
 	g_free (text);
 
 	/* channels */
-	switch (window->priv->n_channels) {
+	n_channels = g_atomic_int_get (&window->priv->atomic.n_channels);
+	switch (n_channels) {
 	case 0:
 		text = g_strdup (_("Unknown"));
 		break;
@@ -963,7 +949,7 @@ fill_in_information (GSRWindow *window,
 		text = g_strdup (_("2 (stereo)"));
 		break;
 	default:
-		text = g_strdup_printf ("%d", window->priv->n_channels);
+		text = g_strdup_printf ("%d", n_channels);
 		break;
 	}
 	gtk_label_set_text (GTK_LABEL (fp->channels), text);
@@ -1137,6 +1123,7 @@ about_cb (GtkAction *action,
 	const char * const authors[] = {"Iain Holmes <iain@prettypeople.org>", 
 		"Ronald Bultje <rbultje@ronald.bitfreak.net>", 
 		"Johan Dahlin  <johan@gnome.org>", 
+		"Tim-Philipp M\303\274ller <tim centricular net>",
 		NULL};
 	const char * const documenters[] = {"Sun Microsystems", NULL};
  
@@ -1161,39 +1148,23 @@ play_cb (GtkAction *action,
 		return;
 
 	if (priv->play) {
-		gst_element_set_state (priv->play->pipeline, GST_STATE_NULL);
-		g_object_unref (priv->play->pipeline);
-	}
-	priv->play = make_play_pipeline (window);
-
-	g_object_set (G_OBJECT (window->priv->play->src),
-		      "location", priv->filename,
-		      NULL);
-
-	if (priv->record && gst_element_get_state (priv->record->pipeline) == GST_STATE_PLAYING) {
-		gst_element_set_state (priv->record->pipeline, GST_STATE_READY);
+		shutdown_pipeline (priv->play);
 	}
 
-	if (priv->play)
-		gst_element_set_state (priv->play->pipeline, GST_STATE_PLAYING);
-}
-
-static void
-cb_rec_eos (GstElement * element,
-	    GSRWindow * window)
-{
-	GSRWindowPrivate *priv = window->priv;
-
-	gst_element_set_state (priv->record->pipeline, GST_STATE_READY);
+	if ((priv->play = make_play_pipeline (window))) {
+		gchar *uri;
 
-	g_free (priv->working_file);
-	priv->working_file = g_strdup (priv->record_filename);
+#warning *** FIXME: do we need to complete relative paths here or is it always an absolute path?
+		uri = g_strdup_printf ("file://%s", priv->filename);
+		g_object_set (window->priv->play->pipeline, "uri", uri, NULL);
+		g_free (uri);
 
-	g_free (priv->filename);
-	priv->filename = g_strdup (priv->record_filename);
+		if (priv->record && priv->record->state == GST_STATE_PLAYING) {
+			gst_element_set_state (priv->record->pipeline, GST_STATE_NULL);
+		}
 
-	priv->dirty = TRUE;
-	priv->has_file = TRUE;
+		gst_element_set_state (priv->play->pipeline, GST_STATE_PLAYING);
+	}
 }
 
 static void
@@ -1202,27 +1173,21 @@ stop_cb (GtkAction *action,
 {
 	GSRWindowPrivate *priv = window->priv;
 
-	/* Work out whats playing */
-	if (priv->play && gst_element_get_state (priv->play->pipeline) == GST_STATE_PLAYING) {
-		gst_element_set_state (priv->play->pipeline, GST_STATE_READY);
-	} else if (priv->record && gst_element_get_state (priv->record->pipeline) == GST_STATE_PLAYING) {
-#if 0
-		gst_element_set_state (priv->record->pipeline, GST_STATE_READY);
-
-		g_free (priv->working_file);
-		priv->working_file = g_strdup (priv->record_filename);
-
-		g_free (priv->filename);
-		priv->filename = g_strdup (priv->record_filename);
+	/* Work out what's playing */
+	if (priv->play && priv->play->state == GST_STATE_PLAYING) {
+		gst_element_set_state (priv->play->pipeline, GST_STATE_NULL);
+	} else if (priv->record && priv->record->state == GST_STATE_PLAYING) {
+		GstPad *pad;
 
-		priv->dirty = TRUE;
-		priv->has_file = TRUE;
-#endif
-		g_signal_connect (priv->record->pipeline, "eos",
-				  G_CALLBACK (cb_rec_eos), window);
-		gst_pad_send_event (gst_element_get_pad (priv->record->src,
-							 "src"),
-				    gst_event_new (GST_EVENT_EOS));
+		pad = gst_element_get_pad (priv->record->src, "src");
+		if (pad) {
+#warning ************ FIX: make EOS programmatically in a sane way *********
+			//////////////// FIXME, this is evil /////////////////////////////
+			GST_PAD_STREAM_LOCK (pad);
+			gst_pad_push_event (pad, gst_event_new_eos ());
+			GST_PAD_STREAM_UNLOCK (pad);
+			gst_object_unref (pad);
+		}
 	}
 }
 
@@ -1233,53 +1198,21 @@ record_cb (GtkAction *action,
 	GSRWindowPrivate *priv = window->priv;
 
 	if (priv->record) {
-		gst_element_set_state (priv->record->pipeline, GST_STATE_NULL);
-		g_object_unref (priv->record->pipeline);
-	}
-	priv->record = make_record_pipeline (window);
-	if (!priv->record)
-		return;
-
-	g_object_set (G_OBJECT (priv->record->sink),
-		      "location", priv->record_filename,
-		      NULL);
-	window->priv->len_secs = 0;
-	window->priv->saved = FALSE;
-	gst_element_set_state (priv->record->pipeline, GST_STATE_PLAYING);
-}
-
-static gboolean
-get_length (GSRWindow *window)
-{
-	gint64 value;
-	GstFormat format = GST_FORMAT_TIME;
-	gboolean query_worked = FALSE;
-
-	if (window->priv->play->sink != NULL) {
-		query_worked = gst_element_query (window->priv->play->sink,
-						  GST_QUERY_TOTAL, &format, &value);
+		shutdown_pipeline (priv->record);
 	}
 
-	if (query_worked) {
-		char *len_str;
+	if ((priv->record = make_record_pipeline (window))) {
+		GstStateChangeReturn ret;
 
-		window->priv->len_secs = value / GST_SECOND;
+		window->priv->len_secs = 0;
+		window->priv->saved = FALSE;
 
-		len_str = seconds_to_full_string (window->priv->len_secs);
-		gtk_label_set (GTK_LABEL (window->priv->length_label), len_str);
-		
-		g_free (len_str);
+		g_object_set (G_OBJECT (priv->record->sink),
+			      "location", priv->record_filename,
+			      NULL);
 
-		return FALSE;
-	} else {
-		if (window->priv->get_length_attempts-- < 1) {
-			/* Attempts to get length ran out. */
-			gtk_label_set (GTK_LABEL (window->priv->length_label), _("Unknown"));
-			return FALSE;
-		}
+		gst_element_set_state (priv->record->pipeline, GST_STATE_PLAYING);
 	}
-
-	return (gst_element_get_state (window->priv->play->pipeline) == GST_STATE_PLAYING);
 }
 
 static gboolean
@@ -1293,97 +1226,106 @@ seek_started (GtkRange *range,
 	return FALSE;
 }
 
+#warning *************** FIX AND CHECK ALL _set_state IF WE NEED TO WAIT *****
+
 static gboolean
 seek_to (GtkRange *range,
 	 GdkEventButton *gdkevent,
 	 GSRWindow *window)
 {
-	double value = range->adjustment->value;
+	gdouble value;
 	gint64 time;
-	GstEvent *event;
-	GstElementState old_state;
 
-	old_state = gst_element_get_state (window->priv->play->pipeline);
-	if (old_state == GST_STATE_READY || old_state == GST_STATE_NULL) {
+	if (window->priv->play->state < GST_STATE_PLAYING)
 		return FALSE;
-	}
 
-	gst_element_set_state (window->priv->play->pipeline, GST_STATE_PAUSED);
-	time = ((value / 100) * window->priv->len_secs) * GST_SECOND;
+	value = range->adjustment->value;
+	time = ((value / 100.0) * window->priv->len_secs) * GST_SECOND;
+
+	gst_element_seek (window->priv->play->pipeline, 1.0, GST_FORMAT_TIME,
+	                  GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time,
+	                  GST_SEEK_TYPE_NONE, 0);
 
-	event = gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_FLAG_FLUSH, time);
-	gst_element_send_event (window->priv->play->sink, event);
-	gst_element_set_state (window->priv->play->pipeline, old_state);
 	window->priv->seek_in_progress = FALSE;
 
 	return FALSE;
 }
 
 static gboolean
-tick_callback (GSRWindow *window)
+play_tick_callback (GSRWindow *window)
 {
-	int secs;
-	gint64 value;
-	gboolean query_worked = FALSE;
+	GstElement *playbin;
 	GstFormat format = GST_FORMAT_TIME;
+	gint64 val = -1;
+
+	g_return_val_if_fail (window->priv->play != NULL, FALSE);
+	g_return_val_if_fail (window->priv->play->pipeline != NULL, FALSE);
+
+	playbin = window->priv->play->pipeline;
 
-	if (gst_element_get_state (window->priv->play->pipeline) != GST_STATE_PLAYING) {
-		/* This check stops us from doing an unnecessary query */
+	/* This check stops us from doing an unnecessary query */
+	if (window->priv->play->state != GST_STATE_PLAYING)
 		return FALSE;
-	}
 
-#if 0
-	if (window->priv->len_secs == 0) {
-		/* Check if we've exhausted the length check yet */
-		if (window->priv->get_length_attempts == 0) {
-			return FALSE;
+	if (gst_element_query_duration (playbin, &format, &val) && val != -1) {
+		gchar *len_str;
+
+		window->priv->len_secs = val / GST_SECOND;
+
+		len_str = seconds_to_full_string (window->priv->len_secs);
+		gtk_label_set (GTK_LABEL (window->priv->length_label), len_str);
+		g_free (len_str);
+	} else {
+		if (window->priv->get_length_attempts <= 0) {
+			/* Attempts to get length ran out. */
+			gtk_label_set (GTK_LABEL (window->priv->length_label), _("Unknown"));
 		} else {
-			return TRUE;
+			--window->priv->get_length_attempts;
 		}
 	}
-#endif
-	get_length (window);
 
 	if (window->priv->seek_in_progress)
 		return TRUE;
 
-	query_worked = gst_element_query (window->priv->play->sink,
-					  GST_QUERY_POSITION, 
-					  &format, &value);
-	if (query_worked && window->priv->len_secs != 0) {
-		double percentage;
-		secs = value / GST_SECOND;
-		
-		percentage = ((double) secs / (double) window->priv->len_secs) * 100.0;
-		gtk_adjustment_set_value (GTK_RANGE (window->priv->scale)->adjustment, percentage + 0.5);
+	if (window->priv->len_secs == 0)
+		return TRUE;
 
+	if (gst_element_query_position (playbin, &format, &val) && val != -1) {
+		gdouble pos, len, percentage;
+		gint secs;
+
+		pos = (gdouble) (val - (val % GST_SECOND));
+		len = (gdouble) window->priv->len_secs * GST_SECOND;
+		percentage = pos / len * 100.0;
+		
+		gtk_adjustment_set_value (GTK_RANGE (window->priv->scale)->adjustment,
+		                          CLAMP (percentage + 0.5, 0.0, 100.0));
 	}
 
-	return (gst_element_get_state (window->priv->play->pipeline) == GST_STATE_PLAYING);
+	return TRUE;
 }
 
 static gboolean
 record_tick_callback (GSRWindow *window)
 {
-	int secs;
-	gint64 value;
-	gboolean query_worked = FALSE;
+	GstElement *pipeline;
 	GstFormat format = GST_FORMAT_TIME;
+	gint64 val = -1;
+	gint secs;
 
-	if (gst_element_get_state (window->priv->record->pipeline) != GST_STATE_PLAYING) {
-		/* This check stops us from doing an unnecessary query */
+	/* This check stops us from doing an unnecessary query */
+	if (window->priv->record->state != GST_STATE_PLAYING)
 		return FALSE;
-	}
 
 	if (window->priv->seek_in_progress)
 		return TRUE;
 
-	query_worked = gst_element_query (window->priv->record->sink,
-					  GST_QUERY_POSITION, 
-					  &format, &value);
-	if (query_worked) {
+	pipeline = window->priv->record->pipeline;
+
+	if (gst_element_query_position (pipeline, &format, &val) && val != -1) {
 		gchar* len_str;
-		secs = value / GST_SECOND;
+
+		secs = val / GST_SECOND;
 		
 		len_str = seconds_to_full_string (secs);
 		window->priv->len_secs = secs;
@@ -1391,36 +1333,29 @@ record_tick_callback (GSRWindow *window)
 		g_free (len_str);
 	}
 
-	return (gst_element_get_state (window->priv->record->pipeline) == GST_STATE_PLAYING);
+	return TRUE;
 }
 
-static gboolean
-play_iterate (GSRWindow *window)
+static void
+play_state_changed_cb (GstBus * bus, GstMessage * msg, GSRWindow * window)
 {
-	gboolean ret;
-	ret =  gst_bin_iterate (GST_BIN (window->priv->play->pipeline));
+	GstState new_state;
 
-	if (!ret)
-		gst_element_set_state (window->priv->play->pipeline, GST_STATE_NULL);
-	return ret;
-}
+	gst_message_parse_state_changed (msg, NULL, &new_state, NULL);
 
-static void
-play_state_changed_cb (GstElement *element,
-		       GstElementState old,
-		       GstElementState state,
-		       GSRWindow *window)
-{
-	switch (state) {
+	g_return_if_fail (GSR_IS_WINDOW (window));
+
+	/* we are only interested in state changes of the top-level pipeline */
+	if (msg->src != GST_OBJECT (window->priv->play->pipeline))
+		return;
+
+	window->priv->play->state = new_state;
+
+	switch (new_state) {
 	case GST_STATE_PLAYING:
-		g_idle_add ((GSourceFunc) play_iterate, window);
-		window->priv->tick_id = g_timeout_add (200, (GSourceFunc) tick_callback, window);
-#if 0
-		if (window->priv->len_secs == 0) {
-			window->priv->get_length_attempts = 16;
-			g_timeout_add (200, (GSourceFunc) get_length, window);
-		}
-#endif		
+		window->priv->play->tick_id =
+			g_timeout_add (200, (GSourceFunc) play_tick_callback, window);
+
 		set_action_sensitive (window, "Stop", TRUE);
 		set_action_sensitive (window, "Play", FALSE);
 		set_action_sensitive (window, "Record", FALSE);
@@ -1434,12 +1369,21 @@ play_state_changed_cb (GstElement *eleme
 				    window->priv->status_message_cid,
 				    _("Playing..."));
 
-		set_ebusy_timeout (window, NULL);
+		if (window->priv->ebusy_timeout_id) {
+			g_source_remove (window->priv->ebusy_timeout_id);
+			window->priv->ebusy_timeout_id = 0;
+			window->priv->ebusy_pipeline = NULL;
+		}
 		break;
 
 	case GST_STATE_READY:
+		if (window->priv->play->tick_id > 0) {
+			g_source_remove (window->priv->play->tick_id);
+			window->priv->play->tick_id = 0;
+		}
 		gtk_adjustment_set_value (GTK_RANGE (window->priv->scale)->adjustment, 0.0);
 		gtk_widget_set_sensitive (window->priv->scale, FALSE);
+		/* fallthrough */
 	case GST_STATE_PAUSED:
 		set_action_sensitive (window, "Stop", FALSE);
 		set_action_sensitive (window, "Play", TRUE);
@@ -1459,25 +1403,60 @@ play_state_changed_cb (GstElement *eleme
 }
 
 static void
-pipeline_deep_notify_cb (GstElement *element,
-			 GstElement *orig,
-			 GParamSpec *param,
-			 GSRWindow *window)
+pipeline_deep_notify_caps_cb (GstObject  *pipeline,
+                              GstObject  *object,
+                              GParamSpec *pspec,
+                              GSRWindow  *window)
 {
 	GSRWindowPrivate *priv;
-	GObject *obj;
-	const char *pname;
+	GstPadDirection direction;
+
+	if (!GST_IS_PAD (object))
+		return;
 
-	obj = G_OBJECT (orig);
 	priv = window->priv;
-	
-	pname = g_param_spec_get_name (param);
-	if (strstr (pname, "channels")) {
-		g_object_get (obj, "channels", &priv->n_channels, NULL);
-	} else if (strstr (pname, "samplerate")) {
-		g_object_get (obj,"samplerate", &priv->samplerate, NULL);
-	} else if (strstr (pname, "bitrate")) {
-		g_object_get (obj, "bitrate", &priv->bitrate, NULL);
+	if (priv->play && pipeline == GST_OBJECT_CAST (priv->play->pipeline)) {
+		direction = GST_PAD_SRC;
+	} else if (priv->record && pipeline == GST_OBJECT_CAST (priv->record->pipeline)) {
+		direction = GST_PAD_SINK;
+	} else {
+		g_return_if_reached ();
+	}
+
+	if (GST_PAD_DIRECTION (object) == direction) {
+		GstObject *pad_parent;
+
+		pad_parent = gst_object_get_parent (object);
+		if (GST_IS_ELEMENT (pad_parent)) {
+			GstElementFactory *factory;
+			GstElement *element;
+			const gchar *klass;
+
+			element = GST_ELEMENT_CAST (pad_parent);
+			factory = gst_element_get_factory (element);
+			klass = gst_element_factory_get_klass (factory);
+			if (klass && strstr (klass, "Audio") &&
+			    (strstr (klass, "Decoder") || strstr (klass, "Encoder"))) {
+				GstCaps *caps;
+
+				caps = gst_pad_get_negotiated_caps (GST_PAD_CAST (object));
+				if (caps) {
+					GstStructure *s;
+					gint val;
+
+					s = gst_caps_get_structure (caps, 0);
+					if (gst_structure_get_int (s, "channels", &val)) {
+						gst_atomic_int_set (&priv->atomic.n_channels, val);
+					}
+					if (gst_structure_get_int (s, "rate", &val)) {
+						gst_atomic_int_set (&priv->atomic.samplerate, val);
+					}
+					gst_caps_unref (caps);
+				}
+			}
+		}
+		if (pad_parent)
+			gst_object_unref (pad_parent);
 	}
 }
 
@@ -1496,56 +1475,88 @@ profile_changed_cb (GObject *object, GSR
 	g_free (id);
 }
 
+static void
+play_eos_msg_cb (GstBus * bus, GstMessage * msg, GSRWindow * window)
+{
+	g_return_if_fail (GSR_IS_WINDOW (window));
+
+	g_print ("Playback pipeline got EOS.\n");
+	gst_element_set_state (window->priv->play->pipeline, GST_STATE_NULL);
+}
+
 static GSRWindowPipeline *
 make_play_pipeline (GSRWindow *window)
 {
 	GSRWindowPipeline *obj;
-	GstElement *pipeline;
-	guint32 id;
-	GstElement *spider, *conv, *scale;
-
-	pipeline = gst_pipeline_new ("play-pipeline");
-	g_signal_connect (pipeline, "deep-notify",
-			  G_CALLBACK (pipeline_deep_notify_cb), window);
-	g_signal_connect (pipeline, "error",
-			  G_CALLBACK (pipeline_error_cb), window);
-	id = g_signal_connect (pipeline, "state-change",
-			       G_CALLBACK (play_state_changed_cb), window);
-
-	obj = g_new (GSRWindowPipeline, 1);
-	obj->pipeline = pipeline;
-	obj->state_change_id = id;
-	
-	obj->src = gst_element_factory_make ("filesrc", "src");
-	if (!obj->src)
-	{
-		g_error ("Could not find \"filesrc\" GStreamer plugin");
-		return NULL;
-	}
-	
- 	spider = gst_element_factory_make ("spider", "spider");
-	if (!spider) {
-		g_error ("Could not find \"spider\" GStreamer plugin");
+	GstElement *playbin;
+	GstElement *audiosink;
+	GstPad *sinkpad;
+
+	audiosink = gst_element_factory_make ("gconfaudiosink", "sink");
+	if (audiosink == NULL) {
+		show_error_dialog (NULL, NULL, _("Could not find \"%s\" GStreamer "
+		                   "plugin - please install it"), "gconfaudiosink");
 		return NULL;
 	}
 
-	conv = gst_element_factory_make ("audioconvert", "conf");
-	scale = gst_element_factory_make ("audioscale", "scale");
-	obj->sink = gst_gconf_get_default_audio_sink ();
-	if (!obj->sink)
-	{
-		g_error ("Could not find default audio output plugin ");
+	playbin = gst_element_factory_make ("playbin", "playbin");
+	if (playbin == NULL) {
+		gst_object_unref (audiosink);
+		show_error_dialog (NULL, NULL, _("Could not find \"%s\" GStreamer "
+		                   "plugin - please install it"), "playbin");
 		return NULL;
 	}
 
-	gst_bin_add_many (GST_BIN (pipeline),
-			  obj->src, spider, conv, scale, obj->sink, NULL);
-	gst_element_link_many (obj->src, spider, conv, scale, obj->sink, NULL);
+	obj = g_new0 (GSRWindowPipeline, 1);
+	obj->pipeline = playbin;
+	obj->src = NULL; /* don't need that for playback */
+	obj->sink = NULL; /* don't need that for playback */
+
+	g_object_set (playbin, "audio-sink", audiosink, NULL);
+
+	/* we ultimately want to find out the caps on the decoder's source pad */
+	g_signal_connect (playbin, "deep-notify::caps",
+	                  G_CALLBACK (pipeline_deep_notify_caps_cb),
+	                  window);
 
+	obj->bus = gst_element_get_bus (playbin);
+
+	gst_bus_add_signal_watch (obj->bus);
+
+	g_signal_connect (obj->bus, "message::state-changed",
+	                  G_CALLBACK (play_state_changed_cb),
+	                  window);
+
+	g_signal_connect (obj->bus, "message::error",
+	                  G_CALLBACK (pipeline_error_cb),
+	                  window);
+
+	g_signal_connect (obj->bus, "message::eos",
+	                  G_CALLBACK (play_eos_msg_cb),
+	                  window);
+	
 	return obj;
 }
 
-extern int sample_count;
+static void
+record_eos_msg_cb (GstBus * bus, GstMessage * msg, GSRWindow * window)
+{
+	g_return_if_fail (GSR_IS_WINDOW (window));
+
+	/* FIXME: why not NULL? (tpm) (do we want to keep the file open? why not pause then?) */
+	gst_element_set_state (window->priv->record->pipeline, GST_STATE_READY);
+
+	g_free (window->priv->working_file);
+	window->priv->working_file = g_strdup (window->priv->record_filename);
+
+	g_free (window->priv->filename);
+	window->priv->filename = g_strdup (window->priv->record_filename);
+
+	window->priv->dirty = TRUE;
+	window->priv->has_file = TRUE;
+}
+
+extern int gsr_sample_count;
 
 static gboolean
 record_start (gpointer user_data) 
@@ -1575,13 +1586,12 @@ record_start (gpointer user_data) 
 	 * there is no active sound sample. Any newly
 	 * recorded samples will be saved to disk with this
 	 * name as default value. */
-	if (sample_count == 1) {
+	if (gsr_sample_count == 1) {
 		name = g_strdup (_("Untitled"));
 	} else {
-		name = g_strdup_printf (_("Untitled-%d"),
-					sample_count);
+		name = g_strdup_printf (_("Untitled-%d"), gsr_sample_count);
 	}
-	sample_count++;
+	++gsr_sample_count;
 	gtk_window_set_title (GTK_WINDOW(window), name);
 
 	g_free (name);
@@ -1590,12 +1600,21 @@ record_start (gpointer user_data) 
 }
 
 static void
-record_state_changed_cb (GstElement *element,
-			 GstElementState old,
-			 GstElementState state,
-			 GSRWindow *window)
+record_state_changed_cb (GstBus *bus, GstMessage *msg, GSRWindow *window)
 {
-	switch (state) {
+	GstState  new_state;
+
+	gst_message_parse_state_changed (msg, NULL, &new_state, NULL);
+
+	g_return_if_fail (GSR_IS_WINDOW (window));
+
+	/* we are only interested in state changes of the top-level pipeline */
+	if (msg->src != GST_OBJECT (window->priv->record->pipeline))
+		return;
+
+	window->priv->record->state = new_state;
+
+	switch (new_state) {
 	case GST_STATE_PLAYING:
 		window->priv->record_id = g_idle_add (record_start, window);
 		gtk_widget_set_sensitive (window->priv->profile, FALSE);
@@ -1624,75 +1643,179 @@ record_state_changed_cb (GstElement *ele
 	}
 }
 
+/* go through a bin, finding the one pad that is unconnected in the given
+ * direction, and return that pad; nicked from the GStreamer gconf plugin */
+static GstPad *
+notgst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
+{
+	GstPad *pad = NULL;
+	GList *elements = NULL;
+	const GList *pads = NULL;
+	GstElement *element = NULL;
+
+	GST_OBJECT_LOCK (bin);
+	elements = bin->children;
+	/* traverse all elements looking for unconnected pads */
+	while (elements && pad == NULL) {
+		element = GST_ELEMENT (elements->data);
+		GST_OBJECT_LOCK (element);
+		pads = element->pads;
+		while (pads) {
+			GstPad *testpad = GST_PAD (pads->data);
+
+			/* check if the direction matches */
+			if (GST_PAD_DIRECTION (testpad) == direction) {
+				GST_OBJECT_LOCK (testpad);
+				if (GST_PAD_PEER (testpad) == NULL) {
+					GST_OBJECT_UNLOCK (testpad);
+					/* found it ! */
+					pad = testpad;
+					break;
+				}
+				GST_OBJECT_UNLOCK (testpad);
+			}
+			pads = g_list_next (pads);
+		}
+		GST_OBJECT_UNLOCK (element);
+		elements = g_list_next (elements);
+	}
+	GST_OBJECT_UNLOCK (bin);
+
+	return pad;
+}
+
+/* nicked from the GStreamer gconf plugin */
+static GstElement *
+notgst_render_bin_from_description (const gchar * description, GError ** err)
+{
+	GstPad *pad = NULL;
+	GstBin *bin;
+ 	gchar *desc;
+
+ 	/* parse the pipeline to a bin */
+ 	desc = g_strdup_printf ("bin.( %s )", description);
+	bin = (GstBin *) gst_parse_launch (desc, err);
+	g_free (desc);
+
+	if (bin == NULL || (err && *err != NULL)) {
+		if (bin)
+			gst_object_unref (bin);
+		return NULL;
+	}
+
+	/* find pads and ghost them if necessary */
+	if ((pad = notgst_bin_find_unconnected_pad (bin, GST_PAD_SRC))) {
+		gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("src", pad));
+	}
+	if ((pad = notgst_bin_find_unconnected_pad (bin, GST_PAD_SINK))) {
+		gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("sink", pad));
+	}
+
+	return GST_ELEMENT (bin);
+}
+
 static GSRWindowPipeline *
 make_record_pipeline (GSRWindow *window)
 {
 	GSRWindowPipeline *pipeline;
-	gint32 id;
 	GMAudioProfile *profile;
-	gchar *pipeline_desc, *source;
-	GstElement *esource = NULL, *encoder, *manager;
-	
-	pipeline = g_new (GSRWindowPipeline, 1);
-	pipeline->pipeline = gst_thread_new ("record-pipeline");
-	id = g_signal_connect (G_OBJECT (pipeline->pipeline),
-			       "state-change",
-			       G_CALLBACK (record_state_changed_cb),
-			       window);
-	pipeline->state_change_id = id;
-	
-	g_signal_connect (G_OBJECT (pipeline->pipeline), "error",
-			  G_CALLBACK (pipeline_error_cb), window);
-	
-        profile = gm_audio_profile_choose_get_active (window->priv->profile);
-	source = gst_gconf_get_string ("default/audiosrc");
-	if (source) {
-		esource = gst_gconf_render_bin_from_description (source);
-	}
-	if (!esource) {
-		show_error_dialog (NULL, _("There is no default GStreamer "
-				   "audio input plugin set - please install "
-				   "the GStreamer-GConf schemas or set one "
-				   "manually"));
+	const gchar *profile_pipeline_desc;
+	GstElement *encoder, *source, *filesink;
+	GError *err = NULL;
+	gchar *pipeline_desc;
+	
+	source = gst_element_factory_make ("gconfaudiosrc", "gconfaudiosource");
+	if (source == NULL) {
+		show_error_dialog (NULL, NULL, _("Could not find \"%s\" GStreamer "
+		                   "plugin - please install it"), "gconfaudiosrc");
 		return NULL;
 	}
-	pipeline->src = manager =
-		gst_element_factory_make ("manager", "manager");
-	gst_bin_add (GST_BIN (manager), esource);
-	gst_bin_add (GST_BIN (pipeline->pipeline), manager);
-
-	pipeline_desc = g_strdup_printf ("audioconvert ! %s",
-					 gm_audio_profile_get_pipeline (profile));
-	g_free (source);
-	
-	encoder = gst_gconf_render_bin_from_description (pipeline_desc);
+
+	/* Any reason we are not using gnomevfssink here?
+	 * just because it's not fast enough over the network? (tpm) */
+	filesink = gst_element_factory_make ("filesink", "sink");
+	if (filesink == NULL)
+	{
+		show_error_dialog (NULL, NULL, _("Could not find \"%s\" GStreamer "
+		                   "plugin - please install it"), "filesink");
+		gst_object_unref (source);
+		return NULL;
+	}
+
+	pipeline = g_new (GSRWindowPipeline, 1);
+
+	pipeline->pipeline = gst_pipeline_new ("record-pipeline");
+	pipeline->src = source;
+	pipeline->sink = filesink;
+
+	gst_bin_add (GST_BIN (pipeline->pipeline), source);
+
+	profile = gm_audio_profile_choose_get_active (window->priv->profile);
+	profile_pipeline_desc = gm_audio_profile_get_pipeline (profile);
+
+	pipeline_desc = g_strdup_printf ("audioconvert ! %s", profile_pipeline_desc);
+	encoder = notgst_render_bin_from_description (pipeline_desc, &err);
 	g_free (pipeline_desc);
-	if (!encoder) {
-		show_error_dialog (NULL, _("Failed to create GStreamer "
-				   "encoder plugins - check your encoding "
-				   "setup"));
+	pipeline_desc = NULL;
+
+	if (err) {
+		show_error_dialog (NULL, err->message, _("Failed to create GStreamer "
+				   "encoder plugins - check your encoding setup."));
+		g_printerr ("Failed to create GStreamer encoder plugins[%s]: %s",
+		           profile_pipeline_desc, err->message);
+		g_error_free (err);
+		gst_object_unref (pipeline->pipeline);
+		gst_object_unref (filesink);
+		g_free (pipeline);
 		return NULL;
 	}
+
 	gst_bin_add (GST_BIN (pipeline->pipeline), encoder);
-	
-	pipeline->sink = gst_element_factory_make ("filesink", "sink");
-	if (!pipeline->sink)
-	{
-		show_error_dialog (NULL, _("Could not find \"filesink\" GStreamer "
-				   "plugin - please install it"));
+	gst_bin_add (GST_BIN (pipeline->pipeline), filesink);
+
+	/* now link it all together */
+	if (!gst_element_link (source, encoder)) {
+		show_error_dialog (NULL, NULL, _("Failed to link input plugin "
+		                   "with encoder plugin - you probably "
+		                   "selected an invalid encoder"));
+		g_error_free (err);
+		gst_object_unref (pipeline->pipeline);
+		g_free (pipeline);
 		return NULL;
 	}
-	gst_bin_add (GST_BIN (pipeline->pipeline), pipeline->sink);
-	
-	if (!gst_element_link (manager, encoder) ||
-	    !gst_element_link (encoder, pipeline->sink))
-	{
-		show_error_dialog (NULL, _("Failed to link encoder plugin "
-				   "with file output plugin - you probably "
-				   "selected an invalid encoder"));
+
+	if (!gst_element_link (encoder, filesink)) {
+		show_error_dialog (NULL, NULL, _("Failed to link encoder plugin "
+		                   "with file output plugin - you probably "
+		                   "selected an invalid encoder"));
+		g_error_free (err);
+		gst_object_unref (pipeline->pipeline);
+		g_free (pipeline);
 		return NULL;
 	}
-	
+
+	/* we ultimately want to find out the caps on the encoder's source pad */
+	g_signal_connect (pipeline->pipeline, "deep-notify::caps",
+	                  G_CALLBACK (pipeline_deep_notify_caps_cb),
+	                  window);
+
+
+	pipeline->bus = gst_element_get_bus (pipeline->pipeline);
+
+	gst_bus_add_signal_watch (pipeline->bus);
+
+	g_signal_connect (pipeline->bus, "message::state-changed",
+	                  G_CALLBACK (record_state_changed_cb),
+	                  window);
+
+	g_signal_connect (pipeline->bus, "message::error",
+	                  G_CALLBACK (pipeline_error_cb),
+	                  window);
+
+	g_signal_connect (pipeline->bus, "message::eos",
+	                  G_CALLBACK (record_eos_msg_cb),
+	                  window);
+
 	return pipeline;
 }
 
@@ -1701,9 +1824,9 @@ calculate_format_value (GtkScale *scale,
 			double value,
 			GSRWindow *window)
 {
-	int seconds;
+	gint seconds;
 
-	if (window->priv->record && gst_element_get_state (window->priv->record->pipeline) == GST_STATE_PLAYING) {
+	if (window->priv->record && window->priv->record->state == GST_STATE_PLAYING) {
 		seconds = value;
 		return seconds_to_string (seconds);
 	} else {
@@ -1843,7 +1966,7 @@ gsr_window_init (GSRWindow *window)
 	gtk_ui_manager_add_ui_from_file (priv->ui_manager, GSR_UIDIR "ui.xml", &error);
 	if (error != NULL)
 	{
-		show_error_dialog (GTK_WINDOW (window),
+		show_error_dialog (GTK_WINDOW (window), error->message,
 			_("Could not load ui.xml. The program may be not properly installed"));
 		g_error_free (error);
 		exit (1);
@@ -1909,9 +2032,9 @@ gsr_window_init (GSRWindow *window)
 	priv->seek_in_progress = FALSE;
 	g_signal_connect (priv->scale, "format-value",
 			  G_CALLBACK (calculate_format_value), window);
-	g_signal_connect (priv->scale, "button_press_event",
+	g_signal_connect (priv->scale, "button-press-event",
 			  G_CALLBACK (seek_started), window);
-	g_signal_connect (priv->scale, "button_release_event",
+	g_signal_connect (priv->scale, "button-release-event",
 			  G_CALLBACK (seek_to), window);
 
 	gtk_scale_set_value_pos (GTK_SCALE (window->priv->scale), GTK_POS_BOTTOM);
@@ -1977,7 +2100,7 @@ gsr_window_init (GSRWindow *window)
 			  GTK_FILL, 0, 0, 0);
 	
 	priv->length_label = gtk_label_new ("");
-	gtk_label_set_selectable (GTK_LABEL (priv->length_label), TRUE);
+	gtk_label_set_selectable (GTK_LABEL (priv->length_label), FALSE);
 	gtk_misc_set_alignment (GTK_MISC (priv->length_label), 0, 0.5);
 	gtk_table_attach (GTK_TABLE (table), priv->length_label,
 			  1, 2, 1, 2,
@@ -2006,7 +2129,6 @@ gsr_window_init (GSRWindow *window)
 	priv->len_secs = 0;
 	priv->get_length_attempts = 16;
 	priv->dirty = FALSE;
-	priv->gstenc_id = 0;
 }
 
 static void
@@ -2116,6 +2238,10 @@ gsr_window_finalize (GObject *object)
 		g_source_remove (priv->record_id);
 	}
 
+	if (priv->ebusy_timeout_id > 0) {
+		g_source_remove (window->priv->ebusy_timeout_id);
+	}
+
 	g_idle_remove_by_data (window);
 
 	if (priv->play != NULL) {
@@ -2195,9 +2321,8 @@ gsr_window_new (const char *filename)
 {
 	GSRWindow *window;
 	struct stat buf;
-	char *short_name;
 
-        /* filename has been changed to be without extension */
+	/* filename has been changed to be without extension */
 	window = g_object_new (GSR_TYPE_WINDOW, 
 			       "location", filename,
 			       NULL);
Index: grecord/src/gsr-window.h
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gsr-window.h,v
retrieving revision 1.4
diff -u -p -r1.4 gsr-window.h
--- grecord/src/gsr-window.h	2 May 2005 10:19:31 -0000	1.4
+++ grecord/src/gsr-window.h	9 Jan 2006 12:26:19 -0000
@@ -57,4 +57,8 @@ GtkWidget	*gsr_window_new		(const char *
 
 void		 gsr_window_close	(GSRWindow *window);
 
+gboolean     gsr_window_is_saved (GSRWindow *window);
+
+void         close_confirmation_dialog (GSRWindow *window);
+
 #endif
Index: grecord/src/gst/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gst/Makefile.am,v
retrieving revision 1.1
diff -u -p -r1.1 Makefile.am
--- grecord/src/gst/Makefile.am	21 Mar 2005 10:23:05 -0000	1.1
+++ grecord/src/gst/Makefile.am	9 Jan 2006 12:26:19 -0000
@@ -1,13 +1,15 @@
-noinst_LTLIBRARIES = \
-	libgstrecelements.la
-
-libgstrecelements_la_SOURCES = \
-	assistant.c \
-	manager.c
-
-libgstrecelements_la_CFLAGS = $(GSR_CFLAGS)
-libgstrecelements_la_LIBADD = $(GSR_LIBS)
-
-noinst_HEADERS = \
-	assistant.h \
-	manager.h
+# We do not need these for GStreamer-0.10
+#
+#noinst_LTLIBRARIES = \
+#	libgstrecelements.la
+#
+#libgstrecelements_la_SOURCES = \
+#	manager.c \
+#	assistant.c
+#
+#libgstrecelements_la_CFLAGS = $(GSR_CFLAGS)
+#libgstrecelements_la_LIBADD = $(GSR_LIBS)
+#
+#noinst_HEADERS = \
+#	assistant.h \
+#	manager.h
Index: grecord/src/gst/assistant.c
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gst/assistant.c,v
retrieving revision 1.1
diff -u -p -r1.1 assistant.c
--- grecord/src/gst/assistant.c	21 Mar 2005 10:23:05 -0000	1.1
+++ grecord/src/gst/assistant.c	9 Jan 2006 12:26:20 -0000
@@ -18,6 +18,7 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+#if 0
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -31,7 +32,7 @@ static void gst_rec_assistant_base_init 
 static void gst_rec_assistant_init (GstRecAssistant * assistant);
 
 /* proxying data */
-static void gst_rec_assistant_chain (GstPad * pad, GstData * data);
+static void gst_rec_assistant_chain (GstPad * pad, GstBuffer * buf);
 
 /* the event handler - it's all about him */
 static gboolean gst_rec_assistant_src_event (GstPad * pad, GstEvent * event);
@@ -87,7 +88,7 @@ gst_rec_assistant_class_init (GstRecAssi
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+  parent_class = g_type_class_peek_parent (klass);
 
   element_class->change_state = gst_rec_assistant_change_state;
 }
@@ -95,7 +96,7 @@ gst_rec_assistant_class_init (GstRecAssi
 static void
 gst_rec_assistant_init (GstRecAssistant * assistant)
 {
-  GST_FLAG_SET (assistant, GST_ELEMENT_EVENT_AWARE);
+  /*  GST_FLAG_SET (assistant, GST_ELEMENT_EVENT_AWARE); */
 
   assistant->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
   gst_pad_set_chain_function (assistant->sinkpad, gst_rec_assistant_chain);
@@ -160,6 +161,9 @@ gst_rec_assistant_change_state (GstEleme
 {
   GstRecAssistant *assistant = GST_REC_ASSISTANT (element);
 
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
   switch (GST_STATE_TRANSITION (element)) {
     case GST_STATE_PAUSED_TO_READY:
       assistant->eos = FALSE;
@@ -168,8 +172,9 @@ gst_rec_assistant_change_state (GstEleme
       break;
   }
 
-  if (GST_ELEMENT_CLASS (parent_class)->change_state)
-    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
 
   return GST_STATE_SUCCESS;
 }
+
+#endif
+
Index: grecord/src/gst/assistant.h
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gst/assistant.h,v
retrieving revision 1.1
diff -u -p -r1.1 assistant.h
--- grecord/src/gst/assistant.h	21 Mar 2005 10:23:05 -0000	1.1
+++ grecord/src/gst/assistant.h	9 Jan 2006 12:26:20 -0000
@@ -18,6 +18,7 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+#if 0
 
 #ifndef __GST_REC_ASSISTANT_H__
 #define __GST_REC_ASSISTANT_H__
@@ -56,3 +57,5 @@ typedef struct _GstRecAssistantClass
 GType gst_rec_assistant_get_type (void);
 
 #endif /* __GST_REC_ASSISTANT_H__ */
+
+#endif
Index: grecord/src/gst/manager.c
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gst/manager.c,v
retrieving revision 1.1
diff -u -p -r1.1 manager.c
--- grecord/src/gst/manager.c	21 Mar 2005 10:23:05 -0000	1.1
+++ grecord/src/gst/manager.c	9 Jan 2006 12:26:20 -0000
@@ -7,7 +7,8 @@
  * a stream, seeks which aren't anything else than a timestamp
  * shift (on elements not supporting seek) and some more. This
  * can be considered an application-extension to GStreamer events,
- * outside it's original goal, and thus not useful inside gst-core.
+ * outside its original goal, and thus not useful inside gst-core.
+ *
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,6 +26,8 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#if 0
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -32,47 +35,17 @@
 #include "assistant.h"
 #include "manager.h"
 
-static void gst_rec_manager_class_init (GstRecManagerClass * klass);
-static void gst_rec_manager_base_init (GstRecManagerClass * klass);
-static void gst_rec_manager_init (GstRecManager * manager);
 static void gst_rec_manager_dispose (GObject * obj);
 
 static void gst_rec_manager_child_eos (GstElement * element, gpointer data);
 
-static void gst_rec_manager_child_add (GstBin * bin, GstElement * child);
-static void gst_rec_manager_child_del (GstBin * bin, GstElement * child);
-
-static GstBinClass *parent_class = NULL;
-
-GType
-gst_rec_manager_get_type (void)
-{
-  static GType gst_rec_manager_type = 0;
-
-  if (!gst_rec_manager_type) {
-    static const GTypeInfo gst_rec_manager_info = {
-      sizeof (GstRecManagerClass),
-      (GBaseInitFunc) gst_rec_manager_base_init,
-      NULL,
-      (GClassInitFunc) gst_rec_manager_class_init,
-      NULL,
-      NULL,
-      sizeof (GstRecManager),
-      0,
-      (GInstanceInitFunc) gst_rec_manager_init,
-      NULL
-    };
-
-    gst_rec_manager_type =
-	g_type_register_static (GST_TYPE_BIN,
-	"GstRecManager", &gst_rec_manager_info, 0);
-  }
+static gboolean gst_rec_manager_child_add (GstBin * bin, GstElement * child);
+static gboolean gst_rec_manager_child_del (GstBin * bin, GstElement * child);
 
-  return gst_rec_manager_type;
-}
+GST_BOILERPLATE (GstRecManager, gst_rec_manager, GstBin, GST_TYPE_BIN);
 
 static void
-gst_rec_manager_base_init (GstRecManagerClass * klass)
+gst_rec_manager_base_init (gpointer klass)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   static GstElementDetails gst_rec_manager_details =
@@ -90,15 +63,13 @@ gst_rec_manager_class_init (GstRecManage
   GstBinClass *bin_class = GST_BIN_CLASS (klass);
   GObjectClass *obj_class = G_OBJECT_CLASS (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_BIN);
-
   bin_class->add_element = gst_rec_manager_child_add;
   bin_class->remove_element = gst_rec_manager_child_del;
   obj_class->dispose = gst_rec_manager_dispose;
 }
 
 static void
-gst_rec_manager_init (GstRecManager * manager)
+gst_rec_manager_init (GstRecManager * manager, GstRecManagerClass * klass)
 {
   GstElement *assistant;
   GstPad *pad;
@@ -137,7 +108,7 @@ gst_rec_manager_child_eos (GstElement * 
   gst_element_set_eos (GST_ELEMENT (data));
 }
 
-static void
+static gboolean
 gst_rec_manager_child_add (GstBin * bin, GstElement * child)
 {
   GstRecManager *manager = GST_REC_MANAGER (bin);
@@ -160,10 +131,12 @@ gst_rec_manager_child_add (GstBin * bin,
   }
 
   if (parent_class->add_element)
-    parent_class->add_element (bin, child);
+    return parent_class->add_element (bin, child);
+
+  return TRUE;
 }
 
-static void
+static gboolean
 gst_rec_manager_child_del (GstBin * bin, GstElement * child)
 {
   GstRecManager *manager = GST_REC_MANAGER (bin);
@@ -185,7 +158,9 @@ gst_rec_manager_child_del (GstBin * bin,
   }
 
   if (parent_class->remove_element)
-    parent_class->remove_element (bin, child);
+    return parent_class->remove_element (bin, child);
+
+  return TRUE;
 }
 
 static gboolean
@@ -217,3 +192,4 @@ gst_rec_elements_init (void)
 {
   _gst_plugin_register_static (&plugin_desc);
 }
+#endif
Index: grecord/src/gst/manager.h
===================================================================
RCS file: /cvs/gnome/gnome-media/grecord/src/gst/manager.h,v
retrieving revision 1.1
diff -u -p -r1.1 manager.h
--- grecord/src/gst/manager.h	21 Mar 2005 10:23:05 -0000	1.1
+++ grecord/src/gst/manager.h	9 Jan 2006 12:26:20 -0000
@@ -18,6 +18,7 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+#if 0
 
 #ifndef __GST_REC_MANAGER_H__
 #define __GST_REC_MANAGER_H__
@@ -59,3 +60,5 @@ GType gst_rec_manager_get_type (void);
 void gst_rec_elements_init (void);
 
 #endif /* __GST_REC_MANAGER_H__ */
+
+#endif
Index: gst-mixer/src/element.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/element.c,v
retrieving revision 1.6
diff -u -p -r1.6 element.c
--- gst-mixer/src/element.c	8 Apr 2005 08:13:58 -0000	1.6
+++ gst-mixer/src/element.c	9 Jan 2006 12:26:21 -0000
@@ -25,7 +25,6 @@
 
 #include <gnome.h>
 #include <gtk/gtk.h>
-#include <gst/mixer/mixer.h>
 
 #include "element.h"
 #include "keys.h"
Index: gst-mixer/src/element.h
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/element.h,v
retrieving revision 1.3
diff -u -p -r1.3 element.h
--- gst-mixer/src/element.h	10 Jan 2005 21:10:42 -0000	1.3
+++ gst-mixer/src/element.h	9 Jan 2006 12:26:21 -0000
@@ -26,7 +26,7 @@
 #include <gtk/gtknotebook.h>
 #include <libgnomeui/gnome-appbar.h>
 #include <gconf/gconf-client.h>
-#include <gst/mixer/mixer.h>
+#include <gst/interfaces/mixer.h>
 
 G_BEGIN_DECLS
 
Index: gst-mixer/src/main.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/main.c,v
retrieving revision 1.8
diff -u -p -r1.8 main.c
--- gst-mixer/src/main.c	21 Dec 2005 14:10:00 -0000	1.8
+++ gst-mixer/src/main.c	9 Jan 2006 12:26:21 -0000
@@ -27,22 +27,12 @@
 #include <glib.h>
 #include <gnome.h>
 #include <gst/gst.h>
-#include <gst/mixer/mixer.h>
-#include <gst/propertyprobe/propertyprobe.h>
+#include <gst/audio/mixerutils.h>
 
 #include "keys.h"
 #include "stock.h"
 #include "window.h"
 
-static gint
-sort_by_rank (GstElement * a, GstElement * b)
-{
-#define gst_element_rank(x) \
-  gst_plugin_feature_get_rank (GST_PLUGIN_FEATURE ( \
-      gst_element_get_factory (x)))
-  return gst_element_rank (b) - gst_element_rank (a);
-}
-
 /*
  * Probe for mixer elements. Set up GList * with elements,
  * where each element has a GObject data node set of the
@@ -53,107 +43,64 @@ sort_by_rank (GstElement * a, GstElement
  * GST_STATE_NULL.
  */
 
-static GList *
-create_mixer_collection (void)
+static gboolean
+mixer_filter_func (GstMixer * mixer, gpointer user_data)
 {
-  const GList *elements;
-  GList *collection = NULL;
-  gint num = 0;
-
-  /* go through all elements of a certain class and check whether
-   * they implement a mixer. If so, add it to the list. */
-  elements = gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY);
-  for ( ; elements != NULL; elements = elements->next) {
-    GstElementFactory *factory = GST_ELEMENT_FACTORY (elements->data);
-    gchar *title = NULL, *name;
-    const gchar *klass;
-    GstElement *element = NULL;
-    const GParamSpec *devspec;
-    GstPropertyProbe *probe;
-    GValueArray *array = NULL;
-    gint n;
-
-    /* check category */
-    klass = gst_element_factory_get_klass (factory);
-    if (strcmp (klass, "Generic/Audio"))
-      goto next;
-
-    /* FIXME:
-     * - maybe we want to rename the element to its actual name
-     *     if we've found that?
-     */
-#define _label N_("Unknown Volume Control %d")
-
-    /* create element */
-    title = g_strdup_printf (gettext("Unknown Volume Control %d"), num);
-    element = gst_element_factory_create (factory, title);
-    if (!element)
-      goto next;
-
-    if (!GST_IS_PROPERTY_PROBE (element))
-      goto next;
-
-    probe = GST_PROPERTY_PROBE (element);
-    if (!(devspec = gst_property_probe_get_property (probe, "device")))
-      goto next;
-    if (!(array = gst_property_probe_probe_and_get_values (probe, devspec)))
-      goto next;
-
-    /* set all devices and test for mixer */
-    for (n = 0; n < array->n_values; n++) {
-      GValue *device = g_value_array_get_nth (array, n);
-      gchar *devname = NULL;
-
-      /* set this device */
-      g_object_set_property (G_OBJECT (element), "device", device);
-      if (gst_element_set_state (element,
-				 GST_STATE_READY) == GST_STATE_FAILURE)
-        continue;
-
-      /* is this device a mixer? */
-      if (!GST_IS_MIXER (element)) {
-        gst_element_set_state (element, GST_STATE_NULL);
-        continue;
-      }
-
-      /* any tracks? */
-      if (!gst_mixer_list_tracks (GST_MIXER (element))) {
-        gst_element_set_state (element, GST_STATE_NULL);
-        continue;
-      }
-
-      /* fetch name */
-      if (g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (element)),
-					"device-name")) {
-        g_object_get (element, "device-name", &devname, NULL);
-      }
-
-      name = g_strdup_printf ("%s (%s)", devname ? devname : title,
-			      gst_element_factory_get_longname (factory));
-      g_free (devname);
-      g_object_set_data (G_OBJECT (element), "gnome-volume-control-name",
-			 name);
-
-      /* add to list */
-      gst_element_set_state (element, GST_STATE_NULL);
-      collection = g_list_append (collection, element);
-      num++;
-
-      /* and recreate this object, since we give it to the mixer */
-      g_free (title);
-      title = g_strdup_printf (gettext("Unknown Volume Control %d"), num);
-      element = gst_element_factory_create (factory, title);
-    }
+  GstElementFactory *factory;
+  const gchar *long_name;
+  gchar *devname = NULL;
+  gchar *name;
+  gint *p_count = (gint *) user_data;
+
+  /* fetch name */
+  if (g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (mixer)),
+                                    "device-name")) {
+    g_object_get (mixer, "device-name", &devname, NULL);
+    GST_DEBUG ("device name: %s", GST_STR_NULL (devname));
+  } else {
+    devname = NULL;
+    GST_DEBUG ("device name unknown, no 'device-name' property");
+  }
+    
+  factory = gst_element_get_factory (GST_ELEMENT (mixer));
+  long_name = gst_element_factory_get_longname (factory);
+
+  if (devname) {
+    name = g_strdup_printf ("%s (%s)", devname, long_name);
+    g_free (devname);
+  } else {
+    gchar *title;
+
+    *p_count += 1;
 
-next:
-    if (element)
-      gst_object_unref (GST_OBJECT (element));
-    if (array)
-      g_value_array_free (array);
+    title = g_strdup_printf (_("Unknown Volume Control %d"),  *p_count);
+    name = g_strdup_printf ("%s (%s)", title, long_name);
     g_free (title);
   }
 
-  return g_list_sort (collection, (GCompareFunc) sort_by_rank);
+  g_object_set_data_full (G_OBJECT (mixer),
+                          "gnome-volume-control-name",
+                          name,
+                          (GDestroyNotify) g_free);
+
+  GST_DEBUG ("Adding '%s' to list of available mixers", name);
+
+  gst_element_set_state (GST_ELEMENT (mixer), GST_STATE_NULL);
+
+  return TRUE; /* add mixer to list */
+}
+
+static GList *
+create_mixer_collection (void)
+{
+  GList *mixer_list;
+  gint counter = 0;
+
+  mixer_list = gst_audio_default_registry_mixer_filter (mixer_filter_func,
+                                                        FALSE,
+                                                        &counter);
+
+  return mixer_list;
 }
 
 static void
@@ -221,10 +168,6 @@ main (gint   argc,
 {
   gchar *appfile;
   GtkWidget *win;
-  struct poptOption options[] = {
-    { NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, "GStreamer", NULL },
-    POPT_TABLEEND
-  };
   GList *elements;
 
   /* i18n */
@@ -232,31 +175,29 @@ main (gint   argc,
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
   textdomain (GETTEXT_PACKAGE);
 
-  /* init gstreamer */
-  options[0].arg = (void *) gst_init_get_popt_table ();
-
-  /* init gtk/gnome */
+/* FIXME: remove when bumping requirements to 2.14 */
+#ifdef GNOME_PARAM_GOPTION_CONTEXT
+  if (1) {
+    GOptionContext *ctx;
+    GOptionGroup *group;
+
+    ctx = g_option_context_new ("gnome-volume-control");
+    g_option_context_add_group (ctx, gst_init_get_option_group ());
+
+    gnome_program_init ("gnome-volume-control", VERSION,
+                        LIBGNOMEUI_MODULE, argc, argv,
+                        GNOME_PARAM_GOPTION_CONTEXT, ctx,
+                        GNOME_PARAM_APP_DATADIR, DATA_DIR,
+                        NULL);
+  }
+#else /* GNOME_PARAM_GOPTION_CONTEXT */
+  gst_init (&argc, &argv);
   gnome_program_init ("gnome-volume-control", VERSION,
 		      LIBGNOMEUI_MODULE, argc, argv,
-		      GNOME_PARAM_POPT_TABLE, options,
 		      GNOME_PARAM_APP_DATADIR, DATA_DIR, NULL);
 
-   if (!gst_scheduler_factory_get_default_name ()) {
-		GtkWidget *dialog;
-
-		dialog = gtk_message_dialog_new (NULL,
-						 0,
-						 GTK_MESSAGE_ERROR,
-						 GTK_BUTTONS_CLOSE,
-						 _("Registry is not present or it is corrupted, please update it by running gst-register"));
-
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (dialog);
-
-		exit (1);
-	}
+#endif /* GNOME_PARAM_GOPTION_CONTEXT */
 
-		
 
   /* init ourselves */
   register_stock_icons ();
Index: gst-mixer/src/preferences.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/preferences.c,v
retrieving revision 1.4
diff -u -p -r1.4 preferences.c
--- gst-mixer/src/preferences.c	3 Apr 2005 15:26:51 -0000	1.4
+++ gst-mixer/src/preferences.c	9 Jan 2006 12:26:22 -0000
@@ -25,7 +25,6 @@
 
 #include <gnome.h>
 #include <gtk/gtk.h>
-#include <gst/mixer/mixer.h>
 
 #include "element.h"
 #include "preferences.h"
Index: gst-mixer/src/preferences.h
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/preferences.h,v
retrieving revision 1.1
diff -u -p -r1.1 preferences.h
--- gst-mixer/src/preferences.h	16 Sep 2004 20:20:11 -0000	1.1
+++ gst-mixer/src/preferences.h	9 Jan 2006 12:26:22 -0000
@@ -25,7 +25,7 @@
 #include <glib.h>
 #include <gtk/gtkdialog.h>
 #include <gconf/gconf-client.h>
-#include <gst/mixer/mixer.h>
+#include <gst/interfaces/mixer.h>
 
 G_BEGIN_DECLS
 
Index: gst-mixer/src/track.h
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/track.h,v
retrieving revision 1.2
diff -u -p -r1.2 track.h
--- gst-mixer/src/track.h	11 Dec 2004 11:26:45 -0000	1.2
+++ gst-mixer/src/track.h	9 Jan 2006 12:26:22 -0000
@@ -26,7 +26,7 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <gst/gst.h>
-#include <gst/mixer/mixer.h>
+#include <gst/interfaces/mixer.h>
 
 #include "button.h"
 
Index: gst-mixer/src/volume.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/volume.c,v
retrieving revision 1.6
diff -u -p -r1.6 volume.c
--- gst-mixer/src/volume.c	8 Aug 2005 21:05:37 -0000	1.6
+++ gst-mixer/src/volume.c	9 Jan 2006 12:26:22 -0000
@@ -29,11 +29,10 @@
 #include <gnome.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
-#include <gst/mixer/mixer.h>
 
+#include "volume.h"
 #include "button.h"
 #include "stock.h"
-#include "volume.h"
 
 static void	gnome_volume_control_volume_class_init	(GnomeVolumeControlVolumeClass *klass);
 static void	gnome_volume_control_volume_init	(GnomeVolumeControlVolume *el);
Index: gst-mixer/src/volume.h
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/volume.h,v
retrieving revision 1.2
diff -u -p -r1.2 volume.h
--- gst-mixer/src/volume.h	11 Jan 2005 15:10:21 -0000	1.2
+++ gst-mixer/src/volume.h	9 Jan 2006 12:26:22 -0000
@@ -24,7 +24,7 @@
 
 #include <glib.h>
 #include <gtk/gtkfixed.h>
-#include <gst/mixer/mixer.h>
+#include <gst/interfaces/mixer.h>
 
 G_BEGIN_DECLS
 
Index: gst-mixer/src/window.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gst-mixer/src/window.c,v
retrieving revision 1.9
diff -u -p -r1.9 window.c
--- gst-mixer/src/window.c	21 Dec 2005 14:57:01 -0000	1.9
+++ gst-mixer/src/window.c	9 Jan 2006 12:26:23 -0000
@@ -276,9 +276,7 @@ gnome_volume_control_window_dispose (GOb
       GstElement *element = GST_ELEMENT (item->data);
 
       gst_element_set_state (element, GST_STATE_NULL);
-      g_free (g_object_get_data (G_OBJECT (element),
-				 "gnome-volume-control-name"));
-      gst_object_unref (GST_OBJECT (element));
+      gst_object_unref (element);
     }
     g_list_free (win->elements);
     win->elements = NULL;
Index: gstreamer-properties/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-media/gstreamer-properties/Makefile.am,v
retrieving revision 1.10
diff -u -p -r1.10 Makefile.am
--- gstreamer-properties/Makefile.am	9 Nov 2004 17:21:53 -0000	1.10
+++ gstreamer-properties/Makefile.am	9 Jan 2006 12:26:23 -0000
@@ -28,7 +28,7 @@ INCLUDES   = \
 	-DGSTPROPS_ICONDIR=\""$(iconsdir)"\" \
 	-DDATADIR=\""$(datadir)"\" \
 	-DGNOMELOCALEDIR="${prefix}/${DATADIRNAME}/locale" \
-	-DG_LOG_DOMAIN="gstreamer-properties"
+	-DG_LOG_DOMAIN="\"gstreamer-properties\""
 
 CLEANFILES = $(GSTPROPS_CLEANFILES) $(desktop_DATA)
 EXTRA_DIST = $(icons_DATA) $(glade_DATA) $(Desktop_in_files)
Index: gstreamer-properties/gstreamer-properties.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gstreamer-properties/gstreamer-properties.c,v
retrieving revision 1.14
diff -u -p -r1.14 gstreamer-properties.c
--- gstreamer-properties/gstreamer-properties.c	8 Jun 2005 09:00:46 -0000	1.14
+++ gstreamer-properties/gstreamer-properties.c	9 Jan 2006 12:26:24 -0000
@@ -3,6 +3,7 @@
 
 /* gstreamer-properties.c
  * Copyright (C) 2002 Jan Schmidt
+ * Copyright (C) 2005 Tim-Philipp Müller <tim centricular net>
  *
  * Written by: Jan Schmidt <thaytan@mad.scientist.com>
  *
@@ -29,9 +30,9 @@
 #include <locale.h>
 #include <string.h>
 #include <gnome.h>
-#include <gst/gconf/gconf.h>
 #include <glade/glade.h>
 #include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
 #include <gst/gst.h>
 #include "gstreamer-properties-structs.h"
 #include "pipeline-tests.h"
@@ -43,303 +44,416 @@ static GtkDialog *main_window;
 static gchar pipeline_editor_property[] = "gstp-editor";
 static gchar pipeline_desc_property[] = "gstp-pipe-desc";
 
+static gchar *
+gst_properties_gconf_get_full_key (const gchar * key)
+{
+  return g_strdup_printf ("/system/gstreamer/%d.%d/%s",
+      GST_VERSION_MAJOR, GST_VERSION_MINOR, key);
+}
+
+gchar *
+gst_properties_gconf_get_string (const gchar * key)
+{
+  GConfClient *client;
+  GError *error = NULL;
+  gchar *value = NULL;
+  gchar *full_key;
+
+  full_key = gst_properties_gconf_get_full_key (key);
+
+  client = gconf_client_get_default ();
+
+  value = gconf_client_get_string (client, full_key, &error);
+  g_free (full_key);
+
+  if (error) {
+    g_warning ("%s() error: %s", __FUNCTION__, error->message);
+    g_error_free (error);
+    return NULL;
+  }
+
+  return value;
+}
+
+void
+gst_properties_gconf_set_string (const gchar * key, const gchar * value)
+{
+  GConfClient *client;
+  GError *error = NULL;
+  gchar *full_key;
+
+  full_key = gst_properties_gconf_get_full_key (key);
+  client = gconf_client_get_default ();
+
+  gconf_client_set_string (client, full_key, value, &error);
+  g_free (full_key);
+
+  if (error) {
+    g_warning ("%s() error: %s", __FUNCTION__, error->message);
+    g_error_free (error);
+  }
+}
+
 static void
 dialog_response (GtkDialog * widget, gint response_id, GladeXML * dialog)
 {
-	if (response_id == GTK_RESPONSE_HELP)
-		gnome_help_display ("gstreamer-properties.xml", NULL, NULL);
-	else
-		gtk_main_quit ();
+  if (response_id == GTK_RESPONSE_HELP)
+    gnome_help_display ("gstreamer-properties.xml", NULL, NULL);
+  else
+    gtk_main_quit ();
 }
 
 static void
 test_button_clicked (GtkButton * button, gpointer user_data)
 {
-	GSTPPipelineEditor* editor = (GSTPPipelineEditor*)(user_data);
-	GSTPPipelineDescription *pipeline_desc = editor->pipeline_desc + editor->cur_pipeline_index;
-	if (pipeline_desc->is_custom) {
-		GtkEntry* entry = editor->entry;
-		pipeline_desc->pipeline = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
-	}
-	
-	user_test_pipeline(interface_xml, GTK_WINDOW(main_window), pipeline_desc);
-	
-	if (pipeline_desc->is_custom) {
-		g_free(pipeline_desc->pipeline);
-		pipeline_desc->pipeline = NULL;
-	}
+  GSTPPipelineEditor *editor = (GSTPPipelineEditor *) (user_data);
+  GSTPPipelineDescription *pipeline_desc =
+      editor->pipeline_desc + editor->cur_pipeline_index;
+  if (pipeline_desc->is_custom) {
+    GtkEntry *entry = editor->entry;
+
+    pipeline_desc->pipeline = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+  }
+
+  user_test_pipeline (interface_xml, GTK_WINDOW (main_window), pipeline_desc);
+
+  if (pipeline_desc->is_custom) {
+    g_free (pipeline_desc->pipeline);
+    pipeline_desc->pipeline = NULL;
+  }
+}
+
+static void
+update_from_option (GSTPPipelineEditor * editor,
+    GSTPPipelineDescription * pipeline_desc)
+{
+  /* optionmenu changed, update the edit box, 
+   * and the appropriate GConf key */
+  /* FIXME g_return_if_fail(editor); */
+  /* g_return_if_fail(pipeline_desc); */
+
+  editor->cur_pipeline_index = pipeline_desc->index;
+
+  if (pipeline_desc->is_custom == FALSE) {
+    if (pipeline_desc->pipeline)
+      gtk_entry_set_text (editor->entry, pipeline_desc->pipeline);
+    gtk_widget_set_sensitive (GTK_WIDGET (editor->entry), FALSE);
+
+    /* Update GConf */
+    gst_properties_gconf_set_string (editor->gconf_key,
+        pipeline_desc->pipeline);
+  } else {
+    gtk_widget_set_sensitive (GTK_WIDGET (editor->entry), TRUE);
+  }
 }
 
 static void
-update_from_option (GSTPPipelineEditor* editor,
-		    GSTPPipelineDescription* pipeline_desc)
+set_menuitem_by_pipeline (GtkWidget * widget, gpointer data)
 {
-	/* optionmenu changed, update the edit box, 
-	 * and the appropriate GConf key */	
-	/* FIXME g_return_if_fail(editor); */
-	/* g_return_if_fail(pipeline_desc); */
-	
-	editor->cur_pipeline_index = pipeline_desc->index;
-	
-	if (pipeline_desc->is_custom == FALSE)
-	{
-		if (pipeline_desc->pipeline)
-			gtk_entry_set_text (editor->entry, pipeline_desc->pipeline);
-		gtk_widget_set_sensitive (GTK_WIDGET (editor->entry), FALSE);
-
-		/* Update GConf */
-		gst_gconf_set_string (editor->gconf_key, pipeline_desc->pipeline);
-	}
-	else
-	{
-		gtk_widget_set_sensitive (GTK_WIDGET (editor->entry), TRUE);
-	}
+  GSTPPipelineEditor *editor = (GSTPPipelineEditor *) (data);
+
+  if (GTK_IS_MENU_ITEM (widget)) {
+    GtkMenuItem *mi = GTK_MENU_ITEM (widget);
+    GSTPPipelineDescription *pipeline_desc =
+        (GSTPPipelineDescription *) (g_object_get_data (G_OBJECT (mi),
+            pipeline_desc_property));
+    if (pipeline_desc == (editor->pipeline_desc + editor->cur_pipeline_index)) {
+      GtkMenuShell *menu =
+          GTK_MENU_SHELL (gtk_option_menu_get_menu (editor->optionmenu));
+      gtk_option_menu_set_history (editor->optionmenu,
+          g_list_index (menu->children, mi));
+    }
+  }
 }
 
 static void
-set_menuitem_by_pipeline (GtkWidget *widget, gpointer data)
+update_from_gconf (GSTPPipelineEditor * editor, const gchar * pipeline_str)
 {
-	GSTPPipelineEditor* editor = (GSTPPipelineEditor*)(data);
-	if (GTK_IS_MENU_ITEM(widget)) {
-		GtkMenuItem* mi = GTK_MENU_ITEM(widget);
-		GSTPPipelineDescription* pipeline_desc =
-			(GSTPPipelineDescription*) (g_object_get_data (G_OBJECT (mi), pipeline_desc_property));
-		if (pipeline_desc == (editor->pipeline_desc + editor->cur_pipeline_index)) {
-			GtkMenuShell* menu = GTK_MENU_SHELL(gtk_option_menu_get_menu(editor->optionmenu));
-			gtk_option_menu_set_history(editor->optionmenu, g_list_index(menu->children, mi));
-		}
-	}
-}
-
-static void 
-update_from_gconf(GSTPPipelineEditor* editor,
-				  const gchar* pipeline_str)
-{
-	/* Iterate over the pipelines in the editor, and locate the one 
-	   matching this pipeline_str. If none, then use 'Custom' entry */
-	int i = 0;
-	gint custom_desc = -1;
-	
-	/* g_return_if_fail (editor != NULL);*/
-	
-	editor->cur_pipeline_index = -1;
-	for (i = 0; i < editor->n_pipeline_desc; i++) {
-		GSTPPipelineDescription *pipeline_desc = editor->pipeline_desc + i;
-
-		if (pipeline_desc->is_custom == TRUE) {
-			custom_desc = i;
-		}
-		else if (!strcmp(pipeline_desc->pipeline, pipeline_str)) {
-			editor->cur_pipeline_index = i;
-			break;
-		}
-	}
-	
-	if (editor->cur_pipeline_index < 0) {
-		editor->cur_pipeline_index = custom_desc;
-		if (custom_desc >= 0) {
-			gtk_entry_set_text (editor->entry, pipeline_str);
-			if (pipeline_str == NULL || *pipeline_str == '\0')
-				gtk_widget_set_sensitive (GTK_WIDGET(editor->test_button), FALSE);
-		}
-	}
-	
-	if (editor->cur_pipeline_index >= 0) {
-		GtkMenu* menu = GTK_MENU(gtk_option_menu_get_menu(editor->optionmenu));
-		gtk_container_foreach(GTK_CONTAINER(menu), set_menuitem_by_pipeline, editor);
-    update_from_option (editor, editor->pipeline_desc + editor->cur_pipeline_index);
-	}
+  /* Iterate over the pipelines in the editor, and locate the one 
+     matching this pipeline_str. If none, then use 'Custom' entry */
+  int i = 0;
+  gint custom_desc = -1;
+
+  /* g_return_if_fail (editor != NULL); */
+
+  editor->cur_pipeline_index = -1;
+  for (i = 0; i < editor->n_pipeline_desc; i++) {
+    GSTPPipelineDescription *pipeline_desc = editor->pipeline_desc + i;
+
+    if (pipeline_desc->is_custom == TRUE) {
+      custom_desc = i;
+    } else if (!strcmp (pipeline_desc->pipeline, pipeline_str)) {
+      editor->cur_pipeline_index = i;
+      break;
+    }
+  }
+
+  if (editor->cur_pipeline_index < 0) {
+    editor->cur_pipeline_index = custom_desc;
+    if (custom_desc >= 0) {
+      gtk_entry_set_text (editor->entry, pipeline_str);
+      if (pipeline_str == NULL || *pipeline_str == '\0')
+        gtk_widget_set_sensitive (GTK_WIDGET (editor->test_button), FALSE);
+    }
+  }
+
+  if (editor->cur_pipeline_index >= 0) {
+    GtkMenu *menu = GTK_MENU (gtk_option_menu_get_menu (editor->optionmenu));
+
+    gtk_container_foreach (GTK_CONTAINER (menu), set_menuitem_by_pipeline,
+        editor);
+    update_from_option (editor,
+        editor->pipeline_desc + editor->cur_pipeline_index);
+  }
 }
 
 static void
 pipeline_option_changed (GtkOptionMenu * optionmenu, gpointer user_data)
 {
-	GSTPPipelineEditor* editor = (GSTPPipelineEditor*)(user_data);
-	GtkMenu *menu = NULL;
-	GtkMenuItem *mi = NULL;
-	GSTPPipelineDescription *pipeline_desc = NULL;
-	/* Determine which option changed, retrieve the pipeline desc,
-	 * and call update_from_option */
-	menu = GTK_MENU (gtk_option_menu_get_menu (optionmenu));
-	/*FIXME: g_return_if_fail (menu != NULL); */
-	mi = GTK_MENU_ITEM (gtk_menu_get_active (menu));
-	pipeline_desc =
-		(GSTPPipelineDescription*) (g_object_get_data (G_OBJECT (mi), pipeline_desc_property));
-	
-	update_from_option (editor, pipeline_desc);
+  GSTPPipelineEditor *editor = (GSTPPipelineEditor *) (user_data);
+  GtkMenu *menu = NULL;
+  GtkMenuItem *mi = NULL;
+  GSTPPipelineDescription *pipeline_desc = NULL;
+
+  /* Determine which option changed, retrieve the pipeline desc,
+   * and call update_from_option */
+  menu = GTK_MENU (gtk_option_menu_get_menu (optionmenu));
+  /*FIXME: g_return_if_fail (menu != NULL); */
+  mi = GTK_MENU_ITEM (gtk_menu_get_active (menu));
+  pipeline_desc =
+      (GSTPPipelineDescription *) (g_object_get_data (G_OBJECT (mi),
+          pipeline_desc_property));
+
+  update_from_option (editor, pipeline_desc);
 }
 
 static void
-entry_changed (GtkEditable *editable, gpointer user_data)
+entry_changed (GtkEditable * editable, gpointer user_data)
 {
-	GSTPPipelineEditor* editor = (GSTPPipelineEditor*)(user_data);
-	const gchar* new_text = gtk_entry_get_text(GTK_ENTRY(editable));
+  GSTPPipelineEditor *editor = (GSTPPipelineEditor *) (user_data);
+  const gchar *new_text = gtk_entry_get_text (GTK_ENTRY (editable));
 
-	if (new_text == NULL || *new_text == '\0') {
-		/* disable test button */
-		gtk_widget_set_sensitive (GTK_WIDGET(editor->test_button), FALSE);
-	} else {
-		gtk_widget_set_sensitive (GTK_WIDGET(editor->test_button), TRUE);
-	}
-	/* Update GConf */
-	gst_gconf_set_string (editor->gconf_key, new_text);
-}
-
-static GtkOptionMenu *create_pipeline_menu (GladeXML * dialog, GSTPPipelineEditor* editor)
-{
-	GtkOptionMenu *option = NULL;
-	gint i;
-	GSTPPipelineDescription *pipeline_desc = editor->pipeline_desc;
-
-	
-	option = GTK_OPTION_MENU (WID (editor->optionmenu_name));
-	if (option)
-	{
-		GtkMenu *menu = GTK_MENU (gtk_menu_new ());
-		GtkMenuItem *mi = NULL;
-		
-		for (i = 0; i < editor->n_pipeline_desc; i++)
-		{
-			GSTPPipelineDescription *cur_pipeline_desc = &(pipeline_desc[i]);
-			GstElement *pipeline;
-			GError     *error = NULL;
-
-			if (cur_pipeline_desc->pipeline != NULL) {
-				pipeline = gst_parse_launch (cur_pipeline_desc->pipeline, &error);
-				if (pipeline != NULL) {
-					gst_object_unref (GST_OBJECT (pipeline));
-				}
-				if (error != NULL) {
-					g_error_free (error);
-					continue;
-				}
-			}
-			
-			mi = GTK_MENU_ITEM (gtk_menu_item_new_with_label(_(cur_pipeline_desc->name)));
-			cur_pipeline_desc->index = i;
-			g_object_set_data (G_OBJECT (mi), pipeline_desc_property,
-					   (gpointer) (cur_pipeline_desc));
-			gtk_widget_show (GTK_WIDGET (mi));
-			gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (mi));
-		}
+  if (new_text == NULL || *new_text == '\0') {
+    /* disable test button */
+    gtk_widget_set_sensitive (GTK_WIDGET (editor->test_button), FALSE);
+  } else {
+    gtk_widget_set_sensitive (GTK_WIDGET (editor->test_button), TRUE);
+  }
+  /* Update GConf */
+  gst_properties_gconf_set_string (editor->gconf_key, new_text);
+}
 
-		gtk_option_menu_set_menu (option, GTK_WIDGET (menu));
-	}
+static gboolean
+element_available (const gchar * pipeline)
+{
+  gboolean res = FALSE;
+  gchar *p, *first_space;
+
+  if (pipeline == NULL || *pipeline == '\0')
+    return FALSE;
+
+  p = g_strdup (pipeline);
+
+  g_strstrip (p);
+
+  /* skip the check and pretend all is fine if it's something that does
+   * not look like an element name (e.g. parentheses to signify a bin) */
+  if (!g_ascii_isalpha (*p)) {
+    g_free (p);
+    return TRUE;
+  }
+
+  /* just the element name, no arguments */
+  first_space = strchr (p, ' ');
+  if (first_space != NULL)
+    *first_space = '\0';
+
+  /* check if element is available */
+  res = gst_default_registry_check_feature_version (p, GST_VERSION_MAJOR,
+      GST_VERSION_MINOR, 0);
+
+  g_free (p);
+  return res;
+}
+
+static GtkOptionMenu *
+create_pipeline_menu (GladeXML * dialog, GSTPPipelineEditor * editor)
+{
+  GtkOptionMenu *option = NULL;
+  gint i;
+  GSTPPipelineDescription *pipeline_desc = editor->pipeline_desc;
+
+
+  option = GTK_OPTION_MENU (WID (editor->optionmenu_name));
+  if (option) {
+    GtkMenu *menu = GTK_MENU (gtk_menu_new ());
+    GtkMenuItem *mi = NULL;
+
+    for (i = 0; i < editor->n_pipeline_desc; i++) {
+      if (element_available (pipeline_desc[i].pipeline)) {
+        GstElement *pipeline;
+        GError *error = NULL;
+
+        pipeline = gst_parse_launch (pipeline_desc[i].pipeline, &error);
+        if (pipeline != NULL) {
+          gst_object_unref (pipeline);
+        }
+        if (error != NULL) {
+          g_error_free (error);
+          continue;
+        }
+      } else if (pipeline_desc[i].pipeline != NULL) {
+        /* FIXME: maybe we should show those in the
+         * combo box, but make them insensitive? Or is
+         * that more confusing than helpful for users? */
+        g_message ("Skipping unavailable plugin '%s'",
+            pipeline_desc[i].pipeline);
+        continue;
+      } else {
+        /* This is probably the 'Custom' pipeline */
+      }
+
+      mi = GTK_MENU_ITEM (gtk_menu_item_new_with_label (_(pipeline_desc[i].
+                  name)));
+      pipeline_desc[i].index = i;
+      g_object_set_data (G_OBJECT (mi), pipeline_desc_property,
+          (gpointer) & pipeline_desc[i]);
+      gtk_widget_show (GTK_WIDGET (mi));
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (mi));
+    }
+
+    gtk_option_menu_set_menu (option, GTK_WIDGET (menu));
+  }
 
-	return option;
+  return option;
 }
 
 static void
-init_pipeline_editor(GladeXML * dialog, GSTPPipelineEditor* editor)
+init_pipeline_editor (GladeXML * dialog, GSTPPipelineEditor * editor)
+{
+  gchar *gconf_init_pipe = NULL;
+
+  /* g_return_if_fail(editor != NULL); */
+
+  editor->optionmenu = create_pipeline_menu (dialog, editor);
+  editor->entry = GTK_ENTRY (WID (editor->entry_name));
+  editor->test_button = GTK_BUTTON (WID (editor->test_button_name));
+
+  /* g_return_if_fail (editor->entry && editor->optionmenu && editor->test_button); */
+  if (!(editor->entry && editor->optionmenu && editor->test_button))
+    return;
+
+  g_object_set_data (G_OBJECT (editor->optionmenu), pipeline_editor_property,
+      (gpointer) (editor));
+  g_signal_connect (G_OBJECT (editor->optionmenu), "changed",
+      (GCallback) pipeline_option_changed, (gpointer) (editor));
+  g_object_set_data (G_OBJECT (editor->entry), pipeline_editor_property,
+      (gpointer) (editor));
+  g_signal_connect (G_OBJECT (editor->entry), "changed",
+      (GCallback) entry_changed, (gpointer) (editor));
+  g_object_set_data (G_OBJECT (editor->test_button), pipeline_editor_property,
+      (gpointer) (editor));
+  g_signal_connect (G_OBJECT (editor->test_button), "clicked",
+      (GCallback) test_button_clicked, (gpointer) (editor));
+
+  gconf_init_pipe = gst_properties_gconf_get_string (editor->gconf_key);
+
+  if (gconf_init_pipe) {
+    update_from_gconf (editor, gconf_init_pipe);
+    g_free (gconf_init_pipe);
+  }
+}
+
+void
+create_dialog (void)
 {
-	gchar* gconf_init_pipe = NULL;
-	
-	/* g_return_if_fail(editor != NULL); */
-	
-	editor->optionmenu = create_pipeline_menu (dialog, editor);
-	editor->entry = GTK_ENTRY (WID (editor->entry_name));
-	editor->test_button = GTK_BUTTON (WID (editor->test_button_name));
-	
-	/* g_return_if_fail (editor->entry && editor->optionmenu && editor->test_button); */
-	if (!(editor->entry && editor->optionmenu && editor->test_button))
-		return;
-
-	g_object_set_data (G_OBJECT (editor->optionmenu), pipeline_editor_property, (gpointer) (editor));
-	g_signal_connect (G_OBJECT (editor->optionmenu), "changed",  (GCallback) pipeline_option_changed, (gpointer) (editor));
-	g_object_set_data (G_OBJECT (editor->entry), pipeline_editor_property, (gpointer) (editor));
-	g_signal_connect (G_OBJECT (editor->entry), "changed",  (GCallback) entry_changed, (gpointer) (editor));
-	g_object_set_data (G_OBJECT (editor->test_button), pipeline_editor_property, (gpointer) (editor));
-	g_signal_connect (G_OBJECT (editor->test_button), "clicked",  (GCallback) test_button_clicked, (gpointer) (editor));
-	
-	gconf_init_pipe = gst_gconf_get_string (editor->gconf_key);
-	
-	if (gconf_init_pipe) {
-		update_from_gconf(editor, gconf_init_pipe);
-		g_free(gconf_init_pipe);
-	}
-}
-
-void create_dialog (void)
-{
-	int i = 0;
-	GdkPixbuf* icon = NULL;
-	
-	for (i = 0; i < pipeline_editors_count; i++) {
-		init_pipeline_editor(interface_xml, pipeline_editors + i);
-	}
-	
-	main_window = GTK_DIALOG(WID("gst_properties_dialog"));
-	if (!main_window) {
-		/* Fatal error */
-		gnome_app_error (GNOME_APP (gnome_program_get ()), _("Failure instantiating main window"));
-		return;
-	}
-	
-	g_signal_connect (G_OBJECT (main_window),
-			  "response", (GCallback) dialog_response, interface_xml);
-	icon = gdk_pixbuf_new_from_file(GSTPROPS_ICONDIR"/gstreamer-properties.png", NULL);
-	if (icon) {
-		gtk_window_set_icon(GTK_WINDOW(main_window), icon);
-	}
-	else {
-		/* FIXME:warning */
-		g_print("Error loading main window icon %s", GSTPROPS_ICONDIR "/gstreamer-properties.png\n");
-	}
-	gtk_widget_show (GTK_WIDGET (main_window));
+  int i = 0;
+  GdkPixbuf *icon = NULL;
+
+  for (i = 0; i < pipeline_editors_count; i++) {
+    init_pipeline_editor (interface_xml, pipeline_editors + i);
+  }
+
+  main_window = GTK_DIALOG (WID ("gst_properties_dialog"));
+  if (!main_window) {
+    /* Fatal error */
+    gnome_app_error (GNOME_APP (gnome_program_get ()),
+        _("Failure instantiating main window"));
+    return;
+  }
+
+  g_signal_connect (G_OBJECT (main_window),
+      "response", (GCallback) dialog_response, interface_xml);
+  icon =
+      gdk_pixbuf_new_from_file (GSTPROPS_ICONDIR "/gstreamer-properties.png",
+      NULL);
+  if (icon) {
+    gtk_window_set_icon (GTK_WINDOW (main_window), icon);
+  } else {
+    /* FIXME:warning */
+    g_print ("Error loading main window icon %s",
+        GSTPROPS_ICONDIR "/gstreamer-properties.png\n");
+  }
+  gtk_widget_show (GTK_WIDGET (main_window));
 }
 
 int
 main (int argc, char **argv)
 {
-	/* bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); */
-	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-	textdomain (GETTEXT_PACKAGE);
-
-	gnome_program_init ("gstreamer-properties", VERSION, LIBGNOMEUI_MODULE,
-			    argc, argv, GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
-	gst_init_with_popt_table (&argc, &argv, NULL);
-
-	if (!gst_scheduler_factory_get_default_name ()) {
-		GtkWidget *dialog;
-
-		dialog = gtk_message_dialog_new (NULL,
-						 0,
-						 GTK_MESSAGE_ERROR,
-						 GTK_BUTTONS_CLOSE,
-						 _("Registry is not present or it is corrupted, please update it by running gst-register."));
-
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (dialog);
-
-		exit (1);
-	}
-
-	/* FIXME: hardcode uninstalled path here */
-	if (g_file_test("gstreamer-properties.glade", G_FILE_TEST_EXISTS) == TRUE) {
-		interface_xml = glade_xml_new ("gstreamer-properties.glade", NULL, NULL);
-	}
-	else if (g_file_test(GSTPROPS_GLADEDIR "/gstreamer-properties.glade", G_FILE_TEST_EXISTS) == TRUE) {
-		interface_xml = glade_xml_new (GSTPROPS_GLADEDIR"/gstreamer-properties.glade", NULL, NULL);
-	}
-	
-	if (!interface_xml) {
-		GtkWidget *dialog;
-
-		dialog = gtk_message_dialog_new (NULL,
-						 0,
-						 GTK_MESSAGE_ERROR,
-						 GTK_BUTTONS_CLOSE,
-						 _("Failed to load glade file; please check your installation."));
-
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (dialog);
-
-		exit (1);
-	}
-	
-	create_dialog ();
-	if (main_window)
-		gtk_main ();
+  /* bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); */
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+  textdomain (GETTEXT_PACKAGE);
+
+/* FIXME: remove when bumping requirements to 2.14 */
+#ifdef GNOME_PARAM_GOPTION_CONTEXT
+  if (1) {
+    GOptionContext *ctx;
+    GOptionGroup *group;
+
+    ctx = g_option_context_new ("gstreamer-properties");
+    g_option_context_add_group (ctx, gst_init_get_option_group ());
+
+    gnome_program_init ("gstreamer-properties", VERSION,
+        LIBGNOMEUI_MODULE, argc, argv,
+        GNOME_PARAM_GOPTION_CONTEXT, ctx,
+        GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
+  }
+#else /* GNOME_PARAM_GOPTION_CONTEXT */
+  gst_init (&argc, &argv);
+
+  gnome_program_init ("gstreamer-properties", VERSION,
+      LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
+#endif /* GNOME_PARAM_GOPTION_CONTEXT */
+
+  /* FIXME: hardcode uninstalled path here */
+  if (g_file_test ("gstreamer-properties.glade", G_FILE_TEST_EXISTS) == TRUE) {
+    interface_xml = glade_xml_new ("gstreamer-properties.glade", NULL, NULL);
+  } else if (g_file_test (GSTPROPS_GLADEDIR "/gstreamer-properties.glade",
+          G_FILE_TEST_EXISTS) == TRUE) {
+    interface_xml =
+        glade_xml_new (GSTPROPS_GLADEDIR "/gstreamer-properties.glade", NULL,
+        NULL);
+  }
+
+  if (!interface_xml) {
+    GtkWidget *dialog;
+
+    dialog = gtk_message_dialog_new (NULL,
+        0,
+        GTK_MESSAGE_ERROR,
+        GTK_BUTTONS_CLOSE,
+        _("Failed to load glade file; please check your installation."));
+
+    gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy (dialog);
+
+    exit (1);
+  }
+
+  create_dialog ();
+
+  if (main_window)
+    gtk_main ();
 
-	return 0;
+  return 0;
 }
Index: gstreamer-properties/pipeline-constants.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gstreamer-properties/pipeline-constants.c,v
retrieving revision 1.12
diff -u -p -r1.12 pipeline-constants.c
--- gstreamer-properties/pipeline-constants.c	1 Jul 2005 08:41:09 -0000	1.12
+++ gstreamer-properties/pipeline-constants.c	9 Jan 2006 12:26:24 -0000
@@ -28,10 +28,11 @@
 #include "gstreamer-properties-structs.h"
 #include <gtk/gtk.h>
 #include <bonobo/bonobo-i18n.h>
- 
+
 /* Test specified inputs for pipelines */
 /* static const gchar audiosink_test_pipe[] = "afsrc location=\"" TEST_MEDIA_FILE "\""; FIXME*/
-static gchar audiosink_test_pipe[] = "sinesrc freq=512";
+static gchar audiosink_test_pipe[] = "audiotestsrc wave=sine freq=512";
+
 /* ffmpegcolorspace is the ripped colorspace element in gst-plugins */
 static gchar videosink_test_pipe[] = "videotestsrc";
 
@@ -46,122 +47,140 @@ extern GSTPPipelineDescription audiosrc_
 extern GSTPPipelineDescription videosrc_pipelines[];
 
 GSTPPipelineDescription audiosink_pipelines[] = {
-	{PIPE_TYPE_AUDIOSINK, 0,"Autodetect", "autoaudiosink", FALSE,
-	 TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
-	{PIPE_TYPE_AUDIOSINK, 0,"ALSA - Advanced Linux Sound Architecture",
-	 "alsasink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
-	{PIPE_TYPE_AUDIOSINK, 0,"Artsd - ART Sound Daemon", 
-	 "artsdsink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
-	{PIPE_TYPE_AUDIOSINK, 0,"ESD - Enlightenment Sound Daemon", 
-	 "esdsink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
-#if 0 /* Disabled this until it works */
-	{PIPE_TYPE_AUDIOSINK, 0,"Jack", "jackbin.( jacksink )", FALSE, 
-	 TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+  {PIPE_TYPE_AUDIOSINK, 0, "Autodetect", "autoaudiosink", FALSE,
+      TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+  {PIPE_TYPE_AUDIOSINK, 0, "ALSA - Advanced Linux Sound Architecture",
+      "alsasink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+#if 0
+  {PIPE_TYPE_AUDIOSINK, 0,
+        "ALSA - Advanced Linux Sound Architecture (Default Device)",
+      "alsasink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+  {PIPE_TYPE_AUDIOSINK, 0,
+        "ALSA - Advanced Linux Sound Architecture (Sound Card #1 Direct)",
+        "alsasink device=hw:0", FALSE, TEST_PIPE_SUPPLIED,
+      audiosink_test_pipe, FALSE},
+  {PIPE_TYPE_AUDIOSINK, 0,
+        "ALSA - Advanced Linux Sound Architecture (Sound Card #1 DMix)",
+        "alsasink device=dmix:0", FALSE, TEST_PIPE_SUPPLIED,
+      audiosink_test_pipe, FALSE},
 #endif
-	{PIPE_TYPE_AUDIOSINK, 0,"OSS - Open Sound System", 
-	 "osssink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, TRUE},
-	{PIPE_TYPE_AUDIOSINK, 0,"Polypaudio Sound Server", 
-	 "polypsink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
-	{PIPE_TYPE_AUDIOSINK, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_SUPPLIED,
-	 audiosink_test_pipe, TRUE}
+  {PIPE_TYPE_AUDIOSINK, 0, "Artsd - ART Sound Daemon",
+      "artsdsink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+  {PIPE_TYPE_AUDIOSINK, 0, "ESD - Enlightenment Sound Daemon",
+      "esdsink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+#if 0                           /* Disabled this until it works */
+  {PIPE_TYPE_AUDIOSINK, 0, "Jack", "jackbin.( jacksink )", FALSE,
+      TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+#endif
+  {PIPE_TYPE_AUDIOSINK, 0, "OSS - Open Sound System",
+      "osssink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, TRUE},
+  {PIPE_TYPE_AUDIOSINK, 0, "Polypaudio Sound Server",
+      "polypsink", FALSE, TEST_PIPE_SUPPLIED, audiosink_test_pipe, FALSE},
+  {PIPE_TYPE_AUDIOSINK, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_SUPPLIED,
+      audiosink_test_pipe, TRUE}
 };
 
 GSTPPipelineDescription videosink_pipelines[] = {
-	{PIPE_TYPE_VIDEOSINK, 0,"Autodetect", "autovideosink", FALSE,
-	 TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
+  {PIPE_TYPE_VIDEOSINK, 0, "Autodetect", "autovideosink", FALSE,
+      TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
 #if 0
   /*
    * aasink is disabled because it is not a serious alternative.
    */
-	{PIPE_TYPE_VIDEOSINK, 0,"Ascii Art - X11", "aasink driver=0", FALSE,
-	 TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
-	{PIPE_TYPE_VIDEOSINK, 0,"Ascii Art - console", "aasink driver=1", FALSE,
-	 TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
+  {PIPE_TYPE_VIDEOSINK, 0, "Ascii Art - X11", "aasink driver=0", FALSE,
+      TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
+  {PIPE_TYPE_VIDEOSINK, 0, "Ascii Art - console", "aasink driver=1", FALSE,
+      TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
 #endif
-#if 0 
- /* Leaving this one disabled, because of a bug in cacasink that
-  * pops up a window in NULL state
-  */
-	{PIPE_TYPE_VIDEOSINK, 0,"Colour Ascii Art", "cacasink", FALSE,
-	 TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
+#if 0
+  /* Leaving this one disabled, because of a bug in cacasink that
+   * pops up a window in NULL state
+   */
+  {PIPE_TYPE_VIDEOSINK, 0, "Colour Ascii Art", "cacasink", FALSE,
+      TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
 #endif
-	{PIPE_TYPE_VIDEOSINK, 0,"SDL - Simple DirectMedia Layer", "sdlvideosink",
-	 FALSE, TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
-	{PIPE_TYPE_VIDEOSINK, 0,"XWindows (No Xv)",
-	 "ximagesink", FALSE, TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
-	{PIPE_TYPE_VIDEOSINK, 0,"XWindows (X11/XShm/Xv)", "xvimagesink", FALSE,
-	 TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
-	{PIPE_TYPE_VIDEOSINK, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_SUPPLIED,
-	 videosink_test_pipe, TRUE}
+  {PIPE_TYPE_VIDEOSINK, 0, "SDL - Simple DirectMedia Layer", "sdlvideosink",
+      FALSE, TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
+  {PIPE_TYPE_VIDEOSINK, 0, "XWindows (No Xv)",
+      "ximagesink", FALSE, TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
+  {PIPE_TYPE_VIDEOSINK, 0, "XWindows (X11/XShm/Xv)", "xvimagesink", FALSE,
+      TEST_PIPE_SUPPLIED, videosink_test_pipe, FALSE},
+  {PIPE_TYPE_VIDEOSINK, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_SUPPLIED,
+      videosink_test_pipe, TRUE}
 };
 
 GSTPPipelineDescription audiosrc_pipelines[] = {
-	{PIPE_TYPE_AUDIOSRC, 0,"ALSA - Advanced Linux Sound Architecture",
-	 "alsasrc", FALSE, TEST_PIPE_AUDIOSINK, NULL, FALSE},
-	{PIPE_TYPE_AUDIOSRC, 0,"ESD - Enlightenment Sound Daemon", "esdmon",
-	 FALSE, TEST_PIPE_AUDIOSINK, NULL, FALSE},
-#if 0 /* Disabled this until it works */
-	{PIPE_TYPE_AUDIOSRC, 0,"Jack", "jackbin{ jacksrc }", FALSE, TEST_PIPE_AUDIOSINK,
-	 NULL, FALSE},
+  {PIPE_TYPE_AUDIOSRC, 0, "ALSA - Advanced Linux Sound Architecture",
+      "alsasrc", FALSE, TEST_PIPE_AUDIOSINK, NULL, FALSE},
+  {PIPE_TYPE_AUDIOSRC, 0, "ESD - Enlightenment Sound Daemon", "esdmon",
+      FALSE, TEST_PIPE_AUDIOSINK, NULL, FALSE},
+#if 0                           /* Disabled this until it works */
+  {PIPE_TYPE_AUDIOSRC, 0, "Jack", "jackbin{ jacksrc }", FALSE,
+        TEST_PIPE_AUDIOSINK,
+      NULL, FALSE},
 #endif
-	{PIPE_TYPE_AUDIOSRC, 0,"OSS - Open Sound System", "osssrc", FALSE,
-	 TEST_PIPE_AUDIOSINK, NULL, FALSE},
-	{PIPE_TYPE_AUDIOSRC, 0,"Polypaudio Sound Server", "polypsrc", FALSE,
-	 TEST_PIPE_AUDIOSINK, NULL, FALSE},
-	{PIPE_TYPE_AUDIOSRC, 0,"Silence", "silence", FALSE, TEST_PIPE_AUDIOSINK,
-	 NULL, FALSE},
-	{PIPE_TYPE_AUDIOSRC, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_AUDIOSINK, NULL,
-	 TRUE}
+  {PIPE_TYPE_AUDIOSRC, 0, "OSS - Open Sound System", "osssrc", FALSE,
+      TEST_PIPE_AUDIOSINK, NULL, FALSE},
+  {PIPE_TYPE_AUDIOSRC, 0, "Polypaudio Sound Server", "polypsrc", FALSE,
+      TEST_PIPE_AUDIOSINK, NULL, FALSE},
+  /* Note: using triangle instead of sine for test sound so we
+   * can test the vorbis encoder as well (otherwise it'd compress too well) */
+  {PIPE_TYPE_AUDIOSRC, 0, "Test Sound", "audiotestsrc wave=triangle is-live=true", FALSE,
+      TEST_PIPE_AUDIOSINK, NULL, FALSE},
+  {PIPE_TYPE_AUDIOSRC, 0, "Silence", "audiotestsrc wave=silence is-live=true", FALSE,
+      TEST_PIPE_AUDIOSINK, NULL, FALSE},
+  {PIPE_TYPE_AUDIOSRC, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_AUDIOSINK, NULL,
+      TRUE}
 };
 
 GSTPPipelineDescription videosrc_pipelines[] = {
-	{PIPE_TYPE_VIDEOSRC, 0,"MJPEG (e.g. Zoran v4l device)", "v4lmjpegsrc", FALSE,
-	 TEST_PIPE_VIDEOSINK, NULL, FALSE},
-	{PIPE_TYPE_VIDEOSRC, 0,"QCAM", "qcamsrc", FALSE, TEST_PIPE_VIDEOSINK,
-	 NULL, FALSE},
-	{PIPE_TYPE_VIDEOSRC, 0,"Test Input", "videotestsrc", FALSE,
-	 TEST_PIPE_VIDEOSINK, NULL, FALSE},
-	{PIPE_TYPE_VIDEOSRC, 0,"Video for Linux (v4l)", "v4lsrc", FALSE,
-	 TEST_PIPE_VIDEOSINK, NULL, FALSE},
-	{PIPE_TYPE_VIDEOSRC, 0,"Video for Linux 2 (v4l2)", "v4l2src", FALSE,
-	 TEST_PIPE_VIDEOSINK, NULL, FALSE},
-	{PIPE_TYPE_VIDEOSRC, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_VIDEOSINK, NULL,
-	 TRUE}
+  {PIPE_TYPE_VIDEOSRC, 0, "MJPEG (e.g. Zoran v4l device)", "v4lmjpegsrc", FALSE,
+      TEST_PIPE_VIDEOSINK, NULL, FALSE},
+  {PIPE_TYPE_VIDEOSRC, 0, "QCAM", "qcamsrc", FALSE, TEST_PIPE_VIDEOSINK,
+      NULL, FALSE},
+  {PIPE_TYPE_VIDEOSRC, 0, "Test Input", "videotestsrc is-live=true", FALSE,
+      TEST_PIPE_VIDEOSINK, NULL, FALSE},
+  {PIPE_TYPE_VIDEOSRC, 0, "Video for Linux (v4l)", "v4lsrc", FALSE,
+      TEST_PIPE_VIDEOSINK, NULL, FALSE},
+  {PIPE_TYPE_VIDEOSRC, 0, "Video for Linux 2 (v4l2)", "v4l2src", FALSE,
+      TEST_PIPE_VIDEOSINK, NULL, FALSE},
+  {PIPE_TYPE_VIDEOSRC, 0, N_("Custom"), NULL, TRUE, TEST_PIPE_VIDEOSINK, NULL,
+      TRUE}
 };
 
 GSTPPipelineEditor pipeline_editors[] = {
-	/* audiosink pipelines */
-	{
-	 G_N_ELEMENTS(audiosink_pipelines),
-	 (GSTPPipelineDescription *)(audiosink_pipelines), 0,
-	 GSTPROPS_KEY_DEFAULT_AUDIOSINK,
-	 "audiosink_optionmenu", "audiosink_pipeline_entry",
-	 "audiosink_test_button",
-	 NULL, NULL, NULL},
-	/* videosink pipelines */
-	{
-	 G_N_ELEMENTS(videosink_pipelines),
-	 (GSTPPipelineDescription *)(videosink_pipelines), 0,
-	 GSTPROPS_KEY_DEFAULT_VIDEOSINK,
-	 "videosink_optionmenu", "videosink_pipeline_entry",
-	 "videosink_test_button",
-	 NULL, NULL, NULL},
-	/* videosrc pipelines */
-	{
-	 G_N_ELEMENTS(videosrc_pipelines),
-	 (GSTPPipelineDescription *)(videosrc_pipelines), 0,
-	 GSTPROPS_KEY_DEFAULT_VIDEOSRC,
-	 "videosrc_optionmenu", "videosrc_pipeline_entry",
-	 "videosrc_test_button",
-	 NULL, NULL, NULL},
-	/* audiosrc pipelines */
-	{
-	 G_N_ELEMENTS(audiosrc_pipelines),
-	 (GSTPPipelineDescription *)(audiosrc_pipelines), 0, 
-	 GSTPROPS_KEY_DEFAULT_AUDIOSRC,
-	 "audiosrc_optionmenu", "audiosrc_pipeline_entry",
-	 "audiosrc_test_button",
-	 NULL, NULL, NULL}
+  /* audiosink pipelines */
+  {
+        G_N_ELEMENTS (audiosink_pipelines),
+        (GSTPPipelineDescription *) (audiosink_pipelines), 0,
+        GSTPROPS_KEY_DEFAULT_AUDIOSINK,
+        "audiosink_optionmenu", "audiosink_pipeline_entry",
+        "audiosink_test_button",
+      NULL, NULL, NULL},
+  /* videosink pipelines */
+  {
+        G_N_ELEMENTS (videosink_pipelines),
+        (GSTPPipelineDescription *) (videosink_pipelines), 0,
+        GSTPROPS_KEY_DEFAULT_VIDEOSINK,
+        "videosink_optionmenu", "videosink_pipeline_entry",
+        "videosink_test_button",
+      NULL, NULL, NULL},
+  /* videosrc pipelines */
+  {
+        G_N_ELEMENTS (videosrc_pipelines),
+        (GSTPPipelineDescription *) (videosrc_pipelines), 0,
+        GSTPROPS_KEY_DEFAULT_VIDEOSRC,
+        "videosrc_optionmenu", "videosrc_pipeline_entry",
+        "videosrc_test_button",
+      NULL, NULL, NULL},
+  /* audiosrc pipelines */
+  {
+        G_N_ELEMENTS (audiosrc_pipelines),
+        (GSTPPipelineDescription *) (audiosrc_pipelines), 0,
+        GSTPROPS_KEY_DEFAULT_AUDIOSRC,
+        "audiosrc_optionmenu", "audiosrc_pipeline_entry",
+        "audiosrc_test_button",
+      NULL, NULL, NULL}
 };
 
-gint pipeline_editors_count = G_N_ELEMENTS(pipeline_editors);
+gint pipeline_editors_count = G_N_ELEMENTS (pipeline_editors);
Index: gstreamer-properties/pipeline-tests.c
===================================================================
RCS file: /cvs/gnome/gnome-media/gstreamer-properties/pipeline-tests.c,v
retrieving revision 1.5
diff -u -p -r1.5 pipeline-tests.c
--- gstreamer-properties/pipeline-tests.c	1 Nov 2004 08:14:39 -0000	1.5
+++ gstreamer-properties/pipeline-tests.c	9 Jan 2006 12:26:24 -0000
@@ -3,6 +3,7 @@
 
 /* pipeline-tests.c
  * Copyright (C) 2002 Jan Schmidt
+ * Copyright (C) 2005 Tim-Philipp Müller <tim centricular net>
  *
  * Written by: Jan Schmidt <thaytan@mad.scientist.com>
  *
@@ -31,169 +32,204 @@
 #include <glade/glade.h>
 #include <gtk/gtk.h>
 #include <gst/gst.h>
-#include <gst/gconf/gconf.h>
 
 #include "pipeline-tests.h"
 #define WID(s) glade_xml_get_widget (interface_xml, s)
 static gint timeout_tag;
 
 static GstElement *gst_test_pipeline;
-static GstClock *s_clock;
 
-static void pipeline_error_dlg(GtkWindow * parent,
-                GSTPPipelineDescription * pipeline_desc);
+static void pipeline_error_dlg (GtkWindow * parent,
+    GSTPPipelineDescription * pipeline_desc, const gchar * error_message);
+
 /* User responded in the dialog */
 static void
-user_test_pipeline_response(GtkDialog * widget, gint response_id,
-			    GladeXML * dialog)
+user_test_pipeline_response (GtkDialog * widget, gint response_id,
+    GladeXML * dialog)
 {
   /* Close the window causing the test to end */
-  gtk_widget_hide(GTK_WIDGET(widget));
+  gtk_widget_hide (GTK_WIDGET (widget));
 }
 
 /* Timer timeout has been occurred */
-static gint user_test_pipeline_timeout( gpointer data )
+static gint
+user_test_pipeline_timeout (gpointer data)
 {
-  gtk_progress_bar_pulse(GTK_PROGRESS_BAR(data));
+  gtk_progress_bar_pulse (GTK_PROGRESS_BAR (data));
   return TRUE;
 }
 
 /* Build the pipeline */
 static gboolean
-build_test_pipeline(GSTPPipelineDescription * pipeline_desc)
+build_test_pipeline (GSTPPipelineDescription * pipeline_desc, GError ** p_err)
 {
+  const gchar *in_between = NULL;
   gboolean return_val = FALSE;
-  GError *error = NULL;
-  gchar* test_pipeline_str = NULL;
-  gchar* full_pipeline_str = NULL;
-  gchar *in_between = NULL;
+  gchar *test_pipeline_str = NULL;
+  gchar *full_pipeline_str = NULL;
+
+  g_assert (p_err != NULL);
 
   switch (pipeline_desc->test_type) {
     case TEST_PIPE_AUDIOSINK:
-      test_pipeline_str = gst_gconf_get_string ("default/audiosink");
+      test_pipeline_str = gst_properties_gconf_get_string ("default/audiosink");
       break;
     case TEST_PIPE_VIDEOSINK:
-      test_pipeline_str = gst_gconf_get_string ("default/videosink");
+      test_pipeline_str = gst_properties_gconf_get_string ("default/videosink");
       break;
     case TEST_PIPE_SUPPLIED:
-      test_pipeline_str = pipeline_desc->test_pipe;
+      test_pipeline_str = g_strdup (pipeline_desc->test_pipe);
       break;
   }
-  if (pipeline_desc->type == PIPE_TYPE_AUDIOSINK ||
-      pipeline_desc->type == PIPE_TYPE_AUDIOSRC) {
-    in_between = "audioconvert ! audioscale";
-  } else {
-    in_between = "ffmpegcolorspace";
+
+  switch (pipeline_desc->type) {
+    case PIPE_TYPE_AUDIOSINK:
+    case PIPE_TYPE_AUDIOSRC:
+      in_between = "audioconvert ! audioresample";
+      break;
+    default:
+      in_between = "ffmpegcolorspace";
+      break;
   }
+
   switch (pipeline_desc->type) {
     case PIPE_TYPE_AUDIOSINK:
     case PIPE_TYPE_VIDEOSINK:
-      full_pipeline_str = g_strdup_printf("{ %s ! %s ! %s }",
+      full_pipeline_str = g_strdup_printf ("%s ! %s ! %s",
           test_pipeline_str, in_between, pipeline_desc->pipeline);
       break;
     case PIPE_TYPE_AUDIOSRC:
     case PIPE_TYPE_VIDEOSRC:
-      full_pipeline_str = g_strdup_printf("{ %s ! %s ! %s }",
+      full_pipeline_str = g_strdup_printf ("%s ! %s ! %s",
           pipeline_desc->pipeline, in_between, test_pipeline_str);
       break;
   }
+
   if (full_pipeline_str) {
-    gst_test_pipeline = (GstElement *)gst_parse_launch(full_pipeline_str, &error);
-    if (!error) {
+    gst_test_pipeline = gst_parse_launch (full_pipeline_str, p_err);
+
+    if (*p_err == NULL && gst_test_pipeline != NULL)
       return_val = TRUE;
-    }
-    else {
-      /* FIXME display the error? */
-      g_error_free(error);
-    }
- 
-    g_free(full_pipeline_str);
   }
+
+done:
+  g_free (test_pipeline_str);
+  g_free (full_pipeline_str);
+
   return return_val;
 }
 
 static void
-pipeline_error_dlg(GtkWindow * parent,
-		   GSTPPipelineDescription * pipeline_desc)
+pipeline_error_dlg (GtkWindow * parent,
+    GSTPPipelineDescription * pipeline_desc, const gchar * error_message)
 {
-  gchar *errstr = g_strdup_printf( _("Failed to construct test pipeline for '%s'"),
-		  pipeline_desc->name);
-    if (parent == NULL) {
-	    g_print(errstr);
-    }
-    else {
-      GtkDialog *dialog = GTK_DIALOG(gtk_message_dialog_new(parent,
-							  GTK_DIALOG_DESTROY_WITH_PARENT,
-							  GTK_MESSAGE_ERROR,
-							  GTK_BUTTONS_CLOSE,
-							  errstr));
-      gtk_dialog_run(GTK_DIALOG(dialog));
-      gtk_widget_destroy(GTK_WIDGET(dialog));
-    }
-    g_free(errstr);
+  gchar *errstr;
+
+  if (error_message) {
+    errstr = g_strdup_printf ("%s: %s", pipeline_desc->name, error_message);
+  } else {
+    errstr = g_strdup_printf (_("Failed to construct test pipeline for '%s'"),
+        pipeline_desc->name);
+  }
+
+  if (parent == NULL) {
+    g_printerr ("%s", errstr);
+  } else {
+    GtkWidget *dialog;
+
+    dialog = gtk_message_dialog_new (parent,
+        GTK_DIALOG_DESTROY_WITH_PARENT,
+        GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", errstr);
+
+    gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy (dialog);
+  }
+
+  g_free (errstr);
 }
 
-/* Construct and iterate the pipeline. Use the indicated parent
-   for any user interaction window.
-*/
+/* Construct and run the pipeline. Use the indicated parent
+ * for any user interaction window.
+ */
 void
-user_test_pipeline(GladeXML * interface_xml,
-		   GtkWindow * parent,
-		   GSTPPipelineDescription * pipeline_desc)
+user_test_pipeline (GladeXML * interface_xml,
+    GtkWindow * parent, GSTPPipelineDescription * pipeline_desc)
 {
+  GstStateChangeReturn ret;
   GtkDialog *dialog = NULL;
+  GstMessage *msg;
+  GError *err = NULL;
+  GstBus *bus;
+
   gst_test_pipeline = NULL;
-  s_clock = NULL;
 
   /* Build the pipeline */
-  if (!build_test_pipeline(pipeline_desc)) {
+  if (!build_test_pipeline (pipeline_desc, &err)) {
     /* Show the error pipeline */
-    pipeline_error_dlg(parent, pipeline_desc);
+    pipeline_error_dlg (parent, pipeline_desc, (err) ? err->message : NULL);
+    if (err)
+      g_error_free (err);
     return;
   }
 
   /* Setup the 'click ok when done' dialog */
   if (parent) {
-    dialog = GTK_DIALOG(WID("test_pipeline"));
+    dialog = GTK_DIALOG (WID ("test_pipeline"));
     /* g_return_if_fail(dialog != NULL); */
-    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
-    gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-    g_signal_connect(G_OBJECT(dialog), "response",
-         (GCallback) user_test_pipeline_response,
-         interface_xml);
-  }
-
-  /* Start the pipeline */
-  if (gst_element_set_state(gst_test_pipeline, GST_STATE_PLAYING) !=
-    GST_STATE_SUCCESS) {
-    pipeline_error_dlg(parent, pipeline_desc);
-    return;
+    gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+    gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
+    g_signal_connect (G_OBJECT (dialog), "response",
+        (GCallback) user_test_pipeline_response, interface_xml);
+  }
+
+  /* Start the pipeline and wait for max. 3 seconds for it to start up */
+  gst_element_set_state (gst_test_pipeline, GST_STATE_PLAYING);
+  ret = gst_element_get_state (gst_test_pipeline, NULL, NULL, 3 * GST_SECOND);
+
+  /* Check if any error messages were posted on the bus */
+  bus = gst_element_get_bus (gst_test_pipeline);
+  msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
+  gst_object_unref (bus);
+
+  if (msg != NULL) {
+    gchar *dbg = NULL;
+
+    gst_message_parse_error (msg, &err, &dbg);
+    gst_message_unref (msg);
+
+    g_message ("Error running pipeline '%s': %s [%s]", pipeline_desc,
+        err->message, (dbg) ? dbg : "no additional debugging details");
+    pipeline_error_dlg (parent, pipeline_desc, err->message);
+    g_error_free (err);
+    g_free (dbg);
+  } else if (ret != GST_STATE_CHANGE_SUCCESS) {
+    pipeline_error_dlg (parent, pipeline_desc, NULL);
+  } else {
+    /* Show the dialog */
+    if (dialog) {
+      gtk_window_present (GTK_WINDOW (dialog));
+      timeout_tag =
+          gtk_timeout_add (50, user_test_pipeline_timeout,
+          WID ("test_pipeline_progress"));
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_timeout_remove (timeout_tag);
+      gtk_widget_hide (GTK_WIDGET (dialog));
+    } else {
+      gint secs;
+
+      /* A bit hacky: No parent dialog, run in limited test mode */
+      for (secs = 0; secs < 5; ++secs) {
+        g_print (".");
+        g_usleep (G_USEC_PER_SEC);      /* 1 second */
+      }
+    }
   }
 
-  s_clock = gst_bin_get_clock(GST_BIN(gst_test_pipeline));
-  /* Show the dialog */
-  if (dialog) {
-    gtk_window_present(GTK_WINDOW(dialog));
-    timeout_tag = gtk_timeout_add(50, user_test_pipeline_timeout, WID("test_pipeline_progress"));    
-    gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_timeout_remove( timeout_tag );
-    gtk_widget_hide(GTK_WIDGET(dialog));
-  }
-  else {
-    gboolean busy;
-    gint secs = 0, max_secs = 5; /* A bit hacky: No parent dialog, run in limited test mode */
-    do {
-      secs++;
-      g_print(".");
-      g_usleep(1000000); // 1 sec
-      busy = (secs < max_secs);
-    } while (busy);
-  }
+done:
 
   if (gst_test_pipeline) {
-    gst_element_set_state(gst_test_pipeline, GST_STATE_NULL);
-    /* Free up the pipeline */
-    gst_object_unref(GST_OBJECT(gst_test_pipeline));
+    gst_element_set_state (gst_test_pipeline, GST_STATE_NULL);
+    gst_object_unref (gst_test_pipeline);
     gst_test_pipeline = NULL;
   }
 }
Index: gstreamer-properties/pipeline-tests.h
===================================================================
RCS file: /cvs/gnome/gnome-media/gstreamer-properties/pipeline-tests.h,v
retrieving revision 1.1
diff -u -p -r1.1 pipeline-tests.h
--- gstreamer-properties/pipeline-tests.h	1 Dec 2002 03:32:13 -0000	1.1
+++ gstreamer-properties/pipeline-tests.h	9 Jan 2006 12:26:24 -0000
@@ -31,5 +31,10 @@
 void user_test_pipeline(GladeXML *interface_xml,
 		    GtkWindow *parent,
 		    GSTPPipelineDescription *pipeline_desc);
+
+void gst_properties_gconf_set_string (const gchar * key, const gchar * value);
+
+gchar *gst_properties_gconf_get_string (const gchar * key);
+
 			
 #endif	
Index: profiles/audio-profile-choose.c
===================================================================
RCS file: /cvs/gnome/gnome-media/profiles/audio-profile-choose.c,v
retrieving revision 1.11
diff -u -p -r1.11 audio-profile-choose.c
--- profiles/audio-profile-choose.c	13 Jun 2005 09:38:43 -0000	1.11
+++ profiles/audio-profile-choose.c	9 Jan 2006 12:26:27 -0000
@@ -28,6 +28,8 @@
 #include "audio-profile.h"
 #include <gtk/gtk.h>
 #include <glade/glade-xml.h>
+#include <libgnomevfs/gnome-vfs-mime-handlers.h>
+#include <libgnomevfs/gnome-vfs-mime.h>
 
 enum
 {
Index: profiles/audio-profiles-edit.c
===================================================================
RCS file: /cvs/gnome/gnome-media/profiles/audio-profiles-edit.c,v
retrieving revision 1.9
diff -u -p -r1.9 audio-profiles-edit.c
--- profiles/audio-profiles-edit.c	24 Jul 2005 08:55:30 -0000	1.9
+++ profiles/audio-profiles-edit.c	9 Jan 2006 12:26:27 -0000
@@ -147,12 +147,15 @@ profile_activated_callback (GtkTreeView 
                       COLUMN_PROFILE_OBJECT,
                       &profile,
                       -1);
-  if (profile)
-  /* FIXME: is this the right function name ? */
-  edit_dialog = gm_audio_profile_edit_new ((GConfClient *) profile, gm_audio_profile_get_id (profile));
-  g_return_if_fail (edit_dialog != NULL);
-  gtk_widget_show_all (GTK_WIDGET (edit_dialog));
-  gtk_dialog_run (GTK_DIALOG (edit_dialog));
+  if (profile) {
+    /* FIXME: is this the right function name ? */
+    edit_dialog = gm_audio_profile_edit_new ((GConfClient *) profile, gm_audio_profile_get_id (profile));
+    g_return_if_fail (edit_dialog != NULL);
+    gtk_widget_show_all (GTK_WIDGET (edit_dialog));
+    gtk_dialog_run (GTK_DIALOG (edit_dialog));
+  } else {
+    g_warning ("Could not retrieve profile");
+  }
 }
 
 static void
Index: profiles/gnome-audio-profiles-test.c
===================================================================
RCS file: /cvs/gnome/gnome-media/profiles/gnome-audio-profiles-test.c,v
retrieving revision 1.2
diff -u -p -r1.2 gnome-audio-profiles-test.c
--- profiles/gnome-audio-profiles-test.c	29 Aug 2004 20:25:43 -0000	1.2
+++ profiles/gnome-audio-profiles-test.c	9 Jan 2006 12:26:27 -0000
@@ -5,28 +5,29 @@
 #include <libgnomeui/libgnomeui.h>
 #include <profiles/gnome-media-profiles.h>
 
-static gboolean
-edit_cb (GtkButton *button, GtkWindow *window)
+static void
+edit_clicked_cb (GtkButton *button, GtkWindow *window)
 {
   GtkWidget *edit_dialog = NULL;
   edit_dialog = gm_audio_profiles_edit_new (gconf_client_get_default (), window);
   g_assert (edit_dialog != NULL);
   gtk_widget_show_all (GTK_WIDGET (edit_dialog));
-
-  return FALSE;
 }
 
-static gboolean
-test_cb (GtkButton *button, GtkWidget *combo)
+static void
+test_clicked_cb (GtkButton *button, GtkWidget *combo)
 {
+  GstStateChangeReturn ret;
   gchar *partialpipe = NULL;
   gchar *extension = NULL;
   gchar *pipeline_desc;
   GError *error = NULL;
-  int i;
-  GstElement *pipeline;
   GMAudioProfile *profile;
+  GstElement *pipeline = NULL;
+  GstMessage *msg = NULL;
+  GstBus *bus = NULL;
 
+  gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
 
   profile = gm_audio_profile_choose_get_active (combo);
   extension = g_strdup (gm_audio_profile_get_extension (profile));
@@ -36,28 +37,84 @@ test_cb (GtkButton *button, GtkWidget *c
            gm_audio_profile_get_name (profile),
            gm_audio_profile_get_pipeline (profile));
 
-  pipeline_desc = g_strdup_printf ("sinesrc ! audioconvert ! %s ! filesink location=test.%s",
+  pipeline_desc = g_strdup_printf ("audiotestsrc wave=sine num-buffers=4096 "
+                                   " ! audioconvert "
+                                   " ! %s "
+                                   " ! filesink location=test.%s",
                                    partialpipe, extension);
+
   g_print ("Going to run pipeline %s\n", pipeline_desc);
 
   pipeline = gst_parse_launch (pipeline_desc, &error);
   if (error)
   {
-    g_print ("Error parsing pipeline: %s\n", error->message);
-    g_error_free (error);
-    return FALSE;
+    g_warning ("Error parsing pipeline: %s", error->message);
+    goto done;
   }
 
+  bus = gst_element_get_bus (pipeline);
+
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
-  g_print ("Writing test sound to test.%s\n", extension);
-  for (i = 0; i < 100; ++i)
-    gst_bin_iterate (GST_BIN (pipeline));
-  gst_element_set_state (pipeline, GST_STATE_NULL);
-  g_free (pipeline);
-  g_free (extension);
+
+  /* wait for state change to complete or to have failed */
+  ret = gst_element_get_state (pipeline, NULL, NULL, -1);
+  if (ret == GST_STATE_CHANGE_FAILURE) {
+    /* check if an error was posted on the bus */
+    if ((msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0))) {
+      gst_message_parse_error (msg, &error, NULL);
+    }
+	                  
+    g_warning ("Error starting pipeline: %s",
+        (error) ? error->message : "UNKNOWN ERROR");
+
+    goto done;
+  }  
+
+  g_print ("Writing test sound to test.%s ...\n", extension);
+
+  /* wait for it finish (error or EOS), but no more than 30 secs */
+  msg = gst_bus_poll (bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS, 30*GST_SECOND);
+
+  if (msg) {
+    switch (GST_MESSAGE_TYPE (msg)) {
+      case GST_MESSAGE_EOS:
+        g_print ("Test finished successfully.\n");
+        break;
+      case GST_MESSAGE_ERROR:
+        gst_message_parse_error (msg, &error, NULL);
+        g_warning ("Error starting pipeline: %s",
+            (error) ? error->message : "UNKNOWN ERROR");
+        break;
+      default:
+        g_assert_not_reached ();
+    }
+  } else {
+    g_warning ("Test did not finish within 30 seconds!\n");
+  }
+
+done:
+
+  g_print ("==============================================================\n");
+
+  if (error)
+    g_error_free (error);
+
+  if (pipeline) {
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+  }
+
+  if (msg)
+    gst_message_unref (msg);
+
+  if (bus)
+    gst_object_unref (bus);
+
+  g_free (pipeline_desc);
   g_free (partialpipe);
+  g_free (extension);
 
-  return FALSE;
+  gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
 }
 
 int
@@ -79,8 +136,8 @@ main (int argc, char **argv)
 
   edit = gtk_button_new_with_mnemonic ("_Edit Profiles");
   test = gtk_button_new_with_mnemonic ("_Test");
-  g_signal_connect (edit, "clicked", (GCallback) edit_cb, window);
-  g_signal_connect (test, "clicked", (GCallback) test_cb, combo);
+  g_signal_connect (edit, "clicked", (GCallback) edit_clicked_cb, window);
+  g_signal_connect (test, "clicked", (GCallback) test_clicked_cb, combo);
   g_signal_connect (edit, "destroy", (GCallback) gtk_main_quit, NULL);
 
   hbox = gtk_hbox_new (FALSE, 7);
Index: profiles/gnome-audio-profiles.schemas.in.in
===================================================================
RCS file: /cvs/gnome/gnome-media/profiles/gnome-audio-profiles.schemas.in.in,v
retrieving revision 1.6
diff -u -p -r1.6 gnome-audio-profiles.schemas.in.in
--- profiles/gnome-audio-profiles.schemas.in.in	9 May 2004 19:04:23 -0000	1.6
+++ profiles/gnome-audio-profiles.schemas.in.in	9 Jan 2006 12:26:28 -0000
@@ -125,7 +125,7 @@
       <applyto>/system/gstreamer/audio/profiles/cdlossy/pipeline</applyto>
       <owner>gnome-media</owner>
       <type>string</type>
-      <default> audio/x-raw-int,rate=44100,channels=2 ! vorbisenc name=enc quality=0.5</default>
+      <default> audio/x-raw-float,rate=44100,channels=2 ! vorbisenc name=enc quality=0.5 ! oggmux</default>
       <locale name="C">
         <short>The partial GStreamer pipeline used</short>
         <long>
