aboutsummaryrefslogtreecommitdiff
path: root/src/volume-warning.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/volume-warning.vala')
-rw-r--r--src/volume-warning.vala408
1 files changed, 204 insertions, 204 deletions
diff --git a/src/volume-warning.vala b/src/volume-warning.vala
index 659240b..24f90e3 100644
--- a/src/volume-warning.vala
+++ b/src/volume-warning.vala
@@ -23,208 +23,208 @@ using PulseAudio;
public abstract class VolumeWarning : Object
{
- // true if headphones are in use
- public bool headphones_active { get; set; default = false; }
-
- // true if the warning dialog is being shown
- public bool active { get; protected set; default = false; }
-
- // true if we're playing unapproved loud multimedia over headphones
- public bool high_volume { get; protected set; default = false; }
-
- public enum Key {
- VOLUME_UP,
- VOLUME_DOWN
- }
-
- public void user_keypress (Key key) {
- if ((key == Key.VOLUME_DOWN) && active) {
- _notification.close ();
- on_user_response (IndicatorSound.WarnNotification.Response.CANCEL);
- }
- }
-
- internal VolumeWarning (IndicatorSound.Options options) {
-
- _options = options;
-
- init_high_volume ();
- init_approved ();
-
- _notification.user_responded.connect ((n, r) => on_user_response (r));
- }
-
- ~VolumeWarning () {
- clear_timer (ref _approved_timer);
- }
-
- /***
- ****
- ***/
-
- // true if the user has approved high volumes recently
- protected bool approved { get; set; default = false; }
-
- // true if multimedia is currently playing
- protected bool multimedia_active { get; set; default = false; }
-
- /* Cached value of the multimedia volume reported by pulse.
- Setting this only updates the cache -- to change the volume,
- use sound_system_set_multimedia_volume.
- NB: This PulseAudio.Volume is typed as uint to unconfuse valac. */
- protected uint multimedia_volume { get; set; default = PulseAudio.Volume.INVALID; }
-
- protected abstract void sound_system_set_multimedia_volume (PulseAudio.Volume volume);
-
- protected void clear_timer (ref uint timer) {
- if (timer != 0) {
- Source.remove (timer);
- timer = 0;
- }
- }
-
- private IndicatorSound.Options _options;
-
- /**
- *** HIGH VOLUME PROPERTY
- **/
-
- private void init_high_volume () {
- const string self_keys[] = {
- "multimedia-volume",
- "multimedia-active",
- "headphones-active",
- "high-volume-approved"
- };
- foreach (var key in self_keys)
- this.notify[key].connect (() => update_high_volume ());
-
- const string options_keys[] = {
- "loud-volume",
- "loud-warning-enabled"
- };
- foreach (var key in options_keys)
- _options.notify[key].connect (() => update_high_volume ());
-
- update_high_volume ();
- }
-
- private void update_high_volume () {
-
- var newval = _options.loud_warning_enabled
- && headphones_active
- && multimedia_active
- && !approved
- && (multimedia_volume != PulseAudio.Volume.INVALID)
- // from the sound specs:
- // "Whenever you increase volume,..., such that acoustic output would be MORE than 85 dB
- && (multimedia_volume > _options.loud_volume);
-
- if (high_volume != newval) {
- debug ("changing high_volume from %d to %d", (int)high_volume, (int)newval);
- if (newval && !active)
- activate ();
- high_volume = newval;
- }
- }
-
- /**
- *** HIGH VOLUME APPROVED PROPERTY
- **/
-
- private Settings _settings = new Settings ("org.ayatana.indicator.sound");
- private static const string TTL_KEY = "warning-volume-confirmation-ttl";
- private uint _approved_timer = 0;
- private int64 _approved_at = 0;
- private int64 _approved_ttl_usec = 0;
-
- private void approve_high_volume () {
- _approved_at = GLib.get_monotonic_time ();
- update_approved ();
- update_approved_timer ();
- }
-
- private void init_approved () {
- _settings.changed[TTL_KEY].connect (() => update_approved_cache ());
- update_approved_cache ();
- }
- private void update_approved_cache () {
- _approved_ttl_usec = _settings.get_int (TTL_KEY);
- _approved_ttl_usec *= 1000000;
-
- update_approved ();
- update_approved_timer ();
- }
- private void update_approved_timer () {
-
- clear_timer (ref _approved_timer);
-
- if (_approved_at == 0)
- return;
-
- int64 expires_at = _approved_at + _approved_ttl_usec;
- int64 now = GLib.get_monotonic_time ();
- if (expires_at > now) {
- var seconds_left = 1 + ((expires_at - now) / 1000000);
- _approved_timer = Timeout.add_seconds ((uint)seconds_left, () => {
- _approved_timer = 0;
- update_approved ();
- return Source.REMOVE;
- });
- }
- }
- private void update_approved () {
- var new_approved = calculate_approved ();
- if (approved != new_approved) {
- debug ("changing approved from %d to %d", (int)approved, (int)new_approved);
- approved = new_approved;
- }
- }
- private bool calculate_approved () {
- int64 now = GLib.get_monotonic_time ();
- return (_approved_at != 0)
- && (_approved_at + _approved_ttl_usec >= now);
- }
-
- // NOTIFICATION
-
- private IndicatorSound.WarnNotification _notification = new IndicatorSound.WarnNotification ();
- private PulseAudio.Volume _ok_volume = PulseAudio.Volume.INVALID;
-
- protected virtual void preshow () {}
-
- private void activate () {
- preshow ();
- _ok_volume = multimedia_volume;
-
- _notification.show ();
- this.active = true;
-
- // lower the volume to just the warning level
- // from the sound specs:
- // "Whenever you increase volume,..., such that acoustic output would be MORE than 85 dB
- sound_system_set_multimedia_volume (_options.loud_volume);
- }
-
- private void on_user_response (IndicatorSound.WarnNotification.Response response) {
-
- this.active = false;
-
- if (response == IndicatorSound.WarnNotification.Response.OK) {
- approve_high_volume ();
- sound_system_set_multimedia_volume (_ok_volume);
- } else {
- this.cancel_pressed (this.volume_to_double(_options.loud_volume));
- }
-
- _ok_volume = PulseAudio.Volume.INVALID;
- }
-
- private static double volume_to_double (PulseAudio.Volume vol)
- {
- double tmp = (double)(vol - PulseAudio.Volume.MUTED);
- return tmp / (double)(PulseAudio.Volume.NORM - PulseAudio.Volume.MUTED);
- }
-
- public signal void cancel_pressed (double cancel_volume);
+ // true if headphones are in use
+ public bool headphones_active { get; set; default = false; }
+
+ // true if the warning dialog is being shown
+ public bool active { get; protected set; default = false; }
+
+ // true if we're playing unapproved loud multimedia over headphones
+ public bool high_volume { get; protected set; default = false; }
+
+ public enum Key {
+ VOLUME_UP,
+ VOLUME_DOWN
+ }
+
+ public void user_keypress (Key key) {
+ if ((key == Key.VOLUME_DOWN) && active) {
+ _notification.close ();
+ on_user_response (IndicatorSound.WarnNotification.Response.CANCEL);
+ }
+ }
+
+ internal VolumeWarning (IndicatorSound.Options options) {
+
+ _options = options;
+
+ init_high_volume ();
+ init_approved ();
+
+ _notification.user_responded.connect ((n, r) => on_user_response (r));
+ }
+
+ ~VolumeWarning () {
+ clear_timer (ref _approved_timer);
+ }
+
+ /***
+ ****
+ ***/
+
+ // true if the user has approved high volumes recently
+ protected bool approved { get; set; default = false; }
+
+ // true if multimedia is currently playing
+ protected bool multimedia_active { get; set; default = false; }
+
+ /* Cached value of the multimedia volume reported by pulse.
+ Setting this only updates the cache -- to change the volume,
+ use sound_system_set_multimedia_volume.
+ NB: This PulseAudio.Volume is typed as uint to unconfuse valac. */
+ protected uint multimedia_volume { get; set; default = PulseAudio.Volume.INVALID; }
+
+ protected abstract void sound_system_set_multimedia_volume (PulseAudio.Volume volume);
+
+ protected void clear_timer (ref uint timer) {
+ if (timer != 0) {
+ Source.remove (timer);
+ timer = 0;
+ }
+ }
+
+ private IndicatorSound.Options _options;
+
+ /**
+ *** HIGH VOLUME PROPERTY
+ **/
+
+ private void init_high_volume () {
+ const string self_keys[] = {
+ "multimedia-volume",
+ "multimedia-active",
+ "headphones-active",
+ "high-volume-approved"
+ };
+ foreach (var key in self_keys)
+ this.notify[key].connect (() => update_high_volume ());
+
+ const string options_keys[] = {
+ "loud-volume",
+ "loud-warning-enabled"
+ };
+ foreach (var key in options_keys)
+ _options.notify[key].connect (() => update_high_volume ());
+
+ update_high_volume ();
+ }
+
+ private void update_high_volume () {
+
+ var newval = _options.loud_warning_enabled
+ && headphones_active
+ && multimedia_active
+ && !approved
+ && (multimedia_volume != PulseAudio.Volume.INVALID)
+ // from the sound specs:
+ // "Whenever you increase volume,..., such that acoustic output would be MORE than 85 dB
+ && (multimedia_volume > _options.loud_volume);
+
+ if (high_volume != newval) {
+ debug ("changing high_volume from %d to %d", (int)high_volume, (int)newval);
+ if (newval && !active)
+ activate ();
+ high_volume = newval;
+ }
+ }
+
+ /**
+ *** HIGH VOLUME APPROVED PROPERTY
+ **/
+
+ private Settings _settings = new Settings ("org.ayatana.indicator.sound");
+ private static const string TTL_KEY = "warning-volume-confirmation-ttl";
+ private uint _approved_timer = 0;
+ private int64 _approved_at = 0;
+ private int64 _approved_ttl_usec = 0;
+
+ private void approve_high_volume () {
+ _approved_at = GLib.get_monotonic_time ();
+ update_approved ();
+ update_approved_timer ();
+ }
+
+ private void init_approved () {
+ _settings.changed[TTL_KEY].connect (() => update_approved_cache ());
+ update_approved_cache ();
+ }
+ private void update_approved_cache () {
+ _approved_ttl_usec = _settings.get_int (TTL_KEY);
+ _approved_ttl_usec *= 1000000;
+
+ update_approved ();
+ update_approved_timer ();
+ }
+ private void update_approved_timer () {
+
+ clear_timer (ref _approved_timer);
+
+ if (_approved_at == 0)
+ return;
+
+ int64 expires_at = _approved_at + _approved_ttl_usec;
+ int64 now = GLib.get_monotonic_time ();
+ if (expires_at > now) {
+ var seconds_left = 1 + ((expires_at - now) / 1000000);
+ _approved_timer = Timeout.add_seconds ((uint)seconds_left, () => {
+ _approved_timer = 0;
+ update_approved ();
+ return Source.REMOVE;
+ });
+ }
+ }
+ private void update_approved () {
+ var new_approved = calculate_approved ();
+ if (approved != new_approved) {
+ debug ("changing approved from %d to %d", (int)approved, (int)new_approved);
+ approved = new_approved;
+ }
+ }
+ private bool calculate_approved () {
+ int64 now = GLib.get_monotonic_time ();
+ return (_approved_at != 0)
+ && (_approved_at + _approved_ttl_usec >= now);
+ }
+
+ // NOTIFICATION
+
+ private IndicatorSound.WarnNotification _notification = new IndicatorSound.WarnNotification ();
+ private PulseAudio.Volume _ok_volume = PulseAudio.Volume.INVALID;
+
+ protected virtual void preshow () {}
+
+ private void activate () {
+ preshow ();
+ _ok_volume = multimedia_volume;
+
+ _notification.show ();
+ this.active = true;
+
+ // lower the volume to just the warning level
+ // from the sound specs:
+ // "Whenever you increase volume,..., such that acoustic output would be MORE than 85 dB
+ sound_system_set_multimedia_volume (_options.loud_volume);
+ }
+
+ private void on_user_response (IndicatorSound.WarnNotification.Response response) {
+
+ this.active = false;
+
+ if (response == IndicatorSound.WarnNotification.Response.OK) {
+ approve_high_volume ();
+ sound_system_set_multimedia_volume (_ok_volume);
+ } else {
+ this.cancel_pressed (this.volume_to_double(_options.loud_volume));
+ }
+
+ _ok_volume = PulseAudio.Volume.INVALID;
+ }
+
+ private static double volume_to_double (PulseAudio.Volume vol)
+ {
+ double tmp = (double)(vol - PulseAudio.Volume.MUTED);
+ return tmp / (double)(PulseAudio.Volume.NORM - PulseAudio.Volume.MUTED);
+ }
+
+ public signal void cancel_pressed (double cancel_volume);
}