[gnome-settings-daemon] power: Add a backlight helper, as xbacklight isn't always present
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] power: Add a backlight helper, as xbacklight isn't always present
- Date: Thu, 4 Aug 2011 16:56:14 +0000 (UTC)
commit 6bf9c04f17ccc1985b8b68efa8d6e69b98e1fc7b
Author: Richard Hughes <richard hughsie com>
Date: Wed Aug 3 11:55:44 2011 +0100
power: Add a backlight helper, as xbacklight isn't always present
This helper uses PolicyKit to do a one-time-authentication, which is not
required by default on an active session. This only works on Linux.
The PolicyKit helper has been moved from the gnome-power-manager project, and
was security reviewed by Vincent Untz.
configure.ac | 5 +
plugins/power/Makefile.am | 29 ++-
plugins/power/gsd-backlight-helper.c | 271 ++++++++++++++++++++
...nome.settings-daemon.plugins.power.policy.in.in | 32 +++
po/POTFILES.in | 1 +
po/POTFILES.skip | 1 +
6 files changed, 335 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 27595f2..9f145bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,6 +77,11 @@ PKG_CHECK_MODULES(SETTINGS_PLUGIN,
gsettings-desktop-schemas
)
+PKG_CHECK_MODULES(BACKLIGHT_HELPER,
+ glib-2.0 >= $GLIB_REQUIRED_VERSION
+ gio-2.0 >= $GIO_REQUIRED_VERSION
+)
+
GSD_PLUGIN_LDFLAGS="-export_dynamic -module -avoid-version -no-undefined"
case $host_os in
darwin*)
diff --git a/plugins/power/Makefile.am b/plugins/power/Makefile.am
index 97968dd..5fee2dd 100644
--- a/plugins/power/Makefile.am
+++ b/plugins/power/Makefile.am
@@ -49,16 +49,37 @@ plugin_in_files = \
plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin)
+org.gnome.settings-daemon.plugins.power.policy.in: org.gnome.settings-daemon.plugins.power.policy.in.in Makefile
+ $(AM_V_GEN) sed -e "s|\ libexecdir\@|$(libexecdir)|" $< > $@
+
+ INTLTOOL_POLICY_RULE@
+polkit_policydir = $(datadir)/polkit-1/actions
+polkit_policy_in_files = org.gnome.settings-daemon.plugins.power.policy.in
+polkit_policy_DATA = $(polkit_policy_in_files:.policy.in=.policy)
+
+libexec_PROGRAMS = \
+ gsd-backlight-helper
+
+gsd_backlight_helper_SOURCES = \
+ gsd-backlight-helper.c
+
+gsd_backlight_helper_LDFLAGS = \
+ $(BACKLIGHT_HELPER_LIBS) \
+ -lm
+
+gsd_backlight_helper_CFLAGS = \
+ $(BACKLIGHT_HELPER_CFLAGS)
+
EXTRA_DIST = \
+ org.gnome.settings-daemon.plugins.power.policy.in.in \
$(plugin_in_files)
clean-local:
rm -f *~
CLEANFILES = \
- $(plugin_DATA)
-
-DISTCLEANFILES = \
- $(plugin_DATA)
+ $(plugin_DATA) \
+ org.gnome.settings-daemon.plugins.power.policy \
+ org.gnome.settings-daemon.plugins.power.policy.in
@GSD_INTLTOOL_PLUGIN_RULE@
diff --git a/plugins/power/gsd-backlight-helper.c b/plugins/power/gsd-backlight-helper.c
new file mode 100644
index 0000000..5ea7943
--- /dev/null
+++ b/plugins/power/gsd-backlight-helper.c
@@ -0,0 +1,271 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010-2011 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <glib-object.h>
+#include <locale.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#define GSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS 0
+#define GSD_BACKLIGHT_HELPER_EXIT_CODE_FAILED 1
+#define GSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID 3
+#define GSD_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER 4
+
+#define GSD_BACKLIGHT_HELPER_SYSFS_LOCATION "/sys/class/backlight"
+
+static gchar *
+gsd_backlight_helper_get_best_backlight ()
+{
+ gchar *filename;
+ guint i;
+ gboolean ret;
+ GDir *dir = NULL;
+ GError *error = NULL;
+ const gchar *first_device;
+
+ /* available kernel interfaces in priority order */
+ static const gchar *backlight_interfaces[] = {
+ "nv_backlight",
+ "asus_laptop",
+ "toshiba",
+ "eeepc",
+ "thinkpad_screen",
+ "acpi_video1",
+ "mbp_backlight",
+ "acpi_video0",
+ "fujitsu-laptop",
+ "sony",
+ "samsung",
+ NULL,
+ };
+
+ /* search each one */
+ for (i=0; backlight_interfaces[i] != NULL; i++) {
+ filename = g_build_filename (GSD_BACKLIGHT_HELPER_SYSFS_LOCATION,
+ backlight_interfaces[i], NULL);
+ ret = g_file_test (filename, G_FILE_TEST_EXISTS);
+ if (ret)
+ goto out;
+ g_free (filename);
+ }
+
+ /* nothing found in the ordered list */
+ filename = NULL;
+
+ /* find any random ones */
+ dir = g_dir_open (GSD_BACKLIGHT_HELPER_SYSFS_LOCATION, 0, &error);
+ if (dir == NULL) {
+ g_warning ("failed to find any devices: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* get first device if any */
+ first_device = g_dir_read_name (dir);
+ if (first_device != NULL) {
+ filename = g_build_filename (GSD_BACKLIGHT_HELPER_SYSFS_LOCATION,
+ first_device, NULL);
+ }
+out:
+ if (dir != NULL)
+ g_dir_close (dir);
+ return filename;
+}
+
+static gboolean
+gsd_backlight_helper_write (const gchar *filename, gint value, GError **error)
+{
+ gchar *text = NULL;
+ gint retval;
+ gint length;
+ gint fd = -1;
+ gboolean ret = TRUE;
+
+ fd = open (filename, O_WRONLY);
+ if (fd < 0) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "failed to open filename: %s", filename);
+ goto out;
+ }
+
+ /* convert to text */
+ text = g_strdup_printf ("%i", value);
+ length = strlen (text);
+
+ /* write to device file */
+ retval = write (fd, text, length);
+ if (retval != length) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "writing '%s' to %s failed", text, filename);
+ goto out;
+ }
+out:
+ if (fd >= 0)
+ close (fd);
+ g_free (text);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GOptionContext *context;
+ gint uid;
+ gint euid;
+ guint retval = 0;
+ const gchar *pkexec_uid_str;
+ GError *error = NULL;
+ gboolean ret = FALSE;
+ gint set_brightness = -1;
+ gboolean get_brightness = FALSE;
+ gboolean get_max_brightness = FALSE;
+ gchar *filename = NULL;
+ gchar *filename_file = NULL;
+ gchar *contents = NULL;
+
+ const GOptionEntry options[] = {
+ { "set-brightness", '\0', 0, G_OPTION_ARG_INT, &set_brightness,
+ /* command line argument */
+ "Set the current brightness", NULL },
+ { "get-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_brightness,
+ /* command line argument */
+ "Get the current brightness", NULL },
+ { "get-max-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_max_brightness,
+ /* command line argument */
+ "Get the number of brightness levels supported", NULL },
+ { NULL}
+ };
+
+ /* setup type system */
+ g_type_init ();
+
+ context = g_option_context_new (NULL);
+ g_option_context_set_summary (context, "GNOME Settings Daemon Backlight Helper");
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+#ifndef __linux__
+ /* the g-s-d plugin should only call this helper on linux */
+ g_critical ("Attempting to call gsb-backlight-helper on non-Linux");
+ g_assert_not_reached ();
+#endif
+
+ /* no input */
+ if (set_brightness == -1 && !get_brightness && !get_max_brightness) {
+ g_print ("%s\n", "No valid option was specified");
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* find device */
+ filename = gsd_backlight_helper_get_best_backlight ();
+ if (filename == NULL) {
+ g_print ("%s\n", "No backlights were found on your system");
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER;
+ goto out;
+ }
+
+ /* GetBrightness */
+ if (get_brightness) {
+ filename_file = g_build_filename (filename, "brightness", NULL);
+ ret = g_file_get_contents (filename_file, &contents, NULL, &error);
+ if (!ret) {
+ g_print ("%s: %s\n",
+ "Could not get the value of the backlight",
+ error->message);
+ g_error_free (error);
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* just print the contents to stdout */
+ g_print ("%s", contents);
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS;
+ goto out;
+ }
+
+ /* GetSteps */
+ if (get_max_brightness) {
+ filename_file = g_build_filename (filename, "max_brightness", NULL);
+ ret = g_file_get_contents (filename_file, &contents, NULL, &error);
+ if (!ret) {
+ g_print ("%s: %s\n",
+ "Could not get the maximum value of the backlight",
+ error->message);
+ g_error_free (error);
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* just print the contents to stdout */
+ g_print ("%s", contents);
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS;
+ goto out;
+ }
+
+ /* get calling process */
+ uid = getuid ();
+ euid = geteuid ();
+ if (uid != 0 || euid != 0) {
+ g_print ("%s\n",
+ "This program can only be used by the root user");
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* check we're not being spoofed */
+ pkexec_uid_str = g_getenv ("PKEXEC_UID");
+ if (pkexec_uid_str == NULL) {
+ g_print ("%s\n",
+ "This program must only be run through pkexec");
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER;
+ goto out;
+ }
+
+ /* SetBrightness */
+ if (set_brightness != -1) {
+ filename_file = g_build_filename (filename, "brightness", NULL);
+ ret = gsd_backlight_helper_write (filename_file, set_brightness, &error);
+ if (!ret) {
+ g_print ("%s: %s\n",
+ "Could not set the value of the backlight",
+ error->message);
+ g_error_free (error);
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+ }
+
+ /* success */
+ retval = GSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS;
+out:
+ g_free (filename);
+ g_free (filename_file);
+ g_free (contents);
+ return retval;
+}
+
diff --git a/plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in b/plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in
new file mode 100644
index 0000000..5adbc41
--- /dev/null
+++ b/plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+
+ <!--
+ Policy definitions for gnome-settings-daemon system-wide actions.
+ Copyright (c) 2010-2011 Richard Hughes <richard hughsie com>
+ -->
+
+ <vendor>GNOME Settings Daemon</vendor>
+ <vendor_url>http://git.gnome.org/browse/gnome-settings-daemon</vendor_url>
+ <icon_name>battery</icon_name>
+
+ <action id="org.gnome.settings-daemon.plugins.power.backlight-helper">
+ <!-- SECURITY:
+ - A normal active user on the local machine does not need permission
+ to change the backlight brightness.
+ -->
+ <_description>Modify the laptop brightness</_description>
+ <_message>Authentication is required to modify the laptop brightness</_message>
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ <annotate key="org.freedesktop.policykit.exec.path">@libexecdir@/gsd-backlight-helper</annotate>
+ </action>
+
+</policyconfig>
+
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f76e230..ef38253 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -31,6 +31,7 @@ plugins/color/gsd-color-manager.c
[type: gettext/ini]plugins/power/power.gnome-settings-plugin.in
plugins/power/gpm-common.c
plugins/power/gsd-power-manager.c
+plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in
plugins/housekeeping/gsd-disk-space.c
plugins/housekeeping/gsd-ldsm-dialog.c
plugins/keybindings/gsd-keybindings-manager.c
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index dda31a6..a4e8c91 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -22,3 +22,4 @@ data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in
data/org.gnome.settings-daemon.plugins.color.gschema.xml.in
plugins/automount/gnome-fallback-mount-helper.desktop.in
+plugins/power/org.gnome.settings-daemon.plugins.power.policy.in
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]