Keyboard/Screen Backlight settings at Ubuntu 12.04
Recently I bought a new laptop (Samsung 700Z) and installed ubuntu 12.04. Most stuff works out of the box, but some details are driving me crazy. I installed the fglrx driver to shut down the fan and also the samsung-tools, so I can change the fan's behaviour. But:
Keys for the keyboard backlight do not work also they are mapped in /lib/udev/rules.d/95-keymap.rules and, what is the worst: keyboard and screen backlight settings are not stored, so after each reboot, suspend and even after screen locks both backlights are set to maximum. This is not only anoying but also wastes energy. Maybe it matters: I'm using gnome instead of unity. I tried to work with unity and some aspects are ok, but it seems I'm an old dog and cannot learn this new tricks. ;)
Using acpi_backlight=vendor in grub does not fix that behaviour, it makes it even worse: I cannot set the screen backlight to high values, just about to 30 percent of the possible max. To there is no acpi_backlight=vendor in my grub configuration.
After struggeling around for some time, I found a way to solve the problem. It includes a hillarious amount of scripts for such a trivial task.
There are three cases we have to care about:
1. Screen locking
2. Normal Startup/Shutdown/Reboot
3. Suspend/Resume
Each of this cases sets the backlights to maximum. Did I mentions, that this is really annoying?
Ok, here is what I did. We start with creating a folder /etc/backlight.
Screensaver handling
gnome-screensaver sends a dbus event when it activates / deactivates. This event can be used to store and restore the backlight settings. This means, when the login screen is shown after the screen has been disabled, both backlights are at full power, but as soon as you login, the settings are restored. The first operation is needed to set the keyboard backlight after a (re)boot. In that case there is no event from screensaver, so we have to trigger the setting manually. Save this pre somewhere, make it executable and add it as a startup program:
#/bin/sh
if [ -f /etc/backlight/kbd_backlight ]
then
cat /etc/backlight/kbd_backlight > /sys/devices/platform/samsung/leds/samsung\:\:kbd_backlight/brightness
fi
function storeSettings()
{
cat /sys/devices/platform/samsung/leds/samsung\:\:kbd_backlight/brightness > /etc/backlight/kbd_backlight
cat /sys/class/backlight/acpi_video0/brightness > /etc/backlight/screen_backlight
}
function loadSettings()
{
cat /etc/backlight/kbd_backlight > /sys/devices/platform/samsung/leds/samsung\:\:kbd_backlight/brightness
cat /etc/backlight/screen_backlight > /sys/class/backlight/acpi_video0/brightness
}
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | \
( while true; \
do read X; \
if echo $X | grep "boolean true" &> /dev/null; \
then storeSettings ; \
elif echo $X | grep "boolean false" &> /dev/null; \
then loadSettings ; \
fi done )
(Re)boot/Shutdown
If the system is shutdown, the screensaver is not invoked, so we have to store the backlight values on another way. I am using this init-script. Don't forget to make it executable.
#! /bin/sh
#
# chkconfig: - 99 99
# description: Stores backlight settings
#
# config: /etc/backlight
### BEGIN INIT INFO
# Provides: backlight
# Should-Start: $all
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop: 6
# Short-Description: Stores backlight settings
# Description: Stored backlight settings
### END INIT INFO
case $1 in
stop)
cat /sys/devices/platform/samsung/leds/samsung\:\:kbd_backlight/brightness > /etc/backlight/kbd_backlight
cat /sys/class/backlight/acpi_video0/brightness > /etc/backlight/screen_backlight
;;
*)
echo "Usage: $0 {stop}" >&2
exit 2
;;
esac
exit 0
This file is stored as /etc/init.d/backlight and symlinked to /etc/rc0.d/K01backlight (shutdown) and /etc/rc6.d/K01backlight (reboot).
For setting the values at startup, we are using /etc/rc.local. Add the following lines:
chmod a+w /sys/devices/platform/samsung/leds/samsung\:\:kbd_backlight/brightness chmod a+w /sys/class/backlight/acpi_video0/brightness chmod a+w /etc/backlight/* if [ -f /etc/backlight/kbd_backlight ] then cat /etc/backlight/kbd_backlight > /sys/devices/platform/samsung/leds/samsung\:\:kbd_backlight/brightness fi if [ -f /etc/backlight/screen_backlight ] then cat /etc/backlight/screen_backlight > /sys/class/backlight/acpi_video0/brightness fi
This keeps the backlight off for most of the booting time. But as soon as the login screen comes up the keyboard backlight shines bright again. That's why we have the additional handling in the screensaver script.
The chmodding is neccesary, because otherwise the operating user cannot change the backlight values and write the data to /etc/backlight/
Suspend/Resume
Create a file /usr/lib/pm-utils/sleep.d/01-backlight-settings with this content:
#!/bin/bash
function storeSettings()
{
cat /sys/devices/platform/samsung/leds/samsung\:\:kbd_backlight/brightness > /etc/backlight/kbd_backlight
cat /sys/class/backlight/acpi_video0/brightness > /etc/backlight/screen_backlight
chmod a+w /etc/backlight/*
}
case "$1" in
hibernate|suspend)
{ storeSettings ; } 2>/dev/null
;;
*)
;;
esac
Unlike the screensaver script, here is no loading of the settings. This values would be overridden at various run levels, so this would just cause flickering. The files in /etc are chmodded. That's just for the case the have been deleted for any reason. This way they can be eddited by the working user after a resume.
Improvement
I am sure, there must be a more elegant way for storing and setting the values without having to allow the whole world (or a specific group) to have full access to the files/devices. But I did not find one yet. It should be also possible to write a single giant script with all pre in one place. Feel free to optimize everything.
Kommentare
Kommentar hinzufügen