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