From 56c76128b0144a5c61e77d2a7aec07a337cfb66d Mon Sep 17 00:00:00 2001 From: Michal Ratajsky Date: Fri, 18 Jul 2014 15:41:59 +0200 Subject: PulseAudio fixes and API updates --- backends/pulse/pulse-sink-input.c | 206 ++++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 96 deletions(-) (limited to 'backends/pulse/pulse-sink-input.c') diff --git a/backends/pulse/pulse-sink-input.c b/backends/pulse/pulse-sink-input.c index 051b351..54cd3b3 100644 --- a/backends/pulse/pulse-sink-input.c +++ b/backends/pulse/pulse-sink-input.c @@ -20,12 +20,14 @@ #include #include +#include #include #include #include "pulse-connection.h" #include "pulse-client-stream.h" +#include "pulse-helpers.h" #include "pulse-monitor.h" #include "pulse-sink.h" #include "pulse-sink-input.h" @@ -36,14 +38,16 @@ static void pulse_sink_input_init (PulseSinkInput *input); G_DEFINE_TYPE (PulseSinkInput, pulse_sink_input, PULSE_TYPE_CLIENT_STREAM); -static gboolean sink_input_set_mute (MateMixerStream *stream, - gboolean mute); -static gboolean sink_input_set_volume (MateMixerStream *stream, - pa_cvolume *volume); -static gboolean sink_input_set_parent (MateMixerClientStream *stream, - MateMixerStream *parent); -static gboolean sink_input_remove (MateMixerClientStream *stream); -static PulseMonitor *sink_input_create_monitor (MateMixerStream *stream); +static void pulse_sink_input_reload (PulseStream *pstream); + +static gboolean pulse_sink_input_set_mute (PulseStream *pstream, + gboolean mute); +static gboolean pulse_sink_input_set_volume (PulseStream *pstream, + pa_cvolume *cvolume); +static gboolean pulse_sink_input_set_parent (PulseClientStream *pclient, + PulseStream *parent); +static gboolean pulse_sink_input_remove (PulseClientStream *pclient); +static PulseMonitor *pulse_sink_input_create_monitor (PulseStream *pstream); static void pulse_sink_input_class_init (PulseSinkInputClass *klass) @@ -53,14 +57,15 @@ pulse_sink_input_class_init (PulseSinkInputClass *klass) stream_class = PULSE_STREAM_CLASS (klass); - stream_class->set_mute = sink_input_set_mute; - stream_class->set_volume = sink_input_set_volume; - stream_class->create_monitor = sink_input_create_monitor; + stream_class->reload = pulse_sink_input_reload; + stream_class->set_mute = pulse_sink_input_set_mute; + stream_class->set_volume = pulse_sink_input_set_volume; + stream_class->create_monitor = pulse_sink_input_create_monitor; client_class = PULSE_CLIENT_STREAM_CLASS (klass); - client_class->set_parent = sink_input_set_parent; - client_class->remove = sink_input_remove; + client_class->set_parent = pulse_sink_input_set_parent; + client_class->remove = pulse_sink_input_remove; } static void @@ -91,7 +96,7 @@ pulse_sink_input_new (PulseConnection *connection, } gboolean -pulse_sink_input_update (PulseStream *stream, +pulse_sink_input_update (PulseStream *pstream, const pa_sink_input_info *info, PulseStream *parent) { @@ -99,66 +104,81 @@ pulse_sink_input_update (PulseStream *stream, MATE_MIXER_STREAM_CLIENT | MATE_MIXER_STREAM_HAS_MUTE | MATE_MIXER_STREAM_HAS_MONITOR; - gchar *name; + PulseClientStream *pclient; + const gchar *prop; + const gchar *description = NULL; + gchar *name; - const gchar *prop; - const gchar *description = NULL; + g_return_val_if_fail (PULSE_IS_SINK_INPUT (pstream), FALSE); + g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (PULSE_IS_SINK_INPUT (stream), FALSE); + pclient = PULSE_CLIENT_STREAM (pstream); /* Let all the information update before emitting notify signals */ - g_object_freeze_notify (G_OBJECT (stream)); + g_object_freeze_notify (G_OBJECT (pstream)); /* Many mixer applications query the Pulse client list and use the client * name here, but we use the name only as an identifier, so let's avoid * this unnecessary overhead and use a custom name. - * Also make sure to make the name unique by including the Pulse index. */ + * Also make sure to make the name unique by including the PulseAudio index. */ name = g_strdup_printf ("pulse-stream-client-output-%lu", (gulong) info->index); - pulse_stream_update_name (stream, name); + pulse_stream_update_name (pstream, name); g_free (name); prop = pa_proplist_gets (info->proplist, PA_PROP_MEDIA_ROLE); + if (prop != NULL) { + MateMixerClientStreamRole role = pulse_convert_media_role_name (prop); - if (prop != NULL && !strcmp (prop, "event")) { - /* The event description seems to provide much better readable - * description for event streams */ - prop = pa_proplist_gets (info->proplist, PA_PROP_EVENT_DESCRIPTION); + if (role == MATE_MIXER_CLIENT_STREAM_ROLE_EVENT) { + /* The event description seems to provide much better readable + * description for event streams */ + prop = pa_proplist_gets (info->proplist, PA_PROP_EVENT_DESCRIPTION); - if (G_LIKELY (prop != NULL)) - description = prop; + if (G_LIKELY (prop != NULL)) + description = prop; + } + pulse_client_stream_update_role (pclient, role); + } else + pulse_client_stream_update_role (pclient, MATE_MIXER_CLIENT_STREAM_ROLE_NONE); - flags |= MATE_MIXER_STREAM_EVENT; - } if (description == NULL) description = info->name; - pulse_stream_update_description (stream, description); - pulse_stream_update_mute (stream, info->mute ? TRUE : FALSE); + pulse_stream_update_description (pstream, description); + pulse_stream_update_mute (pstream, info->mute ? TRUE : FALSE); if (info->client != PA_INVALID_INDEX) - flags |= MATE_MIXER_STREAM_APPLICATION; + pulse_client_stream_update_flags (pclient, MATE_MIXER_CLIENT_STREAM_APPLICATION); + else + pulse_client_stream_update_flags (pclient, MATE_MIXER_CLIENT_STREAM_NO_FLAGS); + + if (G_LIKELY (parent != NULL)) { + if (pulse_sink_get_monitor_index (parent) != PA_INVALID_INDEX) + flags |= MATE_MIXER_STREAM_HAS_MONITOR; - if (pa_channel_map_can_balance (&info->channel_map)) - flags |= MATE_MIXER_STREAM_CAN_BALANCE; - if (pa_channel_map_can_fade (&info->channel_map)) - flags |= MATE_MIXER_STREAM_CAN_FADE; + pulse_client_stream_update_parent (pclient, MATE_MIXER_STREAM (parent)); + } else + pulse_client_stream_update_parent (pclient, NULL); #if PA_CHECK_VERSION(1, 0, 0) - if (info->has_volume) + if (info->has_volume) { flags |= MATE_MIXER_STREAM_HAS_VOLUME | MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME; - if (info->volume_writable) - flags |= MATE_MIXER_STREAM_CAN_SET_VOLUME; + + if (info->volume_writable) + flags |= MATE_MIXER_STREAM_CAN_SET_VOLUME; + } /* Flags needed before volume */ - pulse_stream_update_flags (stream, flags); + pulse_stream_update_flags (pstream, flags); + pulse_stream_update_channel_map (pstream, &info->channel_map); if (info->has_volume) - pulse_stream_update_volume (stream, &info->volume, &info->channel_map, 0); + pulse_stream_update_volume (pstream, &info->volume, 0); else - pulse_stream_update_volume (stream, NULL, &info->channel_map, 0); + pulse_stream_update_volume (pstream, NULL, 0); #else /* Pre-1.0 PulseAudio does not include the has_volume and volume_writable * fields, but does include the volume info, so let's give it a try */ @@ -168,127 +188,121 @@ pulse_sink_input_update (PulseStream *stream, MATE_MIXER_STREAM_CAN_SET_VOLUME; /* Flags needed before volume */ - pulse_stream_update_flags (stream, flags); + pulse_stream_update_flags (pstream, flags); + pulse_stream_update_channel_map (pstream, &info->channel_map); - pulse_stream_update_volume (stream, &info->volume, &info->channel_map, 0); + pulse_stream_update_volume (pstream, &info->volume, 0); #endif prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_NAME); if (prop != NULL) - pulse_client_stream_update_app_name (PULSE_CLIENT_STREAM (stream), prop); + pulse_client_stream_update_app_name (pclient, prop); prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_ID); if (prop != NULL) - pulse_client_stream_update_app_id (PULSE_CLIENT_STREAM (stream), prop); + pulse_client_stream_update_app_id (pclient, prop); prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_VERSION); if (prop != NULL) - pulse_client_stream_update_app_version (PULSE_CLIENT_STREAM (stream), prop); + pulse_client_stream_update_app_version (pclient, prop); prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_ICON_NAME); if (prop != NULL) - pulse_client_stream_update_app_icon (PULSE_CLIENT_STREAM (stream), prop); - - if (G_LIKELY (parent != NULL)) - pulse_client_stream_update_parent (PULSE_CLIENT_STREAM (stream), - MATE_MIXER_STREAM (parent)); - else - pulse_client_stream_update_parent (PULSE_CLIENT_STREAM (stream), NULL); + pulse_client_stream_update_app_icon (pclient, prop); // XXX needs to fix monitor if parent changes - g_object_thaw_notify (G_OBJECT (stream)); + g_object_thaw_notify (G_OBJECT (pstream)); return TRUE; } -static gboolean -sink_input_set_mute (MateMixerStream *stream, gboolean mute) +static void +pulse_sink_input_reload (PulseStream *pstream) { - PulseStream *pulse; + g_return_if_fail (PULSE_IS_SINK_INPUT (pstream)); - g_return_val_if_fail (PULSE_IS_SINK_INPUT (stream), FALSE); + pulse_connection_load_sink_input_info (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream)); +} - pulse = PULSE_STREAM (stream); +static gboolean +pulse_sink_input_set_mute (PulseStream *pstream, gboolean mute) +{ + g_return_val_if_fail (PULSE_IS_SINK_INPUT (pstream), FALSE); - return pulse_connection_set_sink_input_mute (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse), + return pulse_connection_set_sink_input_mute (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream), mute); } static gboolean -sink_input_set_volume (MateMixerStream *stream, pa_cvolume *volume) +pulse_sink_input_set_volume (PulseStream *pstream, pa_cvolume *cvolume) { - PulseStream *pulse; - - g_return_val_if_fail (PULSE_IS_SINK_INPUT (stream), FALSE); - g_return_val_if_fail (volume != NULL, FALSE); - - pulse = PULSE_STREAM (stream); + g_return_val_if_fail (PULSE_IS_SINK_INPUT (pstream), FALSE); + g_return_val_if_fail (cvolume != NULL, FALSE); - return pulse_connection_set_sink_input_volume (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse), - volume); + return pulse_connection_set_sink_input_volume (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream), + cvolume); } static gboolean -sink_input_set_parent (MateMixerClientStream *stream, MateMixerStream *parent) +pulse_sink_input_set_parent (PulseClientStream *pclient, PulseStream *parent) { - PulseStream *pulse; + PulseStream *pstream; - g_return_val_if_fail (PULSE_IS_SINK_INPUT (stream), FALSE); + g_return_val_if_fail (PULSE_IS_SINK_INPUT (pclient), FALSE); - if (G_UNLIKELY (!PULSE_IS_SINK (parent))) { + if (!PULSE_IS_SINK (parent)) { g_warning ("Could not change stream parent to %s: not a parent output stream", - mate_mixer_stream_get_name (parent)); + mate_mixer_stream_get_name (MATE_MIXER_STREAM (parent))); return FALSE; } - pulse = PULSE_STREAM (stream); + pstream = PULSE_STREAM (pclient); - return pulse_connection_move_sink_input (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse), - pulse_stream_get_index (PULSE_STREAM (parent))); + return pulse_connection_move_sink_input (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream), + pulse_stream_get_index (parent)); } static gboolean -sink_input_remove (MateMixerClientStream *stream) +pulse_sink_input_remove (PulseClientStream *pclient) { - PulseStream *pulse; + PulseStream *pstream; - g_return_val_if_fail (PULSE_IS_SINK_INPUT (stream), FALSE); + g_return_val_if_fail (PULSE_IS_SINK_INPUT (pclient), FALSE); - pulse = PULSE_STREAM (stream); + pstream = PULSE_STREAM (pclient); - return pulse_connection_kill_sink_input (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse)); + return pulse_connection_kill_sink_input (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream)); } static PulseMonitor * -sink_input_create_monitor (MateMixerStream *stream) +pulse_sink_input_create_monitor (PulseStream *pstream) { MateMixerStream *parent; - PulseStream *pulse; guint32 index; - g_return_val_if_fail (PULSE_IS_SINK_INPUT (stream), NULL); + g_return_val_if_fail (PULSE_IS_SINK_INPUT (pstream), NULL); - parent = mate_mixer_client_stream_get_parent (MATE_MIXER_CLIENT_STREAM (stream)); + parent = mate_mixer_client_stream_get_parent (MATE_MIXER_CLIENT_STREAM (pstream)); if (G_UNLIKELY (parent == NULL)) { g_debug ("Not creating monitor for client stream %s as it is not available", - mate_mixer_stream_get_name (stream)); + mate_mixer_stream_get_name (MATE_MIXER_STREAM (pstream))); return NULL; } - pulse = PULSE_STREAM (stream); index = pulse_sink_get_monitor_index (PULSE_STREAM (parent)); if (G_UNLIKELY (index == PA_INVALID_INDEX)) { g_debug ("Not creating monitor for client stream %s as it is not available", - mate_mixer_stream_get_name (stream)); + mate_mixer_stream_get_name (MATE_MIXER_STREAM (pstream))); return NULL; } - return pulse_connection_create_monitor (pulse_stream_get_connection (pulse), + return pulse_connection_create_monitor (pulse_stream_get_connection (pstream), index, - pulse_stream_get_index (pulse)); + pulse_stream_get_index (pstream)); } -- cgit v1.2.1