diff options
author | Richard Hughes <richard@hughsie.com> | 2015-05-18 12:51:05 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2015-05-19 13:27:33 +0100 |
commit | 8592d8f08b6befcfab2e412a6b1561ff404eff3e (patch) | |
tree | 5591c88c34c6e8dd87f949f9c3db6a0328f335a5 | |
parent | 173380f2672a2204099482b5abc096a839fd5d35 (diff) | |
download | gnome-settings-daemon-wip/rhughes/iio-proxy.tar.gz |
Add support for ambient light devices supported by iio-proxywip/rhughes/iio-proxy
-rw-r--r-- | data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in | 13 | ||||
-rw-r--r-- | plugins/power/gsd-power-manager.c | 124 |
2 files changed, 133 insertions, 4 deletions
diff --git a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in index 1fd60e73..52cede84 100644 --- a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in +++ b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in @@ -66,5 +66,18 @@ <summary>Battery critical low action</summary> <description>The action to take when the battery is critically low.</description> </key> + + <!-- ambient light sensor --> + <key name="ambient-enabled" type="b"> + <default>true</default> + <summary>Enable the ALS sensor</summary> + <description>If the ambient light sensor functionality is enabled.</description> + </key> + <key name="ambient-smooth" type="d"> + <default>0.3</default> + <summary>Backlight smoothing factor for the ambient light sensor</summary> + <description>The amount of backlight smoothing for ambient light changes.</description> + </key> + </schema> </schemalist> diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c index afe9405b..07cf42eb 100644 --- a/plugins/power/gsd-power-manager.c +++ b/plugins/power/gsd-power-manager.c @@ -1,7 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> - * Copyright (C) 2011-2012 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2011-2015 Richard Hughes <richard@hughsie.com> * Copyright (C) 2011 Ritesh Khadgaray <khadgaray@gmail.com> * Copyright (C) 2012-2013 Red Hat Inc. * @@ -157,6 +157,14 @@ struct GsdPowerManagerPrivate gint kbd_brightness_old; gint kbd_brightness_pre_dim; + /* Ambient */ + GDBusProxy *iio_proxy; + gboolean ambient_norm_required; + gdouble ambient_accumulator; + gdouble ambient_norm_value; + gdouble ambient_percentage_old; + gdouble ambient_last_absolute; + /* Sound */ guint32 critical_alert_timeout_id; @@ -2079,6 +2087,19 @@ idle_became_active_cb (GnomeIdleMonitor *monitor, } static void +ch_backlight_renormalize (GsdPowerManager *manager) +{ + if (manager->priv->ambient_percentage_old < 0) + return; + if (manager->priv->ambient_last_absolute < 0) + return; + manager->priv->ambient_norm_value = manager->priv->ambient_last_absolute / + (gdouble) manager->priv->ambient_percentage_old; + manager->priv->ambient_norm_value *= 100.f; + manager->priv->ambient_norm_required = FALSE; +} + +static void engine_settings_key_changed_cb (GSettings *settings, const gchar *key, GsdPowerManager *manager) @@ -2420,15 +2441,81 @@ on_rr_screen_acquired (GObject *object, /* queue a signal in case the proxy from gnome-shell was created before we got here (likely, considering that to get here we need a reply from gnome-shell) */ - if (manager->priv->backlight_available) + if (manager->priv->backlight_available) { + manager->priv->ambient_percentage_old = backlight_get_percentage (manager->priv->rr_screen, NULL); backlight_iface_emit_changed (manager, GSD_POWER_DBUS_INTERFACE_SCREEN, - backlight_get_percentage (manager->priv->rr_screen, NULL)); - else + manager->priv->ambient_percentage_old); + } else { backlight_iface_emit_changed (manager, GSD_POWER_DBUS_INTERFACE_SCREEN, -1); + } gnome_settings_profile_end (NULL); } +static void +iio_proxy_changed_cb (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + gpointer user_data) +{ + GsdPowerManager *manager = (GsdPowerManager *) user_data; + GError *error = NULL; + GVariant *val_has = NULL; + GVariant *val_lux = NULL; + gdouble alpha; + gdouble brightness; + gint pc; + + /* no display hardware */ + if (!manager->priv->backlight_available) + return; + + /* disabled */ + if (!g_settings_get_boolean (manager->priv->settings, "ambient-enabled")) + return; + + /* get latest results, which do not have to be Lux */ + val_has = g_dbus_proxy_get_cached_property (proxy, "HasAmbientLight"); + if (val_has == NULL || !g_variant_get_boolean (val_has)) + goto out; + val_lux = g_dbus_proxy_get_cached_property (proxy, "LightLevel"); + if (val_lux == NULL) + goto out; + manager->priv->ambient_last_absolute = g_variant_get_double (val_lux); + + /* the user has asked to renormalize */ + if (manager->priv->ambient_norm_required) { + manager->priv->ambient_accumulator = manager->priv->ambient_percentage_old; + ch_backlight_renormalize (manager); + } + + /* calculate exponential moving average */ + alpha = g_settings_get_double (manager->priv->settings, "ambient-smooth"); + brightness = manager->priv->ambient_last_absolute * 100.f / manager->priv->ambient_norm_value; + brightness = MIN (brightness, 100.f); + brightness = MAX (brightness, 0.f); + manager->priv->ambient_accumulator = (alpha * brightness) + (1.0 - alpha) * manager->priv->ambient_accumulator; + + /* no valid readings yet */ + if (manager->priv->ambient_accumulator < 0.f) + goto out; + + /* set new value */ + g_debug ("set brightness from ambient %.1f%%", + manager->priv->ambient_accumulator); + pc = manager->priv->ambient_accumulator; + if (!backlight_set_percentage (manager->priv->rr_screen, &pc, &error)) { + g_warning ("failed to set brightness: %s", error->message); + g_error_free (error); + } + manager->priv->ambient_percentage_old = pc; +out: + if (val_has != NULL) + g_variant_unref (val_has); + if (val_lux != NULL) + g_variant_unref (val_lux); +} + gboolean gsd_power_manager_start (GsdPowerManager *manager, GError **error) @@ -2472,6 +2559,26 @@ gsd_power_manager_start (GsdPowerManager *manager, manager->priv->settings_bus = g_settings_new ("org.gnome.desktop.session"); manager->priv->settings_xrandr = g_settings_new (GSD_XRANDR_SETTINGS_SCHEMA); + /* setup ambient light support */ + manager->priv->iio_proxy = + g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + 0, + NULL, + "net.hadess.SensorProxy", + "/net/hadess/SensorProxy", + "net.hadess.SensorProxy", + NULL, + error); + if (manager->priv->iio_proxy != NULL) { + g_signal_connect (manager->priv->iio_proxy, "g-properties-changed", + G_CALLBACK (iio_proxy_changed_cb), manager); + } + manager->priv->ambient_norm_required = TRUE; + manager->priv->ambient_accumulator = -1.f; + manager->priv->ambient_norm_value = -1.f; + manager->priv->ambient_percentage_old = -1.f; + manager->priv->ambient_last_absolute = -1.f; + gnome_settings_profile_end (NULL); return TRUE; } @@ -2507,6 +2614,7 @@ gsd_power_manager_stop (GsdPowerManager *manager) g_clear_object (&manager->priv->settings_screensaver); g_clear_object (&manager->priv->settings_bus); g_clear_object (&manager->priv->up_client); + g_clear_object (&manager->priv->iio_proxy); if (manager->priv->inhibit_lid_switch_fd != -1) { close (manager->priv->inhibit_lid_switch_fd); @@ -2629,6 +2737,10 @@ handle_method_call_screen (GsdPowerManager *manager, g_assert_not_reached (); } + /* ambient brightness no longer valid */ + manager->priv->ambient_percentage_old = value; + manager->priv->ambient_norm_required = TRUE; + out: /* return value */ if (value < 0) { @@ -2755,6 +2867,10 @@ handle_set_property_other (GsdPowerManager *manager, g_variant_get (value, "i", &brightness_value); if (backlight_set_percentage (manager->priv->rr_screen, &brightness_value, error)) { backlight_iface_emit_changed (manager, GSD_POWER_DBUS_INTERFACE_SCREEN, brightness_value); + + /* ambient brightness no longer valid */ + manager->priv->ambient_percentage_old = brightness_value; + manager->priv->ambient_norm_required = TRUE; return TRUE; } else { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, |