diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2018-03-06 08:40:47 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2018-03-12 11:18:26 +0100 |
commit | d3893a39eb0165809325071ab07984797d78e57a (patch) | |
tree | ad48738682ee38a743635bc79a99c62515f3998b /audio/audio.c | |
parent | a88afc649e53adc1cac00bb5803fbafdd4d99994 (diff) |
audio: add driver registry
Add registry for audio drivers, using the existing audio_driver struct.
Make all drivers register themself. The old list of audio_driver struct
pointers is now a list of audio driver names, specifying the priority
(aka probe order) in case no driver is explicitly asked for.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20180306074053.22856-2-kraxel@redhat.com
Diffstat (limited to 'audio/audio.c')
-rw-r--r-- | audio/audio.c | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/audio/audio.c b/audio/audio.c index 7658d2af66..2384612b87 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -45,15 +45,32 @@ The 1st one is the one used by default, that is the reason that we generate the list. */ -static struct audio_driver *drvtab[] = { -#ifdef CONFIG_SPICE - &spice_audio_driver, -#endif +static const char *audio_prio_list[] = { + "spice", CONFIG_AUDIO_DRIVERS - &no_audio_driver, - &wav_audio_driver + "none", + "wav", }; +static QLIST_HEAD(, audio_driver) audio_drivers; + +void audio_driver_register(audio_driver *drv) +{ + QLIST_INSERT_HEAD(&audio_drivers, drv, next); +} + +audio_driver *audio_driver_lookup(const char *name) +{ + struct audio_driver *d; + + QLIST_FOREACH(d, &audio_drivers, next) { + if (strcmp(name, d->name) == 0) { + return d; + } + } + return NULL; +} + struct fixed_settings { int enabled; int nb_voices; @@ -1656,11 +1673,10 @@ static void audio_pp_nb_voices (const char *typ, int nb) void AUD_help (void) { - size_t i; + struct audio_driver *d; audio_process_options ("AUDIO", audio_options); - for (i = 0; i < ARRAY_SIZE (drvtab); i++) { - struct audio_driver *d = drvtab[i]; + QLIST_FOREACH(d, &audio_drivers, next) { if (d->options) { audio_process_options (d->name, d->options); } @@ -1672,8 +1688,7 @@ void AUD_help (void) printf ("Available drivers:\n"); - for (i = 0; i < ARRAY_SIZE (drvtab); i++) { - struct audio_driver *d = drvtab[i]; + QLIST_FOREACH(d, &audio_drivers, next) { printf ("Name: %s\n", d->name); printf ("Description: %s\n", d->descr); @@ -1807,6 +1822,7 @@ static void audio_init (void) const char *drvname; VMChangeStateEntry *e; AudioState *s = &glob_audio_state; + struct audio_driver *driver; if (s->drv) { return; @@ -1842,32 +1858,27 @@ static void audio_init (void) } if (drvname) { - int found = 0; - - for (i = 0; i < ARRAY_SIZE (drvtab); i++) { - if (!strcmp (drvname, drvtab[i]->name)) { - done = !audio_driver_init (s, drvtab[i]); - found = 1; - break; - } - } - - if (!found) { + driver = audio_driver_lookup(drvname); + if (driver) { + done = !audio_driver_init(s, driver); + } else { dolog ("Unknown audio driver `%s'\n", drvname); dolog ("Run with -audio-help to list available drivers\n"); } } if (!done) { - for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) { - if (drvtab[i]->can_be_default) { - done = !audio_driver_init (s, drvtab[i]); + for (i = 0; !done && i < ARRAY_SIZE(audio_prio_list); i++) { + driver = audio_driver_lookup(audio_prio_list[i]); + if (driver && driver->can_be_default) { + done = !audio_driver_init(s, driver); } } } if (!done) { - done = !audio_driver_init (s, &no_audio_driver); + driver = audio_driver_lookup("none"); + done = !audio_driver_init(s, driver); assert(done); dolog("warning: Using timer based audio emulation\n"); } |