Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5614)
+++ ChangeLog	(revision 5615)
@@ -1,4 +1,5 @@
 v. 1.0beta5 - ?
 	* Fixed pa_xfree() (Closes: #293)
+	* Allow passing of extra parameters to cdrivers (Closes: #290)
 
 v. 1.0beta4 - Mon Aug 06 2012 16:43 CEST
Index: include/libroareio/driver.h
===================================================================
--- include/libroareio/driver.h	(revision 5381)
+++ include/libroareio/driver.h	(revision 5615)
@@ -46,4 +46,8 @@
 int roar_cdriver_open(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir);
 
+int roar_cdriver_open2(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen);
+
+ssize_t roar_cdriver_list   (const char ** list, size_t len, size_t offset) _LIBROAR_STREAM_STDATTRS;
+
 // driver prototypes:
 int roar_cdriver_oss (struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir);
Index: libroareio/driver.c
===================================================================
--- libroareio/driver.c	(revision 5388)
+++ libroareio/driver.c	(revision 5615)
@@ -32,8 +32,8 @@
 #endif
 
-int roar_cdriver_null(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir) {
+static int roar_cdriver_null(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen) {
  ROAR_DBG("roar_cdriver_null(calls=%p, name='%s', dev='%s', info=%p{...}, dir=%i(?)) = ?", calls, name, dev, info, dir);
 
- (void)name, (void)dev, (void)info, (void)dir;
+ (void)name, (void)dev, (void)info, (void)dir, (void)para, (void)paralen;
 
  memset(calls, 0, sizeof(struct roar_vio_calls));
@@ -47,18 +47,22 @@
 }
 
-struct roar_cdriver _g_roar_cdriver[] = {
- {"null", roar_cdriver_null},
- {"roar", roar_cdriver_roar},
+struct {
+ const char * name;
+ int  (*open)(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir);
+ int  (*open2)(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen);
+} _g_roar_cdriver[] = {
+ {"null", NULL, roar_cdriver_null},
+ {"roar", roar_cdriver_roar, NULL},
 #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS)
- {"oss",  roar_cdriver_oss},
+ {"oss",  roar_cdriver_oss, NULL},
 #endif
 #ifdef ROAR_HAVE_AD_ESDFW
 #include "driver_esdfw.c"
 #endif
- {NULL, NULL}
+ {NULL, NULL, NULL}
 };
 
 
-static int roar_cdriver_open_default(struct roar_vio_calls * calls, const char * dev, struct roar_audio_info * info, int dir) {
+static int roar_cdriver_open_default(struct roar_vio_calls * calls, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen) {
  const char * names[] = {
   // native APIs:
@@ -77,35 +81,72 @@
 
  for (i = 0; i < (sizeof(names)/sizeof(*names)); i++) {
-  ret = roar_cdriver_open(calls, names[i], dev, info, dir);
+  ret = roar_cdriver_open2(calls, names[i], dev, info, dir, para, paralen);
   if ( ret != -1 )
    return ret;
  }
 
+ // roar_error is still set to the error of the last tested driver.
  return -1;
 }
 
-int roar_cdriver_open(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir) {
+int roar_cdriver_open2(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int
+ dir, struct roar_keyval * para, ssize_t paralen) {
  int i;
  char *delm;
 
  if ( name == NULL )
-  return roar_cdriver_open_default(calls, dev, info, dir);
+  return roar_cdriver_open_default(calls, dev, info, dir, para, paralen);
 
  for (i = 0; _g_roar_cdriver[i].name != NULL; i++) {
   ROAR_DBG("roar_cdriver_open(*): _g_roar_cdriver[i].name='%s' <cmp> name='%s'", _g_roar_cdriver[i].name, name);
 
-  if ( !strcmp(_g_roar_cdriver[i].name, name) )
-   return _g_roar_cdriver[i].open(calls, name, dev, info, dir);
+  if ( !strcmp(_g_roar_cdriver[i].name, name) ) {
+   if ( _g_roar_cdriver[i].open2 != NULL )
+    return _g_roar_cdriver[i].open2(calls, name, dev, info, dir, para, paralen);
+   if ( _g_roar_cdriver[i].open != NULL )
+    return _g_roar_cdriver[i].open(calls, name, dev, info, dir);
+  }
 
   if ( (delm = strstr(_g_roar_cdriver[i].name, ":")) != NULL ) {
    ROAR_DBG("roar_cdriver_open(*): delm+1='%s' <cmp> name='%s'", delm+1, name);
-   if ( !strcmp(delm+1, name) )
-    return _g_roar_cdriver[i].open(calls, name, dev, info, dir);
+   if ( !strcmp(delm+1, name) ) {
+    if ( _g_roar_cdriver[i].open2 != NULL )
+     return _g_roar_cdriver[i].open2(calls, name, dev, info, dir, para, paralen);
+    if ( _g_roar_cdriver[i].open != NULL )
+     return _g_roar_cdriver[i].open(calls, name, dev, info, dir);
+   }
   }
 
  }
 
+ roar_err_set(ROAR_ERROR_NOENT);
  return -1;
 }
 
+ssize_t   roar_profiles_list   (const char ** list, size_t len, size_t offset) {
+ size_t i;
+ size_t idx = 0;
+
+ if ( list == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return -1;
+ }
+
+ if ( len == 0 )
+  return 0;
+
+ if ( offset >= (sizeof(_g_roar_cdriver)/sizeof(*_g_roar_cdriver)) )
+  return 0;
+
+ for (i = offset; _g_roar_cdriver[i].name != NULL; i++) {
+  list[idx++] = _g_roar_cdriver[i].name;
+ }
+
+ return idx;
+}
+
+int roar_cdriver_open(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir) {
+ return roar_cdriver_open2(calls, name, dev, info, dir, NULL, -1); 
+}
+
 //ll
