X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/63c1eb14d889fe052afad16dfc470802cc48bb4a..f4f4c42fc611b0bca2293e9b517a88a525f2c1fb:/src/modules/module-always-sink.c diff --git a/src/modules/module-always-sink.c b/src/modules/module-always-sink.c index 8b67a36d..e0a64510 100644 --- a/src/modules/module-always-sink.c +++ b/src/modules/module-always-sink.c @@ -5,7 +5,7 @@ PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -26,18 +26,18 @@ #include #include -#include +#include +#include +#include #include #include -#include -#include #include "module-always-sink-symdef.h" PA_MODULE_AUTHOR("Colin Guthrie"); -PA_MODULE_DESCRIPTION("Always keeps at least one sink loaded even if it's a null one"); +PA_MODULE_DESCRIPTION(_("Always keeps at least one sink loaded even if it's a null one")); PA_MODULE_VERSION(PACKAGE_VERSION); -PA_MODULE_LOAD_ONCE(TRUE); +PA_MODULE_LOAD_ONCE(true); PA_MODULE_USAGE( "sink_name="); @@ -50,8 +50,8 @@ static const char* const valid_modargs[] = { struct userdata { pa_hook_slot *put_slot, *unlink_slot; - pa_module* null_module; - pa_bool_t ignore; + uint32_t null_module; + bool ignore; char *sink_name; }; @@ -59,14 +59,15 @@ static void load_null_sink_if_needed(pa_core *c, pa_sink *sink, struct userdata* pa_sink *target; uint32_t idx; char *t; + pa_module *m; pa_assert(c); pa_assert(u); - pa_assert(!u->null_module); + pa_assert(u->null_module == PA_INVALID_INDEX); /* Loop through all sinks and check to see if we have *any* * sinks. Ignore the sink passed in (if it's not null) */ - for (target = pa_idxset_first(c->sinks, &idx); target; target = pa_idxset_next(c->sinks, &idx)) + PA_IDXSET_FOREACH(target, c->sinks, idx) if (!sink || target != sink) break; @@ -75,15 +76,17 @@ static void load_null_sink_if_needed(pa_core *c, pa_sink *sink, struct userdata* pa_log_debug("Autoloading null-sink as no other sinks detected."); - u->ignore = TRUE; + u->ignore = true; - t = pa_sprintf_malloc("sink_name=%s", u->sink_name); - u->null_module = pa_module_load(c, "module-null-sink", t); + t = pa_sprintf_malloc("sink_name=%s sink_properties='device.description=\"%s\"'", u->sink_name, + _("Dummy Output")); + m = pa_module_load(c, "module-null-sink", t); + u->null_module = m ? m->index : PA_INVALID_INDEX; pa_xfree(t); - u->ignore = FALSE; + u->ignore = false; - if (!u->null_module) + if (!m) pa_log_warn("Unable to load module-null-sink"); } @@ -98,18 +101,22 @@ static pa_hook_result_t put_hook_callback(pa_core *c, pa_sink *sink, void* userd if (u->ignore) return PA_HOOK_OK; + /* There's no point in doing anything if the core is shut down anyway */ + if (c->state == PA_CORE_SHUTDOWN) + return PA_HOOK_OK; + /* Auto-loaded null-sink not active, so ignoring newly detected sink. */ - if (!u->null_module) + if (u->null_module == PA_INVALID_INDEX) return PA_HOOK_OK; /* This is us detecting ourselves on load in a different way... just ignore this too. */ - if (sink->module == u->null_module) + if (sink->module && sink->module->index == u->null_module) return PA_HOOK_OK; pa_log_info("A new sink has been discovered. Unloading null-sink."); - pa_module_unload_request(u->null_module); - u->null_module = NULL; + pa_module_unload_request_by_index(c, u->null_module, true); + u->null_module = PA_INVALID_INDEX; return PA_HOOK_OK; } @@ -122,12 +129,16 @@ static pa_hook_result_t unlink_hook_callback(pa_core *c, pa_sink *sink, void* us pa_assert(u); /* First check to see if it's our own null-sink that's been removed... */ - if (u->null_module && sink->module == u->null_module) { + if (u->null_module != PA_INVALID_INDEX && sink->module && sink->module->index == u->null_module) { pa_log_debug("Autoloaded null-sink removed"); - u->null_module = NULL; + u->null_module = PA_INVALID_INDEX; return PA_HOOK_OK; } + /* There's no point in doing anything if the core is shut down anyway */ + if (c->state == PA_CORE_SHUTDOWN) + return PA_HOOK_OK; + load_null_sink_if_needed(c, sink, u); return PA_HOOK_OK; @@ -148,8 +159,8 @@ int pa__init(pa_module*m) { u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME)); u->put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE, (pa_hook_cb_t) put_hook_callback, u); u->unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) unlink_hook_callback, u); - u->null_module = NULL; - u->ignore = FALSE; + u->null_module = PA_INVALID_INDEX; + u->ignore = false; pa_modargs_free(ma); @@ -170,8 +181,8 @@ void pa__done(pa_module*m) { pa_hook_slot_free(u->put_slot); if (u->unlink_slot) pa_hook_slot_free(u->unlink_slot); - if (u->null_module) - pa_module_unload_request(u->null_module); + if (u->null_module != PA_INVALID_INDEX && m->core->state != PA_CORE_SHUTDOWN) + pa_module_unload_request_by_index(m->core, u->null_module, true); pa_xfree(u->sink_name); pa_xfree(u);