diff options
Diffstat (limited to 'backends/pulse/pulse-source.c')
-rw-r--r-- | backends/pulse/pulse-source.c | 225 |
1 files changed, 133 insertions, 92 deletions
diff --git a/backends/pulse/pulse-source.c b/backends/pulse/pulse-source.c index b443402..e7dce6f 100644 --- a/backends/pulse/pulse-source.c +++ b/backends/pulse/pulse-source.c @@ -18,8 +18,9 @@ #include <glib.h> #include <glib-object.h> -#include <libmatemixer/matemixer-stream.h> #include <libmatemixer/matemixer-port.h> +#include <libmatemixer/matemixer-port-private.h> +#include <libmatemixer/matemixer-stream.h> #include <pulse/pulseaudio.h> @@ -34,13 +35,20 @@ static void pulse_source_init (PulseSource *source); G_DEFINE_TYPE (PulseSource, pulse_source, PULSE_TYPE_STREAM); -static gboolean source_set_mute (MateMixerStream *stream, - gboolean mute); -static gboolean source_set_volume (MateMixerStream *stream, - pa_cvolume *volume); -static gboolean source_set_active_port (MateMixerStream *stream, - const gchar *port_name); -static PulseMonitor *source_create_monitor (MateMixerStream *stream); +static void pulse_source_reload (PulseStream *pstream); + +static gboolean pulse_source_set_mute (PulseStream *pstream, + gboolean mute); +static gboolean pulse_source_set_volume (PulseStream *pstream, + pa_cvolume *cvolume); +static gboolean pulse_source_set_active_port (PulseStream *pstream, + MateMixerPort *port); + +static PulseMonitor *pulse_source_create_monitor (PulseStream *pstream); + +static void update_ports (PulseStream *pstream, + pa_source_port_info **ports, + pa_source_port_info *active); static void pulse_source_class_init (PulseSourceClass *klass) @@ -49,10 +57,11 @@ pulse_source_class_init (PulseSourceClass *klass) stream_class = PULSE_STREAM_CLASS (klass); - stream_class->set_mute = source_set_mute; - stream_class->set_volume = source_set_volume; - stream_class->set_active_port = source_set_active_port; - stream_class->create_monitor = source_create_monitor; + stream_class->reload = pulse_source_reload; + stream_class->set_mute = pulse_source_set_mute; + stream_class->set_volume = pulse_source_set_volume; + stream_class->set_active_port = pulse_source_set_active_port; + stream_class->create_monitor = pulse_source_create_monitor; } static void @@ -83,63 +92,40 @@ pulse_source_new (PulseConnection *connection, } gboolean -pulse_source_update (PulseStream *stream, +pulse_source_update (PulseStream *pstream, const pa_source_info *info, PulseDevice *device) { MateMixerStreamFlags flags = MATE_MIXER_STREAM_INPUT | MATE_MIXER_STREAM_HAS_MUTE | + MATE_MIXER_STREAM_HAS_MONITOR | MATE_MIXER_STREAM_HAS_VOLUME | MATE_MIXER_STREAM_CAN_SET_VOLUME | MATE_MIXER_STREAM_CAN_SUSPEND; - GList *ports = NULL; - guint32 i; - g_return_val_if_fail (PULSE_IS_SOURCE (stream), FALSE); + g_return_val_if_fail (PULSE_IS_SOURCE (pstream), FALSE); + g_return_val_if_fail (info != NULL, FALSE); /* Let all the information update before emitting notify signals */ - g_object_freeze_notify (G_OBJECT (stream)); - - pulse_stream_update_name (stream, info->name); - pulse_stream_update_description (stream, info->description); - pulse_stream_update_mute (stream, info->mute ? TRUE : FALSE); + g_object_freeze_notify (G_OBJECT (pstream)); - /* List of ports */ - for (i = 0; i < info->n_ports; i++) { - MateMixerPortFlags flags = MATE_MIXER_PORT_NO_FLAGS; - -#if PA_CHECK_VERSION(2, 0, 0) - if (info->ports[i]->available == PA_PORT_AVAILABLE_YES) - flags |= MATE_MIXER_PORT_AVAILABLE; -#endif - ports = g_list_prepend (ports, - mate_mixer_port_new (info->ports[i]->name, - info->ports[i]->description, - NULL, - info->ports[i]->priority, - flags)); - } - pulse_stream_update_ports (stream, ports); - - /* Active port */ - if (info->active_port) - pulse_stream_update_active_port (stream, info->active_port->name); - else - pulse_stream_update_active_port (stream, NULL); + pulse_stream_update_name (pstream, info->name); + pulse_stream_update_description (pstream, info->description); + pulse_stream_update_mute (pstream, info->mute ? TRUE : FALSE); /* Stream state */ switch (info->state) { case PA_SOURCE_RUNNING: - pulse_stream_update_state (stream, MATE_MIXER_STREAM_RUNNING); + pulse_stream_update_state (pstream, MATE_MIXER_STREAM_STATE_RUNNING); break; case PA_SOURCE_IDLE: - pulse_stream_update_state (stream, MATE_MIXER_STREAM_IDLE); + pulse_stream_update_state (pstream, MATE_MIXER_STREAM_STATE_IDLE); break; case PA_SOURCE_SUSPENDED: - pulse_stream_update_state (stream, MATE_MIXER_STREAM_SUSPENDED); + pulse_stream_update_state (pstream, MATE_MIXER_STREAM_STATE_SUSPENDED); break; default: - pulse_stream_update_state (stream, MATE_MIXER_STREAM_UNKNOWN_STATE); + pulse_stream_update_state (pstream, MATE_MIXER_STREAM_STATE_UNKNOWN); break; } @@ -149,79 +135,134 @@ pulse_source_update (PulseStream *stream, if (info->flags & PA_SINK_FLAT_VOLUME) flags |= MATE_MIXER_STREAM_HAS_FLAT_VOLUME; - 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; - /* Flags must be updated 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 (pstream, &info->volume, info->base_volume); - pulse_stream_update_volume (stream, - &info->volume, - &info->channel_map, - info->base_volume); + pulse_stream_update_device (pstream, MATE_MIXER_DEVICE (device)); - pulse_stream_update_device (stream, MATE_MIXER_DEVICE (device)); + /* Ports must be updated after device */ + if (info->ports != NULL) { + update_ports (pstream, info->ports, info->active_port); + } - g_object_thaw_notify (G_OBJECT (stream)); + g_object_thaw_notify (G_OBJECT (pstream)); return TRUE; } -static gboolean -source_set_mute (MateMixerStream *stream, gboolean mute) +static void +pulse_source_reload (PulseStream *pstream) { - PulseStream *pulse; + g_return_if_fail (PULSE_IS_SOURCE (pstream)); - g_return_val_if_fail (PULSE_IS_SOURCE (stream), FALSE); + pulse_connection_load_source_info (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream)); +} - pulse = PULSE_STREAM (stream); +static gboolean +pulse_source_set_mute (PulseStream *pstream, gboolean mute) +{ + g_return_val_if_fail (PULSE_IS_SOURCE (pstream), FALSE); - return pulse_connection_set_source_mute (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse), + return pulse_connection_set_source_mute (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream), mute); } static gboolean -source_set_volume (MateMixerStream *stream, pa_cvolume *volume) +pulse_source_set_volume (PulseStream *pstream, pa_cvolume *cvolume) { - PulseStream *pulse; - - g_return_val_if_fail (PULSE_IS_SOURCE (stream), FALSE); - g_return_val_if_fail (volume != NULL, FALSE); - - pulse = PULSE_STREAM (stream); + g_return_val_if_fail (PULSE_IS_SOURCE (pstream), FALSE); + g_return_val_if_fail (cvolume != NULL, FALSE); - return pulse_connection_set_source_volume (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse), - volume); + return pulse_connection_set_source_volume (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream), + cvolume); } static gboolean -source_set_active_port (MateMixerStream *stream, const gchar *port_name) +pulse_source_set_active_port (PulseStream *pstream, MateMixerPort *port) { - PulseStream *pulse; + g_return_val_if_fail (PULSE_IS_SOURCE (pstream), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE); - g_return_val_if_fail (PULSE_IS_SOURCE (stream), FALSE); - g_return_val_if_fail (port_name != NULL, FALSE); + return pulse_connection_set_source_port (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream), + mate_mixer_port_get_name (port)); +} - pulse = PULSE_STREAM (stream); +static PulseMonitor * +pulse_source_create_monitor (PulseStream *pstream) +{ + g_return_val_if_fail (PULSE_IS_SOURCE (pstream), NULL); - return pulse_connection_set_source_port (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse), - port_name); + return pulse_connection_create_monitor (pulse_stream_get_connection (pstream), + pulse_stream_get_index (pstream), + PA_INVALID_INDEX); } -static PulseMonitor * -source_create_monitor (MateMixerStream *stream) +static void +update_ports (PulseStream *pstream, + pa_source_port_info **ports, + pa_source_port_info *active) { - PulseStream *pulse; + MateMixerPort *port; + MateMixerDevice *device; + GHashTable *hash; - g_return_val_if_fail (PULSE_IS_SOURCE (stream), NULL); + hash = pulse_stream_get_ports (pstream); - pulse = PULSE_STREAM (stream); + while (*ports != NULL) { + MateMixerPortFlags flags = MATE_MIXER_PORT_NO_FLAGS; + pa_source_port_info *info = *ports; + const gchar *icon = NULL; - return pulse_connection_create_monitor (pulse_stream_get_connection (pulse), - pulse_stream_get_index (pulse), - PA_INVALID_INDEX); + device = mate_mixer_stream_get_device (MATE_MIXER_STREAM (pstream)); + if (device != NULL) { + port = mate_mixer_device_get_port (device, info->name); + + if (port != NULL) { + flags = mate_mixer_port_get_flags (port); + icon = mate_mixer_port_get_icon (port); + } + } + +#if PA_CHECK_VERSION(2, 0, 0) + if (info->available == PA_PORT_AVAILABLE_YES) + flags |= MATE_MIXER_PORT_AVAILABLE; + else + flags &= ~MATE_MIXER_PORT_AVAILABLE; +#endif + + port = g_hash_table_lookup (hash, info->name); + + if (port != NULL) { + /* Update existing port */ + _mate_mixer_port_update_description (port, info->description); + _mate_mixer_port_update_icon (port, icon); + _mate_mixer_port_update_priority (port, info->priority); + _mate_mixer_port_update_flags (port, flags); + } else { + /* Add previously unknown port to the hash table */ + port = _mate_mixer_port_new (info->name, + info->description, + icon, + info->priority, + flags); + + g_hash_table_insert (hash, g_strdup (info->name), port); + } + + ports++; + } + + /* Active port */ + if (G_LIKELY (active != NULL)) + port = g_hash_table_lookup (hash, active->name); + else + port = NULL; + + pulse_stream_update_active_port (pstream, port); } |