Thursday, October 25, 2007

"FN Keys" en Linux

Un problema que he tenido con todas las distribuciones que he probado últimamente ha sido el tema de las teclas especiales del portátil, esas que sirven para ajustar el volumen, hibernar, etc. En algunas distros funcionaban algunas cosas, en otras salía el OSD pero no funcionaban y en la mayoría no funcionaban en absoluto. En las distribuciones de prueba ni me he molestado en investigar sobre el asunto pero en mi gentoo tenía que hacer que funcionasen estas teclas ya que su comodidad es incomparable a hacer las cosas con el raton desde algun menú, como el de KMix.

Los pasos para tener las teclas fn funcionando en un Sony Vaio SZ son:
1. Instalar soporte de teclas especiales sony en el kernel. Antes el módulo se llamaba sony_acpi, pero ahora es sony-laptop. Con esto conseguimos que el kernel genere eventos acpi cada vez que pulsamos la tecla fn + f1-f12
2. Procesar los eventos acpi. Para esto basta una sección adicional en el script /etc/acpi/default.sh. Por supuesto, se puede llamar a un script aparte poniendo el clasificador correspondiente en /etc/acpi/events/ y creando el script en la carpeta anterior, o en una subcarpeta, a gusto del usuario. En mi caso, la seccion relevante del default.sh es:
  1. #!/bin/sh
  2. # /etc/acpi/default.sh
  3. [...]
  4. case "$group" in
  5. button) [...]
  6. sony)
  7. case "$value" in
  8. 0000000d)
  9. logger "mute"
  10. /usr/local/bin/vol_mute
  11. ;;
  12. 0000000e)
  13. logger "bajando el volumen"
  14. /usr/local/bin/vol_down
  15. ;;
  16. 0000000f)
  17. logger "subiendo el volumen"
  18. /usr/local/bin/vol_up
  19. ;;
  20. 00000010)
  21. logger "bajando el brillo"
  22. /usr/local/bin/bright_down
  23. ;;
  24. 00000011)
  25. logger "subiendo el brillo"
  26. /usr/local/bin/bright_up
  27. ;;
  28. *)
  29. logger "acpid: sony action $value is not defined"
  30. ;;
  31. esac
  32. ;;
  33. ac_adapter) [...]]
  34. *) log_unhandled $* ;;
  35. esac
3. Crear los scripts que den la funcionalidad. En caso del volumen se puede usar el comando amixer. Para el brillo basta leer/escribir en /sys/class/backlight/sony/brightness. Por supuesto se pueden asignar las funciones que se quieran a las teclas, como ejecutar scripts de mantenimiento, arrancar navegadores... Como ejemplo dejo dos scripts de control de brillo y volumen, que es lo mas usado.
Brillo:
  1. #!/bin/bash
  2. BRIGHTNESS="$(cat /sys/class/backlight/sony/brightness)"
  3. if (( BRIGHTNESS < 7))
  4. then
  5. BRIGHTNESS=$((BRIGHTNESS+1))
  6. echo $BRIGHTNESS > /sys/class/backlight/sony/brightness
  7. # DESCOMENTAR PARA OSD
  8. # PERC="$(( (BRIGHTNESS*100)/7 ))"
  9. # osd_cat --pos=middle --align=center --barmode=percentage --percentage=$PERC --text=BRILLO &
  10. fi
Volumen:
  1. #!/bin/bash
  2. VOLUMEN=$(/usr/local/bin/vol_get)
  3. (( VOLUMEN = VOLUMEN + 5 ))
  4. if [ $VOLUMEN -gt 100 ]; then
  5. VOLUMEN=100
  6. fi
  7. /usr/local/bin/vol_set $VOLUMEN
Siendo vol_get:
  1. amixer sget Master | grep Left: | sed -e "s/[^[]*\[\([^%]*\).*/\1/"
Y vol_set:
  1. #!/bin/bash
  2. if [ $# -lt 1 ]
  3. then
  4. echo "Uso: $0 VOLUMEN"
  5. exit 1
  6. fi
  7. amixer -q sset Master ${1}%
Los scripts son de andar por casa y chapuceros, de hecho creo que son los primeros que he escrito, así que no tengo mucha idea de normas de estilo, ni siquiera de normas en general ;) Pero espero que sirvan para ilustrar el proceso a seguir para ajustar el comportamiento al gusto de cada uno. Y por supuesto la regexp de sed ha sido copiada de una web y modificada para que funcione con la salida del amixer (salida filtrada chapuceramente con grep xD).
Por supuesto, existen otros métodos como mapear los eventos acpi a pulsaciones de teclas en X, o a través de módulos de KDE, pero esas soluciones o son más complejas y menos potentes o se acercan más al Plug & Pray y si no funcionan a la primera, no hay manera de arreglarlas.

PD: el codigo para la su publicación ha sido porcesado usando esta página. Increíble lo que he tardado en encontrar una página de ese tipo, la relación señal/ruido en Internet cada vez es peor.

No comments: