I don't want any modules to update the sink input proplist in the FIXATE hook. module-match is the only module that does that. The reason for not wanting proplist updates in the FIXATE hook is that the sink input description is stored in the proplist, and I want to derive the node description from the sink input description, and the sink input node should be created before the FIXATE hook is fired. If module-match updates the sink input description in the FIXATE hook, that update won't be visible at the time the node description is set. --- src/modules/module-match.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/modules/module-match.c b/src/modules/module-match.c index 8ce3f00..185fdf9 100644 --- a/src/modules/module-match.c +++ b/src/modules/module-match.c @@ -80,6 +80,7 @@ struct rule { struct userdata { struct rule *rules; char *property_key; + pa_hook_slot *sink_input_new_hook_slot; pa_hook_slot *sink_input_fixate_hook_slot; }; @@ -213,6 +214,31 @@ finish: return ret; } +static pa_hook_result_t sink_input_new_hook_callback(void *hook_data, void *call_data, void *userdata) { + struct userdata *u = userdata; + struct rule *r; + const char *n; + pa_sink_input_new_data *data = call_data; + + pa_assert(u); + pa_assert(data); + + if (!(n = pa_proplist_gets(data->proplist, u->property_key))) + return PA_HOOK_OK; + + for (r = u->rules; r; r = r->next) { + if (!r->proplist) + continue; + + if (!regexec(&r->regex, n, 0, NULL, 0)) { + pa_log_debug("Updating the proplist of sink input '%s'", n); + pa_proplist_update(data->proplist, r->mode, r->proplist); + } + } + + return PA_HOOK_OK; +} + static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *si, struct userdata *u) { struct rule *r; const char *n; @@ -227,10 +253,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu for (r = u->rules; r; r = r->next) { if (!regexec(&r->regex, n, 0, NULL, 0)) { - if (r->proplist) { - pa_log_debug("updating proplist of sink input '%s'", n); - pa_proplist_update(si->proplist, r->mode, r->proplist); - } else if (si->volume_writable) { + if (si->volume_writable) { pa_cvolume cv; pa_log_debug("changing volume of sink input '%s' to 0x%03x", n, r->volume); pa_cvolume_set(&cv, si->sample_spec.channels, r->volume); @@ -263,6 +286,9 @@ int pa__init(pa_module*m) { if (load_rules(u, pa_modargs_get_value(ma, "table", NULL)) < 0) goto fail; + u->sink_input_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_NORMAL, + sink_input_new_hook_callback, u); + /* hook EARLY - 1, to match before stream-restore */ u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY - 1, (pa_hook_cb_t) sink_input_fixate_hook_callback, u); @@ -289,6 +315,9 @@ void pa__done(pa_module*m) { if (u->sink_input_fixate_hook_slot) pa_hook_slot_free(u->sink_input_fixate_hook_slot); + if (u->sink_input_new_hook_slot) + pa_hook_slot_free(u->sink_input_new_hook_slot); + if (u->property_key) pa_xfree(u->property_key); -- 1.8.3.1