From 57734ec414c7411a9a8724a2f9ee0cb77c6a37f9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 20:31:08 +0000 Subject: [PATCH] hook into move operations for resuming/suspending devices appropriately git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1643 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-suspend-on-idle.c | 128 +++++++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 19 deletions(-) diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index 0d21cfb..d2f9b7d 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -50,8 +50,23 @@ struct userdata { pa_core *core; pa_usec_t timeout; pa_hashmap *device_infos; - pa_hook_slot *sink_new_slot, *source_new_slot, *sink_disconnect_slot, *source_disconnect_slot, *sink_state_changed_slot, *source_state_changed_slot; - pa_hook_slot *sink_input_new_slot, *source_output_new_slot, *sink_input_disconnect_slot, *source_output_disconnect_slot; + pa_hook_slot + *sink_new_slot, + *source_new_slot, + *sink_disconnect_slot, + *source_disconnect_slot, + *sink_state_changed_slot, + *source_state_changed_slot; + + pa_hook_slot + *sink_input_new_slot, + *source_output_new_slot, + *sink_input_disconnect_slot, + *source_output_disconnect_slot, + *sink_input_move_slot, + *source_output_move_slot, + *sink_input_move_post_slot, + *source_output_move_post_slot; }; struct device_info { @@ -90,10 +105,31 @@ static void restart(struct device_info *d) { pa_timeval_add(&tv, d->userdata->timeout*1000000); d->userdata->core->mainloop->time_restart(d->time_event, &tv); - if (d->source) - pa_log_debug("Source %s becomes idle.", d->source->name); if (d->sink) pa_log_debug("Sink %s becomes idle.", d->sink->name); + if (d->source) + pa_log_debug("Source %s becomes idle.", d->source->name); +} + +static void resume(struct device_info *d) { + pa_assert(d); + + d->userdata->core->mainloop->time_restart(d->time_event, NULL); + + if (d->sink) { + pa_sink_suspend(d->sink, 0); + pa_source_suspend(d->sink->monitor_source, 0); + + pa_log_debug("Sink %s becomes busy.", d->sink->name); + } + + if (d->source) { + pa_source_suspend(d->source, 0); + if (d->source->monitor_of) + pa_sink_suspend(d->source->monitor_of, 0); + + pa_log_debug("Source %s becomes busy.", d->source->name); + } } static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { @@ -104,12 +140,7 @@ static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, str pa_assert(u); pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); - d->userdata->core->mainloop->time_restart(d->time_event, NULL); - - pa_sink_suspend(s->sink, 0); - pa_source_suspend(s->sink->monitor_source, 0); - - pa_log_debug("Sink %s becomes busy.", s->sink->name); + resume(d); return PA_HOOK_OK; } @@ -122,13 +153,7 @@ static pa_hook_result_t source_output_new_hook_cb(pa_core *c, pa_source_output * pa_assert(u); pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); - d->userdata->core->mainloop->time_restart(d->time_event, NULL); - - pa_source_suspend(s->source, 0); - if (s->source->monitor_of) - pa_sink_suspend(s->source->monitor_of, 0); - - pa_log_debug("Source %s becomes busy.", s->source->name); + resume(d); return PA_HOOK_OK; } @@ -161,6 +186,58 @@ static pa_hook_result_t source_output_disconnect_hook_cb(pa_core *c, pa_source_o return PA_HOOK_OK; } +static pa_hook_result_t sink_input_move_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { + pa_assert(c); + pa_sink_input_assert_ref(s); + pa_assert(u); + + if (pa_sink_used_by(s->sink) <= 1) { + struct device_info *d; + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); + restart(d); + } + + return PA_HOOK_OK; +} + +static pa_hook_result_t sink_input_move_post_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { + struct device_info *d; + pa_assert(c); + pa_sink_input_assert_ref(s); + pa_assert(u); + + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); + resume(d); + + return PA_HOOK_OK; +} + +static pa_hook_result_t source_output_move_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + pa_assert(c); + pa_source_output_assert_ref(s); + pa_assert(u); + + if (pa_source_used_by(s->source) <= 1) { + struct device_info *d; + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); + restart(d); + } + + return PA_HOOK_OK; +} + +static pa_hook_result_t source_output_move_post_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + struct device_info *d; + pa_assert(c); + pa_source_output_assert_ref(s); + pa_assert(u); + + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); + resume(d); + + return PA_HOOK_OK; +} + static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { struct device_info *d; @@ -276,8 +353,8 @@ int pa__init(pa_module*m) { u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); u->source_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); - u->sink_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT], (pa_hook_cb_t) device_disconnect_hook_cb, u); - u->source_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT], (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->sink_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT_POST], (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->source_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT_POST], (pa_hook_cb_t) device_disconnect_hook_cb, u); u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); u->source_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); @@ -285,6 +362,11 @@ int pa__init(pa_module*m) { u->source_output_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], (pa_hook_cb_t) source_output_new_hook_cb, u); u->sink_input_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST], (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); u->source_output_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST], (pa_hook_cb_t) source_output_disconnect_hook_cb, u); + u->sink_input_move_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE], (pa_hook_cb_t) sink_input_move_hook_cb, u); + u->source_output_move_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE], (pa_hook_cb_t) source_output_move_hook_cb, u); + u->sink_input_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], (pa_hook_cb_t) sink_input_move_post_hook_cb, u); + u->source_output_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST], (pa_hook_cb_t) source_output_move_post_hook_cb, u); + pa_modargs_free(ma); return 0; @@ -326,11 +408,19 @@ void pa__done(pa_module*m) { pa_hook_slot_free(u->sink_input_new_slot); if (u->sink_input_disconnect_slot) pa_hook_slot_free(u->sink_input_disconnect_slot); + if (u->sink_input_move_slot) + pa_hook_slot_free(u->sink_input_move_slot); + if (u->sink_input_move_post_slot) + pa_hook_slot_free(u->sink_input_move_post_slot); if (u->source_output_new_slot) pa_hook_slot_free(u->source_output_new_slot); if (u->source_output_disconnect_slot) pa_hook_slot_free(u->source_output_disconnect_slot); + if (u->source_output_move_slot) + pa_hook_slot_free(u->source_output_move_slot); + if (u->source_output_move_post_slot) + pa_hook_slot_free(u->source_output_move_post_slot); while ((d = pa_hashmap_steal_first(u->device_infos))) device_info_free(d); -- 2.7.4