Index: configure.ac
===================================================================
RCS file: /cvs/gnome/rhythmbox/configure.ac,v
retrieving revision 1.149
diff -u -r1.149 configure.ac
--- configure.ac	20 Jul 2005 14:20:32 -0000	1.149
+++ configure.ac	9 Aug 2005 15:37:42 -0000
@@ -52,6 +52,8 @@
 dnl function was added in that release.
 dnl enable_ipod = "no"
 
+HAL_REQUIRED=0.2.92
+
 AC_ARG_ENABLE(ipod,
 	      AC_HELP_STRING([--enable-ipod],
 			     [Enable iPod support in Rhythmbox]))
@@ -59,10 +61,11 @@
 if test x"$enable_ipod" = xyes; then
 	AC_DEFINE(WITH_IPOD_SUPPORT, 1, [Define if iPod support is enabled])
 	USE_HAL=""
-	PKG_CHECK_MODULES(HAL, hal >= $HAL_MIN_REQS hal < $HAL_MAX_REQS gnome-vfs-2.0 >= 2.7.4,
-		[ AC_DEFINE([HAVE_HAL], 1, [Use the HAL library]) ]
-		[ USE_HAL="dbus-glib-1 hal >= $HAL_MIN_REQS hal < $HAL_MAX_REQS" ], :)
+dnl	PKG_CHECK_MODULES(HAL, hal >= $HAL_REQUIRED gnome-vfs-2.0 >= 2.7.4,
+dnl		[ AC_DEFINE([HAVE_HAL], 1, [Use the HAL library]) ]
+dnl		[ USE_HAL="dbus-glib-1 hal >= $HAL_REQUIRED" ], :)
 fi
+AM_CONDITIONAL(WITH_IPOD_SUPPORT, test "x$enable_ipod" = "xyes")
 
 PKG_CHECK_MODULES(RHYTHMBOX,				\
 		  gtk+-2.0 >= $GTK_REQS			\
@@ -230,15 +233,11 @@
 fi
 
 dnl CD Audio support		  
-dnl AC_ARG_ENABLE(audiocd, AC_HELP_STRING([--enable-audiocd],
-dnl				[build with Audio CD support]),enable_audiocd=yes)
-dnl For now.
-enable_audiocd=no
-
-if test "x$enable_audiocd" = "xyes"; then
-  if test x"$enable_musicbrainz" != xyes; then
-	AC_MSG_ERROR([MusicBrainz is required for AudioCD support])
-  fi
+AC_ARG_WITH(audiocd, AC_HELP_STRING([--with-audiocd],
+			[build with Audio CD support]),with_audiocd=yes)
+
+if test "x$with_audiocd" = "xyes"; then
+  AC_DEFINE(WITH_AUDIOCD_SUPPORT, 1, [Define if audio cd support is enabled])
   AC_CHECK_HEADER(linux/cdrom.h,[enable_linux_cdrom=yes],)
   if test "x$enable_linux_cdrom" = "xyes"; then
     AC_MSG_CHECKING([whether linux/cdrom.h actually works])
@@ -262,15 +261,16 @@
 else
   AC_MSG_NOTICE([CD audio support disabled])
 fi
-if test "x$enable_audiocd" = "xyes"; then
-  AM_GST_ELEMENT_CHECK(cdparanoia,,missing_gst_elements="$missing_gst_elements cdparanoia")
+if test "x$with_audiocd" = "xyes"; then
+  if test x"$have_gstreamer" = xyes; then
+    AM_GST_ELEMENT_CHECK(cdparanoia,,missing_gst_elements="$missing_gst_elements cdparanoia")
+  fi
   AC_DEFINE(HAVE_AUDIOCD,,[Define if we have CD Audio support])
-  AC_SUBST(AUDIOCD_INCLUDES, ["#include \"monkey-media-audio-cd.h\""])
 else
   :
   AC_SUBST(AUDIOCD_INCLUDES, [])
 fi
-AM_CONDITIONAL(HAVE_AUDIOCD, test "x$enable_audiocd" = "xyes")
+AM_CONDITIONAL(WITH_AUDIOCD_SUPPORT, test "x$with_audiocd" = "xyes")
 AM_CONDITIONAL(HAVE_LINUX_CDROM, test "x$enable_linux_cdrom" = "xyes")
 
 dnl CD burner support
@@ -497,12 +497,11 @@
 	AC_MSG_NOTICE([   D-BUS control/activation disabled])
 fi
 
-dnl if test "x$enable_audiocd" != "xyes"; then
-dnl 	AC_MSG_NOTICE([   Audio CD support is disabled])
-dnl else
-dnl 	AC_MSG_NOTICE([** Audio CD support is enabled])
-dnl 	AC_MSG_WARN([Audio CD support is experimental!])
-dnl fi
+if test x"$with_audiocd" = xyes; then
+	AC_MSG_NOTICE([** Audio CD support enabled])
+else
+	AC_MSG_NOTICE([   Audio CD support disabled])
+fi
 if test x"$missing_gst_output_element" != x; then
 	AC_MSG_WARN([Neither osssink nor alsasink could be found on your system])
 fi	
Index: lib/rb-util.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/lib/rb-util.c,v
retrieving revision 1.14
diff -u -r1.14 rb-util.c
--- lib/rb-util.c	19 Jun 2005 18:29:44 -0000	1.14
+++ lib/rb-util.c	9 Aug 2005 15:37:49 -0000
@@ -38,6 +38,12 @@
 	return FALSE;
 }
 
+gpointer
+rb_null_function (gpointer dummy)
+{
+	return NULL;
+}
+
 int
 rb_gvalue_compare (GValue *a, GValue *b)
 {
Index: lib/rb-util.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/lib/rb-util.h,v
retrieving revision 1.11
diff -u -r1.11 rb-util.h
--- lib/rb-util.h	12 Jun 2005 17:16:48 -0000	1.11
+++ lib/rb-util.h	9 Aug 2005 15:37:49 -0000
@@ -32,6 +32,7 @@
 
 gboolean rb_true_function (gpointer dummy);
 gboolean rb_false_function (gpointer dummy);
+gpointer rb_null_function (gpointer dummy);
 
 gboolean rb_gvalue_compare (GValue *a, GValue *b);
 
Index: player/rb-player-gst.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/player/rb-player-gst.c,v
retrieving revision 1.39
diff -u -r1.39 rb-player-gst.c
--- player/rb-player-gst.c	31 Jul 2005 14:49:33 -0000	1.39
+++ player/rb-player-gst.c	9 Aug 2005 15:37:53 -0000
@@ -37,8 +37,35 @@
 #include "rb-debug.h"
 #include "rb-marshal.h"
 
+#define RB_TYPE_PLAYER_SUBTYPE 		(rb_player_subtype_get_type ())
+#define RB_PLAYER_SUBTYPE(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_PLAYER_SUBTYPE, RBPlayerSubtype))
+#define RB_PLAYER_SUBTYPE_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_PLAYER_SUBTYPE, RBPlayerSubtypeClass))
+#define RB_IS_PLAYER_SUBTYPE(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_PLAYER_SUBTYPE))
+#define RB_IS_PLAYER_SUBTYPE_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_PLAYER_SUBTYPE))
+#define RB_PLAYER_SUBTYPE_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_PLAYER_SUBTYPE, RBPlayerSubtypeClass))
+
+GType rb_player_cdda_subtype_get_type (void);
+
 G_DEFINE_TYPE(RBPlayer, rb_player, G_TYPE_OBJECT)
 
+typedef struct
+{
+	GObject parent;
+} RBPlayerSubtype;
+
+typedef struct
+{
+	GObjectClass parent_class;
+
+	gboolean (*pre_open)		(RBPlayerSubtype *subtype, GstElement *playbin, const char *uri, GError **error);
+	void (*got_source)		(RBPlayerSubtype *subtype, GstElement *playbin, GstElement *source);
+	void (*pre_close)		(RBPlayerSubtype *subtype, GstElement *playbin, GError **error);
+} RBPlayerSubtypeClass;
+
+GType rb_player_subtype_get_type (void);
+	
+G_DEFINE_TYPE(RBPlayerSubtype, rb_player_subtype, G_TYPE_OBJECT)
+	
 static void rb_player_finalize (GObject *object);
 
 struct RBPlayerPrivate
@@ -57,6 +84,8 @@
 	float cur_volume;
 
 	guint tick_timeout_id;
+
+	RBPlayerSubtype *subtype;
 };
 
 typedef enum
@@ -353,6 +382,20 @@
 }
 
 static void
+got_source_cb (GObject *object, GParamSpec *pspec, RBPlayer *player)
+{
+	GstElement *playbin = GST_ELEMENT (object);
+	GstElement *source;
+
+	gst_element_get (playbin, "source", &source, NULL);
+	rb_debug ("got source %p", source);
+	if (source && player->priv->subtype) {
+		RBPlayerSubtypeClass *subtype_class = RB_PLAYER_SUBTYPE_GET_CLASS (player->priv->subtype);
+		(*subtype_class->got_source) (player->priv->subtype, playbin, source);
+	}
+}
+
+static void
 rb_player_construct (RBPlayer *mp, GError **error)
 {
 	char *element_name = NULL;
@@ -368,6 +411,10 @@
 				 "found_tag",
 				 G_CALLBACK (found_tag_cb),
 				 mp, 0);
+	g_signal_connect_object (G_OBJECT (mp->priv->playbin),
+				 "notify::source",
+				 G_CALLBACK (got_source_cb),
+				 mp, 0);
 
 	mp->priv->buffering_signal_id =
 		g_signal_connect_object (G_OBJECT (mp->priv->playbin),
@@ -479,6 +526,7 @@
 void
 rb_player_open (RBPlayer *mp,
 		const char *uri,
+		GObject *subtype,
 		GError **error)
 {
 	g_return_if_fail (RB_IS_PLAYER (mp));
@@ -498,6 +546,20 @@
 		mp->priv->playing = FALSE;
 		return;
 	}
+
+	if (subtype) {
+		RBPlayerSubtypeClass *subtype_class;
+
+		g_return_if_fail (RB_IS_PLAYER_SUBTYPE (subtype));
+
+		g_object_ref (subtype);
+		mp->priv->subtype = RB_PLAYER_SUBTYPE (subtype);
+
+		subtype_class = RB_PLAYER_SUBTYPE_GET_CLASS (mp->priv->subtype);
+		if ((*subtype_class->pre_open) (mp->priv->subtype, mp->priv->playbin, uri, error) == FALSE)
+			return;
+	}
+	
 	g_object_set (G_OBJECT (mp->priv->playbin), "uri", uri, NULL);	
 	mp->priv->uri = g_strdup (uri);
 
@@ -519,6 +581,14 @@
 	if (mp->priv->playbin == NULL)
 		return;
 
+	if (mp->priv->subtype) {
+		RBPlayerSubtypeClass *subtype_class = RB_PLAYER_SUBTYPE_GET_CLASS (mp->priv->subtype);
+		(*subtype_class->pre_close) (mp->priv->subtype, mp->priv->playbin, error);
+
+		g_object_unref (mp->priv->subtype);
+		mp->priv->subtype = NULL;
+	}
+
 	if (gst_element_set_state (mp->priv->playbin,
 				   GST_STATE_READY) != GST_STATE_SUCCESS) {
 		g_set_error (error,
@@ -684,3 +754,98 @@
 	} else
 		return -1;
 }
+
+/**** subtype handling ****/
+	
+static gboolean default_subtype_pre_open (RBPlayerSubtype *subtype, GstElement *playbin, const char *uri, GError **error);
+static void default_subtype_got_source (RBPlayerSubtype *subtype, GstElement *playbin, GstElement *source);
+static void default_subtype_pre_close (RBPlayerSubtype *subtype, GstElement *playbin, GError **error);
+
+static void
+rb_player_subtype_class_init (RBPlayerSubtypeClass *klass)
+{
+	klass->pre_open = default_subtype_pre_open;
+	klass->got_source = default_subtype_got_source;
+	klass->pre_close = default_subtype_pre_close;
+}
+
+static void
+rb_player_subtype_init (RBPlayerSubtype *subtype)
+{
+	/* nothing */
+}
+
+static gboolean
+default_subtype_pre_open (RBPlayerSubtype *subtype, GstElement *playbin, const char *uri, GError **error)
+{
+	return TRUE;
+}
+
+static void
+default_subtype_got_source (RBPlayerSubtype *subtype, GstElement *playbin, GstElement *source)
+{
+	/* nothing */
+}
+
+static void
+default_subtype_pre_close (RBPlayerSubtype *subtype, GstElement *playbin, GError **error)
+{
+	/* nothing */
+}
+
+/* CD audio subtype implementation */
+
+#define RB_TYPE_PLAYER_CDDA_SUBTYPE 	(rb_player_cdda_subtype_get_type ())
+#define RB_PLAYER_CDDA_SUBTYPE(o)	(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_PLAYER_CDDA_SUBTYPE, RBPlayerCDDASubtype))
+
+typedef struct
+{
+	RBPlayerSubtype parent;
+	char *cdda_device;
+} RBPlayerCDDASubtype;
+	
+typedef struct
+{
+	RBPlayerSubtypeClass parent_class;
+} RBPlayerCDDASubtypeClass;
+
+G_DEFINE_TYPE(RBPlayerCDDASubtype, rb_player_cdda_subtype, RB_TYPE_PLAYER_SUBTYPE)
+
+static void rb_player_cdda_subtype_got_source (RBPlayerSubtype *subtype, 
+					       GstElement *playbin, 
+					       GstElement *source);
+
+static void
+rb_player_cdda_subtype_class_init (RBPlayerCDDASubtypeClass *klass)
+{
+	RBPlayerSubtypeClass *subtype_class = RB_PLAYER_SUBTYPE_CLASS (klass);
+	subtype_class->got_source = rb_player_cdda_subtype_got_source;
+}
+
+static void
+rb_player_cdda_subtype_init (RBPlayerCDDASubtype *subtype)
+{
+	/* nothing */
+}
+
+static void 
+rb_player_cdda_subtype_got_source (RBPlayerSubtype *subtype, 
+				   GstElement *playbin, 
+				   GstElement *source)
+{
+	RBPlayerCDDASubtype *st = RB_PLAYER_CDDA_SUBTYPE (subtype);
+
+	if (source && st->cdda_device) {
+		rb_debug ("setting device %s on source element", st->cdda_device);
+		gst_element_set (source, "device", st->cdda_device, NULL);
+	}
+}
+
+GObject *
+rb_player_cdda_subtype_new (const char *device)
+{
+	RBPlayerCDDASubtype *subtype = g_object_new (RB_TYPE_PLAYER_CDDA_SUBTYPE, NULL);
+	subtype->cdda_device = g_strdup (device);
+	return G_OBJECT (subtype);
+}
+
Index: player/rb-player.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/player/rb-player.h,v
retrieving revision 1.9
diff -u -r1.9 rb-player.h
--- player/rb-player.h	29 Jul 2005 14:53:09 -0000	1.9
+++ player/rb-player.h	9 Aug 2005 15:37:53 -0000
@@ -24,7 +24,7 @@
 #define __RB_PLAYER_H
 
 #include <glib-object.h>
-#include "rb-metadata.h"
+#include "metadata/rb-metadata.h"
 
 G_BEGIN_DECLS
 
@@ -80,6 +80,7 @@
 
 void		rb_player_open       (RBPlayer *mp,
 				      const char *uri,
+				      GObject *subtype,
 				      GError **error);
 
 gboolean	rb_player_opened     (RBPlayer *mp);
@@ -104,6 +105,8 @@
 void		rb_player_set_time   (RBPlayer *mp,
 				      long time);
 long		rb_player_get_time   (RBPlayer *mp);
+
+GObject *	rb_player_cdda_subtype_new (const char *device);
 
 G_END_DECLS
 
Index: shell/Makefile.am
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/Makefile.am,v
retrieving revision 1.47
diff -u -r1.47 Makefile.am
--- shell/Makefile.am	19 Jun 2005 18:30:57 -0000	1.47
+++ shell/Makefile.am	9 Aug 2005 15:38:04 -0000
@@ -36,6 +36,8 @@
 	rb-shell-clipboard.h				\
 	rb-playlist-manager.c				\
 	rb-playlist-manager.h				\
+	rb-device-manager.c				\
+	rb-device-manager.h				\
 	rb-history.c					\
 	rb-history.h					\
 	rb-play-order.c					\
Index: shell/rb-shell-player.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-shell-player.c,v
retrieving revision 1.160
diff -u -r1.160 rb-shell-player.c
--- shell/rb-shell-player.c	1 Aug 2005 20:34:41 -0000	1.160
+++ shell/rb-shell-player.c	9 Aug 2005 15:38:21 -0000
@@ -919,11 +919,13 @@
 					RBShellPlayer *player)
 {
 	GError *error = NULL;
+	GObject *player_subtype;
 
 	if (rb_player_playing (player->priv->mmplayer))
 		return;
 
-	rb_player_open (player->priv->mmplayer, uri, &error);
+	g_object_get (player->priv->source, "player-subtype", &player_subtype, NULL);
+	rb_player_open (player->priv->mmplayer, uri, player_subtype, &error);
 	if (error != NULL) {
 		if (player->priv->playlist_parse_error != NULL) {
 			g_error_free (player->priv->playlist_parse_error);
@@ -978,7 +980,9 @@
 	g_object_unref (playlist);
 	if (!playlist_parsed) {
 		/* We get here if we failed to parse as a playlist */
-		rb_player_open (player->priv->mmplayer, location, error);
+		GObject *player_subtype;
+		g_object_get (player->priv->source, "player-subtype", &player_subtype, NULL);
+		rb_player_open (player->priv->mmplayer, location, player_subtype, error);
 	} else if (playlist_result == TOTEM_PL_PARSER_RESULT_ERROR
 		   && error
 		   && player->priv->playlist_parse_error) {
Index: shell/rb-shell.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-shell.c,v
retrieving revision 1.308
diff -u -r1.308 rb-shell.c
--- shell/rb-shell.c	4 Aug 2005 14:18:04 -0000	1.308
+++ shell/rb-shell.c	9 Aug 2005 15:38:32 -0000
@@ -54,6 +54,7 @@
 #include "rb-file-helpers.h"
 #include "rb-source.h"
 #include "rb-playlist-manager.h"
+#include "rb-device-manager.h"
 #include "rb-preferences.h"
 #include "rb-druid.h"
 #include "rb-shell-clipboard.h"
@@ -64,15 +65,8 @@
 #include "rb-statusbar.h"
 #include "rb-shell-preferences.h"
 #include "rb-library-source.h"
-#ifdef WITH_IPOD_SUPPORT
-#include "rb-ipod-source.h"
-#endif /* WITH_IPOD_SUPPORT */
 #include "rb-load-failure-dialog.h"
 #include "rb-new-station-dialog.h"
-#include "rb-iradio-source.h"
-#ifdef HAVE_AUDIOCD
-#include "rb-audiocd-source.h"
-#endif
 #include "rb-shell-preferences.h"
 #include "rb-playlist-source.h"
 #include "eel-gconf-extensions.h"
@@ -136,6 +130,7 @@
 static void rb_shell_playlist_added_cb (RBPlaylistManager *mgr, RBSource *source, RBShell *shell);
 static void rb_shell_playlist_load_start_cb (RBPlaylistManager *mgr, RBShell *shell);
 static void rb_shell_playlist_load_finish_cb (RBPlaylistManager *mgr, RBShell *shell);
+static void rb_shell_device_added_cb (RBDeviceManager *mgr, RBSource *source, RBShell *shell);
 static void rb_shell_source_deleted_cb (RBSource *source, RBShell *shell);
 static void rb_shell_set_window_title (RBShell *shell, const char *window_title);
 static void rb_shell_set_duration (RBShell *shell, const char *duration);
@@ -196,11 +191,6 @@
 					guint cnxn_id,
 					GConfEntry *entry,
 					RBShell *shell);
-#ifdef HAVE_AUDIOCD
-static void audiocd_changed_cb (MonkeyMediaAudioCD *cd,
-				gboolean available,
-				gpointer data);
-#endif
 static void sourcelist_drag_received_cb (RBSourceList *sourcelist,
 					 RBSource *source,
 					 GtkSelectionData *data,
@@ -253,9 +243,6 @@
 static SourceCreateFunc known_sources[] = {
 	rb_library_source_new,
 	rb_iradio_source_new,
-#ifdef WITH_IPOD_SUPPORT
-	rb_ipod_source_new,	
-#endif /* WITH_IPOD_SUPPORT */
 	NULL,
 };
 
@@ -338,15 +325,12 @@
 	RBSourceHeader *source_header;
 	RBStatusbar *statusbar;
 	RBPlaylistManager *playlist_manager;
+	RBDeviceManager *device_manager;
 
 	GtkWidget *load_error_dialog;
 	GList *supported_media_extensions;
 	gboolean show_db_errors;
 
-#ifdef HAVE_AUDIOCD
- 	MonkeyMediaAudioCD *cd;
-#endif
-
 	RBSource *selected_source;
 
 	GtkWidget *prefs;
@@ -355,6 +339,11 @@
 
 	char *cached_title;
 	char *cached_duration;
+
+	guint selected_source_notify_id;
+	guint sourcelist_visibility_notify_id;
+	guint smalldisplay_notify_id;
+	guint paned_changed_notify_id;
 };
 
 static GtkActionEntry rb_shell_actions [] =
@@ -767,10 +756,16 @@
 	g_hash_table_destroy (shell->priv->sources_hash);
 
 	g_object_unref (G_OBJECT (shell->priv->playlist_manager));
+	g_object_unref (G_OBJECT (shell->priv->device_manager));
 
 	g_object_unref (G_OBJECT (shell->priv->clipboard_shell));
 
 	gtk_widget_destroy (shell->priv->window);
+	
+	eel_gconf_notification_remove (shell->priv->selected_source_notify_id);
+	eel_gconf_notification_remove (shell->priv->sourcelist_visibility_notify_id);
+	eel_gconf_notification_remove (shell->priv->smalldisplay_notify_id);
+	eel_gconf_notification_remove (shell->priv->paned_changed_notify_id);
 
 	rb_debug ("shutting down DB");
 	rhythmdb_shutdown (shell->priv->db);
@@ -959,18 +954,22 @@
 
 	rb_debug ("shell: adding gconf notification");
 	/* sync state */
-	eel_gconf_notification_add (CONF_STATE_SELECTED_SOURCE,
-				    (GConfClientNotifyFunc) selected_source_changed_cb,
-				    shell);
-	eel_gconf_notification_add (CONF_UI_SOURCELIST_HIDDEN,
-				    (GConfClientNotifyFunc) sourcelist_visibility_changed_cb,
-				    shell);
-	eel_gconf_notification_add (CONF_UI_SMALL_DISPLAY,
-				    (GConfClientNotifyFunc) smalldisplay_changed_cb,
-				    shell);
-	eel_gconf_notification_add (CONF_STATE_PANED_POSITION,
-				    (GConfClientNotifyFunc) paned_changed_cb,
-				    shell);
+	shell->priv->selected_source_notify_id =
+		eel_gconf_notification_add (CONF_STATE_SELECTED_SOURCE,
+			(GConfClientNotifyFunc) selected_source_changed_cb,
+			shell);
+	shell->priv->sourcelist_visibility_notify_id =
+		eel_gconf_notification_add (CONF_UI_SOURCELIST_HIDDEN,
+			(GConfClientNotifyFunc) sourcelist_visibility_changed_cb,
+		shell);
+	shell->priv->smalldisplay_notify_id =
+		eel_gconf_notification_add (CONF_UI_SMALL_DISPLAY,
+			(GConfClientNotifyFunc) smalldisplay_changed_cb,
+			shell);
+	shell->priv->paned_changed_notify_id =
+		eel_gconf_notification_add (CONF_STATE_PANED_POSITION,
+			(GConfClientNotifyFunc) paned_changed_cb,
+			shell);
 
 	rb_debug ("shell: syncing with gconf");
 	rb_shell_sync_sourcelist_visibility (shell);
@@ -1016,6 +1015,14 @@
 	g_signal_connect_object (G_OBJECT (shell->priv->playlist_manager), "load_finish",
 				 G_CALLBACK (rb_shell_playlist_load_finish_cb), shell, 0);
 
+	/* Initialize device manager */
+	rb_debug ("shell: creating device manager");
+	shell->priv->device_manager = rb_device_manager_new (shell,
+								 RB_SOURCELIST (shell->priv->sourcelist));
+
+	g_signal_connect_object (G_OBJECT (shell->priv->device_manager), "device_added",
+				 G_CALLBACK (rb_shell_device_added_cb), shell, 0);
+
 	rb_debug ("shell: loading ui");
 	gtk_ui_manager_insert_action_group (shell->priv->ui_manager,
 					    shell->priv->actiongroup, 0);
@@ -1050,27 +1057,6 @@
 	rb_shell_sync_window_state (shell);
 
 	rb_shell_select_source_internal (shell, library_source);
-
-#ifdef HAVE_AUDIOCD
-        if (rb_audiocd_is_any_device_available () == TRUE) {
-		rb_debug ("AudioCD device is available");
-		shell->priv->cd = monkey_media_audio_cd_new (NULL);
-
-		if (monkey_media_audio_cd_available (shell->priv->cd, NULL)) {
-			rb_debug ("Calling audiocd_changed_cb");
-			audiocd_changed_cb (shell->priv->cd,
-					    TRUE,
-					    shell);
-		}
-		else
-			rb_debug("CD is not available");
-
-		g_signal_connect_object (G_OBJECT (shell->priv->cd), "cd_changed",
-					 G_CALLBACK (audiocd_changed_cb), shell, 0);
-        }
-	else
-		rb_debug ("No AudioCD device is available!");
-#endif
 	
 	/* GO GO GO! */
 	if (rhythmdb_exists) {
@@ -1319,9 +1305,17 @@
 }
 
 static void
+rb_shell_device_added_cb (RBDeviceManager *mgr, RBSource *source, RBShell *shell)
+{
+	rb_shell_append_source (shell, source);
+}
+
+static void
 rb_shell_source_deleted_cb (RBSource *source,
 			    RBShell *shell)
 {
+	rb_debug ("removing source %p", source);
+
 	if (source == rb_shell_player_get_playing_source (shell->priv->player_shell)) {
 		rb_shell_player_set_playing_source (shell->priv->player_shell, NULL);
 	}
@@ -1766,6 +1760,7 @@
 	rb_debug ("load complete");
 
 	rb_playlist_manager_load_playlists (shell->priv->playlist_manager);
+	rb_device_manager_load_devices (shell->priv->device_manager);
 	rb_shell_sync_selected_source (shell);
 	shell->priv->load_complete = TRUE;
 
Index: sources/Makefile.am
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/Makefile.am,v
retrieving revision 1.18
diff -u -r1.18 Makefile.am
--- sources/Makefile.am	12 Jun 2005 13:57:38 -0000	1.18
+++ sources/Makefile.am	9 Aug 2005 15:38:32 -0000
@@ -13,8 +13,10 @@
 	rb-library-source.h		\
 	rb-iradio-source.c		\
 	rb-iradio-source.h		\
+	rb-device-source.c		\
+	rb-device-source.h		\
 	rb-playlist-source.c            \
-	rb-playlist-source.h		
+	rb-playlist-source.h
 
 INCLUDES =						\
         -DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \
@@ -24,7 +26,7 @@
 	-I$(top_builddir)/lib 				\
 	-I$(top_srcdir)/corba 				\
 	-I$(top_builddir)/corba				\
-	-I$(top_srcdir)/rhythmdb			\
+	-I$(top_srcdir)/rhythmdb				\
 	-I$(top_srcdir)/widgets 			\
 	-I$(top_srcdir)/library 			\
 	-I$(top_srcdir)/player	 			\
@@ -39,17 +41,23 @@
 libsources_la_LDFLAGS = -export-dynamic
 libsourcesimpl_la_LDFLAGS = -export-dynamic
 
-if USE_IPOD
-libsourcesimpl_la_SOURCES +=         \
-	rb-ipod-source.c             \
-	rb-ipod-source.h	     \
-	itunesdb.c		     \
+if WITH_IPOD_SUPPORT
+libsourcesimpl_la_SOURCES +=		\
+	rb-ipod-source.c		\
+	rb-ipod-source.h		\
+	itunesdb.c			\
 	itunesdb.h
 endif
 
+if WITH_AUDIOCD_SUPPORT
+libsourcesimpl_la_SOURCES +=		\
+	rb-audiocd-source.c		\
+	rb-audiocd-source.h
+endif
+
 if USE_CD_BURNER
 libsourcesimpl_la_SOURCES += 		\
-	rb-playlist-source-recorder.c   \
+	rb-playlist-source-recorder.c	\
 	rb-playlist-source-recorder.h	
 
 INCLUDES += $(LIBNAUTILUS_BURN_CFLAGS)
Index: sources/rb-ipod-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-ipod-source.c,v
retrieving revision 1.13
diff -u -r1.13 rb-ipod-source.c
--- sources/rb-ipod-source.c	6 Jul 2005 15:01:37 -0000	1.13
+++ sources/rb-ipod-source.c	9 Aug 2005 15:38:32 -0000
@@ -41,30 +41,17 @@
 static void rb_ipod_source_init (RBiPodSource *source);
 static void rb_ipod_source_finalize (GObject *object);
 static void rb_ipod_source_class_init (RBiPodSourceClass *klass);
-static GObject *rb_ipod_source_constructor (GType type, 
-					    guint n_construct_properties,
-					    GObjectConstructParam *construct_properties);
-
-static gboolean rb_ipod_is_volume_ipod (GnomeVFSVolume *volume);
-static void rb_ipod_volume_mounted_cb (GnomeVFSVolumeMonitor *monitor, 
-				       GnomeVFSVolume *volume, gpointer data);
-static void rb_ipod_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
-					 GnomeVFSVolume *volume, 
-					 gpointer data);
-static void rb_ipod_plugged   (RBiPodSource *source, 
-			       const gchar *mount_path,
-			       GnomeVFSVolume *volume);
-static void rb_ipod_unplugged (RBiPodSource *source);
+
+static void impl_device_plugged (RBDeviceSource *source);
+static void impl_device_unplugged (RBDeviceSource *source);
 static gchar *rb_ipod_get_mount_path (GnomeVFSVolume *volume);
 
-static void rb_ipod_monitor (RBiPodSource *source, gboolean enable);
 #ifdef HAVE_HAL
 static gboolean hal_udi_is_ipod (const char *udi);
 #endif
 
 struct RBiPodSourcePrivate
 {
-	GnomeVFSVolume *ipod_volume;
 	iPodParser *parser;
 	gchar *ipod_mount_path;
 };
@@ -105,74 +92,14 @@
 rb_ipod_source_class_init (RBiPodSourceClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	RBDeviceSourceClass *device_source_class = RB_DEVICE_SOURCE_CLASS (klass);
 
 	parent_class = g_type_class_peek_parent (klass);
 
 	object_class->finalize = rb_ipod_source_finalize;
-	object_class->constructor = rb_ipod_source_constructor;
-}
-
 
-static GObject *
-rb_ipod_source_constructor (GType type, guint n_construct_properties,
-			    GObjectConstructParam *construct_properties)
-{
-	GObject *object;
-	RBiPodSourceClass *klass;
-	GObjectClass *parent_class;  
-
-	/* Invoke parent constructor. */
-	klass = RB_IPOD_SOURCE_CLASS (g_type_class_peek (RB_TYPE_IPOD_SOURCE));
-	parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-	object = parent_class->constructor (type,
-					    n_construct_properties,
-					    construct_properties);
-  
-	/* This needs to be done once the GObject properties are set
-	 * since rb_ipod_monitor expect the properties on the
-	 * RBiPodSource to be set (especially the "db" property)
-	 */
-	rb_ipod_monitor (RB_IPOD_SOURCE (object), TRUE);
-	return object;
-}
-
-
-static void
-rb_ipod_monitor (RBiPodSource *source, gboolean enable)
-{
-	GnomeVFSVolumeMonitor *monitor;
-	
-	monitor = gnome_vfs_get_volume_monitor ();
-
-	if (enable) {
-		GList *volumes;
-		GList *it;
-
-		/* Look for already plugged iPod */
-		volumes = gnome_vfs_volume_monitor_get_mounted_volumes (monitor);
-		for (it = volumes; it != NULL; it = it->next) {
-			if (rb_ipod_is_volume_ipod (GNOME_VFS_VOLUME (it->data))) {
-				rb_ipod_plugged (source, NULL,
-						 GNOME_VFS_VOLUME (it->data));
-			}
-		}
-		
-		/* Monitor new (un)mounted file systems to look for an iPod */
-		g_signal_connect (G_OBJECT (monitor), "volume-mounted", 
-				  G_CALLBACK (rb_ipod_volume_mounted_cb), 
-				  source);
-		g_signal_connect (G_OBJECT (monitor), "volume-unmounted", 
-				  G_CALLBACK (rb_ipod_volume_unmounted_cb), 
-				  source);
-	} else {
-		g_signal_handlers_disconnect_by_func (G_OBJECT (monitor), 
-						      G_CALLBACK (rb_ipod_volume_mounted_cb), 
-						      source);
-		g_signal_handlers_disconnect_by_func (G_OBJECT (monitor), 
-						      G_CALLBACK (rb_ipod_volume_unmounted_cb), 
-						      source);
-
-	}
+	device_source_class->impl_device_plugged = impl_device_plugged;
+	device_source_class->impl_device_unplugged = impl_device_unplugged;
 }
 
 static void
@@ -187,17 +114,11 @@
 {
 	RBiPodSource *source = RB_IPOD_SOURCE (object);
 
-	rb_ipod_monitor (source, FALSE);
-
 	if (source->priv->parser != NULL) {
 		ipod_parser_destroy (source->priv->parser);
 		source->priv->parser = NULL;
 	}
 
-	if (source->priv->ipod_volume != NULL) {
-		gnome_vfs_volume_unref (source->priv->ipod_volume);
-		source->priv->ipod_volume = NULL;
-	}
 	g_free (source->priv->ipod_mount_path);
 	g_free (source->priv);
 
@@ -229,21 +150,25 @@
 	return icon;
 }
 
-RBSource *
-rb_ipod_source_new (RBShell *shell)
+RBDeviceSource *
+rb_ipod_source_new (RBShell *shell, GnomeVFSVolume *volume)
 {
-	RBSource *source;
+	char *display_name = gnome_vfs_volume_get_display_name (volume);
+	char *internal_name = g_strdup_printf ("<ipod:%s>", gnome_vfs_volume_get_device_path (volume));
+	RBDeviceSource *source;
 
-	source = RB_SOURCE (g_object_new (RB_TYPE_IPOD_SOURCE,
-					  "name", _("iPod"),
+	source = RB_DEVICE_SOURCE (g_object_new (RB_TYPE_IPOD_SOURCE,
+					  "name", display_name,
 					  "entry-type", RHYTHMDB_ENTRY_TYPE_IPOD,
-					  "internal-name", "<ipod>",
+					  "internal-name", internal_name,
 					  "icon", rb_ipod_get_icon (),
 					  "shell", shell,
 					  "visibility", FALSE,
 					  NULL));
 
-	rb_shell_register_entry_type_for_source (shell, source, 
+	g_free (internal_name);
+
+	rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), 
 						 RHYTHMDB_ENTRY_TYPE_IPOD);
 
 	return source;
@@ -418,47 +343,23 @@
 
 
 static void
-rb_ipod_plugged (RBiPodSource *source, 
-		 const gchar *mount_path,
-		 GnomeVFSVolume *volume)
+impl_device_plugged (RBDeviceSource *source)
 {
-	int res;
-
-	rb_debug ("iPod plugged\n");
-
-	if (source->priv->ipod_mount_path != NULL) {
-		/* Only one iPod can be recognized at once */
-		return;
-	}
+	RBiPodSource *ipod_source = RB_IPOD_SOURCE (source);
+	GnomeVFSVolume *volume;
 	
-	source->priv->ipod_mount_path = rb_ipod_get_mount_path (volume);
-	res = rb_ipod_load_songs (source);
-	if (res == 0) {
-		source->priv->ipod_volume = volume;
-		gnome_vfs_volume_ref (volume);
-		g_object_set (G_OBJECT (source), "visibility", TRUE, NULL);
-	} else {
-		g_free (source->priv->ipod_mount_path);
-		source->priv->ipod_mount_path = NULL;
-	}
-	/* FIXME: should we suspend this monitor until the iPod 
-	 * database has been read and fed to rhythmbox?
-	 */
+	g_object_get (G_OBJECT (source), "volume", &volume, NULL);
+	ipod_source->priv->ipod_mount_path = rb_ipod_get_mount_path (volume);
+	
+	rb_ipod_load_songs (ipod_source);
 }
 
 static void
-rb_ipod_unplugged (RBiPodSource *source)
+impl_device_unplugged (RBDeviceSource *source)
 {
-	rb_debug ("iPod unplugged\n");
+	RBiPodSource *ipod_source = RB_IPOD_SOURCE (source);
 	
-	g_assert (source->priv->ipod_mount_path != NULL);
-
-	source->priv->ipod_volume = NULL;
-	gnome_vfs_volume_unref (source->priv->ipod_volume);
-	g_free (source->priv->ipod_mount_path);
-	source->priv->ipod_mount_path = NULL;
-	g_object_set (G_OBJECT (source), "visibility", FALSE, NULL);
-	rb_ipod_unload_songs (source);
+	rb_ipod_unload_songs (ipod_source);
 }
 
 RhythmDBEntryType rhythmdb_entry_ipod_get_type (void) 
@@ -510,7 +411,7 @@
 	return result;
 }
 
-static gboolean
+gboolean
 rb_ipod_is_volume_ipod (GnomeVFSVolume *volume)
 {
 	gchar *itunesdb_path;
@@ -540,37 +441,6 @@
 	}
 
 	return result;
-}
-
-static void 
-rb_ipod_volume_mounted_cb (GnomeVFSVolumeMonitor *monitor,
-			   GnomeVFSVolume *volume, 
-			   gpointer data)
-{
-	RBiPodSource *source = RB_IPOD_SOURCE (data);
-
-	if (source->priv->ipod_volume != NULL) {
-		rb_debug ("iPod plugged while another one is already present, ignoring the new one");
-		return;
-	}
-
-	if (rb_ipod_is_volume_ipod (volume)) {
-		rb_ipod_plugged (source, NULL, volume);
-	}
-}
-
-static void 
-rb_ipod_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
-			     GnomeVFSVolume *volume, 
-			     gpointer data)
-{
-	RBiPodSource *source = RB_IPOD_SOURCE (data);
-
-	g_assert (volume != NULL);
-
-	if (source->priv->ipod_volume == volume) {
-		rb_ipod_unplugged (source);
-	}
 }
 
 
Index: sources/rb-ipod-source.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-ipod-source.h,v
retrieving revision 1.3
diff -u -r1.3 rb-ipod-source.h
--- sources/rb-ipod-source.h	10 Sep 2004 05:12:59 -0000	1.3
+++ sources/rb-ipod-source.h	9 Aug 2005 15:38:33 -0000
@@ -23,7 +23,7 @@
 #define __RB_IPOD_SOURCE_H
 
 #include "rb-shell.h"
-#include "rb-library-source.h"
+#include "rb-device-source.h"
 #include "rhythmdb.h"
 
 G_BEGIN_DECLS
@@ -41,17 +41,18 @@
 
 typedef struct
 {
-	RBLibrarySource parent;
+	RBDeviceSource parent;
 
 	RBiPodSourcePrivate *priv;
 } RBiPodSource;
 
 typedef struct
 {
-	RBLibrarySourceClass parent;
+	RBDeviceSourceClass parent;
 } RBiPodSourceClass;
 
-RBSource *	rb_ipod_source_new		(RBShell *shell);
+RBDeviceSource*	rb_ipod_source_new		(RBShell *shell, GnomeVFSVolume *volume);
+gboolean	rb_ipod_is_volume_ipod		(GnomeVFSVolume *volume);
 
 GType		rb_ipod_source_get_type	        (void);
 
Index: sources/rb-library-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-library-source.c,v
retrieving revision 1.108
diff -u -r1.108 rb-library-source.c
--- sources/rb-library-source.c	23 Jul 2005 12:41:07 -0000	1.108
+++ sources/rb-library-source.c	9 Aug 2005 15:38:37 -0000
@@ -125,6 +125,7 @@
 static const char * impl_get_album (RBSource *player);
 static gboolean impl_receive_drag (RBSource *source, GtkSelectionData *data);
 static gboolean impl_show_popup (RBSource *source);
+static const char * default_get_paned_key (RBLibrarySource *status);
 static void rb_library_source_do_query (RBLibrarySource *source, RBLibraryQueryType qtype);
 
 void rb_library_source_browser_views_activated_cb (GtkWidget *widget,
@@ -141,10 +142,10 @@
 #define CONF_UI_LIBRARY_DIR CONF_PREFIX "/ui/library"
 #define CONF_UI_LIBRARY_BROWSER_VIEWS CONF_PREFIX "/ui/library/browser_views"
 #define CONF_STATE_LIBRARY_DIR CONF_PREFIX "/state/library"
-#define CONF_STATE_LIBRARY_SORTING CONF_PREFIX "/state/library/sorting"
-#define CONF_STATE_PANED_POSITION CONF_PREFIX "/state/library/paned_position"
-#define CONF_STATE_SHOW_BROWSER   CONF_PREFIX "/state/library/show_browser"
-#define CONF_STATE_SEARCH_TEXT   CONF_PREFIX "/state/library/search_text"
+#define CONF_STATE_LIBRARY_SORTING CONF_STATE_LIBRARY_DIR "/sorting"
+#define CONF_STATE_PANED_POSITION CONF_STATE_LIBRARY_DIR "/paned_position"
+#define CONF_STATE_SHOW_BROWSER   CONF_STATE_LIBRARY_DIR "/show_browser"
+#define CONF_STATE_SEARCH_TEXT   CONF_STATE_LIBRARY_DIR "/search_text"
 
 struct RBLibrarySourcePrivate
 {
@@ -190,7 +191,8 @@
 	GSList *browser_views_group;
 	
 	RhythmDBEntryType entry_type;
-	
+
+	char * sorting_key;
 	guint ui_dir_notify_id;
 	guint state_dir_notify_id;
 	guint browser_view_notify_id;
@@ -215,7 +217,8 @@
 {
 	PROP_0,
 	PROP_ICON,
-	PROP_ENTRY_TYPE
+	PROP_ENTRY_TYPE,
+	PROP_SORTING_KEY
 };
 
 static GObjectClass *parent_class = NULL;
@@ -287,6 +290,8 @@
 	source_class->impl_receive_drag = impl_receive_drag;
 	source_class->impl_show_popup = impl_show_popup;
 
+	klass->impl_get_paned_key = default_get_paned_key;
+
 	g_object_class_install_property (object_class,
 					 PROP_ICON,
 					 g_param_spec_object ("icon",
@@ -304,6 +309,14 @@
 							    RHYTHMDB_ENTRY_TYPE_SONG,
 							    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
+	g_object_class_install_property (object_class,
+					 PROP_SORTING_KEY,
+					 g_param_spec_string ("sorting-key",
+							      "Sorting key",
+							      "GConf key for storing sort-order",
+							      CONF_STATE_LIBRARY_SORTING,
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
 }
 
 static void
@@ -441,6 +454,7 @@
 	eel_gconf_notification_remove (source->priv->state_dir_notify_id);
 	eel_gconf_notification_remove (source->priv->browser_view_notify_id);
 
+	g_free (source->priv->sorting_key);
 	g_free (source->priv->artist);
 	g_free (source->priv->album);
 
@@ -525,7 +539,7 @@
 	source->priv->browser = gtk_hbox_new (TRUE, 5);
 
 	/* set up songs tree view */
-	source->priv->songs = rb_entry_view_new (source->priv->db, CONF_STATE_LIBRARY_SORTING,
+	source->priv->songs = rb_entry_view_new (source->priv->db, source->priv->sorting_key,
 						 TRUE, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TRACK_NUMBER);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TITLE);
@@ -652,6 +666,10 @@
 	case PROP_ENTRY_TYPE:
 		source->priv->entry_type = g_value_get_uint (value);
 		break;
+	case PROP_SORTING_KEY:
+		g_free (source->priv->sorting_key);
+		source->priv->sorting_key = g_strdup (g_value_get_string (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -674,6 +692,9 @@
 	case PROP_ENTRY_TYPE:
 		g_value_set_uint (value, source->priv->entry_type);
 		break;
+	case PROP_SORTING_KEY:
+		g_value_set_string (value, source->priv->sorting_key);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -942,6 +963,12 @@
 	rb_library_source_do_query (source, RB_LIBRARY_QUERY_TYPE_SEARCH);
 }
 
+static const char *
+default_get_paned_key (RBLibrarySource *status)
+{
+	return CONF_STATE_PANED_POSITION;
+}
+
 static char *
 impl_get_status (RBSource *asource)
 {
@@ -1191,21 +1218,26 @@
 {
 	/* save state */
 	rb_debug ("paned size allocate");
-	eel_gconf_set_integer (CONF_STATE_PANED_POSITION,
+	eel_gconf_set_integer (rb_library_source_get_paned_key (source),
 			       gtk_paned_get_position (GTK_PANED (source->priv->paned)));
 }
 
 static void
 rb_library_source_state_prefs_sync (RBLibrarySource *source)
 {
+	const char *key;
+
 	rb_debug ("syncing state");
-	gtk_paned_set_position (GTK_PANED (source->priv->paned),
-				eel_gconf_get_integer (CONF_STATE_PANED_POSITION));
-	
-	if (eel_gconf_get_boolean (CONF_STATE_SHOW_BROWSER))
-		gtk_widget_show (source->priv->browser);
-	else
-		gtk_widget_hide (source->priv->browser);
+	key = rb_library_source_get_paned_key (source);
+	if (key)
+		gtk_paned_set_position (GTK_PANED (source->priv->paned),
+					eel_gconf_get_integer (key));
+
+	key = rb_source_get_browser_key (RB_SOURCE (source));
+	if (key && eel_gconf_get_boolean (key))
+			gtk_widget_show (source->priv->browser);
+		else
+			gtk_widget_hide (source->priv->browser);
 }
 
 static void
@@ -1334,6 +1366,14 @@
 {
 	_rb_source_show_popup (RB_SOURCE (source), "/LibrarySourcePopup");
 	return TRUE;
+}
+
+const char *
+rb_library_source_get_paned_key (RBLibrarySource *source)
+{
+	RBLibrarySourceClass *klass = RB_LIBRARY_SOURCE_GET_CLASS (source);
+
+	return klass->impl_get_paned_key (source);
 }
 
 static void
Index: sources/rb-library-source.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-library-source.h,v
retrieving revision 1.12
diff -u -r1.12 rb-library-source.h
--- sources/rb-library-source.h	10 Sep 2004 05:12:59 -0000	1.12
+++ sources/rb-library-source.h	9 Aug 2005 15:38:37 -0000
@@ -50,19 +50,20 @@
 typedef struct
 {
 	RBSourceClass parent;
+
+	const char *	(*impl_get_paned_key)	(RBLibrarySource *source);
 } RBLibrarySourceClass;
 
 GType		rb_library_source_get_type	(void);
 
 RBSource *      rb_library_source_new           (RBShell *shell);
 
-void		rb_library_source_show_browser	(RBLibrarySource *source,
-						 gboolean show);
-
 void		rb_library_source_add_location	(RBLibrarySource *source, GtkWindow *win);
 
 void            rb_library_source_class_add_actions (RBShell *shell, 
 						     GtkActionGroup *uimgr);
+
+const char *	rb_library_source_get_paned_key	(RBLibrarySource *source);
 
 G_END_DECLS
 
Index: sources/rb-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-source.c,v
retrieving revision 1.36
diff -u -r1.36 rb-source.c
--- sources/rb-source.c	7 Jul 2005 14:30:20 -0000	1.36
+++ sources/rb-source.c	9 Aug 2005 15:38:39 -0000
@@ -67,6 +67,7 @@
 	
 	RBShell *shell;
 	gboolean visible;
+	GObject *player_subtype;
 };
 
 enum
@@ -76,7 +77,8 @@
 	PROP_INTERNAL_NAME,
 	PROP_SHELL,
 	PROP_UI_MANAGER,
-	PROP_VISIBLE
+	PROP_VISIBLE,
+	PROP_PLAYER_SUBTYPE
 };
 
 enum
@@ -194,6 +196,14 @@
 							       TRUE,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
+	g_object_class_install_property (object_class,
+					 PROP_PLAYER_SUBTYPE,
+					 g_param_spec_object ("player-subtype",
+							      "GObject",
+							      "RBPlayerSubtype object",
+							      G_TYPE_OBJECT,
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
 	rb_source_signals[DELETED] =
 		g_signal_new ("deleted",
 			      RB_TYPE_SOURCE,
@@ -285,6 +295,9 @@
 			  source->priv->name, 
 			  source->priv->visible);
 		break;
+	case PROP_PLAYER_SUBTYPE:
+		source->priv->player_subtype = g_value_get_object (value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -323,6 +336,9 @@
 		g_object_unref (G_OBJECT(manager));
 		break;
 	}
+	case PROP_PLAYER_SUBTYPE:
+		g_value_set_object (value, source->priv->player_subtype);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -691,4 +707,14 @@
 
 	klass->impl_delete_thyself (source);
 	g_signal_emit (G_OBJECT (source), rb_source_signals[DELETED], 0);
+}
+
+
+RhythmDBEntryType
+rb_source_get_entry_type (RBSource *source)
+{
+	RhythmDBEntryType entry_type;
+
+	g_object_get (G_OBJECT (source), "entry_type", &entry_type, NULL);
+	return entry_type;
 }
Index: sources/rb-source.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-source.h,v
retrieving revision 1.22
diff -u -r1.22 rb-source.h
--- sources/rb-source.h	12 Jun 2005 16:02:15 -0000	1.22
+++ sources/rb-source.h	9 Aug 2005 15:38:39 -0000
@@ -163,6 +163,8 @@
 
 void		rb_source_delete_thyself	(RBSource *source);
 
+RhythmDBEntryType rb_source_get_entry_type	(RBSource *source);
+
 /* Protected method, should only be used by objects inheriting from RBSource */
 void            _rb_source_show_popup           (RBSource *source, 
 						 const char *ui_path);
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/gnome/rhythmbox/tests/Makefile.am,v
retrieving revision 1.9
diff -u -r1.9 Makefile.am
--- tests/Makefile.am	16 Dec 2003 15:36:45 -0000	1.9
+++ tests/Makefile.am	9 Aug 2005 15:38:45 -0000
@@ -57,7 +57,7 @@
 
 test_cmdline_LDFLAGS = -export-dynamic
 
-if HAVE_AUDIOCD
+if WITH_AUDIOCD_SUPPORT
 noinst_PROGRAMS += test-cd
 
 test_cd_SOURCES = test-cd.c
