int pa_classify_sink(struct userdata *u, struct pa_sink *sink, uint32_t flag_mask, uint32_t flag_value, char *buf, int len) { struct pa_classify *classify; struct pa_classify_device_def *defs; const char *name; pa_assert(u); pa_assert_se((classify = u->classify)); pa_assert(classify->sinks); pa_assert_se((defs = classify->sinks->defs)); name = pa_sink_ext_get_name(sink); return devices_classify(defs, sink->proplist, name, flag_mask, flag_value, buf, len); }
int pa_classify_is_port_sink_typeof(struct userdata *u, struct pa_sink *sink, const char *type, struct pa_classify_device_data **d) { struct pa_classify *classify; struct pa_classify_device_def *defs; const char *name; pa_assert(u); pa_assert_se((classify = u->classify)); pa_assert(classify->sinks); pa_assert_se((defs = classify->sinks->defs)); if (!sink || !type) return FALSE; name = pa_sink_ext_get_name(sink); return port_device_is_typeof(defs, name, type, d); }
static const char *object_name(struct pa_policy_object *object) { const char *name; switch (object->type) { case pa_policy_object_module: name = pa_module_ext_get_name((struct pa_module *)object->ptr); break; case pa_policy_object_card: name = pa_card_ext_get_name((struct pa_card *)object->ptr); break; case pa_policy_object_sink: name = pa_sink_ext_get_name((struct pa_sink *)object->ptr); break; case pa_policy_object_source: name = pa_source_ext_get_name((struct pa_source *)object->ptr); break; case pa_policy_object_sink_input: name = pa_sink_input_ext_get_name((struct pa_sink_input *)object->ptr); break; case pa_policy_object_source_output: name = pa_source_output_ext_get_name( (struct pa_source_output *)object->ptr); break; default: name = "<unknown>"; break; } return name; }
static pa_hook_result_t sink_input_neew(void *hook_data, void *call_data, void *slot_data) { static uint32_t route_flags = PA_POLICY_GROUP_FLAG_SET_SINK | PA_POLICY_GROUP_FLAG_ROUTE_AUDIO; static pa_volume_t max_volume = PA_VOLUME_NORM; struct pa_sink_input_new_data *data = (struct pa_sink_input_new_data *)call_data; struct userdata *u = (struct userdata *)slot_data; uint32_t flags; const char *group_name; const char *sinp_name; const char *sink_name; int local_route; int local_volume; struct pa_policy_group *group; pa_assert(u); pa_assert(data); if ((group_name = pa_classify_sink_input_by_data(u,data,&flags)) != NULL && (group = pa_policy_group_find(u, group_name) ) != NULL ){ /* Let's just set the policy group property here already so that we * don't have to classify again when the sink input is put, because we * can just retrieve the group from the proplist. Also, this prevents * the classification from breaking later because of the proplist * overwriting done below. */ pa_proplist_sets(data->proplist, PA_PROP_POLICY_GROUP, group_name); /* Proplist overwriting can also mess up the retrieval of * stream-specific flags later on, so we need to store those to the * proplist as well (ugly hack). We could probably cope without this * one though, since the stream-specific flags don't really seem to be * used. */ pa_proplist_set(data->proplist, PA_PROP_POLICY_STREAM_FLAGS, (void*)&flags, sizeof(flags)); if (group->properties != NULL) { pa_proplist_update(data->proplist, PA_UPDATE_REPLACE, group->properties); pa_log_debug("new sink input inserted into %s. " "force the following properties:", group_name); } if (group->sink != NULL) { sinp_name = pa_proplist_gets(data->proplist, PA_PROP_MEDIA_NAME); if (!sinp_name) sinp_name = "<unknown>"; local_route = flags & PA_POLICY_LOCAL_ROUTE; local_volume = flags & PA_POLICY_LOCAL_VOLMAX; if (group->mutebyrt && !local_route) { sink_name = u->nullsink->name; pa_log_debug("force stream '%s'/'%s' to sink '%s' due to " "mute-by-route", group_name,sinp_name, sink_name); #ifdef HAVE_OLD_LIBPULSE data->sink = u->nullsink->sink; #else pa_sink_input_new_data_set_sink(data, u->nullsink->sink, false); #endif } else if (group->flags & route_flags) { sink_name = pa_sink_ext_get_name(group->sink); pa_log_debug("force stream '%s'/'%s' to sink '%s'", group_name, sinp_name, sink_name); #ifdef HAVE_OLD_LIBPULSE data->sink = group->sink; #else pa_sink_input_new_data_set_sink(data, group->sink, false); #endif } if (local_volume) { pa_log_debug("force stream '%s'/'%s' volume to %d", group_name, sinp_name, (max_volume * 100) / PA_VOLUME_NORM); pa_cvolume_set(&data->volume, data->channel_map.channels, max_volume); data->volume_is_set = TRUE; data->save_volume = FALSE; } } } return PA_HOOK_OK; }