[gnome-settings-daemon] power: Fall back to the backlight helper if xbacklight is not available
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] power: Fall back to the backlight helper if xbacklight is not available
- Date: Thu, 4 Aug 2011 16:56:19 +0000 (UTC)
commit 89430d59412a6057c8436b30aeb605b951418cfe
Author: Richard Hughes <richard hughsie com>
Date: Wed Aug 3 17:09:03 2011 +0100
power: Fall back to the backlight helper if xbacklight is not available
NOTE: we still prefer xbacklight, and if xbacklight is present but does not
work we do not fall back to sysfs. Madness would ensue if we did that...
plugins/power/Makefile.am | 1 +
plugins/power/gsd-power-manager.c | 404 ++++++++++++++++++++++++++++++-------
2 files changed, 335 insertions(+), 70 deletions(-)
---
diff --git a/plugins/power/Makefile.am b/plugins/power/Makefile.am
index 5fee2dd..10099f4 100644
--- a/plugins/power/Makefile.am
+++ b/plugins/power/Makefile.am
@@ -22,6 +22,7 @@ libpower_la_CPPFLAGS = \
-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
-DGTKBUILDERDIR=\""$(pkgdatadir)"\" \
-DSBINDIR=\"$(sbindir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
$(AM_CPPFLAGS)
libpower_la_CFLAGS = \
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
index b845fd5..f7ffd6b 100644
--- a/plugins/power/gsd-power-manager.c
+++ b/plugins/power/gsd-power-manager.c
@@ -2182,7 +2182,9 @@ get_primary_output (GsdPowerManager *manager)
for (i = 0; outputs[i] != NULL; i++) {
if (gnome_rr_output_is_connected (outputs[i]) &&
- gnome_rr_output_is_laptop (outputs[i])) {
+ gnome_rr_output_is_laptop (outputs[i]) &&
+ gnome_rr_output_get_backlight_min (outputs[i]) >= 0 &&
+ gnome_rr_output_get_backlight_max (outputs[i]) > 0) {
output = outputs[i];
break;
}
@@ -2191,15 +2193,330 @@ out:
return output;
}
+/**
+ * backlight_helper_get_value:
+ *
+ * Gets a brightness value from the PolicyKit helper.
+ *
+ * Return value: the signed integer value from the helper, or -1
+ * for failure. If -1 then @error is set.
+ **/
+static gint
+backlight_helper_get_value (const gchar *argument, GError **error)
+{
+ gboolean ret;
+ gchar *stdout_data = NULL;
+ gint exit_status = 0;
+ guint64 value = -1;
+ gchar *command = NULL;
+ gchar *endptr = NULL;
+
+#ifndef __linux__
+ /* non-Linux platforms won't have /sys/class/backlight */
+ g_set_error_literal (error,
+ GSD_POWER_MANAGER_ERROR,
+ GSD_POWER_MANAGER_ERROR_FAILED,
+ "The sysfs backlight helper is only for Linux");
+ goto out;
+#endif
+
+ /* get the data */
+ command = g_strdup_printf (LIBEXECDIR "/gsd-backlight-helper --%s",
+ argument);
+ ret = g_spawn_command_line_sync (command,
+ &stdout_data,
+ NULL,
+ &exit_status,
+ error);
+ if (!ret)
+ goto out;
+
+ g_debug ("executed %s retval: %i", command, exit_status);
+
+ /* parse */
+ value = g_ascii_strtoull (stdout_data, &endptr, 10);
+
+ /* parsing error */
+ if (endptr == stdout_data) {
+ g_set_error (error,
+ GSD_POWER_MANAGER_ERROR,
+ GSD_POWER_MANAGER_ERROR_FAILED,
+ "failed to parse value: %s",
+ stdout_data);
+ goto out;
+ }
+
+ /* out of range */
+ if (value > G_MAXINT) {
+ value = -1;
+ g_set_error (error,
+ GSD_POWER_MANAGER_ERROR,
+ GSD_POWER_MANAGER_ERROR_FAILED,
+ "value out of range: %s",
+ stdout_data);
+ goto out;
+ }
+
+out:
+ g_free (command);
+ g_free (stdout_data);
+ return value;
+}
+
+/**
+ * backlight_helper_set_value:
+ *
+ * Sets a brightness value using the PolicyKit helper.
+ *
+ * Return value: Success. If FALSE then @error is set.
+ **/
+static gboolean
+backlight_helper_set_value (const gchar *argument,
+ gint value,
+ GError **error)
+{
+ gboolean ret;
+ gint exit_status = 0;
+ gchar *command = NULL;
+
+#ifndef __linux__
+ /* non-Linux platforms won't have /sys/class/backlight */
+ g_set_error_literal (error,
+ GSD_POWER_MANAGER_ERROR,
+ GSD_POWER_MANAGER_ERROR_FAILED,
+ "The sysfs backlight helper is only for Linux");
+ goto out;
+#endif
+
+ /* get the data */
+ command = g_strdup_printf ("pkexec " LIBEXECDIR "/gsd-backlight-helper --%s %i",
+ argument, value);
+ ret = g_spawn_command_line_sync (command,
+ NULL,
+ NULL,
+ &exit_status,
+ error);
+ if (!ret)
+ goto out;
+
+ g_debug ("executed %s retval: %i", command, exit_status);
+out:
+ g_free (command);
+ return ret;
+}
+
+static gint
+backlight_get_abs (GsdPowerManager *manager, GError **error)
+{
+ GnomeRROutput *output;
+ guint value;
+
+ /* prefer xbacklight */
+ output = get_primary_output (manager);
+ if (output != NULL) {
+ value = gnome_rr_output_get_backlight (output,
+ error);
+ goto out;
+ }
+
+ /* fall back to the polkit helper */
+ value = backlight_helper_get_value ("get-brightness", error);
+out:
+ return value;
+}
+
+static gint
+backlight_get_percentage (GsdPowerManager *manager, GError **error)
+{
+ GnomeRROutput *output;
+ guint now;
+ guint value = -1;
+ gint min = 0;
+ gint max;
+
+ /* prefer xbacklight */
+ output = get_primary_output (manager);
+ if (output != NULL) {
+
+ min = gnome_rr_output_get_backlight_min (output);
+ max = gnome_rr_output_get_backlight_max (output);
+ now = gnome_rr_output_get_backlight (output, error);
+ if (now < 0)
+ goto out;
+ value = ABS_TO_PERCENTAGE (min, max, now);
+ goto out;
+ }
+
+ /* fall back to the polkit helper */
+ max = backlight_helper_get_value ("get-max-brightness", error);
+ if (max < 0)
+ goto out;
+ now = backlight_helper_get_value ("get-brightness", error);
+ if (now < 0)
+ goto out;
+ value = ABS_TO_PERCENTAGE (min, max, now);
+out:
+ return value;
+}
+
+static gboolean
+backlight_set_percentage (GsdPowerManager *manager,
+ guint value,
+ GError **error)
+{
+ GnomeRROutput *output;
+ gboolean ret = FALSE;
+ gint min = 0;
+ gint max;
+ guint discrete;
+
+ /* prefer xbacklight */
+ output = get_primary_output (manager);
+ if (output != NULL) {
+ min = gnome_rr_output_get_backlight_min (output);
+ max = gnome_rr_output_get_backlight_max (output);
+ if (min < 0 || max < 0) {
+ g_warning ("no xrandr backlight capability");
+ goto out;
+ }
+ discrete = PERCENTAGE_TO_ABS (min, max, value);
+ ret = gnome_rr_output_set_backlight (output,
+ discrete,
+ error);
+ goto out;
+ }
+
+ /* fall back to the polkit helper */
+ max = backlight_helper_get_value ("get-max-brightness", error);
+ if (max < 0)
+ goto out;
+ discrete = PERCENTAGE_TO_ABS (min, max, value);
+ ret = backlight_helper_set_value ("set-brightness",
+ discrete,
+ error);
+out:
+ return ret;
+}
+
+static gboolean
+backlight_step_up (GsdPowerManager *manager, GError **error)
+{
+ GnomeRROutput *output;
+ gboolean ret = FALSE;
+ gint min = 0;
+ gint max;
+ gint now;
+ guint discrete;
+ guint step;
+
+ /* prefer xbacklight */
+ output = get_primary_output (manager);
+ if (output != NULL) {
+
+ min = gnome_rr_output_get_backlight_min (output);
+ max = gnome_rr_output_get_backlight_max (output);
+ now = gnome_rr_output_get_backlight (output, error);
+ if (now < 0)
+ goto out;
+ step = BRIGHTNESS_STEP_AMOUNT (max - min + 1);
+ discrete = MIN (now + step, max);
+ ret = gnome_rr_output_set_backlight (output,
+ discrete,
+ error);
+ goto out;
+ }
+
+ /* fall back to the polkit helper */
+ now = backlight_helper_get_value ("get-brightness", error);
+ if (now < 0)
+ goto out;
+ max = backlight_helper_get_value ("get-max-brightness", error);
+ if (max < 0)
+ goto out;
+ step = BRIGHTNESS_STEP_AMOUNT (max - min + 1);
+ discrete = MIN (now + step, max);
+ ret = backlight_helper_set_value ("set-brightness",
+ discrete,
+ error);
+out:
+ return ret;
+}
+
+static gboolean
+backlight_step_down (GsdPowerManager *manager, GError **error)
+{
+ GnomeRROutput *output;
+ gboolean ret = FALSE;
+ gint min = 0;
+ gint max;
+ gint now;
+ guint discrete;
+ guint step;
+
+ /* prefer xbacklight */
+ output = get_primary_output (manager);
+ if (output != NULL) {
+
+ min = gnome_rr_output_get_backlight_min (output);
+ max = gnome_rr_output_get_backlight_max (output);
+ now = gnome_rr_output_get_backlight (output, error);
+ if (now < 0)
+ goto out;
+ step = BRIGHTNESS_STEP_AMOUNT (max - min + 1);
+ discrete = MAX (now - step, 0);
+ ret = gnome_rr_output_set_backlight (output,
+ discrete,
+ error);
+ goto out;
+ }
+
+ /* fall back to the polkit helper */
+ now = backlight_helper_get_value ("get-brightness", error);
+ if (now < 0)
+ goto out;
+ max = backlight_helper_get_value ("get-max-brightness", error);
+ if (max < 0)
+ goto out;
+ step = BRIGHTNESS_STEP_AMOUNT (max - min + 1);
+ discrete = MAX (now - step, 0);
+ ret = backlight_helper_set_value ("set-brightness",
+ discrete,
+ error);
+out:
+ return ret;
+}
+
+static gint
+backlight_set_abs (GsdPowerManager *manager,
+ guint value,
+ GError **error)
+{
+ GnomeRROutput *output;
+ gboolean ret = FALSE;
+
+ /* prefer xbacklight */
+ output = get_primary_output (manager);
+ if (output != NULL) {
+ ret = gnome_rr_output_set_backlight (output,
+ value,
+ error);
+ goto out;
+ }
+
+ /* fall back to the polkit helper */
+ ret = backlight_helper_set_value ("set-brightness",
+ value,
+ error);
+out:
+ return ret;
+}
+
static void
idle_set_mode (GsdPowerManager *manager, GsdPowerIdleMode mode)
{
gboolean ret = FALSE;
GError *error = NULL;
gint idle_brigntness;
- gint min, max;
- gint value;
- GnomeRROutput *output;
GsdPowerActionType action_type;
if (mode == manager->priv->current_idle_mode)
@@ -2210,13 +2527,7 @@ idle_set_mode (GsdPowerManager *manager, GsdPowerIdleMode mode)
/* save current brightness, and set dim level */
if (mode == GSD_POWER_IDLE_MODE_DIM) {
- output = get_primary_output (manager);
- if (output == NULL) {
- g_debug ("no laptop screen to control");
- return;
- }
- manager->priv->pre_dim_brightness = gnome_rr_output_get_backlight (output,
- &error);
+ manager->priv->pre_dim_brightness = backlight_get_abs (manager, &error);
if (manager->priv->pre_dim_brightness < 0) {
g_warning ("failed to get existing backlight: %s",
error->message);
@@ -2225,16 +2536,9 @@ idle_set_mode (GsdPowerManager *manager, GsdPowerIdleMode mode)
}
idle_brigntness = g_settings_get_int (manager->priv->settings,
"idle-brightness");
- min = gnome_rr_output_get_backlight_min (output);
- max = gnome_rr_output_get_backlight_max (output);
- if (min < 0 || max < 0) {
- g_warning ("no xrandr backlight capability");
- return;
- }
- value = PERCENTAGE_TO_ABS (min, max, idle_brigntness);
- ret = gnome_rr_output_set_backlight (output,
- value,
- &error);
+ ret = backlight_set_percentage (manager,
+ idle_brigntness,
+ &error);
if (!ret) {
g_warning ("failed to set dim backlight to %i: %s",
idle_brigntness,
@@ -2280,14 +2584,9 @@ idle_set_mode (GsdPowerManager *manager, GsdPowerIdleMode mode)
g_clear_error (&error);
}
- output = get_primary_output (manager);
- if (output == NULL) {
- g_debug ("no laptop screen to control");
- return;
- }
- ret = gnome_rr_output_set_backlight (output,
- manager->priv->pre_dim_brightness,
- &error);
+ ret = backlight_set_abs (manager,
+ manager->priv->pre_dim_brightness,
+ &error);
if (!ret) {
g_warning ("failed to restore backlight to %i: %s",
manager->priv->pre_dim_brightness,
@@ -3088,75 +3387,40 @@ handle_method_call_screen (GsdPowerManager *manager,
GDBusMethodInvocation *invocation)
{
gboolean ret = FALSE;
- gint min, max, now;
- guint step;
gint value = -1;
guint value_tmp;
- guint percentage;
- GnomeRROutput *output;
GError *error = NULL;
- /* get the laptop screen only */
- output = get_primary_output (manager);
- if (output == NULL) {
- g_dbus_method_invocation_return_error (invocation,
- GSD_POWER_MANAGER_ERROR,
- GSD_POWER_MANAGER_ERROR_FAILED,
- "no laptop screen to control");
- return;
- }
-
- /* get capabilities (cached) */
- min = gnome_rr_output_get_backlight_min (output);
- max = gnome_rr_output_get_backlight_max (output);
- if (min < 0 || max < 0) {
- g_dbus_method_invocation_return_error (invocation,
- GSD_POWER_MANAGER_ERROR,
- GSD_POWER_MANAGER_ERROR_FAILED,
- "no xrandr backlight capability");
- return;
- }
-
- /* get what we are now */
- now = gnome_rr_output_get_backlight (output, &error);
- if (now < 0)
- goto out;
-
- step = BRIGHTNESS_STEP_AMOUNT (max - min + 1);
if (g_strcmp0 (method_name, "GetPercentage") == 0) {
g_debug ("screen get percentage");
- value = gnome_rr_output_get_backlight (output, &error);
+ value = backlight_get_percentage (manager, &error);
if (value >= 0)
ret = TRUE;
} else if (g_strcmp0 (method_name, "SetPercentage") == 0) {
g_debug ("screen set percentage");
g_variant_get (parameters, "(u)", &value_tmp);
- value = PERCENTAGE_TO_ABS (min, max, value_tmp);
- ret = gnome_rr_output_set_backlight (output, value, &error);
+ ret = backlight_set_percentage (manager, value_tmp, &error);
} else if (g_strcmp0 (method_name, "StepUp") == 0) {
g_debug ("screen step up");
- value = MIN (now + step, max);
- ret = gnome_rr_output_set_backlight (output, value, &error);
+ ret = backlight_step_up (manager, &error);
} else if (g_strcmp0 (method_name, "StepDown") == 0) {
g_debug ("screen step down");
- value = MAX (now - step, 0);
- ret = gnome_rr_output_set_backlight (output, value, &error);
+ ret = backlight_step_down (manager, &error);
} else {
g_assert_not_reached ();
}
-out:
+
/* return value */
if (!ret) {
g_dbus_method_invocation_return_gerror (invocation,
error);
g_error_free (error);
} else {
- percentage = ABS_TO_PERCENTAGE (min, max, value);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(u)",
- percentage));
+ value));
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]