diff options
Diffstat (limited to 'backends/pulse/pulse-source-output.c')
-rw-r--r-- | backends/pulse/pulse-source-output.c | 306 |
1 files changed, 118 insertions, 188 deletions
diff --git a/backends/pulse/pulse-source-output.c b/backends/pulse/pulse-source-output.c index 6cbd888..69fc3e4 100644 --- a/backends/pulse/pulse-source-output.c +++ b/backends/pulse/pulse-source-output.c @@ -17,56 +17,39 @@ #include <glib.h> #include <glib-object.h> -#include <string.h> - -#include <libmatemixer/matemixer-client-stream.h> -#include <libmatemixer/matemixer-stream.h> +#include <libmatemixer/matemixer.h> +#include <libmatemixer/matemixer-private.h> #include <pulse/pulseaudio.h> #include "pulse-connection.h" -#include "pulse-client-stream.h" #include "pulse-helpers.h" #include "pulse-monitor.h" -#include "pulse-stream.h" #include "pulse-source.h" #include "pulse-source-output.h" +#include "pulse-stream.h" +#include "pulse-stream-control.h" static void pulse_source_output_class_init (PulseSourceOutputClass *klass); static void pulse_source_output_init (PulseSourceOutput *output); -G_DEFINE_TYPE (PulseSourceOutput, pulse_source_output, PULSE_TYPE_CLIENT_STREAM); - -static void pulse_source_output_reload (PulseStream *pstream); - -static gboolean pulse_source_output_set_mute (PulseStream *pstream, - gboolean mute); -static gboolean pulse_source_output_set_volume (PulseStream *pstream, - pa_cvolume *cvolume); +G_DEFINE_TYPE (PulseSourceOutput, pulse_source_output, PULSE_TYPE_STREAM_CONTROL); -static gboolean pulse_source_output_set_parent (PulseClientStream *pclient, - PulseStream *parent); -static gboolean pulse_source_output_remove (PulseClientStream *pclient); - -static PulseMonitor *pulse_source_output_create_monitor (PulseStream *pstream); +static gboolean pulse_source_output_set_mute (PulseStreamControl *psc, + gboolean mute); +static gboolean pulse_source_output_set_volume (PulseStreamControl *psc, + pa_cvolume *cvolume); +static PulseMonitor *pulse_source_output_create_monitor (PulseStreamControl *psc); static void pulse_source_output_class_init (PulseSourceOutputClass *klass) { - PulseStreamClass *stream_class; - PulseClientStreamClass *client_class; - - stream_class = PULSE_STREAM_CLASS (klass); - - stream_class->reload = pulse_source_output_reload; - stream_class->set_mute = pulse_source_output_set_mute; - stream_class->set_volume = pulse_source_output_set_volume; - stream_class->create_monitor = pulse_source_output_create_monitor; - - client_class = PULSE_CLIENT_STREAM_CLASS (klass); + PulseStreamControlClass *control_class; - client_class->set_parent = pulse_source_output_set_parent; - client_class->remove = pulse_source_output_remove; + control_class = PULSE_STREAM_CONTROL_CLASS (klass); + control_class->set_mute = pulse_source_output_set_mute; + control_class->set_volume = pulse_source_output_set_volume; + control_class->create_monitor = pulse_source_output_create_monitor; } static void @@ -74,210 +57,157 @@ pulse_source_output_init (PulseSourceOutput *output) { } -PulseStream * -pulse_source_output_new (PulseConnection *connection, - const pa_source_output_info *info, - PulseStream *parent) +PulseSourceOutput * +pulse_source_output_new (PulseSource *source, + const pa_source_output_info *info) { PulseSourceOutput *output; + gchar *name; + const gchar *prop; + MateMixerAppInfo *app_info = NULL; - g_return_val_if_fail (PULSE_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (info != NULL, NULL); - - /* Consider the sink input index as unchanging parameter */ - output = g_object_new (PULSE_TYPE_SOURCE_OUTPUT, - "connection", connection, - "index", info->index, - NULL); - - /* Other data may change at any time, so let's make a use of our update function */ - pulse_source_output_update (PULSE_STREAM (output), info, parent); + MateMixerStreamControlFlags flags = MATE_MIXER_STREAM_CONTROL_MUTE_READABLE | + MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE | + MATE_MIXER_STREAM_CONTROL_HAS_MONITOR; + MateMixerStreamControlRole role = MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN; - return PULSE_STREAM (output); -} + MateMixerStreamControlMediaRole media_role = MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN; -gboolean -pulse_source_output_update (PulseStream *pstream, - const pa_source_output_info *info, - PulseStream *parent) -{ - MateMixerStreamFlags flags = MATE_MIXER_STREAM_INPUT | - MATE_MIXER_STREAM_CLIENT; - PulseClientStream *pclient; - const gchar *prop; - const gchar *description = NULL; - gchar *name; + g_return_val_if_fail (PULSE_IS_SOURCE (source), NULL); + g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (pstream), FALSE); - g_return_val_if_fail (info != NULL, FALSE); + /* 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 PulseAudio index. */ + name = g_strdup_printf ("pulse-input-control-%lu", (gulong) info->index); - pclient = PULSE_CLIENT_STREAM (pstream); +#if PA_CHECK_VERSION(1, 0, 0) + if (info->has_volume) { + flags |= + MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE | + MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL; - /* Let all the information update before emitting notify signals */ - g_object_freeze_notify (G_OBJECT (pstream)); + if (info->volume_writable) + flags |= MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE; + } +#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 */ + flags |= + MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE | + MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE | + MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL; +#endif - /* Many other 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. */ - name = g_strdup_printf ("pulse-stream-client-input-%lu", (gulong) info->index); + if (info->client != PA_INVALID_INDEX) { + app_info = _mate_mixer_app_info_new (); - pulse_stream_update_name (pstream, name); - g_free (name); + role = MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION; - prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_NAME); - if (prop != NULL) - pulse_client_stream_update_app_name (pclient, prop); + prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_NAME); + if (prop != NULL) + _mate_mixer_app_info_set_name (app_info, prop); - prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_ID); - if (prop != NULL) - pulse_client_stream_update_app_id (pclient, prop); + prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_ID); + if (prop != NULL) + _mate_mixer_app_info_set_id (app_info, prop); - prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_VERSION); - if (prop != NULL) - pulse_client_stream_update_app_version (pclient, prop); + prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_VERSION); + if (prop != NULL) + _mate_mixer_app_info_set_version (app_info, prop); - prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_ICON_NAME); - if (prop != NULL) - pulse_client_stream_update_app_icon (pclient, prop); + prop = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_ICON_NAME); + if (prop != NULL) + _mate_mixer_app_info_set_icon (app_info, prop); + } prop = pa_proplist_gets (info->proplist, PA_PROP_MEDIA_ROLE); - if (prop != NULL) { - MateMixerClientStreamRole role = pulse_convert_media_role_name (prop); + if (prop != NULL) + media_role = pulse_convert_media_role_name (prop); - 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); + output = g_object_new (PULSE_TYPE_SOURCE_OUTPUT, + "name", name, + "label", info->name, + "flags", flags, + "role", role, + "media-role", media_role, + "index", info->index, + "stream", source, + NULL); + g_free (name); - 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); + if (app_info != NULL) + pulse_stream_control_set_app_info (PULSE_STREAM_CONTROL (output), app_info); - if (description == NULL) - description = info->name; + pulse_source_output_update (output, info); + return output; +} - pulse_stream_update_description (pstream, description); +void +pulse_source_output_update (PulseSourceOutput *output, + const pa_source_output_info *info) +{ + g_return_if_fail (PULSE_IS_SOURCE_OUTPUT (output)); + g_return_if_fail (info != NULL); - if (info->client != PA_INVALID_INDEX) - pulse_client_stream_update_flags (pclient, MATE_MIXER_CLIENT_STREAM_APPLICATION); - else - pulse_client_stream_update_flags (pclient, MATE_MIXER_CLIENT_STREAM_NO_FLAGS); + /* Let all the information update before emitting notify signals */ + g_object_freeze_notify (G_OBJECT (output)); - if (G_LIKELY (parent != NULL)) { - pulse_client_stream_update_parent (pclient, MATE_MIXER_STREAM (parent)); - flags |= MATE_MIXER_STREAM_HAS_MONITOR; - } else - pulse_client_stream_update_parent (pclient, NULL); + _mate_mixer_stream_control_set_mute (MATE_MIXER_STREAM_CONTROL (output), + info->mute ? TRUE : FALSE); #if PA_CHECK_VERSION(1, 0, 0) - if (info->has_volume) { - flags |= MATE_MIXER_STREAM_HAS_VOLUME; - - if (info->volume_writable) - flags |= MATE_MIXER_STREAM_CAN_SET_VOLUME; - } - - flags |= MATE_MIXER_STREAM_HAS_MUTE; - - /* Flags needed before volume */ - pulse_stream_update_flags (pstream, flags); - pulse_stream_update_channel_map (pstream, &info->channel_map); - pulse_stream_update_mute (pstream, info->mute ? TRUE : FALSE); + pulse_stream_control_set_channel_map (PULSE_STREAM_CONTROL (output), + &info->channel_map); if (info->has_volume) - pulse_stream_update_volume (pstream, &info->volume, 0); + pulse_stream_control_set_cvolume (PULSE_STREAM_CONTROL (output), + &info->volume, + 0); else - pulse_stream_update_volume (pstream, NULL, 0); + pulse_stream_control_set_cvolume (PULSE_STREAM_CONTROL (output), + NULL, + 0); #else - /* Flags needed before volume */ - pulse_stream_update_flags (pstream, flags); + pulse_stream_control_set_channel_map (PULSE_STREAM_CONTROL (output), + &info->channel_map); - pulse_stream_update_channel_map (pstream, &info->channel_map); - pulse_stream_update_volume (pstream, NULL, 0); + pulse_stream_control_set_volume (PULSE_STREAM_CONTROL (output), + &info->volume, + 0); #endif - // XXX needs to fix monitor if parent changes - - g_object_thaw_notify (G_OBJECT (pstream)); - return TRUE; -} - -static void -pulse_source_output_reload (PulseStream *pstream) -{ - g_return_if_fail (PULSE_IS_SOURCE_OUTPUT (pstream)); - - pulse_connection_load_source_output_info (pulse_stream_get_connection (pstream), - pulse_stream_get_index (pstream)); + g_object_thaw_notify (G_OBJECT (output)); } static gboolean -pulse_source_output_set_mute (PulseStream *pstream, gboolean mute) +pulse_source_output_set_mute (PulseStreamControl *psc, gboolean mute) { - g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (pstream), FALSE); + g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (psc), FALSE); - return pulse_connection_set_source_output_mute (pulse_stream_get_connection (pstream), - pulse_stream_get_index (pstream), + return pulse_connection_set_source_output_mute (PULSE_STREAM_CONTROL_GET_CONNECTION (psc), + pulse_stream_control_get_index (psc), mute); } static gboolean -pulse_source_output_set_volume (PulseStream *pstream, pa_cvolume *cvolume) +pulse_source_output_set_volume (PulseStreamControl *psc, pa_cvolume *cvolume) { - g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (pstream), FALSE); + g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (psc), FALSE); g_return_val_if_fail (cvolume != NULL, FALSE); - return pulse_connection_set_source_output_volume (pulse_stream_get_connection (pstream), - pulse_stream_get_index (pstream), + return pulse_connection_set_source_output_volume (PULSE_STREAM_CONTROL_GET_CONNECTION (psc), + pulse_stream_control_get_index (psc), cvolume); } -static gboolean -pulse_source_output_set_parent (PulseClientStream *pclient, PulseStream *parent) -{ - PulseStream *pstream; - - g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (pclient), FALSE); - - pstream = PULSE_STREAM (pclient); - - return pulse_connection_move_sink_input (pulse_stream_get_connection (pstream), - pulse_stream_get_index (pstream), - pulse_stream_get_index (parent)); -} - -static gboolean -pulse_source_output_remove (PulseClientStream *pclient) -{ - PulseStream *pstream; - - g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (pclient), FALSE); - - pstream = PULSE_STREAM (pclient); - - return pulse_connection_kill_source_output (pulse_stream_get_connection (pstream), - pulse_stream_get_index (pstream)); -} - static PulseMonitor * -pulse_source_output_create_monitor (PulseStream *pstream) +pulse_source_output_create_monitor (PulseStreamControl *psc) { - MateMixerStream *parent; - - g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (pstream), NULL); - - 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: not available", - mate_mixer_stream_get_name (MATE_MIXER_STREAM (pstream))); - return NULL; - } + g_return_val_if_fail (PULSE_IS_SOURCE_OUTPUT (psc), NULL); - return pulse_connection_create_monitor (pulse_stream_get_connection (pstream), - pulse_stream_get_index (PULSE_STREAM (parent)), + return pulse_connection_create_monitor (PULSE_STREAM_CONTROL_GET_CONNECTION (psc), + PULSE_STREAM_CONTROL_GET_STREAM_INDEX (psc), PA_INVALID_INDEX); } |