summaryrefslogtreecommitdiff
path: root/backends/pulse/pulse-sink.c
diff options
context:
space:
mode:
Diffstat (limited to 'backends/pulse/pulse-sink.c')
-rw-r--r--backends/pulse/pulse-sink.c175
1 files changed, 134 insertions, 41 deletions
diff --git a/backends/pulse/pulse-sink.c b/backends/pulse/pulse-sink.c
index 64eb4c1..53ed64f 100644
--- a/backends/pulse/pulse-sink.c
+++ b/backends/pulse/pulse-sink.c
@@ -27,41 +27,55 @@
#include "pulse-stream.h"
#include "pulse-sink.h"
-struct _MateMixerPulseSinkPrivate
+struct _PulseSinkPrivate
{
guint32 index_monitor;
};
-G_DEFINE_TYPE (MateMixerPulseSink, mate_mixer_pulse_sink, MATE_MIXER_TYPE_PULSE_STREAM);
+enum {
+ PROP_0,
+ N_PROPERTIES
+};
+
+static gboolean sink_set_mute (MateMixerStream *stream,
+ gboolean mute);
+static gboolean sink_set_volume (MateMixerStream *stream,
+ pa_cvolume *volume);
+static gboolean sink_set_active_port (MateMixerStream *stream,
+ const gchar *port_name);
+
+G_DEFINE_TYPE (PulseSink, pulse_sink, PULSE_TYPE_STREAM);
static void
-mate_mixer_pulse_sink_init (MateMixerPulseSink *sink)
+pulse_sink_init (PulseSink *sink)
{
sink->priv = G_TYPE_INSTANCE_GET_PRIVATE (sink,
- MATE_MIXER_TYPE_PULSE_SINK,
- MateMixerPulseSinkPrivate);
+ PULSE_TYPE_SINK,
+ PulseSinkPrivate);
}
static void
-mate_mixer_pulse_sink_class_init (MateMixerPulseSinkClass *klass)
+pulse_sink_class_init (PulseSinkClass *klass)
{
- MateMixerPulseStreamClass *stream_class;
+ PulseStreamClass *stream_class;
- stream_class = MATE_MIXER_PULSE_STREAM_CLASS (klass);
+ stream_class = PULSE_STREAM_CLASS (klass);
- stream_class->set_volume = mate_mixer_pulse_sink_set_volume;
- stream_class->set_mute = mate_mixer_pulse_sink_set_mute;
+ stream_class->set_mute = sink_set_mute;
+ stream_class->set_volume = sink_set_volume;
+ stream_class->set_active_port = sink_set_active_port;
- g_type_class_add_private (G_OBJECT (klass), sizeof (MateMixerPulseSinkPrivate));
+ g_type_class_add_private (klass, sizeof (PulseSinkPrivate));
}
-MateMixerPulseStream *
-mate_mixer_pulse_sink_new (MateMixerPulseConnection *connection, const pa_sink_info *info)
+PulseStream *
+pulse_sink_new (PulseConnection *connection, const pa_sink_info *info)
{
- MateMixerPulseStream *stream;
- GList *ports = NULL;
- int i;
+ PulseSink *sink;
+ GList *ports = NULL;
+ int i;
+ /* Convert the list of sink ports to a GList of MateMixerPorts */
for (i = 0; i < info->n_ports; i++) {
MateMixerPort *port;
MateMixerPortStatus status = MATE_MIXER_PORT_UNKNOWN_STATUS;
@@ -88,43 +102,122 @@ mate_mixer_pulse_sink_new (MateMixerPulseConnection *connection, const pa_sink_i
ports = g_list_prepend (ports, port);
}
- if (ports)
- ports = g_list_reverse (ports);
+ /* Consider the sink index as unchanging parameter */
+ sink = g_object_new (PULSE_TYPE_SINK,
+ "connection", connection,
+ "index", info->index,
+ NULL);
- stream = g_object_new (MATE_MIXER_TYPE_PULSE_STREAM,
- "connection", connection,
- "index", info->index,
- "name", info->name,
- "description", info->description,
- "channels", info->channel_map.channels,
- "mute", info->mute ? TRUE : FALSE,
- NULL);
+ /* According to the PulseAudio code, the list of sink port never changes with
+ * updates.
+ * This may be not future-proof, but checking and validating the list of ports on
+ * each update would be an expensive operation, so let's set the list only during
+ * the construction */
+ pulse_stream_update_ports (PULSE_STREAM (sink), g_list_reverse (ports));
- return stream;
+ /* Other data may change at any time, so let's make a use of our update function */
+ pulse_sink_update (PULSE_STREAM (sink), info);
+
+ return PULSE_STREAM (sink);
}
gboolean
-mate_mixer_pulse_sink_set_volume (MateMixerStream *stream, guint32 volume)
+pulse_sink_update (PulseStream *stream, const pa_sink_info *info)
{
- g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+ PulseSink *sink;
+ MateMixerStreamFlags flags = MATE_MIXER_STREAM_OUTPUT |
+ MATE_MIXER_STREAM_HAS_MUTE |
+ MATE_MIXER_STREAM_HAS_VOLUME |
+ MATE_MIXER_STREAM_CAN_SET_VOLUME;
+
+ g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE);
+
+ sink = PULSE_SINK (stream);
+
+ /* 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);
+ pulse_stream_update_channel_map (stream, &info->channel_map);
+ pulse_stream_update_volume_extended (stream,
+ &info->volume,
+ info->base_volume,
+ info->n_volume_steps);
+ if (info->active_port)
+ pulse_stream_update_active_port (stream, info->active_port->name);
+
+ switch (info->state) {
+ case PA_SINK_RUNNING:
+ pulse_stream_update_status (stream, MATE_MIXER_STREAM_RUNNING);
+ break;
+ case PA_SINK_IDLE:
+ pulse_stream_update_status (stream, MATE_MIXER_STREAM_IDLE);
+ break;
+ case PA_SINK_SUSPENDED:
+ pulse_stream_update_status (stream, MATE_MIXER_STREAM_SUSPENDED);
+ break;
+ default:
+ pulse_stream_update_status (stream, MATE_MIXER_STREAM_UNKNOWN_STATUS);
+ break;
+ }
-/*
- return mate_mixer_pulse_connection_set_sink_volume (mate_mixer_pulse_stream_get_connection (MATE_MIXER_PULSE_STREAM (stream)),
- volume);
-*/
+ /* Build the flag list */
+ if (info->flags & PA_SINK_DECIBEL_VOLUME)
+ flags |= MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME;
+ if (info->flags & PA_SINK_FLAT_VOLUME)
+ flags |= MATE_MIXER_STREAM_HAS_FLAT_VOLUME;
+
+ if (info->monitor_source_name)
+ flags |= MATE_MIXER_STREAM_OUTPUT_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_stream_update_flags (stream, flags);
+
+ if (sink->priv->index_monitor != info->monitor_source) {
+ sink->priv->index_monitor = info->monitor_source;
+
+ // TODO: provide a property
+ // g_object_notify (G_OBJECT (stream), "monitor");
+ }
+
+ g_object_thaw_notify (G_OBJECT (stream));
return TRUE;
}
-gboolean
-mate_mixer_pulse_sink_set_mute (MateMixerStream *stream, gboolean mute)
+static gboolean
+sink_set_mute (MateMixerStream *stream, gboolean mute)
+{
+ g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE);
+
+ return pulse_connection_set_sink_mute (pulse_stream_get_connection (PULSE_STREAM (stream)),
+ pulse_stream_get_index (PULSE_STREAM (stream)),
+ mute);
+}
+
+static gboolean
+sink_set_volume (MateMixerStream *stream, pa_cvolume *volume)
{
- MateMixerPulseStream *pulse_stream;
+ g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE);
+ g_return_val_if_fail (volume != NULL, FALSE);
- g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+ return pulse_connection_set_sink_volume (pulse_stream_get_connection (PULSE_STREAM (stream)),
+ pulse_stream_get_index (PULSE_STREAM (stream)),
+ volume);
+}
- pulse_stream = MATE_MIXER_PULSE_STREAM (stream);
+static gboolean
+sink_set_active_port (MateMixerStream *stream, const gchar *port_name)
+{
+ g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE);
+ g_return_val_if_fail (port_name != NULL, FALSE);
- return mate_mixer_pulse_connection_set_sink_mute (mate_mixer_pulse_stream_get_connection (pulse_stream),
- mate_mixer_pulse_stream_get_index (pulse_stream),
- mute);
+ return pulse_connection_set_sink_port (pulse_stream_get_connection (PULSE_STREAM (stream)),
+ pulse_stream_get_index (PULSE_STREAM (stream)),
+ port_name);
}