From ec5cf3e0de6715803e64b65abb059e2155b3d6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 22 Nov 2019 18:09:21 +0100 Subject: [PATCH] mixer-control: Expose stream state The state can be used to determine whether audio is currently playing or not, which can be useful information. https://gitlab.gnome.org/GNOME/libgnome-volume-control/merge_requests/8 --- gvc-mixer-control.c | 16 ++++++++++++++++ gvc-mixer-stream.c | 38 ++++++++++++++++++++++++++++++++++++++ gvc-mixer-stream.h | 11 +++++++++++ meson.build | 12 ++++++++---- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/gvc-mixer-control.c b/gvc-mixer-control.c index c611a41..21fc233 100644 --- a/gvc-mixer-control.c +++ b/gvc-mixer-control.c @@ -1452,6 +1452,21 @@ set_icon_name_from_proplist (GvcMixerStream *stream, gvc_mixer_stream_set_icon_name (stream, t); } +static GvcMixerStreamState +translate_pa_state (pa_sink_state_t state) { + switch (state) { + case PA_SINK_RUNNING: + return GVC_STREAM_STATE_RUNNING; + case PA_SINK_IDLE: + return GVC_STREAM_STATE_IDLE; + case PA_SINK_SUSPENDED: + return GVC_STREAM_STATE_SUSPENDED; + case PA_SINK_INVALID_STATE: + default: + return GVC_STREAM_STATE_INVALID; + } +} + /* * Called when anything changes with a sink. */ @@ -1521,6 +1536,7 @@ update_sink (GvcMixerControl *control, gvc_mixer_stream_set_is_muted (stream, info->mute); gvc_mixer_stream_set_can_decibel (stream, !!(info->flags & PA_SINK_DECIBEL_VOLUME)); gvc_mixer_stream_set_base_volume (stream, (guint32) info->base_volume); + gvc_mixer_stream_set_state (stream, translate_pa_state (info->state)); /* Messy I know but to set the port everytime regardless of whether it has changed will cost us a * port change notify signal which causes the frontend to resync. diff --git a/gvc-mixer-stream.c b/gvc-mixer-stream.c index af13ba3..c324900 100644 --- a/gvc-mixer-stream.c +++ b/gvc-mixer-stream.c @@ -32,6 +32,7 @@ #include "gvc-mixer-stream.h" #include "gvc-mixer-stream-private.h" #include "gvc-channel-map-private.h" +#include "gvc-enum-types.h" static guint32 stream_serial = 1; @@ -57,6 +58,7 @@ struct GvcMixerStreamPrivate char *port; char *human_port; GList *ports; + GvcMixerStreamState state; }; enum @@ -80,6 +82,7 @@ enum PROP_IS_VIRTUAL, PROP_CARD_INDEX, PROP_PORT, + PROP_STATE, }; static void gvc_mixer_stream_finalize (GObject *object); @@ -580,6 +583,27 @@ gvc_mixer_stream_get_ports (GvcMixerStream *stream) return stream->priv->ports; } +gboolean +gvc_mixer_stream_set_state (GvcMixerStream *stream, + GvcMixerStreamState state) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + if (stream->priv->state != state) { + stream->priv->state = state; + g_object_notify (G_OBJECT (stream), "state"); + } + + return TRUE; +} + +GvcMixerStreamState +gvc_mixer_stream_get_state (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), GVC_STREAM_STATE_INVALID); + return stream->priv->state; +} + static int sort_ports (GvcMixerStreamPort *a, GvcMixerStreamPort *b) @@ -686,6 +710,9 @@ gvc_mixer_stream_set_property (GObject *object, case PROP_PORT: gvc_mixer_stream_set_port (self, g_value_get_string (value)); break; + case PROP_STATE: + gvc_mixer_stream_set_state (self, g_value_get_enum (value)); + break; case PROP_CARD_INDEX: self->priv->card_index = g_value_get_long (value); break; @@ -757,6 +784,9 @@ gvc_mixer_stream_get_property (GObject *object, case PROP_PORT: g_value_set_string (value, self->priv->port); break; + case PROP_STATE: + g_value_set_enum (value, self->priv->state); + break; case PROP_CARD_INDEX: g_value_set_long (value, self->priv->card_index); break; @@ -986,6 +1016,14 @@ gvc_mixer_stream_class_init (GvcMixerStreamClass *klass) "The name of the current port for this stream", NULL, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_STATE, + g_param_spec_enum ("state", + "State", + "The current state of this stream", + GVC_TYPE_MIXER_STREAM_STATE, + GVC_STREAM_STATE_INVALID, + G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_CARD_INDEX, g_param_spec_long ("card-index", diff --git a/gvc-mixer-stream.h b/gvc-mixer-stream.h index 76cfb43..586ec75 100644 --- a/gvc-mixer-stream.h +++ b/gvc-mixer-stream.h @@ -64,6 +64,14 @@ typedef struct gboolean available; } GvcMixerStreamPort; +typedef enum +{ + GVC_STREAM_STATE_INVALID, + GVC_STREAM_STATE_RUNNING, + GVC_STREAM_STATE_IDLE, + GVC_STREAM_STATE_SUSPENDED +} GvcMixerStreamState; + GType gvc_mixer_stream_port_get_type (void) G_GNUC_CONST; GType gvc_mixer_stream_get_type (void) G_GNUC_CONST; @@ -95,6 +103,7 @@ const char * gvc_mixer_stream_get_application_id (GvcMixerStream *stream) gboolean gvc_mixer_stream_is_event_stream (GvcMixerStream *stream); gboolean gvc_mixer_stream_is_virtual (GvcMixerStream *stream); guint gvc_mixer_stream_get_card_index (GvcMixerStream *stream); +GvcMixerStreamState gvc_mixer_stream_get_state (GvcMixerStream *stream); /* private */ gboolean gvc_mixer_stream_set_volume (GvcMixerStream *stream, @@ -129,6 +138,8 @@ gboolean gvc_mixer_stream_set_ports (GvcMixerStream *stream, GList *ports); gboolean gvc_mixer_stream_set_card_index (GvcMixerStream *stream, guint card_index); +gboolean gvc_mixer_stream_set_state (GvcMixerStream *stream, + GvcMixerStreamState state); G_END_DECLS diff --git a/meson.build b/meson.build index 9608df1..3118806 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gvc', 'c', - meson_version: '>= 0.38.0', + meson_version: '>= 0.42.0', default_options: ['static=true'] ) @@ -27,6 +27,10 @@ libgvc_gir_headers = [ 'gvc-mixer-ui-device.h' ] +libgvc_enums = gnome.mkenums_simple('gvc-enum-types', + sources: libgvc_gir_headers +) + libgvc_gir_sources = [ 'gvc-channel-map.c', 'gvc-mixer-card.c', @@ -75,7 +79,7 @@ endif if enable_static libgvc_static = static_library('gvc', - sources: libgvc_gir_sources + libgvc_no_gir_sources, + sources: libgvc_gir_sources + libgvc_no_gir_sources + libgvc_enums, dependencies: libgvc_deps, c_args: c_args ) @@ -87,7 +91,7 @@ else endif libgvc_shared = shared_library('gvc', - sources: libgvc_gir_sources + libgvc_no_gir_sources, + sources: libgvc_gir_sources + libgvc_no_gir_sources + libgvc_enums, dependencies: libgvc_deps, c_args: c_args, install_dir: pkglibdir, @@ -101,7 +105,7 @@ if enable_introspection assert(pkgdatadir != '', 'Installing introspection, but pkgdatadir is unset!') libgvc_gir = gnome.generate_gir(libgvc, - sources: libgvc_gir_sources + libgvc_gir_headers, + sources: libgvc_gir_sources + libgvc_gir_headers + libgvc_enums, nsversion: '1.0', namespace: 'Gvc', includes: ['Gio-2.0', 'GObject-2.0'],