};
uint32_t sample_rate;
pa_cvolume volume;
- pa_bool_t is_muted;
+ dbus_bool_t mute;
pa_proplist *proplist;
+ bool has_volume;
+
pa_dbus_protocol *dbus_protocol;
pa_subscription *subscription;
pa_hook_slot *send_event_slot;
static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
-static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
-static void handle_get_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata);
-static void handle_set_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
static void handle_get_buffer_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_get_device_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_get_resample_method(DBusConnection *conn, DBusMessage *msg, void *userdata);
PROPERTY_HANDLER_SAMPLE_RATE,
PROPERTY_HANDLER_CHANNELS,
PROPERTY_HANDLER_VOLUME,
- PROPERTY_HANDLER_IS_MUTED,
+ PROPERTY_HANDLER_MUTE,
PROPERTY_HANDLER_BUFFER_LATENCY,
PROPERTY_HANDLER_DEVICE_LATENCY,
PROPERTY_HANDLER_RESAMPLE_METHOD,
[PROPERTY_HANDLER_SAMPLE_RATE] = { .property_name = "SampleRate", .type = "u", .get_cb = handle_get_sample_rate, .set_cb = NULL },
[PROPERTY_HANDLER_CHANNELS] = { .property_name = "Channels", .type = "au", .get_cb = handle_get_channels, .set_cb = NULL },
[PROPERTY_HANDLER_VOLUME] = { .property_name = "Volume", .type = "au", .get_cb = handle_get_volume, .set_cb = handle_set_volume },
- [PROPERTY_HANDLER_IS_MUTED] = { .property_name = "IsMuted", .type = "b", .get_cb = handle_get_is_muted, .set_cb = handle_set_is_muted },
+ [PROPERTY_HANDLER_MUTE] = { .property_name = "Mute", .type = "b", .get_cb = handle_get_mute, .set_cb = handle_set_mute },
[PROPERTY_HANDLER_BUFFER_LATENCY] = { .property_name = "BufferLatency", .type = "t", .get_cb = handle_get_buffer_latency, .set_cb = NULL },
[PROPERTY_HANDLER_DEVICE_LATENCY] = { .property_name = "DeviceLatency", .type = "t", .get_cb = handle_get_device_latency, .set_cb = NULL },
[PROPERTY_HANDLER_RESAMPLE_METHOD] = { .property_name = "ResampleMethod", .type = "s", .get_cb = handle_get_resample_method, .set_cb = NULL },
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;
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;
}
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;
}
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;
}
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;
}
pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, volume, s->volume.channels);
}
-static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
pa_dbusiface_stream *s = userdata;
- unsigned stream_channels = 0;
+ bool volume_writable = true;
+ DBusMessageIter array_iter;
+ int stream_channels = 0;
dbus_uint32_t *volume = NULL;
- unsigned n_volume_entries = 0;
+ int n_volume_entries = 0;
pa_cvolume new_vol;
- unsigned i = 0;
+ int i = 0;
pa_assert(conn);
pa_assert(msg);
+ 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.");
+ volume_writable = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->volume_writable : false;
+
+ if (!s->has_volume || !volume_writable) {
+ 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 (!volume_writable)
+ pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "%s has read-only volume.", str);
+ pa_xfree(str);
+
return;
}
- pa_cvolume_init(&new_vol);
-
stream_channels = s->sink_input->channel_map.channels;
- new_vol.channels = stream_channels;
+ dbus_message_iter_recurse(iter, &array_iter);
+ dbus_message_iter_get_fixed_array(&array_iter, &volume, &n_volume_entries);
- if (pa_dbus_get_fixed_array_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &volume, &n_volume_entries) < 0)
- return;
-
- if (n_volume_entries != stream_channels) {
+ if (n_volume_entries != stream_channels && n_volume_entries != 1) {
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
"Expected %u volume entries, got %u.", stream_channels, n_volume_entries);
return;
}
+ pa_cvolume_init(&new_vol);
+ new_vol.channels = n_volume_entries;
+
for (i = 0; i < n_volume_entries; ++i) {
- if (volume[i] > PA_VOLUME_MAX) {
- pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too large volume value: %u", volume[i]);
+ if (!PA_VOLUME_IS_VALID(volume[i])) {
+ pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u", volume[i]);
return;
}
new_vol.values[i] = volume[i];
}
- pa_sink_input_set_volume(s->sink_input, &new_vol, TRUE, TRUE);
+ pa_sink_input_set_volume(s->sink_input, &new_vol, true, true);
pa_dbus_send_empty_reply(conn, msg);
}
-static void handle_get_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
pa_dbusiface_stream *s = userdata;
pa_assert(conn);
return;
}
- pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &s->is_muted);
+ pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &s->mute);
}
-static void handle_set_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
pa_dbusiface_stream *s = userdata;
- dbus_bool_t is_muted = FALSE;
+ dbus_bool_t mute = FALSE;
pa_assert(conn);
pa_assert(msg);
+ pa_assert(iter);
pa_assert(s);
- if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_BOOLEAN, &is_muted) < 0)
- return;
+ dbus_message_iter_get_basic(iter, &mute);
if (s->type == STREAM_TYPE_RECORD) {
pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Record streams don't have mute.");
return;
}
- pa_sink_input_set_mute(s->sink_input, is_muted, TRUE);
+ pa_sink_input_set_mute(s->sink_input, mute, true);
pa_dbus_send_empty_reply(conn, msg);
-};
+}
static void handle_get_buffer_latency(DBusConnection *conn, DBusMessage *msg, void *userdata) {
pa_dbusiface_stream *s = userdata;
else
resample_method = pa_resample_method_to_string(s->source_output->actual_resample_method);
+ if (!resample_method)
+ resample_method = "";
+
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &resample_method);
}
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;
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 {
client_path = pa_dbusiface_core_get_client_path(s->core, client);
for (i = 0; i < channel_map->channels; ++i)
channels[i] = channel_map->map[i];
+ if (!resample_method)
+ resample_method = "";
pa_assert_se((reply = dbus_message_new_method_return(msg)));
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_IS_MUTED].property_name, DBUS_TYPE_BOOLEAN, &s->is_muted);
+ pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &s->mute);
}
pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_BUFFER_LATENCY].property_name, DBUS_TYPE_UINT64, &buffer_latency);
static void handle_move(DBusConnection *conn, DBusMessage *msg, void *userdata) {
pa_dbusiface_stream *s = userdata;
const char *device = NULL;
- DBusError error;
pa_assert(conn);
pa_assert(msg);
pa_assert(s);
- dbus_error_init(&error);
-
- if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &device, DBUS_TYPE_INVALID)) {
- pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
- dbus_error_free(&error);
- return;
- }
+ pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device, DBUS_TYPE_INVALID));
if (s->type == STREAM_TYPE_PLAYBACK) {
pa_sink *sink = pa_dbusiface_core_get_sink(s->core, device);
return;
}
- if (pa_sink_input_move_to(s->sink_input, sink, TRUE) < 0) {
+ if (pa_sink_input_move_to(s->sink_input, sink, true) < 0) {
pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
"Moving playback stream %u to sink %s failed.", s->sink_input->index, sink->name);
return;
return;
}
- if (pa_source_output_move_to(s->source_output, source, TRUE) < 0) {
+ if (pa_source_output_move_to(s->source_output, source, true) < 0) {
pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
"Moving record stream %u to source %s failed.", s->source_output->index, source->name);
return;
static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
pa_dbusiface_stream *s = userdata;
- DBusMessage *signal = NULL;
+ DBusMessage *signal_msg = NULL;
const char *new_device_path = NULL;
uint32_t new_sample_rate = 0;
pa_proplist *new_proplist = NULL;
new_device_path = pa_dbusiface_core_get_sink_path(s->core, new_sink);
- pa_assert_se(signal = dbus_message_new_signal(s->path,
- PA_DBUSIFACE_STREAM_INTERFACE,
- signals[SIGNAL_DEVICE_UPDATED].name));
- pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID));
+ pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+ PA_DBUSIFACE_STREAM_INTERFACE,
+ signals[SIGNAL_DEVICE_UPDATED].name));
+ pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID));
- pa_dbus_protocol_send_signal(s->dbus_protocol, signal);
- dbus_message_unref(signal);
- signal = NULL;
+ pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+ dbus_message_unref(signal_msg);
+ signal_msg = NULL;
}
} else {
pa_source *new_source = s->source_output->source;
new_device_path = pa_dbusiface_core_get_source_path(s->core, new_source);
- pa_assert_se(signal = dbus_message_new_signal(s->path,
- PA_DBUSIFACE_STREAM_INTERFACE,
- signals[SIGNAL_DEVICE_UPDATED].name));
- pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID));
+ pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+ PA_DBUSIFACE_STREAM_INTERFACE,
+ signals[SIGNAL_DEVICE_UPDATED].name));
+ pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID));
- pa_dbus_protocol_send_signal(s->dbus_protocol, signal);
- dbus_message_unref(signal);
- signal = NULL;
+ pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+ dbus_message_unref(signal_msg);
+ signal_msg = NULL;
}
}
if (s->sample_rate != new_sample_rate) {
s->sample_rate = new_sample_rate;
- pa_assert_se(signal = dbus_message_new_signal(s->path,
- PA_DBUSIFACE_STREAM_INTERFACE,
- signals[SIGNAL_SAMPLE_RATE_UPDATED].name));
- pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_UINT32, &s->sample_rate, DBUS_TYPE_INVALID));
+ pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+ PA_DBUSIFACE_STREAM_INTERFACE,
+ signals[SIGNAL_SAMPLE_RATE_UPDATED].name));
+ pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_UINT32, &s->sample_rate, DBUS_TYPE_INVALID));
- pa_dbus_protocol_send_signal(s->dbus_protocol, signal);
- dbus_message_unref(signal);
- signal = NULL;
+ pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+ dbus_message_unref(signal_msg);
+ signal_msg = NULL;
}
if (s->type == STREAM_TYPE_PLAYBACK) {
- pa_cvolume new_volume;
- pa_bool_t new_muted = FALSE;
+ bool 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 = dbus_message_new_signal(s->path,
- PA_DBUSIFACE_STREAM_INTERFACE,
- signals[SIGNAL_VOLUME_UPDATED].name));
- pa_assert_se(dbus_message_append_args(signal,
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, s->volume.channels,
- DBUS_TYPE_INVALID));
-
- pa_dbus_protocol_send_signal(s->dbus_protocol, signal);
- dbus_message_unref(signal);
- signal = NULL;
+ for (i = 0; i < s->volume.channels; ++i)
+ volume[i] = s->volume.values[i];
+
+ 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_muted = pa_sink_input_get_mute(s->sink_input);
+ new_mute = s->sink_input->muted;
- if (s->is_muted != new_muted) {
- s->is_muted = new_muted;
+ if (s->mute != new_mute) {
+ s->mute = new_mute;
- pa_assert_se(signal = dbus_message_new_signal(s->path,
- PA_DBUSIFACE_STREAM_INTERFACE,
- signals[SIGNAL_MUTE_UPDATED].name));
- pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_BOOLEAN, &s->is_muted, DBUS_TYPE_INVALID));
+ pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+ PA_DBUSIFACE_STREAM_INTERFACE,
+ signals[SIGNAL_MUTE_UPDATED].name));
+ pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &s->mute, DBUS_TYPE_INVALID));
- pa_dbus_protocol_send_signal(s->dbus_protocol, signal);
- dbus_message_unref(signal);
- signal = NULL;
+ pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+ dbus_message_unref(signal_msg);
+ signal_msg = NULL;
}
}
pa_proplist_update(s->proplist, PA_UPDATE_SET, new_proplist);
- pa_assert_se(signal = dbus_message_new_signal(s->path,
- PA_DBUSIFACE_STREAM_INTERFACE,
- signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
- dbus_message_iter_init_append(signal, &msg_iter);
+ pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+ PA_DBUSIFACE_STREAM_INTERFACE,
+ signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
+ dbus_message_iter_init_append(signal_msg, &msg_iter);
pa_dbus_append_proplist(&msg_iter, s->proplist);
- pa_dbus_protocol_send_signal(s->dbus_protocol, signal);
- dbus_message_unref(signal);
- signal = NULL;
+ pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+ dbus_message_unref(signal_msg);
+ signal_msg = NULL;
}
}
static pa_hook_result_t send_event_cb(void *hook_data, void *call_data, void *slot_data) {
pa_dbusiface_stream *s = slot_data;
- DBusMessage *signal = NULL;
+ DBusMessage *signal_msg = NULL;
DBusMessageIter msg_iter;
const char *name = NULL;
pa_proplist *property_list = NULL;
property_list = data->data;
}
- pa_assert_se(signal = dbus_message_new_signal(s->path,
- PA_DBUSIFACE_STREAM_INTERFACE,
- signals[SIGNAL_STREAM_EVENT].name));
- dbus_message_iter_init_append(signal, &msg_iter);
+ pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+ PA_DBUSIFACE_STREAM_INTERFACE,
+ signals[SIGNAL_STREAM_EVENT].name));
+ dbus_message_iter_init_append(signal_msg, &msg_iter);
pa_assert_se(dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name));
pa_dbus_append_proplist(&msg_iter, property_list);
- pa_dbus_protocol_send_signal(s->dbus_protocol, signal);
- dbus_message_unref(signal);
+ pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+ dbus_message_unref(signal_msg);
return PA_HOOK_OK;
}
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->is_muted = pa_sink_input_get_mute(sink_input);
+ s->has_volume = pa_sink_input_is_volume_readable(sink_input);
+
+ if (s->has_volume)
+ pa_sink_input_get_volume(sink_input, &s->volume, true);
+ else
+ pa_cvolume_init(&s->volume);
+
+ s->mute = sink_input->muted;
s->proplist = pa_proplist_copy(sink_input->proplist);
s->dbus_protocol = pa_dbus_protocol_get(sink_input->core);
s->subscription = pa_subscription_new(sink_input->core, PA_SUBSCRIPTION_MASK_SINK_INPUT, subscription_cb, s);
s->source = pa_source_ref(source_output->source);
s->sample_rate = source_output->sample_spec.rate;
pa_cvolume_init(&s->volume);
- s->is_muted = FALSE;
+ s->mute = false;
s->proplist = pa_proplist_copy(source_output->proplist);
+ s->has_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],