From c493fe837d6573c5819899b409ba0186ef524132 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Wed, 20 Oct 2010 15:27:23 +0200 Subject: [PATCH 1/2] Drop HAL brightness backend, add polkit sysfs backend HAL has been deprecated and unmaintained for a long time now, and isn't being installed by newer distros any more, so it's time to get rid of the HAL brightness backend entirely, so drop it. Since there are still X.org drivers which do not support brightness setting through XRandR, add a xfpm-power-backlight-helper program which reads/writes brightness setting in /sys/class/backlight/, and use it as a fallback if XRandR brightness isn't available. Reading doesn't require any privileges, but for writing the helper needs to be run as root through pkexec, so add a default policy which allows running that without a password for the local foreground console. This was inspired from gnome-power-manager: http://git.gnome.org/browse/gnome-power-manager/commit/?id=4886023c and the helper code comes from gpm, with slight adaptions. http://bugzilla.xfce.org/show_bug.cgi?id=6116 --- common/Makefile.am | 3 +- common/xfpm-brightness.c | 359 ++++++++++++++++++----------------------- common/xfpm-brightness.h | 12 -- configure.ac.in | 1 + po/POTFILES.in | 1 + src/Makefile.am | 34 ++++- src/org.xfce.power.policy.in2 | 32 ++++ src/xfpm-backlight-helper.c | 261 ++++++++++++++++++++++++++++++ src/xfpm-backlight.c | 17 -- 9 files changed, 485 insertions(+), 235 deletions(-) create mode 100644 src/org.xfce.power.policy.in2 create mode 100644 src/xfpm-backlight-helper.c diff --git a/common/Makefile.am b/common/Makefile.am index fd5d98c..e004a46 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -12,6 +12,7 @@ libxfpmcommon_la_SOURCES = \ libxfpmcommon_la_CFLAGS = \ -I$(top_srcdir) \ + -DSBINDIR=\"$(sbindir)\" \ $(GTK_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBXFCE4UTIL_CFLAGS) @@ -24,4 +25,4 @@ libxfpmcommon_la_CFLAGS += \ libxfpmcommon_la_LIBADD = \ $(top_builddir)/libhal/libxfpmhal.la -endif \ No newline at end of file +endif diff --git a/common/xfpm-brightness.c b/common/xfpm-brightness.c index 887aeb1..84e6b87 100644 --- a/common/xfpm-brightness.c +++ b/common/xfpm-brightness.c @@ -36,12 +36,6 @@ #include -#ifdef WITH_HAL -#include -#include "libhal/hal-manager.h" -#include "libhal/hal-device.h" -#endif - #include "xfpm-brightness.h" #include "xfpm-debug.h" @@ -56,20 +50,12 @@ struct XfpmBrightnessPrivate Atom backlight; gint output; gboolean xrandr_has_hw; + gboolean helper_has_hw; gint max_level; gint current_level; gint min_level; gint step; - -#ifdef WITH_HAL - HalManager *manager; - DBusGConnection *bus; - DBusGProxy *hal_proxy; - gboolean hal_brightness_in_hw; - gboolean hal_hw_found; - gboolean connected; -#endif }; G_DEFINE_TYPE (XfpmBrightness, xfpm_brightness, G_TYPE_OBJECT) @@ -294,178 +280,187 @@ xfpm_brightness_xrand_down (XfpmBrightness *brightness, gint *new_level) } /* - * Begin HAL optional brightness code. - * + * Non-XRandR fallback using xfpm-backlight-helper */ -#ifdef WITH_HAL -static gboolean -xfpm_brightness_hal_get_level (XfpmBrightness *brg, gint *level) +#ifdef ENABLE_POLKIT + +static gint +xfpm_brightness_helper_get_value (const gchar *argument) { + gboolean ret; GError *error = NULL; - gboolean ret = FALSE; - - if (!brg->priv->connected) - return FALSE; - - ret = dbus_g_proxy_call (brg->priv->hal_proxy, "GetBrightness", &error, - G_TYPE_INVALID, - G_TYPE_INT, level, - G_TYPE_INVALID); - - if (error) + gchar *stdout_data = NULL; + gint exit_status = 0; + gint value = -1; + gchar *command = NULL; + + command = g_strdup_printf (SBINDIR "/xfpm-power-backlight-helper --%s", argument); + ret = g_spawn_command_line_sync (command, + &stdout_data, NULL, &exit_status, &error); + if ( !ret ) { - g_warning ("GetBrightness failed : %s\n", error->message); + g_warning ("failed to get value: %s", error->message); g_error_free (error); + goto out; } - - return ret; + g_debug ("executed %s; retval: %i", command, exit_status); + if ( exit_status != 0 ) + goto out; + + value = atoi (stdout_data); + +out: + g_free (command); + g_free (stdout_data); + return value; } static gboolean -xfpm_brightness_hal_set_level (XfpmBrightness *brg, gint level) +xfpm_brightness_setup_helper (XfpmBrightness *brightness) { - GError *error = NULL; - gboolean ret = FALSE; - gint dummy; - - if (!brg->priv->connected) - return FALSE; - - TRACE ("Setting level %d", level); - - ret = dbus_g_proxy_call (brg->priv->hal_proxy, "SetBrightness", &error, - G_TYPE_INT, level, - G_TYPE_INVALID, - G_TYPE_INT, &dummy, /* Just to avoid a warning! */ - G_TYPE_INVALID ); - - if ( error ) - { - g_critical ("Error setting brightness level: %s\n", error->message); - g_error_free (error); - return FALSE; + int ret; + + ret = xfpm_brightness_helper_get_value ("get-max-brightness"); + g_debug ("xfpm_brightness_setup_helper: get-max-brightness returned %i", ret); + if ( ret < 0 ) { + brightness->priv->helper_has_hw = FALSE; + } else { + brightness->priv->helper_has_hw = TRUE; + brightness->priv->min_level = 0; + brightness->priv->max_level = ret; + brightness->priv->step = ret <= 20 ? 1 : ret / 10; } - - if (!ret) + + return brightness->priv->helper_has_hw; +} + +static gboolean +xfpm_brightness_helper_get_level (XfpmBrightness *brg, gint *level) +{ + int ret; + + if ( ! brg->priv->helper_has_hw ) + return FALSE; + + ret = xfpm_brightness_helper_get_value ("get-brightness"); + + g_debug ("xfpm_brightness_helper_get_level: get-brightness returned %i", ret); + + if ( ret >= 0 ) { - g_warning ("SetBrightness failed\n"); + *level = ret; + return TRUE; } - - return TRUE; -} + return FALSE; +} static gboolean -xfpm_brightness_hal_up (XfpmBrightness *brightness) +xfpm_brightness_helper_set_level (XfpmBrightness *brg, gint level) { - gint hw_level; - gint set_level; - gboolean ret = TRUE; - - ret = xfpm_brightness_hal_get_level (brightness, &hw_level); - + gboolean ret; + GError *error = NULL; + gint exit_status = 0; + gchar *command = NULL; + + command = g_strdup_printf ("pkexec " SBINDIR "/xfpm-power-backlight-helper --set-brightness %i", level); + ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error); if ( !ret ) - return FALSE; - - if ( hw_level == brightness->priv->max_level ) { - return TRUE; + g_warning ("xfpm_brightness_helper_set_level: failed to set value: %s", error->message); + g_error_free (error); + goto out; } - - set_level = MIN (hw_level + brightness->priv->step, brightness->priv->max_level ); - - ret = xfpm_brightness_hal_set_level (brightness, set_level); - + g_debug ("executed %s; retval: %i", command, exit_status); + ret = (exit_status == 0); + +out: + g_free (command); return ret; } static gboolean -xfpm_brightness_hal_down (XfpmBrightness *brightness) +xfpm_brightness_helper_up (XfpmBrightness *brightness, gint *new_level) { gint hw_level; + gboolean ret = FALSE; gint set_level; - gboolean ret = TRUE; - ret = xfpm_brightness_hal_get_level (brightness, &hw_level); + ret = xfpm_brightness_helper_get_level (brightness, &hw_level); if ( !ret ) return FALSE; - if ( hw_level == brightness->priv->min_level ) + if ( hw_level == brightness->priv->max_level ) + { + *new_level = brightness->priv->max_level; return TRUE; + } - set_level = MAX (hw_level - brightness->priv->step, brightness->priv->min_level); + set_level = MIN (hw_level + brightness->priv->step, brightness->priv->max_level ); + + g_warn_if_fail (xfpm_brightness_helper_set_level (brightness, set_level)); + + ret = xfpm_brightness_helper_get_level (brightness, new_level); - ret = xfpm_brightness_hal_set_level (brightness, brightness->priv->min_level); + if ( !ret ) + { + g_warning ("xfpm_brightness_helper_up failed for %d", set_level); + return FALSE; + } + + /* Nothing changed in the hardware*/ + if ( *new_level == hw_level ) + { + g_warning ("xfpm_brightness_helper_up did not change the hw level to %d", set_level); + return FALSE; + } - return ret; -} - -static void -xfpm_brightness_hal_connection_changed_cb (HalManager *manager, gboolean connected, XfpmBrightness *brightness) -{ - brightness->priv->connected = connected; + return TRUE; } static gboolean -xfpm_brightness_setup_hal (XfpmBrightness *brightness) +xfpm_brightness_helper_down (XfpmBrightness *brightness, gint *new_level) { - DBusGConnection *bus; - HalDevice *device; - gchar **udi = NULL; + gint hw_level; + gboolean ret; + gint set_level; + ret = xfpm_brightness_helper_get_level (brightness, &hw_level); - if ( !brightness->priv->manager ) - { - brightness->priv->manager = hal_manager_new (); - - g_signal_connect (brightness->priv->manager, "connection-changed", - G_CALLBACK (xfpm_brightness_hal_connection_changed_cb), brightness); - } - brightness->priv->connected = hal_manager_get_is_connected (brightness->priv->manager); - - udi = hal_manager_find_device_by_capability (brightness->priv->manager, "laptop_panel"); - - if ( !udi || !udi[0]) + if ( !ret ) + return FALSE; + + if ( hw_level == brightness->priv->min_level ) { - return FALSE; + *new_level = brightness->priv->min_level; + return TRUE; } - device = hal_device_new (); - hal_device_set_udi (device, udi[0]); - - brightness->priv->max_level = hal_device_get_property_int (device, "laptop_panel.num_levels") - 1; - brightness->priv->step = brightness->priv->max_level <= 20 ? 1 : brightness->priv->max_level / 20; - brightness->priv->min_level = brightness->priv->step; - brightness->priv->hal_hw_found = TRUE; + set_level = MAX (hw_level - brightness->priv->step, brightness->priv->min_level); - if ( hal_device_has_key (device, "laptop_panel.brightness_in_hardware") ) - brightness->priv->hal_brightness_in_hw = hal_device_get_property_bool (device ,"laptop_panel.brightness_in_hardware"); + g_warn_if_fail (xfpm_brightness_helper_set_level (brightness, set_level)); - TRACE ("laptop_panel.num_levels=%d\n", brightness->priv->max_level); - - g_object_unref (device); - - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); + ret = xfpm_brightness_helper_get_level (brightness, new_level); - brightness->priv->hal_proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.Hal", - udi[0], - "org.freedesktop.Hal.Device.LaptopPanel"); - - if ( !brightness->priv->hal_proxy ) + if ( !ret ) { - g_warning ("Unable to get proxy for device %s\n", udi[0]); - brightness->priv->hal_hw_found = FALSE; + g_warning ("xfpm_brightness_helper_down failed for %d", set_level); + return FALSE; } - hal_manager_free_string_array (udi); - brightness->priv->bus = bus; + /* Nothing changed in the hardware*/ + if ( *new_level == hw_level ) + { + g_warning ("xfpm_brightness_helper_down did not change the hw level to %d", set_level); + return FALSE; + } - return brightness->priv->hal_hw_found; + return TRUE; } -#endif /* WITH_HAL*/ + +#endif static void xfpm_brightness_class_init (XfpmBrightnessClass *klass) @@ -484,19 +479,12 @@ xfpm_brightness_init (XfpmBrightness *brightness) brightness->priv->resource = NULL; brightness->priv->xrandr_has_hw = FALSE; + brightness->priv->helper_has_hw = FALSE; brightness->priv->max_level = 0; brightness->priv->min_level = 0; brightness->priv->current_level = 0; brightness->priv->output = 0; brightness->priv->step = 0; - -#ifdef WITH_HAL - brightness->priv->bus = NULL; - brightness->priv->hal_proxy = NULL; - brightness->priv->hal_brightness_in_hw = FALSE; - brightness->priv->hal_hw_found = FALSE; - brightness->priv->manager = NULL; -#endif } static void @@ -504,14 +492,6 @@ xfpm_brightness_free_data (XfpmBrightness *brightness) { if ( brightness->priv->resource ) XRRFreeScreenResources (brightness->priv->resource); - -#ifdef WITH_HAL - if ( brightness->priv->bus ) - dbus_g_connection_unref (brightness->priv->bus); - - if ( brightness->priv->hal_proxy ) - g_object_unref (brightness->priv->hal_proxy); -#endif } static void @@ -523,11 +503,6 @@ xfpm_brightness_finalize (GObject *object) xfpm_brightness_free_data (brightness); -#ifdef WITH_HAL - if ( brightness->priv->manager ) - g_object_unref (brightness->priv->manager); -#endif - G_OBJECT_CLASS (xfpm_brightness_parent_class)->finalize (object); } @@ -555,17 +530,21 @@ xfpm_brightness_setup (XfpmBrightness *brightness) brightness->priv->min_level, brightness->priv->max_level); + return TRUE; } -#ifdef WITH_HAL - else if ( !brightness->priv->xrandr_has_hw ) +#ifdef ENABLE_POLKIT + else { - g_debug ("Unable to control brightness via xrandr, trying to use HAL"); - if ( xfpm_brightness_setup_hal (brightness) ) + if ( xfpm_brightness_setup_helper (brightness) ) { + g_debug ("xrandr not available, brightness controlled by sysfs helper; min_level=%d max_level=%d", + brightness->priv->min_level, + brightness->priv->max_level); return TRUE; + } } #endif - - return brightness->priv->xrandr_has_hw; + g_debug ("no brightness controls available"); + return FALSE; } gboolean xfpm_brightness_up (XfpmBrightness *brightness, gint *new_level) @@ -576,12 +555,10 @@ gboolean xfpm_brightness_up (XfpmBrightness *brightness, gint *new_level) { ret = xfpm_brightness_xrand_up (brightness, new_level); } -#ifdef WITH_HAL - else if ( brightness->priv->hal_hw_found ) +#ifdef ENABLE_POLKIT + else if ( brightness->priv->helper_has_hw ) { - ret = xfpm_brightness_hal_up (brightness); - if ( ret ) - ret = xfpm_brightness_hal_get_level (brightness, new_level); + ret = xfpm_brightness_helper_up (brightness, new_level); } #endif return ret; @@ -597,12 +574,10 @@ gboolean xfpm_brightness_down (XfpmBrightness *brightness, gint *new_level) if ( ret ) ret = xfpm_brightness_xrandr_get_level (brightness, brightness->priv->output, new_level); } -#ifdef WITH_HAL - else if ( brightness->priv->hal_hw_found ) +#ifdef ENABLE_POLKIT + else if ( brightness->priv->helper_has_hw ) { - ret = xfpm_brightness_hal_down (brightness); - if ( ret ) - ret = xfpm_brightness_hal_get_level (brightness, new_level); + ret = xfpm_brightness_helper_down (brightness, new_level); } #endif return ret; @@ -610,12 +585,7 @@ gboolean xfpm_brightness_down (XfpmBrightness *brightness, gint *new_level) gboolean xfpm_brightness_has_hw (XfpmBrightness *brightness) { -#ifdef WITH_HAL - if ( !brightness->priv->xrandr_has_hw ) - return brightness->priv->hal_hw_found; -#endif - - return brightness->priv->xrandr_has_hw; + return brightness->priv->xrandr_has_hw || brightness->priv->helper_has_hw; } gint xfpm_brightness_get_max_level (XfpmBrightness *brightness) @@ -629,9 +599,9 @@ gboolean xfpm_brightness_get_level (XfpmBrightness *brightness, gint *level) if ( brightness->priv->xrandr_has_hw ) ret = xfpm_brightness_xrandr_get_level (brightness, brightness->priv->output, level); -#ifdef WITH_HAL - else if ( brightness->priv->hal_hw_found ) - ret = xfpm_brightness_hal_get_level (brightness, level); +#ifdef ENABLE_POLKIT + else if ( brightness->priv->helper_has_hw ) + ret = xfpm_brightness_helper_get_level (brightness, level); #endif return ret; @@ -643,9 +613,9 @@ gboolean xfpm_brightness_set_level (XfpmBrightness *brightness, gint level) if (brightness->priv->xrandr_has_hw ) ret = xfpm_brightness_xrandr_set_level (brightness, brightness->priv->output, level); -#ifdef WITH_HAL - else if ( brightness->priv->hal_hw_found ) - ret = xfpm_brightness_hal_set_level (brightness, level); +#ifdef ENABLE_POLKIT + else if ( brightness->priv->helper_has_hw ) + ret = xfpm_brightness_helper_set_level (brightness, level); #endif return ret; @@ -657,29 +627,10 @@ gboolean xfpm_brightness_dim_down (XfpmBrightness *brightness) if (brightness->priv->xrandr_has_hw ) ret = xfpm_brightness_xrandr_set_level (brightness, brightness->priv->output, brightness->priv->min_level); -#ifdef WITH_HAL - else if ( brightness->priv->hal_hw_found ) - ret = xfpm_brightness_hal_set_level (brightness, brightness->priv->min_level); +#ifdef ENABLE_POLKIT + else if ( brightness->priv->helper_has_hw ) + ret = xfpm_brightness_helper_set_level (brightness, brightness->priv->min_level); #endif return ret; } - -XfpmBrightnessControl xfpm_brightness_get_control (XfpmBrightness *brightness) -{ - if ( brightness->priv->xrandr_has_hw ) - return XFPM_BRIGHTNESS_CONTROL_XRANDR; -#ifdef WITH_HAL - else if ( brightness->priv->hal_hw_found ) - return XFPM_BRIGHTNESS_CONTROL_HAL; -#endif - return XFPM_BRIGHTNESS_CONTROL_UNKNOWN; -} - -gboolean xfpm_brightness_in_hw (XfpmBrightness *brightness) -{ -#ifdef WITH_HAL - return brightness->priv->hal_brightness_in_hw; -#endif - return FALSE; -} diff --git a/common/xfpm-brightness.h b/common/xfpm-brightness.h index 4fa37d7..e687371 100644 --- a/common/xfpm-brightness.h +++ b/common/xfpm-brightness.h @@ -29,14 +29,6 @@ G_BEGIN_DECLS #define XFPM_BRIGHTNESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XFPM_TYPE_BRIGHTNESS, XfpmBrightness)) #define XFPM_IS_BRIGHTNESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XFPM_TYPE_BRIGHTNESS)) -typedef enum -{ - XFPM_BRIGHTNESS_CONTROL_UNKNOWN, - XFPM_BRIGHTNESS_CONTROL_XRANDR, - XFPM_BRIGHTNESS_CONTROL_HAL - -} XfpmBrightnessControl; - typedef struct XfpmBrightnessPrivate XfpmBrightnessPrivate; typedef struct @@ -76,10 +68,6 @@ gboolean xfpm_brightness_set_level (XfpmBrightness *brightness, gboolean xfpm_brightness_dim_down (XfpmBrightness *brightness); -XfpmBrightnessControl xfpm_brightness_get_control (XfpmBrightness *brightness); - -gboolean xfpm_brightness_in_hw (XfpmBrightness *brightness); - G_END_DECLS #endif /* __XFPM_BRIGHTNESS_H */ diff --git a/configure.ac.in b/configure.ac.in index 1cf592c..f5cba7b 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -96,6 +96,7 @@ else AC_DEFINE(ENABLE_POLKIT, 1 , [PolicyKit support]) polkit="yes" fi +AM_CONDITIONAL([ENABLE_POLKIT], [test "x$polkit" = "xyes"]) #=======================================================# # Use HAL? # diff --git a/po/POTFILES.in b/po/POTFILES.in index ccb3559..f30c97f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -14,5 +14,6 @@ src/xfpm-dpms.c src/xfpm-inhibit.c src/xfpm-power-info.c src/xfce4-power-manager.desktop.in +src/org.xfce.power.policy.in panel-plugins/brightness/brightness-button.c panel-plugins/brightness/xfce4-brightness-plugin.desktop.in.in diff --git a/src/Makefile.am b/src/Makefile.am index 3c42142..52bd53c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,6 +102,35 @@ xfce4_power_information_LDADD = \ $(LIBXFCE4UI_LIBS) \ $(top_builddir)/libdbus/libxfpmdbus.la +if ENABLE_POLKIT + +sbin_PROGRAMS = xfpm-power-backlight-helper + +xfpm_power_backlight_helper_SOURCES = \ + xfpm-backlight-helper.c + +xfpm_power_backlight_helper_LDADD = \ + $(GLIB_LIBS) \ + -lm + +xfpm_power_backlight_helper_CFLAGS = \ + $(GLIB_CFLAGS) \ + $(PLATFORM_CPPFLAGS) \ + $(PLATFORM_CFLAGS) + +polkit_policydir = $(datadir)/polkit-1/actions +polkit_policy_DATA = \ + org.xfce.power.policy + +# You will need a recent intltool or the patch from this bug +# http://bugzilla.gnome.org/show_bug.cgi?id=462312 +@INTLTOOL_POLICY_RULE@ + +.in2.in: + sed "s|[@]sbindir@|${sbindir}|" $< > $@ + +endif + manpagedir = $(mandir)/man1 manpage_DATA = xfce4-power-manager.1 @@ -172,8 +201,11 @@ autostart_DATA = $(autostart_in_files:.desktop.in=.desktop) EXTRA_DIST = \ xfpm-marshal.list \ $(autostart_in_files) \ + org.gnome.power.policy.in2 \ $(manpage_DATA) DISTCLEANFILES = \ $(BUILT_SOURCES) \ - xfce4-power-manager.desktop + xfce4-power-manager.desktop \ + org.gnome.power.policy \ + org.gnome.power.policy.in diff --git a/src/org.xfce.power.policy.in2 b/src/org.xfce.power.policy.in2 new file mode 100644 index 0000000..5a05964 --- /dev/null +++ b/src/org.xfce.power.policy.in2 @@ -0,0 +1,32 @@ + + + + + + + XFCE Power Manager + http://goodies.xfce.org/projects/applications/xfce4-power-manager + battery + + + + <_description>Modify the laptop display brightness + <_message>Authentication is required to modify the laptop display brightness + + no + no + yes + + @sbindir@/xfpm-power-backlight-helper + + + + diff --git a/src/xfpm-backlight-helper.c b/src/xfpm-backlight-helper.c new file mode 100644 index 0000000..9e5bd47 --- /dev/null +++ b/src/xfpm-backlight-helper.c @@ -0,0 +1,261 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2010 Richard Hughes + * + * 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 +#include +#include +#include +#include + +#define GCM_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS 0 +#define GCM_BACKLIGHT_HELPER_EXIT_CODE_FAILED 1 +#define GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID 3 +#define GCM_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER 4 + +#define GCM_BACKLIGHT_HELPER_SYSFS_LOCATION "/sys/class/backlight" + +/** + * gcm_backlight_helper_get_best_backlight: + **/ +static gchar * +gcm_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 (GCM_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 (GCM_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 (GCM_BACKLIGHT_HELPER_SYSFS_LOCATION, + first_device, NULL); + } +out: + if (dir != NULL) + g_dir_close (dir); + return filename; +} + +/** + * gcm_backlight_helper_write: + **/ +static gboolean +gcm_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; +} + +/** + * main: + **/ +gint +main (gint argc, gchar *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} + }; + + context = g_option_context_new (NULL); + g_option_context_set_summary (context, "XFCE Power Manager Backlight Helper"); + g_option_context_add_main_entries (context, options, NULL); + g_option_context_parse (context, &argc, &argv, NULL); + g_option_context_free (context); + + /* no input */ + if (set_brightness == -1 && !get_brightness && !get_max_brightness) { + puts ("No valid option was specified"); + retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; + goto out; + } + + /* find device */ + filename = gcm_backlight_helper_get_best_backlight (); + if (filename == NULL) { + puts ("No backlights were found on your system"); + retval = GCM_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 ("Could not get the value of the backlight: %s\n", error->message); + g_error_free (error); + retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; + goto out; + } + + /* just print the contents to stdout */ + g_print ("%s", contents); + retval = GCM_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 ("Could not get the maximum value of the backlight: %s\n", error->message); + g_error_free (error); + retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; + goto out; + } + + /* just print the contents to stdout */ + g_print ("%s", contents); + retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS; + goto out; + } + + /* get calling process */ + uid = getuid (); + euid = geteuid (); + if (uid != 0 || euid != 0) { + puts ("This program can only be used by the root user"); + retval = GCM_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) { + puts ("This program must only be run through pkexec"); + retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER; + goto out; + } + + /* SetBrightness */ + if (set_brightness != -1) { + filename_file = g_build_filename (filename, "brightness", NULL); + ret = gcm_backlight_helper_write (filename_file, set_brightness, &error); + if (!ret) { + g_print ("Could not set the value of the backlight: %s\n", error->message); + g_error_free (error); + retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; + goto out; + } + } + + /* success */ + retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS; +out: + g_free (filename); + g_free (filename_file); + g_free (contents); + return retval; +} + diff --git a/src/xfpm-backlight.c b/src/xfpm-backlight.c index bdf6d22..a5d93f8 100644 --- a/src/xfpm-backlight.c +++ b/src/xfpm-backlight.c @@ -77,9 +77,6 @@ struct XfpmBacklightPrivate gboolean dimmed; gboolean block; -#ifdef WITH_HAL - gboolean brightness_in_hw; -#endif }; G_DEFINE_TYPE (XfpmBacklight, xfpm_backlight, G_TYPE_OBJECT) @@ -282,26 +279,16 @@ xfpm_backlight_button_pressed_cb (XfpmButton *button, XfpmButtonKey type, XfpmBa if ( type == BUTTON_MON_BRIGHTNESS_UP ) { backlight->priv->block = TRUE; -#ifdef WITH_HAL - if ( !backlight->priv->brightness_in_hw && enable_brightness) - ret = xfpm_brightness_up (backlight->priv->brightness, &level); -#else if ( enable_brightness ) ret = xfpm_brightness_up (backlight->priv->brightness, &level); -#endif if ( ret && show_popup) xfpm_backlight_show (backlight, level); } else if ( type == BUTTON_MON_BRIGHTNESS_DOWN ) { backlight->priv->block = TRUE; -#ifdef WITH_HAL - if ( !backlight->priv->brightness_in_hw && enable_brightness ) - ret = xfpm_brightness_down (backlight->priv->brightness, &level); -#else if ( enable_brightness ) ret = xfpm_brightness_down (backlight->priv->brightness, &level); -#endif if ( ret && show_popup) xfpm_backlight_show (backlight, level); } @@ -404,10 +391,6 @@ xfpm_backlight_init (XfpmBacklight *backlight) backlight->priv->power = xfpm_power_get (); backlight->priv->notify = xfpm_notify_new (); backlight->priv->max_level = xfpm_brightness_get_max_level (backlight->priv->brightness); -#ifdef WITH_HAL - if ( xfpm_brightness_get_control (backlight->priv->brightness) == XFPM_BRIGHTNESS_CONTROL_HAL ) - backlight->priv->brightness_in_hw = xfpm_brightness_in_hw (backlight->priv->brightness); -#endif g_signal_connect (backlight->priv->idle, "alarm-expired", G_CALLBACK (xfpm_backlight_alarm_timeout_cb), backlight); -- 1.7.1