summaryrefslogtreecommitdiff
path: root/backends/pulse/pulse-source.c
diff options
context:
space:
mode:
Diffstat (limited to 'backends/pulse/pulse-source.c')
-rw-r--r--backends/pulse/pulse-source.c225
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);
}