From 270e82e3dbb65b8ccd57a3334cf2bed2a62b4db3 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sat, 26 Mar 2011 17:59:22 +0100 Subject: [PATCH] GnomeVolumeControl: track PulseAudio connection state and expose it Adds get_state() and ::state-changed signals, that replace connecting and ready, as well as providing indication of when the object was closed or the connection to PulseAudio failed. https://bugzilla.gnome.org/show_bug.cgi?id=645708 --- src/gvc/gvc-mixer-control.c | 43 +++++++++++++++++++------------------ src/gvc/gvc-mixer-control.h | 15 ++++++++++--- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/gvc/gvc-mixer-control.c b/src/gvc/gvc-mixer-control.c index 0e6416544..4d3a9f403 100644 --- a/src/gvc/gvc-mixer-control.c +++ b/src/gvc/gvc-mixer-control.c @@ -81,11 +81,12 @@ struct GvcMixerControlPrivate GHashTable *cards; GvcMixerStream *new_default_stream; /* new default stream, used in gvc_mixer_control_set_default_sink () */ + + GvcMixerControlState state; }; enum { - CONNECTING, - READY, + STATE_CHANGED, STREAM_ADDED, STREAM_REMOVED, CARD_ADDED, @@ -508,16 +509,17 @@ dec_outstanding (GvcMixerControl *control) } if (--control->priv->n_outstanding <= 0) { - g_signal_emit (G_OBJECT (control), signals[READY], 0); + control->priv->state = GVC_STATE_READY; + g_signal_emit (G_OBJECT (control), signals[STATE_CHANGED], 0, GVC_STATE_READY); } } -gboolean -gvc_mixer_control_is_ready (GvcMixerControl *control) +GvcMixerControlState +gvc_mixer_control_get_state (GvcMixerControl *control) { g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE); - return (control->priv->n_outstanding == 0); + return control->priv->state; } @@ -1943,7 +1945,8 @@ _pa_context_state_cb (pa_context *context, break; case PA_CONTEXT_FAILED: - g_warning ("Connection failed, reconnecting..."); + control->priv->state = GVC_STATE_FAILED; + g_signal_emit (control, signals[STATE_CHANGED], 0, GVC_STATE_FAILED); if (control->priv->reconnect_id == 0) control->priv->reconnect_id = g_timeout_add_seconds (RECONNECT_DELAY, idle_reconnect, control); break; @@ -1968,7 +1971,8 @@ gvc_mixer_control_open (GvcMixerControl *control) _pa_context_state_cb, control); - g_signal_emit (G_OBJECT (control), signals[CONNECTING], 0); + control->priv->state = GVC_STATE_CONNECTING; + g_signal_emit (G_OBJECT (control), signals[STATE_CHANGED], 0, GVC_STATE_CONNECTING); res = pa_context_connect (control->priv->pa_context, NULL, (pa_context_flags_t) PA_CONTEXT_NOFAIL, NULL); if (res < 0) { g_warning ("Failed to connect context: %s", @@ -1985,6 +1989,9 @@ gvc_mixer_control_close (GvcMixerControl *control) g_return_val_if_fail (control->priv->pa_context != NULL, FALSE); pa_context_disconnect (control->priv->pa_context); + + control->priv->state = GVC_STATE_CLOSED; + g_signal_emit (G_OBJECT (control), signals[STATE_CHANGED], 0, GVC_STATE_CLOSED); return TRUE; } @@ -2125,22 +2132,14 @@ gvc_mixer_control_class_init (GvcMixerControlClass *klass) NULL, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - signals [CONNECTING] = - g_signal_new ("connecting", + signals [STATE_CHANGED] = + g_signal_new ("state-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GvcMixerControlClass, connecting), + G_STRUCT_OFFSET (GvcMixerControlClass, state_changed), NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals [READY] = - g_signal_new ("ready", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GvcMixerControlClass, ready), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); signals [STREAM_ADDED] = g_signal_new ("stream-added", G_TYPE_FROM_CLASS (klass), @@ -2212,6 +2211,8 @@ gvc_mixer_control_init (GvcMixerControl *control) control->priv->cards = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); control->priv->clients = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_free); + + control->priv->state = GVC_STATE_CLOSED; } static void diff --git a/src/gvc/gvc-mixer-control.h b/src/gvc/gvc-mixer-control.h index 3aa2c948e..598ca0193 100644 --- a/src/gvc/gvc-mixer-control.h +++ b/src/gvc/gvc-mixer-control.h @@ -27,6 +27,14 @@ G_BEGIN_DECLS +typedef enum +{ + GVC_STATE_CLOSED, + GVC_STATE_READY, + GVC_STATE_CONNECTING, + GVC_STATE_FAILED +} GvcMixerControlState; + #define GVC_TYPE_MIXER_CONTROL (gvc_mixer_control_get_type ()) #define GVC_MIXER_CONTROL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_CONTROL, GvcMixerControl)) #define GVC_MIXER_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_CONTROL, GvcMixerControlClass)) @@ -46,8 +54,8 @@ typedef struct { GObjectClass parent_class; - void (*connecting) (GvcMixerControl *control); - void (*ready) (GvcMixerControl *control); + void (*state_changed) (GvcMixerControl *control, + GvcMixerControlState new_state); void (*stream_added) (GvcMixerControl *control, guint id); void (*stream_removed) (GvcMixerControl *control, @@ -68,7 +76,6 @@ GvcMixerControl * gvc_mixer_control_new (const char *name); gboolean gvc_mixer_control_open (GvcMixerControl *control); gboolean gvc_mixer_control_close (GvcMixerControl *control); -gboolean gvc_mixer_control_is_ready (GvcMixerControl *control); GSList * gvc_mixer_control_get_cards (GvcMixerControl *control); GSList * gvc_mixer_control_get_streams (GvcMixerControl *control); @@ -94,6 +101,8 @@ gboolean gvc_mixer_control_set_default_source (GvcMixerControl *con gdouble gvc_mixer_control_get_vol_max_norm (GvcMixerControl *control); gdouble gvc_mixer_control_get_vol_max_amplified (GvcMixerControl *control); +GvcMixerControlState gvc_mixer_control_get_state (GvcMixerControl *control); + G_END_DECLS #endif /* __GVC_MIXER_CONTROL_H */