Poder cambiar la luminosidad de una pantalla siempre es algo práctico, para ajustarla cuando hay más o menos luz, o incluso apagarla para que un portatil siga procesando sin la pantalla encendida. Esto suele funcionar solo cuando utilizamos un entorno como KDE o Gnome, pero puede que no sea así si no utilizamos ciertos drivers o si preferimos entornos más configurables (como awesome).

Si preferimos hacerlo a mano, podemos desde la línea de comandos en /sys/class/backlight/, en el directorio de cada dispositivo hay un archivo brightness que marca el brillo actual (y que acepta cambios) y otro, max_brightness, donde indica el valor máximo que acepta, por ejemplo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Buscamos el dispositivo disponible
$ ls /sys/class/backlight/
radeon_bl0

# Brillo actual
$ cat /sys/class/backlight/radeon_bl0/brightness
100

# Brillo máximo
$ cat /sys/class/backlight/radeon_bl0/max_brightness
255

# Ponemos el brillo al máximo. Ojo! hace falta root
$ echo 255 | sudo tee /sys/class/backlight/radeon_bl0/brightness
255

Sabiendo esto, podemos montar un scriptillo para que lo haga automáticamente, tendría que poder...

Listar los dispositivos:

1
2
def get_device_list():
    return os.listdir('/sys/class/backlight/')

Mostrar el brillo actual y el máximo:

1
2
3
4
5
6
7
def get_brightness(backlight):
    return int(open('/sys/class/backlight/{backlight}/brightness'
                    .format(backlight=backlight), 'rt').read())

def get_max_brightness(backlight):
    return int(open('/sys/class/backlight/{backlight}/max_brightness'
                    .format(backlight=backlight), 'rt').read())

Cambiar el brillo:

1
2
3
def set_brightness(backlight, value):
    return open('/sys/class/backlight/{backlight}/brightness'
                .format(backlight=backlight), 'wt').write(str(value))

Con esto ya podemos hacer un par de funciones para aumentar y disminuir el brillo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def less(backlight):
    brightness = get_brightness(backlight)
    max_brightness = get_max_brightness(backlight)

    set_brightness(backlight, max(0, brightness - max(1, max_brightness / 10)))


def more(backlight):
    brightness = get_brightness(backlight)
    max_brightness = get_max_brightness(backlight)

    set_brightness(backlight, max(0, brightness + max(1, max_brightness / 10)))

Le añadimos una función de ayuda y un main y está listo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def show_help():
    print('''brightness.py (less|more) device

Devices:
    {}'''.format('\n    '.join(get_device_list())))


if __name__ == '__main__':
    if len(sys.argv) == 3 and sys.argv[1] in ('less', 'more'):
        if sys.argv[2] not in get_device_list():
            print('Device {} not found'.format(sys.argv[2]))
        elif sys.argv[1] == 'less':
            less(sys.argv[2])
        elif sys.argv[1] == 'more':
            more(sys.argv[2])

    else:
        show_help()

Y el script está listo [ brightness.py ], pero hay un problema... para cambiar el brillo hacen falta permisos de root. Podemos ejecutar el script con sudo, pero podemos hacer que no sea necesario con setuid.

El tema de usar setuid con python tiene truco, resulta que usarlo en scripts que indiquen el intérprete con #! implica problemas de seguridad y está desactivado en sistemas modernos. La solución es compilar el script, por ejemplo con cython.

1
2
3
4
5
6
7
8
# Compilamos el script a un .c
$ cython --embed brightness.py

# Compilamos el brightness.c a un .o
$ gcc -c brightness.c -I/usr/include/python2.7

# Compilamos el brightness.o a un ejecutable
$ gcc -o brightness brightness.o -lpython2.7

OJO: gcc no require demasiados parámetros por que es un script sencillo, pero no tiene por que ser así, hay por ahí Makefiles más completos

Una vez compilado ya podemos hacerlo setuid como root:

1
2
3
4
5
# Cambiamos el usuario a root
$ sudo chown root brightness

# Activamos setuid
$ sudo chmod +s brightness

Así que con esto ya debería bastar:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Listamos los dispositivos
$ ./brightness
brightness.py (less|more) device

Devices:
    radeon_bl0

# Aumentamos el brillo
$ ./brightness more radeon_bl0

# Reducimos el brillo
$ ./brightness less radeon_bl0

Y ya podemos modificarlo con cualquier usuario desde la consola!

Pero, y si tenemos un entorno de escritorio Awesome y queremos que funcionen las teclas de brillo? Pues eso es bastante sencillo, en el rc.lua hay una sección, clientkeys, donde podemos configurarlo:

1
2
3
4
5
clientkeys = awful.util.table.join(
    awful.key({                   }, "XF86MonBrightnessDown",
     function () awful.util.spawn('RUTA/AL/EJECUTABLE/brightness less DISPOSITIVO') end),
    awful.key({                   }, "XF86MonBrightnessUp",
     function () awful.util.spawn('RUTA/AL/EJECUTABLE/brightness more DISPOSITIVO') end),

Y con esto ya estaría completo y podremos ajustar el brillo sin necesidad de ningún extra (más... :P).

PD: el código, para hacer make y tirar millas está en GitLab.