diff options
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/coreaudio/module-coreaudio-device.c | 2 | ||||
-rw-r--r-- | src/modules/dbus/iface-stream.c | 121 | ||||
-rw-r--r-- | src/modules/echo-cancel/module-echo-cancel.c | 6 | ||||
-rw-r--r-- | src/modules/module-equalizer-sink.c | 4 | ||||
-rw-r--r-- | src/modules/module-ladspa-sink.c | 3 | ||||
-rw-r--r-- | src/modules/module-remap-sink.c | 3 | ||||
-rw-r--r-- | src/modules/module-solaris.c | 2 | ||||
-rw-r--r-- | src/modules/module-stream-restore.c | 14 | ||||
-rw-r--r-- | src/modules/module-virtual-sink.c | 3 | ||||
-rw-r--r-- | src/modules/module-virtual-source.c | 3 |
10 files changed, 110 insertions, 51 deletions
diff --git a/src/modules/coreaudio/module-coreaudio-device.c b/src/modules/coreaudio/module-coreaudio-device.c index 5e6d49c2..cc4600b5 100644 --- a/src/modules/coreaudio/module-coreaudio-device.c +++ b/src/modules/coreaudio/module-coreaudio-device.c @@ -747,7 +747,7 @@ int pa__init(pa_module *m) { ca_device_create_streams(m, TRUE); /* create the message thread */ - if (!(u->thread = pa_thread_new(thread_func, u))) { + if (!(u->thread = pa_thread_new("coreaudio", thread_func, u))) { pa_log("Failed to create thread."); goto fail; } diff --git a/src/modules/dbus/iface-stream.c b/src/modules/dbus/iface-stream.c index 681790b7..a9eb373f 100644 --- a/src/modules/dbus/iface-stream.c +++ b/src/modules/dbus/iface-stream.c @@ -56,6 +56,9 @@ struct pa_dbusiface_stream { dbus_bool_t mute; pa_proplist *proplist; + pa_bool_t has_volume; + pa_bool_t read_only_volume; + pa_dbus_protocol *dbus_protocol; pa_subscription *subscription; pa_hook_slot *send_event_slot; @@ -189,6 +192,14 @@ static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userd pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx); } +/* The returned string has to be freed with pa_xfree() by the caller. */ +static char *stream_to_string(pa_dbusiface_stream *s) { + if (s->type == STREAM_TYPE_PLAYBACK) + return pa_sprintf_malloc("Playback stream %u", (unsigned) s->sink_input->index); + else + return pa_sprintf_malloc("Record stream %u", (unsigned) s->source_output->index); +} + static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_dbusiface_stream *s = userdata; const char *driver = NULL; @@ -200,12 +211,11 @@ static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *user driver = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->driver : s->source_output->driver; if (!driver) { - if (s->type == STREAM_TYPE_PLAYBACK) - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, - "Playback stream %u doesn't have a driver.", s->sink_input->index); - else - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, - "Record stream %u doesn't have a driver.", s->source_output->index); + char *str = stream_to_string(s); + + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have a driver.", str); + pa_xfree(str); + return; } @@ -224,12 +234,11 @@ static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void owner_module = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->module : s->source_output->module; if (!owner_module) { - if (s->type == STREAM_TYPE_PLAYBACK) - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, - "Playback stream %u doesn't have an owner module.", s->sink_input->index); - else - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, - "Record stream %u doesn't have an owner module.", s->source_output->index); + char *str = stream_to_string(s); + + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have an owner module.", str); + pa_xfree(str); + return; } @@ -250,12 +259,11 @@ static void handle_get_client(DBusConnection *conn, DBusMessage *msg, void *user client = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->client : s->source_output->client; if (!client) { - if (s->type == STREAM_TYPE_PLAYBACK) - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, - "Playback stream %u isn't associated to any client.", s->sink_input->index); - else - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, - "Record stream %u isn't associated to any client.", s->source_output->index); + char *str = stream_to_string(s); + + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s isn't associated to any client.", str); + pa_xfree(str); + return; } @@ -332,8 +340,12 @@ static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *user pa_assert(msg); pa_assert(s); - if (s->type == STREAM_TYPE_RECORD) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Record streams don't have volume."); + if (!s->has_volume) { + char *str = stream_to_string(s); + + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have volume.", str); + pa_xfree(str); + return; } @@ -357,8 +369,15 @@ static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessag pa_assert(iter); pa_assert(s); - if (s->type == STREAM_TYPE_RECORD) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Record streams don't have volume."); + if (!s->has_volume || s->read_only_volume) { + char *str = stream_to_string(s); + + if (!s->has_volume) + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have volume.", str); + else if (s->read_only_volume) + pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "%s has read-only volume.", str); + pa_xfree(str); + return; } @@ -509,6 +528,11 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat pa_assert(msg); pa_assert(s); + if (s->has_volume) { + for (i = 0; i < s->volume.channels; ++i) + volume[i] = s->volume.values[i]; + } + if (s->type == STREAM_TYPE_PLAYBACK) { idx = s->sink_input->index; driver = s->sink_input->driver; @@ -517,8 +541,6 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat device = pa_dbusiface_core_get_sink_path(s->core, s->sink); sample_format = s->sink_input->sample_spec.format; channel_map = &s->sink_input->channel_map; - for (i = 0; i < s->volume.channels; ++i) - volume[i] = s->volume.values[i]; buffer_latency = pa_sink_input_get_latency(s->sink_input, &device_latency); resample_method = pa_resample_method_to_string(s->sink_input->actual_resample_method); } else { @@ -555,11 +577,12 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat if (client) pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CLIENT].property_name, DBUS_TYPE_OBJECT_PATH, &client_path); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEVICE].property_name, DBUS_TYPE_OBJECT_PATH, &device); pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &sample_format); pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &s->sample_rate); pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CHANNELS].property_name, DBUS_TYPE_UINT32, channels, channel_map->channels); - if (s->type == STREAM_TYPE_PLAYBACK) { + if (s->has_volume) { pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VOLUME].property_name, DBUS_TYPE_UINT32, volume, s->volume.channels); pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &s->mute); } @@ -707,30 +730,33 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t } if (s->type == STREAM_TYPE_PLAYBACK) { - pa_cvolume new_volume; pa_bool_t new_mute = FALSE; - pa_sink_input_get_volume(s->sink_input, &new_volume, TRUE); + if (s->has_volume) { + pa_cvolume new_volume; - if (!pa_cvolume_equal(&s->volume, &new_volume)) { - dbus_uint32_t volume[PA_CHANNELS_MAX]; - dbus_uint32_t *volume_ptr = volume; + pa_sink_input_get_volume(s->sink_input, &new_volume, TRUE); - s->volume = new_volume; + if (!pa_cvolume_equal(&s->volume, &new_volume)) { + dbus_uint32_t volume[PA_CHANNELS_MAX]; + dbus_uint32_t *volume_ptr = volume; - for (i = 0; i < s->volume.channels; ++i) - volume[i] = s->volume.values[i]; + s->volume = new_volume; - pa_assert_se(signal_msg = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_VOLUME_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal_msg, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, s->volume.channels, - DBUS_TYPE_INVALID)); + for (i = 0; i < s->volume.channels; ++i) + volume[i] = s->volume.values[i]; - pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); - dbus_message_unref(signal_msg); - signal_msg = NULL; + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_VOLUME_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, s->volume.channels, + DBUS_TYPE_INVALID)); + + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; + } } new_mute = pa_sink_input_get_mute(s->sink_input); @@ -822,7 +848,14 @@ pa_dbusiface_stream *pa_dbusiface_stream_new_playback(pa_dbusiface_core *core, p s->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, PLAYBACK_OBJECT_NAME, sink_input->index); s->sink = pa_sink_ref(sink_input->sink); s->sample_rate = sink_input->sample_spec.rate; - pa_sink_input_get_volume(sink_input, &s->volume, TRUE); + s->has_volume = pa_sink_input_is_volume_readable(sink_input); + s->read_only_volume = s->has_volume ? !pa_sink_input_is_volume_writable(sink_input) : FALSE; + + if (s->has_volume) + pa_sink_input_get_volume(sink_input, &s->volume, TRUE); + else + pa_cvolume_init(&s->volume); + s->mute = pa_sink_input_get_mute(sink_input); s->proplist = pa_proplist_copy(sink_input->proplist); s->dbus_protocol = pa_dbus_protocol_get(sink_input->core); @@ -853,6 +886,8 @@ pa_dbusiface_stream *pa_dbusiface_stream_new_record(pa_dbusiface_core *core, pa_ pa_cvolume_init(&s->volume); s->mute = FALSE; s->proplist = pa_proplist_copy(source_output->proplist); + s->has_volume = FALSE; + s->read_only_volume = FALSE; s->dbus_protocol = pa_dbus_protocol_get(source_output->core); s->subscription = pa_subscription_new(source_output->core, PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscription_cb, s); s->send_event_slot = pa_hook_connect(&source_output->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT], diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c index 611ebb71..0108c31b 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -1502,6 +1502,7 @@ int pa__init(pa_module*m) { source_output_data.driver = __FILE__; source_output_data.module = m; source_output_data.source = source_master; + source_output_data.destination_source = u->source; /* FIXME source_output_data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; */ @@ -1531,11 +1532,14 @@ int pa__init(pa_module*m) { u->source_output->moving = source_output_moving_cb; u->source_output->userdata = u; + u->source->output_from_master = u->source_output; + /* Create sink input */ pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = sink_master; + sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &sink_ss); @@ -1566,6 +1570,8 @@ int pa__init(pa_module*m) { u->sink_input->mute_changed = sink_input_mute_changed_cb; u->sink_input->userdata = u; + u->sink->input_to_master = u->sink_input; + pa_sink_input_get_silence(u->sink_input, &silence); u->source_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c index bc349ce0..a28405b6 100644 --- a/src/modules/module-equalizer-sink.c +++ b/src/modules/module-equalizer-sink.c @@ -1200,6 +1200,7 @@ int pa__init(pa_module*m) { sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = master; + sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); @@ -1225,9 +1226,10 @@ int pa__init(pa_module*m) { u->sink_input->moving = sink_input_moving_cb; u->sink_input->volume_changed = sink_input_volume_changed_cb; u->sink_input->mute_changed = sink_input_mute_changed_cb; - u->sink_input->userdata = u; + u->sink->input_to_master = u->sink_input; + dbus_init(u); /* default filter to these */ diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index 88df67ec..cdccf1a3 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -832,6 +832,7 @@ int pa__init(pa_module*m) { sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = master; + sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "LADSPA Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); @@ -859,6 +860,8 @@ int pa__init(pa_module*m) { u->sink_input->mute_changed = sink_input_mute_changed_cb; u->sink_input->userdata = u; + u->sink->input_to_master = u->sink_input; + pa_sink_put(u->sink); pa_sink_input_put(u->sink_input); diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index 43748bd0..7f64f306 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -420,6 +420,7 @@ int pa__init(pa_module*m) { sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = master; + sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); @@ -446,6 +447,8 @@ int pa__init(pa_module*m) { u->sink_input->moving = sink_input_moving_cb; u->sink_input->userdata = u; + u->sink->input_to_master = u->sink_input; + pa_sink_put(u->sink); pa_sink_input_put(u->sink_input); diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c index 396094ce..5c1a86c2 100644 --- a/src/modules/module-solaris.c +++ b/src/modules/module-solaris.c @@ -1015,7 +1015,7 @@ int pa__init(pa_module *m) { else pa_log_warn("Could not register SIGPOLL handler"); - if (!(u->thread = pa_thread_new(thread_func, u))) { + if (!(u->thread = pa_thread_new("solaris", thread_func, u))) { pa_log("Failed to create thread."); goto fail; } diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index f8fecd89..f4e4a55c 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -1168,6 +1168,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 } if (sink_input->save_volume) { + pa_assert(pa_sink_input_is_volume_writable(sink_input)); + entry.channel_map = sink_input->channel_map; pa_sink_input_get_volume(sink_input, &entry.volume, FALSE); entry.volume_valid = TRUE; @@ -1327,8 +1329,11 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu if ((e = read_entry(u, name))) { if (u->restore_volume && e->volume_valid) { - - if (!new_data->volume_is_set) { + if (!pa_sink_input_new_data_is_volume_writable(new_data)) + pa_log_debug("Not restoring volume for sink input %s, because its volume can't be changed.", name); + else if (new_data->volume_is_set) + pa_log_debug("Not restoring volume for sink input %s, because already set.", name); + else { pa_cvolume v; pa_log_info("Restoring volume for sink input %s.", name); @@ -1339,8 +1344,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu new_data->volume_is_absolute = FALSE; new_data->save_volume = TRUE; - } else - pa_log_debug("Not restoring volume for sink input %s, because already set.", name); + } } if (u->restore_muted && e->muted_valid) { @@ -1615,7 +1619,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) { } pa_xfree(n); - if (u->restore_volume && e->volume_valid) { + if (u->restore_volume && e->volume_valid && pa_sink_input_is_volume_writable(si)) { pa_cvolume v; v = e->volume; diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c index fac204d4..40bab5aa 100644 --- a/src/modules/module-virtual-sink.c +++ b/src/modules/module-virtual-sink.c @@ -556,6 +556,7 @@ int pa__init(pa_module*m) { sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = master; + sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); @@ -583,6 +584,8 @@ int pa__init(pa_module*m) { u->sink_input->mute_changed = sink_input_mute_changed_cb; u->sink_input->userdata = u; + u->sink->input_to_master = u->sink_input; + /* (9) IF YOU REQUIRE A FIXED BLOCK SIZE MAKE SURE TO PASS A * SILENCE MEMBLOCK AS LAST PARAMETER * HERE. pa_sink_input_get_silence() IS USEFUL HERE. */ diff --git a/src/modules/module-virtual-source.c b/src/modules/module-virtual-source.c index fdf89b02..a2b073fa 100644 --- a/src/modules/module-virtual-source.c +++ b/src/modules/module-virtual-source.c @@ -629,6 +629,7 @@ int pa__init(pa_module*m) { source_output_data.driver = __FILE__; source_output_data.module = m; source_output_data.source = master; + source_output_data.destination_source = u->source; /* FIXME source_output_data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; */ @@ -654,6 +655,8 @@ int pa__init(pa_module*m) { u->source_output->moving = source_output_moving_cb; u->source_output->userdata = u; + u->source->output_from_master = u->source_output; + pa_source_put(u->source); pa_source_output_put(u->source_output); |