diff options
author | Ted Gould <ted@gould.cx> | 2013-10-28 17:49:04 -0700 |
---|---|---|
committer | Ted Gould <ted@gould.cx> | 2013-10-28 17:49:04 -0700 |
commit | 4f6b673281fecd22c618c700af0bd798ee5c26f1 (patch) | |
tree | 9bc4564892d82786c6e00c446dda58bb100c9e9c /src/volume-control.vala | |
parent | fd5fc9ed4aca0753779432de3ccc60cce6499af3 (diff) | |
parent | a440eb1df8296a6b431613ec03aac94db38292c6 (diff) | |
download | ayatana-indicator-sound-4f6b673281fecd22c618c700af0bd798ee5c26f1.tar.gz ayatana-indicator-sound-4f6b673281fecd22c618c700af0bd798ee5c26f1.tar.bz2 ayatana-indicator-sound-4f6b673281fecd22c618c700af0bd798ee5c26f1.zip |
Merge trunk
Diffstat (limited to 'src/volume-control.vala')
-rw-r--r-- | src/volume-control.vala | 122 |
1 files changed, 84 insertions, 38 deletions
diff --git a/src/volume-control.vala b/src/volume-control.vala index 9475f53..c6db38c 100644 --- a/src/volume-control.vala +++ b/src/volume-control.vala @@ -27,6 +27,8 @@ public class VolumeControl : Object /* this is static to ensure it being freed after @context (loop does not have ref counting) */ private static PulseAudio.GLibMainLoop loop; + private uint _reconnect_timer = 0; + private PulseAudio.Context context; private bool _mute = true; private double _volume = 0.0; @@ -46,20 +48,13 @@ public class VolumeControl : Object if (loop == null) loop = new PulseAudio.GLibMainLoop (); - var props = new Proplist (); - props.sets (Proplist.PROP_APPLICATION_NAME, "Ubuntu Audio Settings"); - props.sets (Proplist.PROP_APPLICATION_ID, "com.canonical.settings.sound"); - props.sets (Proplist.PROP_APPLICATION_ICON_NAME, "multimedia-volume-control"); - props.sets (Proplist.PROP_APPLICATION_VERSION, "0.1"); - - context = new PulseAudio.Context (loop.get_api(), null, props); - - context.set_state_callback (context_state_callback); + this.reconnect_to_pulse (); + } - if (context.connect(null, Context.Flags.NOFAIL, null) < 0) - { - warning( "pa_context_connect() failed: %s\n", PulseAudio.strerror(context.errno())); - return; + ~VolumeControl () + { + if (_reconnect_timer != 0) { + Source.remove (_reconnect_timer); } } @@ -133,12 +128,14 @@ public class VolumeControl : Object context.get_server_info (server_info_cb_for_props); } + private void update_source_get_server_info_cb (PulseAudio.Context c, PulseAudio.ServerInfo? i) { + if (i != null) + context.get_source_info_by_name (i.default_source_name, source_info_cb); + } + private void update_source () { - context.get_server_info ( (c, i) => { - if (i != null) - context.get_source_info_by_name (i.default_source_name, source_info_cb); - }); + context.get_server_info (update_source_get_server_info_cb); } private void source_output_info_cb (Context c, SourceOutputInfo? i, int eol) @@ -153,18 +150,65 @@ public class VolumeControl : Object private void context_state_callback (Context c) { - if (c.get_state () == Context.State.READY) - { - c.subscribe (PulseAudio.Context.SubscriptionMask.SINK | - PulseAudio.Context.SubscriptionMask.SOURCE | - PulseAudio.Context.SubscriptionMask.SOURCE_OUTPUT); - c.set_subscribe_callback (context_events_cb); - update_sink (); - update_source (); - this.ready = true; + switch (c.get_state ()) { + case Context.State.READY: + c.subscribe (PulseAudio.Context.SubscriptionMask.SINK | + PulseAudio.Context.SubscriptionMask.SOURCE | + PulseAudio.Context.SubscriptionMask.SOURCE_OUTPUT); + c.set_subscribe_callback (context_events_cb); + update_sink (); + update_source (); + this.ready = true; + break; + + case Context.State.FAILED: + case Context.State.TERMINATED: + if (_reconnect_timer == 0) + _reconnect_timer = Timeout.add_seconds (2, reconnect_timeout); + break; + + default: + this.ready = false; + break; } - else + } + + bool reconnect_timeout () + { + _reconnect_timer = 0; + reconnect_to_pulse (); + return false; // G_SOURCE_REMOVE + } + + void reconnect_to_pulse () + { + if (this.ready) { + this.context.disconnect (); + this.context = null; this.ready = false; + } + + var props = new Proplist (); + props.sets (Proplist.PROP_APPLICATION_NAME, "Ubuntu Audio Settings"); + props.sets (Proplist.PROP_APPLICATION_ID, "com.canonical.settings.sound"); + props.sets (Proplist.PROP_APPLICATION_ICON_NAME, "multimedia-volume-control"); + props.sets (Proplist.PROP_APPLICATION_VERSION, "0.1"); + + this.context = new PulseAudio.Context (loop.get_api(), null, props); + this.context.set_state_callback (context_state_callback); + + if (context.connect(null, Context.Flags.NOFAIL, null) < 0) + warning( "pa_context_connect() failed: %s\n", PulseAudio.strerror(context.errno())); + } + + void sink_info_list_callback_set_mute (PulseAudio.Context context, PulseAudio.SinkInfo? sink, int eol) { + if (sink != null) + context.set_sink_mute_by_index (sink.index, true, null); + } + + void sink_info_list_callback_unset_mute (PulseAudio.Context context, PulseAudio.SinkInfo? sink, int eol) { + if (sink != null) + context.set_sink_mute_by_index (sink.index, false, null); } /* Mute operations */ @@ -172,10 +216,10 @@ public class VolumeControl : Object { return_if_fail (context.get_state () == Context.State.READY); - context.get_sink_info_list ((context, sink, eol) => { - if (sink != null) - context.set_sink_mute_by_index (sink.index, mute, null); - }); + if (mute) + context.get_sink_info_list (sink_info_list_callback_set_mute); + else + context.get_sink_info_list (sink_info_list_callback_unset_mute); } public void toggle_mute () @@ -245,19 +289,21 @@ public class VolumeControl : Object mic_volume_changed (_mic_volume); } + void set_mic_volume_get_server_info_cb (PulseAudio.Context c, PulseAudio.ServerInfo? i) { + if (i != null) { + unowned CVolume cvol = CVolume (); + cvol = vol_set (cvol, 1, double_to_volume (_mic_volume)); + c.set_source_volume_by_name (i.default_source_name, cvol, set_mic_volume_success_cb); + } + } + public void set_mic_volume (double volume) { return_if_fail (context.get_state () == Context.State.READY); _mic_volume = volume; - context.get_server_info ( (c, i) => { - if (i != null) { - unowned CVolume cvol = CVolume (); - cvol = vol_set (cvol, 1, double_to_volume (_mic_volume)); - c.set_source_volume_by_name (i.default_source_name, cvol, set_mic_volume_success_cb); - } - }); + context.get_server_info (set_mic_volume_get_server_info_cb); } public double get_volume () |