summaryrefslogtreecommitdiff
path: root/backends/pulse/pulse-ext-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'backends/pulse/pulse-ext-stream.c')
-rw-r--r--backends/pulse/pulse-ext-stream.c374
1 files changed, 224 insertions, 150 deletions
diff --git a/backends/pulse/pulse-ext-stream.c b/backends/pulse/pulse-ext-stream.c
index b00e967..3e7490a 100644
--- a/backends/pulse/pulse-ext-stream.c
+++ b/backends/pulse/pulse-ext-stream.c
@@ -19,252 +19,326 @@
#include <glib.h>
#include <glib-object.h>
-#include <libmatemixer/matemixer-client-stream.h>
-#include <libmatemixer/matemixer-enums.h>
-#include <libmatemixer/matemixer-stream.h>
+#include <libmatemixer/matemixer.h>
+#include <libmatemixer/matemixer-private.h>
#include <pulse/pulseaudio.h>
#include <pulse/ext-stream-restore.h>
#include "pulse-connection.h"
-#include "pulse-client-stream.h"
#include "pulse-ext-stream.h"
#include "pulse-helpers.h"
#include "pulse-stream.h"
+#include "pulse-stream-control.h"
-static void pulse_ext_stream_class_init (PulseExtStreamClass *klass);
-static void pulse_ext_stream_init (PulseExtStream *ext);
+struct _PulseExtStreamPrivate
+{
+ MateMixerAppInfo *app_info;
+ MateMixerDirection direction;
+};
-G_DEFINE_TYPE (PulseExtStream, pulse_ext_stream, PULSE_TYPE_CLIENT_STREAM);
+enum {
+ PROP_0,
+ PROP_DIRECTION
+};
-static void pulse_ext_stream_reload (PulseStream *pstream);
+static void mate_mixer_stored_control_interface_init (MateMixerStoredControlInterface *iface);
-static gboolean pulse_ext_stream_set_mute (PulseStream *pstream,
- gboolean mute);
-static gboolean pulse_ext_stream_set_volume (PulseStream *pstream,
- pa_cvolume *cvolume);
-static gboolean pulse_ext_stream_set_parent (PulseClientStream *pclient,
- PulseStream *parent);
-static gboolean pulse_ext_stream_remove (PulseClientStream *pclient);
+static void pulse_ext_stream_class_init (PulseExtStreamClass *klass);
-static void
-pulse_ext_stream_class_init (PulseExtStreamClass *klass)
-{
- PulseStreamClass *stream_class;
- PulseClientStreamClass *client_class;
+static void pulse_ext_stream_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void pulse_ext_stream_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
- stream_class = PULSE_STREAM_CLASS (klass);
+static void pulse_ext_stream_init (PulseExtStream *ext);
- stream_class->reload = pulse_ext_stream_reload;
- stream_class->set_mute = pulse_ext_stream_set_mute;
- stream_class->set_volume = pulse_ext_stream_set_volume;
+G_DEFINE_TYPE_WITH_CODE (PulseExtStream, pulse_ext_stream, PULSE_TYPE_STREAM_CONTROL,
+ G_IMPLEMENT_INTERFACE (MATE_MIXER_TYPE_STORED_CONTROL,
+ mate_mixer_stored_control_interface_init))
- client_class = PULSE_CLIENT_STREAM_CLASS (klass);
+static MateMixerDirection pulse_ext_stream_get_direction (MateMixerStoredControl *mmsc);
- client_class->set_parent = pulse_ext_stream_set_parent;
- client_class->remove = pulse_ext_stream_remove;
-}
+static MateMixerAppInfo * pulse_ext_stream_get_app_info (MateMixerStreamControl *mmsc);
+
+static gboolean pulse_ext_stream_set_stream (MateMixerStreamControl *mmsc,
+ MateMixerStream *mms);
+
+static gboolean pulse_ext_stream_set_mute (PulseStreamControl *control,
+ gboolean mute);
+static gboolean pulse_ext_stream_set_volume (PulseStreamControl *control,
+ pa_cvolume *cvolume);
+
+static void fill_ext_stream_restore_info (PulseStreamControl *control,
+ pa_ext_stream_restore_info *info);
static void
-pulse_ext_stream_init (PulseExtStream *ext)
+mate_mixer_stored_control_interface_init (MateMixerStoredControlInterface *iface)
{
+ iface->get_direction = pulse_ext_stream_get_direction;
}
-PulseStream *
-pulse_ext_stream_new (PulseConnection *connection,
- const pa_ext_stream_restore_info *info,
- PulseStream *parent)
+static void
+pulse_ext_stream_class_init (PulseExtStreamClass *klass)
{
- PulseStream *ext;
+ GObjectClass *object_class;
+ MateMixerStreamControlClass *control_class;
+ PulseStreamControlClass *pulse_class;
- g_return_val_if_fail (PULSE_IS_CONNECTION (connection), NULL);
- g_return_val_if_fail (info != NULL, NULL);
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = pulse_ext_stream_get_property;
+ object_class->set_property = pulse_ext_stream_set_property;
- ext = g_object_new (PULSE_TYPE_EXT_STREAM,
- "connection", connection,
- NULL);
+ control_class = MATE_MIXER_STREAM_CONTROL_CLASS (klass);
+ control_class->get_app_info = pulse_ext_stream_get_app_info;
+ control_class->set_stream = pulse_ext_stream_set_stream;
- /* Consider the stream name as unchanging parameter */
- pulse_stream_update_name (ext, info->name);
+ pulse_class = PULSE_STREAM_CONTROL_CLASS (klass);
+ pulse_class->set_mute = pulse_ext_stream_set_mute;
+ pulse_class->set_volume = pulse_ext_stream_set_volume;
- /* Other data may change at any time, so let's make a use of our update function */
- pulse_ext_stream_update (ext, info, parent);
+ g_object_class_override_property (object_class, PROP_DIRECTION, "direction");
- return ext;
+ g_type_class_add_private (object_class, sizeof (PulseExtStreamPrivate));
}
-gboolean
-pulse_ext_stream_update (PulseStream *pstream,
- const pa_ext_stream_restore_info *info,
- PulseStream *parent)
+static void
+pulse_ext_stream_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- MateMixerClientStreamRole role = MATE_MIXER_CLIENT_STREAM_ROLE_NONE;
- MateMixerStreamFlags flags = MATE_MIXER_STREAM_CLIENT |
- MATE_MIXER_STREAM_HAS_VOLUME |
- MATE_MIXER_STREAM_HAS_MUTE |
- MATE_MIXER_STREAM_CAN_SET_VOLUME;
- MateMixerClientStreamFlags client_flags =
- MATE_MIXER_CLIENT_STREAM_CACHED;
+ PulseExtStream *ext;
- PulseClientStream *pclient;
- gchar *suffix;
+ ext = PULSE_EXT_STREAM (object);
- g_return_val_if_fail (PULSE_IS_EXT_STREAM (pstream), FALSE);
- g_return_val_if_fail (info != NULL, FALSE);
+ switch (param_id) {
+ case PROP_DIRECTION:
+ g_value_set_enum (value, ext->priv->direction);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
- pclient = PULSE_CLIENT_STREAM (pstream);
+static void
+pulse_ext_stream_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PulseExtStream *ext;
- suffix = strchr (info->name, ':');
- if (suffix != NULL)
- suffix++;
+ ext = PULSE_EXT_STREAM (object);
- /* Let all the information update before emitting notify signals */
- g_object_freeze_notify (G_OBJECT (pstream));
+ switch (param_id) {
+ case PROP_DIRECTION:
+ ext->priv->direction = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+pulse_ext_stream_init (PulseExtStream *ext)
+{
+ ext->priv = G_TYPE_INSTANCE_GET_PRIVATE (ext,
+ PULSE_TYPE_EXT_STREAM,
+ PulseExtStreamPrivate);
+}
+
+PulseExtStream *
+pulse_ext_stream_new (PulseConnection *connection,
+ const pa_ext_stream_restore_info *info,
+ PulseStream *parent)
+{
+ PulseExtStream *ext;
+ gchar *suffix;
+ MateMixerDirection direction;
+ MateMixerStreamControlFlags flags = MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE |
+ MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE |
+ MATE_MIXER_STREAM_CONTROL_MUTE_READABLE |
+ MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE;
+ MateMixerStreamControlRole role = MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN;
+ MateMixerAppInfo *app_info;
+
+ MateMixerStreamControlMediaRole media_role = MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN;
+
+ g_return_val_if_fail (PULSE_IS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (info != NULL, NULL);
if (g_str_has_prefix (info->name, "sink-input"))
- flags |= MATE_MIXER_STREAM_OUTPUT;
+ direction = MATE_MIXER_DIRECTION_OUTPUT;
else if (g_str_has_prefix (info->name, "source-output"))
- flags |= MATE_MIXER_STREAM_INPUT;
+ direction = MATE_MIXER_DIRECTION_INPUT;
else
- g_debug ("Unknown ext-stream %s", info->name);
+ direction = MATE_MIXER_DIRECTION_UNKNOWN;
+
+ app_info = _mate_mixer_app_info_new ();
+
+ suffix = strchr (info->name, ':');
+ if (suffix != NULL)
+ suffix++;
if (strstr (info->name, "-by-media-role:")) {
if (G_LIKELY (suffix != NULL))
- role = pulse_convert_media_role_name (suffix);
+ media_role = pulse_convert_media_role_name (suffix);
}
else if (strstr (info->name, "-by-application-name:")) {
- client_flags |= MATE_MIXER_CLIENT_STREAM_APPLICATION;
+ role = MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION;
if (G_LIKELY (suffix != NULL))
- pulse_client_stream_update_app_name (pclient, suffix);
+ _mate_mixer_app_info_set_name (app_info, suffix);
}
else if (strstr (info->name, "-by-application-id:")) {
- client_flags |= MATE_MIXER_CLIENT_STREAM_APPLICATION;
+ role = MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION;
if (G_LIKELY (suffix != NULL))
- pulse_client_stream_update_app_id (pclient, suffix);
+ _mate_mixer_app_info_set_id (app_info, suffix);
}
- /* Flags needed before volume */
- pulse_stream_update_flags (pstream, flags);
+ ext = g_object_new (PULSE_TYPE_EXT_STREAM,
+ "flags", flags,
+ "role", role,
+ "media-role", media_role,
+ "name", info->name,
+ "connection", connection,
+ "direction", direction,
+ "stream", parent,
+ NULL);
- pulse_stream_update_channel_map (pstream, &info->channel_map);
- pulse_stream_update_volume (pstream, &info->volume, 0);
+ if (role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION)
+ ext->priv->app_info = app_info;
+ else
+ _mate_mixer_app_info_free (app_info);
- pulse_stream_update_mute (pstream, info->mute ? TRUE : FALSE);
+ pulse_ext_stream_update (ext, info, parent);
+ return ext;
+}
- pulse_client_stream_update_flags (pclient, client_flags);
- pulse_client_stream_update_role (pclient, role);
+void
+pulse_ext_stream_update (PulseExtStream *ext,
+ const pa_ext_stream_restore_info *info,
+ PulseStream *parent)
+{
+ g_return_if_fail (PULSE_IS_EXT_STREAM (ext));
+ g_return_if_fail (info != NULL);
- if (parent != NULL)
- pulse_client_stream_update_parent (pclient, MATE_MIXER_STREAM (parent));
- else
- pulse_client_stream_update_parent (pclient, NULL);
+ /* Let all the information update before emitting notify signals */
+ g_object_freeze_notify (G_OBJECT (ext));
+
+ _mate_mixer_stream_control_set_mute (MATE_MIXER_STREAM_CONTROL (ext),
+ info->mute ? TRUE : FALSE);
- g_object_thaw_notify (G_OBJECT (pstream));
- return TRUE;
+ pulse_stream_control_set_channel_map (PULSE_STREAM_CONTROL (ext),
+ &info->channel_map);
+
+ pulse_stream_control_set_cvolume (PULSE_STREAM_CONTROL (ext),
+ &info->volume,
+ 0);
+
+ _mate_mixer_stream_control_set_stream (MATE_MIXER_STREAM_CONTROL (ext),
+ MATE_MIXER_STREAM (parent));
+
+ g_object_thaw_notify (G_OBJECT (ext));
}
-static void
-pulse_ext_stream_reload (PulseStream *pstream)
+static MateMixerDirection
+pulse_ext_stream_get_direction (MateMixerStoredControl *mmsc)
{
- g_return_if_fail (PULSE_IS_EXT_STREAM (pstream));
+ g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), MATE_MIXER_DIRECTION_UNKNOWN);
- pulse_connection_load_ext_stream_info (pulse_stream_get_connection (pstream));
+ return PULSE_EXT_STREAM (mmsc)->priv->direction;
}
-static gboolean
-pulse_ext_stream_set_mute (PulseStream *pstream, gboolean mute)
+static MateMixerAppInfo *
+pulse_ext_stream_get_app_info (MateMixerStreamControl *mmsc)
{
- MateMixerStream *parent;
- const pa_channel_map *map;
- const pa_cvolume *cvolume;
- pa_ext_stream_restore_info info;
+ g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), NULL);
- g_return_val_if_fail (PULSE_IS_EXT_STREAM (pstream), FALSE);
+ return PULSE_EXT_STREAM (mmsc)->priv->app_info;
+}
- info.name = mate_mixer_stream_get_name (MATE_MIXER_STREAM (pstream));
- info.mute = mute;
+static gboolean
+pulse_ext_stream_set_stream (MateMixerStreamControl *mmsc, MateMixerStream *mms)
+{
+ pa_ext_stream_restore_info info;
- map = pulse_stream_get_channel_map (pstream);
- info.channel_map = *map;
+ g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE);
+ g_return_val_if_fail (mms == NULL || PULSE_IS_STREAM (mms), FALSE);
- cvolume = pulse_stream_get_cvolume (pstream);
- info.volume = *cvolume;
+ fill_ext_stream_restore_info (PULSE_STREAM_CONTROL (mms), &info);
- parent = mate_mixer_client_stream_get_parent (MATE_MIXER_CLIENT_STREAM (pstream));
- if (parent != NULL)
- info.device = mate_mixer_stream_get_name (parent);
+ if (mms != NULL)
+ info.device = mate_mixer_stream_get_name (mms);
else
info.device = NULL;
- return pulse_connection_write_ext_stream (pulse_stream_get_connection (pstream), &info);
+ return pulse_connection_write_ext_stream (pulse_stream_control_get_connection (PULSE_STREAM_CONTROL (mmsc)),
+ &info);
}
static gboolean
-pulse_ext_stream_set_volume (PulseStream *pstream, pa_cvolume *cvolume)
+pulse_ext_stream_set_mute (PulseStreamControl *control, gboolean mute)
{
- MateMixerStream *parent;
- const pa_channel_map *map;
pa_ext_stream_restore_info info;
- g_return_val_if_fail (PULSE_IS_EXT_STREAM (pstream), FALSE);
- g_return_val_if_fail (cvolume != NULL, FALSE);
-
- info.name = mate_mixer_stream_get_name (MATE_MIXER_STREAM (pstream));
- info.mute = mate_mixer_stream_get_mute (MATE_MIXER_STREAM (pstream));
+ g_return_val_if_fail (PULSE_IS_EXT_STREAM (control), FALSE);
- map = pulse_stream_get_channel_map (pstream);
- info.channel_map = *map;
-
- parent = mate_mixer_client_stream_get_parent (MATE_MIXER_CLIENT_STREAM (pstream));
- if (parent != NULL)
- info.device = mate_mixer_stream_get_name (parent);
- else
- info.device = NULL;
+ fill_ext_stream_restore_info (control, &info);
- info.volume = *cvolume;
+ info.mute = mute;
- return pulse_connection_write_ext_stream (pulse_stream_get_connection (pstream), &info);
+ return pulse_connection_write_ext_stream (pulse_stream_control_get_connection (control),
+ &info);
}
static gboolean
-pulse_ext_stream_set_parent (PulseClientStream *pclient, PulseStream *parent)
+pulse_ext_stream_set_volume (PulseStreamControl *control, pa_cvolume *cvolume)
{
- PulseStream *pstream;
- const pa_channel_map *map;
- const pa_cvolume *cvolume;
pa_ext_stream_restore_info info;
- g_return_val_if_fail (PULSE_IS_EXT_STREAM (pclient), FALSE);
- g_return_val_if_fail (PULSE_IS_STREAM (parent), FALSE);
-
- pstream = PULSE_STREAM (pclient);
-
- info.name = mate_mixer_stream_get_name (MATE_MIXER_STREAM (pstream));
- info.mute = mate_mixer_stream_get_mute (MATE_MIXER_STREAM (pstream));
+ g_return_val_if_fail (PULSE_IS_EXT_STREAM (control), FALSE);
+ g_return_val_if_fail (cvolume != NULL, FALSE);
- map = pulse_stream_get_channel_map (pstream);
- info.channel_map = *map;
+ fill_ext_stream_restore_info (control, &info);
- cvolume = pulse_stream_get_cvolume (pstream);
info.volume = *cvolume;
- info.device = mate_mixer_stream_get_name (MATE_MIXER_STREAM (parent));
-
- return pulse_connection_write_ext_stream (pulse_stream_get_connection (pstream), &info);
+ return pulse_connection_write_ext_stream (pulse_stream_control_get_connection (control),
+ &info);
}
-static gboolean
-pulse_ext_stream_remove (PulseClientStream *pclient)
+static void
+fill_ext_stream_restore_info (PulseStreamControl *control,
+ pa_ext_stream_restore_info *info)
{
- PulseStream *pstream;
- const gchar *name;
+ MateMixerStream *stream;
+ MateMixerStreamControl *mmsc;
+ const pa_channel_map *map;
+ const pa_cvolume *cvolume;
+
+ mmsc = MATE_MIXER_STREAM_CONTROL (control);
- g_return_val_if_fail (PULSE_IS_EXT_STREAM (pclient), FALSE);
+ info->name = mate_mixer_stream_control_get_name (mmsc);
+ info->mute = mate_mixer_stream_control_get_mute (mmsc);
- pstream = PULSE_STREAM (pclient);
- name = mate_mixer_stream_get_name (MATE_MIXER_STREAM (pstream));
+ map = pulse_stream_control_get_channel_map (control);
+ info->channel_map = *map;
- return pulse_connection_delete_ext_stream (pulse_stream_get_connection (pstream), name);
+ cvolume = pulse_stream_control_get_cvolume (control);
+ info->volume = *cvolume;
+
+ stream = mate_mixer_stream_control_get_stream (mmsc);
+ if (stream != NULL)
+ info->device = mate_mixer_stream_get_name (stream);
+ else
+ info->device = NULL;
}