From 8e39a1368f88e6173af3ace237d6ce3bc4cd9c53 Mon Sep 17 00:00:00 2001
From: Stan Seibert <volsung@xiph.org>
Date: Mon, 14 Jul 2003 01:55:47 +0000
Subject: [PATCH] Patch from David Walser <luigiwalser@yahoo.com> to do plugin
 detection in a better way.  Sort the plugin priorities and do them in
 descending order. Also makes use of arts/esd functions to test if they are
 holding the device or not.  If present, we check the those plugins first and
 only use them if they are currently holding the device.

git-svn-id: http://svn.xiph.org/trunk/ao@5136 0101bb08-14d6-0310-b084-bc0e0c8e3800
---
 configure.in                   |  4 +++
 src/audio_out.c                | 52 +++++++++++++++++++++++++---------
 src/plugins/alsa/ao_alsa.c     |  2 +-
 src/plugins/alsa09/ao_alsa09.c |  2 +-
 src/plugins/arts/ao_arts.c     | 12 +++++++-
 src/plugins/esd/ao_esd.c       | 11 ++++---
 6 files changed, 63 insertions(+), 20 deletions(-)

diff --git a/configure.in b/configure.in
index 2a310bf..f9dd849 100644
--- a/configure.in
+++ b/configure.in
@@ -248,6 +248,10 @@ if test "$BUILD_ARTS" = "yes"; then
   then
 	ARTS_CFLAGS=`$ac_cv_path_ARTSC_CONFIG --cflags`
 	ARTS_LIBS=`$ac_cv_path_ARTSC_CONFIG --libs`
+	SAVELIBS=$LIBS
+	LIBS="$LIBS $ARTS_LIBS"
+	AC_CHECK_FUNCS(arts_suspended)
+	LIBS=$SAVELIBS
   fi
 fi
 AM_CONDITIONAL(HAVE_ARTS,test "x$ac_cv_path_ARTSC_CONFIG" != x)
diff --git a/src/audio_out.c b/src/audio_out.c
index ff9cac0..b3102bb 100644
--- a/src/audio_out.c
+++ b/src/audio_out.c
@@ -161,7 +161,6 @@ static int _find_default_driver_id (const char *name)
 {
 	int def_id;
 	int id;
-	int priority;
 	ao_info *info;
 	driver_list *driver = driver_head;
 
@@ -170,16 +169,15 @@ static int _find_default_driver_id (const char *name)
 		def_id = -1;
 		
 		id = 0;
-		priority = 0; /* This forces the null driver to be skipped */ 
 		while (driver != NULL) {
 
 			info = driver->functions->driver_info();
 
 			if ( info->type == AO_TYPE_LIVE && 
-			     info->priority > priority &&
+			     info->priority > 0 && /* Skip static drivers */
 			     driver->functions->test() ) {
-				priority = info->priority;
 				def_id = id; /* Found a usable driver */
+				break;
 			}
 
 			driver = driver->next;
@@ -264,15 +262,29 @@ static void _append_dynamic_drivers(driver_list *end)
 }
 
 
+/* Compare two drivers based on priority 
+   Used as compar function for qsort() in _make_info_table() */
+static int _compar_driver_priority (const driver_list **a, 
+				    const driver_list **b)
+{
+	return memcmp(&((*b)->functions->driver_info()->priority),
+		      &((*a)->functions->driver_info()->priority),
+		      sizeof(int));
+}
+
+
 /* Make a table of driver info structures for ao_driver_info_list(). */
-static ao_info ** _make_info_table (driver_list *head, int *driver_count)
+static ao_info ** _make_info_table (driver_list **head, int *driver_count)
 {
 	driver_list *list;
 	int i;
 	ao_info **table;
+	driver_list **drivers_table;
+
+	*driver_count = 0;
 
 	/* Count drivers */
-	list = head;
+	list = *head;
 	i = 0;
 	while (list != NULL) {
 		i++;
@@ -280,15 +292,29 @@ static ao_info ** _make_info_table (driver_list *head, int *driver_count)
 	}
 
 	
+	/* Sort driver_list */
+	drivers_table = (driver_list **) calloc(i, sizeof(driver_list *));
+	if (drivers_table == NULL)
+		return (ao_info **) NULL;
+	list = *head;
+	*driver_count = i;
+	for (i = 0; i < *driver_count; i++, list = list->next)
+		drivers_table[i] = list;
+	qsort(drivers_table, i, sizeof(driver_list *), _compar_driver_priority);
+	*head = drivers_table[0];
+	for (i = 1; i < *driver_count; i++)
+		drivers_table[i-1]->next = drivers_table[i];
+	drivers_table[i-1]->next = NULL;
+
+
 	/* Alloc table */
 	table = (ao_info **) calloc(i, sizeof(ao_info *));
 	if (table != NULL) {
-		*driver_count = i;
-		list = head;
-		for (i = 0; i < *driver_count; i++, list = list->next)
-			table[i] = list->functions->driver_info();
-	} else
-		*driver_count = 0;
+		for (i = 0; i < *driver_count; i++)
+			table[i] = drivers_table[i]->functions->driver_info();
+	}
+
+	free(drivers_table);
 
 	return table;
 }
@@ -515,7 +541,7 @@ void ao_initialize(void)
 	}
 
 	/* Create the table of driver info structs */
-	info_table = _make_info_table(driver_head, &driver_count);
+	info_table = _make_info_table(&driver_head, &driver_count);
 }
 
 
diff --git a/src/plugins/alsa/ao_alsa.c b/src/plugins/alsa/ao_alsa.c
index ec47ab3..a21d785 100644
--- a/src/plugins/alsa/ao_alsa.c
+++ b/src/plugins/alsa/ao_alsa.c
@@ -46,7 +46,7 @@ static ao_info ao_alsa_info =
 	"Stan Seibert <volsung@asu.edu>",
 	"Outputs to the Advanced Linux Sound Architecture version 0.5.x.",
 	AO_FMT_NATIVE,
-	30,
+	34,
 	ao_alsa_options,
 	3
 };
diff --git a/src/plugins/alsa09/ao_alsa09.c b/src/plugins/alsa09/ao_alsa09.c
index 70d38fa..bf6e01c 100644
--- a/src/plugins/alsa09/ao_alsa09.c
+++ b/src/plugins/alsa09/ao_alsa09.c
@@ -50,7 +50,7 @@ static ao_info ao_alsa_info =
 	"Bill Currie <bill@taniwha.org>",
 	"Outputs to the Advanced Linux Sound Architecture version 0.9.x.",
 	AO_FMT_NATIVE,
-	30,
+	35,
 	ao_alsa_options,
 	3
 };
diff --git a/src/plugins/arts/ao_arts.c b/src/plugins/arts/ao_arts.c
index d97e881..e3d0ccf 100644
--- a/src/plugins/arts/ao_arts.c
+++ b/src/plugins/arts/ao_arts.c
@@ -39,7 +39,11 @@ static ao_info ao_arts_info =
 	"Rik Hemsley (rikkus) <rik@kde.org>",
 	"Outputs to the aRts soundserver.",
 	AO_FMT_NATIVE,
-	10,
+#ifdef HAVE_ARTS_SUSPENDED
+	45,
+#else
+	15,
+#endif
 	NULL,
 	0
 };
@@ -54,6 +58,12 @@ typedef struct ao_arts_internal
 int ao_plugin_test()
 {
 	if (arts_init() == 0) {
+#ifdef HAVE_ARTS_SUSPENDED
+		if (arts_suspended() == 1) {
+			arts_free();
+			return 0;
+		}
+#endif
 		arts_free();
 		return 1;
 	} else
diff --git a/src/plugins/esd/ao_esd.c b/src/plugins/esd/ao_esd.c
index fd0797e..c73a9eb 100644
--- a/src/plugins/esd/ao_esd.c
+++ b/src/plugins/esd/ao_esd.c
@@ -43,7 +43,7 @@ static ao_info ao_esd_info =
 	"Stan Seibert <volsung@asu.edu>",
 	"Outputs to the Enlightened Sound Daemon.",
 	AO_FMT_NATIVE,
-	10,
+	40,
 	ao_esd_options,
 	1
 };
@@ -63,12 +63,15 @@ int ao_plugin_test()
 	/* don't wake up the beast while detecting */
 	setenv("ESD_NO_SPAWN", "1", 1); 
 	sock = esd_open_sound(NULL);
-	if (sock < 0) 
+	if (sock < 0)
 		return 0;
-	else {
+	if (esd_get_standby_mode(sock) != ESM_RUNNING) {
 		esd_close(sock);
-		return 1;
+		return 0;
 	}
+
+	esd_close(sock);
+	return 1;
 }
 
 
-- 
GitLab