Version 1.0
Author: Oliver Meyer <o [dot] meyer [at] projektfarm [dot] de>


Diese Anleitung veranschaulicht wie Du die Funktionstasten Deines Laptops auf Fedora aktivierst. Ich habe dies mit Fedora 8 getestet, es sollte aber auch auf anderen Fedora Versionen funktionieren - und vielleicht mit geringfügigen Änderungen auch auf anderen Distributionen.

Diese Anleitung ist ein praktischer Leitfaden ohne jegliche Garantie - theoretisches Hintergrundwissen wird nicht abgedeckt. Es gibt viele Möglichkeiten ein solches System einzurichten - dies ist der Weg, den ich gewählt habe.

1 Vorbereitung

1.1 Benötigte Pakete

Wir werden xbindkeys verwenden, um den Funktionstasten Funktionen zuzuweisen, die keinen ACPI Event erzeugen.
  • xbindkeys

1.2 Xserver Konfiguration

Um das Touchpad ein und aus schalten zu können, müssen wir die xserver Konfiguration anpassen (Root Privilegien werden benötigt).

vi /etc/X11/xorg.conf

Suche den Bereich "InputDevice"mit dem Identifier "Synaptics" und füge folgende Zeile in diesen Bereich ein.

Option "SHMConfig" "on"

Dieser Bereich sollte nun wie folgt aussehen:
Section "InputDevice"
Identifier "Synaptics" Driver "synaptics" Option "Device" "/dev/input/mice" Option "Protocol" "auto-dev" Option "Emulate3Buttons" "yes" Option "SHMConfig" "on" EndSection
Speichere danach die Änderungen. Melde Dich danach ab und wieder an um die Änderungen zu übernehmen.

1.3 Funktionstasten-Events

Lass uns nun herausfinden, was passiert, wenn wir die Funktionstasten betätigen.

1.3.1 ACPI

Die meisten Funktionstasten wie zum Beispiel die "Fn-Tasten" erzeugen einen ACPI Event - wir sehen uns diese also einmal an. Führe dies aus ...

acpi_listen

... und drücke ein paar Mal eine Funktionstaste. Du solltest in etwa folgende Ausgabe sehen:

hotkey ATKD 00000031 0000001a
hotkey ATKD 00000031 0000001b
hotkey ATKD 00000031 0000001c

Wie Du siehst ist die erste Zahle (Position3) statisch und die zweite dynamisch. Wir brauchen nur die statische Nummer. Drücke nun all Deine Funktionstasten eine nach der anderen und notiere die statische Nummer - die brauchst Du später.

1.3.2 Xev

Einige Funktionstasten erzeugen statt eines ACPI Events einen Keycode.

xev

Ein neues Fenster mit einem kleinen Viereck öffnet sich. Bewege den Cursor in das Viereck und drücke alle Funktionstasten, die im vorherigen Schritt keinen ACPI Event erzeugt haben. Bewege Deine Mouse währenddessen nicht - sonst siehst Du eine Menge Events, die nur von Deiner Mouse erzeugt werden und nicht von den Funktionstasten. Im Terminalfenster siehst Du den Keycode für jede Funktionstaste - so könnte es aussehen:

KeyPress event, serial 30, synthetic NO, window 0x3a00001,
root 0x13b, subw 0x3a00002, time 3282991713, (49,43), root:(1105,203),
state 0x0, keycode 162 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False

KeyRelease event, serial 30, synthetic NO, window 0x3a00001,
root 0x13b, subw 0x3a00002, time 3282991781, (49,43), root:(1105,203),
state 0x0, keycode 162 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False

Notiere die Keycode Nummern - Du brauchst sie später.

2 Die ACPI Events handhaben

Zunächst müssen wir dem ACPI Event-Handler mitteilen, dass unser besonderes Skript, das wir gleich erstellen werden, ausgeführt werden soll, wenn eine Funktionstaste gedrückt wird (Root Privilegien werden benötigt).

vi /etc/acpi/events/hotkeys.conf

Der Inhalt sollte wie folgt aussehen:
# Hotkey configuration
event=hotkey (ATKD|HOTK)*
action=/etc/acpi/actions/hotkeys.sh %e
Als Nächstes erstellen wir ein besonderes Skript, das die Funktionstasten-Events abarbeitet (Root Privilegien werden benötigt).

vi /etc/acpi/events/hotkeys.sh

Im Folgenden werde ich die einzelnen Teile des Skripts beschreiben. Zuerst müssen wir die Shell und die Pfade, in denen das Skript die Anwendungen sucht, die Du ausführen möchtest, definieren.

#!/bin/sh

PATH=/sbin:/bin:/usr/bin

Das Skript kann auf multi-Benutzer Systemen mehr als eine Session handhaben. Wenn Du auf dem System der einzige Benutzer sein solltest, dann gib Deinen Benuzternamen in das entsprechende Feld ein.


# Possible values:
# "0" = multi user system
# "your_username" = single user system
user="0"

Dies ist der Teil, der den Benutzer der derzeitigen Session auf multi-Benutzer Systemen erkennt - hier müssen wir nichts einstellen.


# Detect the currently active user on multi user systems
checkuser()
{
if [ $user = "0" ]
then
uid_session=$(
ck-list-sessions |
awk '
/^Session[0-9]+:$/ { uid = active = x11 = "" ; next }
{ gsub(/'''/, "", $3) }
$1 == "uid" { uid = $3 }
$1 == "active" { active = $3 }
$1 == "x11-display" { x11 = $3 }
active == "TRUE" && x11 != "" {
print uid
exit
}'
)
user_data=(`cat /etc/passwd | grep $uid_session | tr ':' ' '`)
user=${user_data[0]}
fi
}

Nun sind wir beim interessanten Teil angekommen - hier weisen wir den Funktionstasten Aktionen zu. Erinnere Dich an die Funktionstasten-Events von Schritt 1.3.1 - die dritte Stelle der ACPI Events beinhaltet die statische Nummer, die wir benötigen, um die Events unterscheiden zu können. Da wir den ganzen ACPI Event an dieses Skript übergeben haben, müssen wir dem Skript mitteilen, dass es die dritte Stelle des Events verwenden soll - dies ist in $3.

# Assign actions to the hotkeys
case $3 in

Die folgenden Konfigurationen der Funktionstasten sind Beispiele von meinem Laptop (ASUS G1S) - Du musst also die Event-Nummern ersetzen, so dass sie auf Dein System passen. Wir starten den E-Mail Client Evolution. Wenn ich die E-Mail-Funktionstaste auf meinem Laptop drücke, ist die statische Event-Nummer 00000050. Wenn die Taste gedrückt wird, wird die Funktion "checkuser" aufgerufen, um den Bentuzer der derzeitigen Session erkennen zu können. Danach führt das Skript Evolution unter den Rechten des aktuell angemeldeten Bentuzers aus und schickt die Ausgabe ins Nirwana :) Das ist sehr wichtig - sonst würde die Anwendung das Skript blocken bis Du die Anwendung schließt. Vergiss also nicht " &> /dev/null &" an Befehle anzuhängen, die eine Anwendung ausführen, die ausgeführt wird bis Du sie schließt. Hänge " &> /dev/null" an andere Anwendungen an, die eine Ausgabe erzeugen.


# Start Evolution (email button)
00000050)
checkuser
su - $user -c "evolution --component=mail &> /dev/null &"
;;

Die Konfiguration für den Web Browser ist fast die gleiche wie die obere.

# Start Firefox (browser button)
00000051)
checkuser
su - $user -c "firefox &> /dev/null &"
;;

Nun haben wir die Touchpad Konfiguration erreicht. Viele Laptops haben eine besondere Funktionstaste für das Touchpad - wir werden den synclient verwenden um unser Touchpad an und aus zu schalten wenn diese Funktionstaste gedrückt wird (wir haben den Synclient in Schritt 1.2 aktiviert). Dies ist Benutzer-unabhängig, wir müssen die "checkuser"-Funktion also nicht aufrufen.

# Toggle touchpad on|off (touchpad button)
0000006b)
tp_status=(`synclient -l | grep TouchpadOff`)

if [ ${tp_status[2]} = "1" ]
then synclient TouchpadOff=0
else synclient TouchpadOff=1
fi
;;

Als Nächstes müssen wir die Funktionstasten konfigurieren, um die Lautstärke zu verringern und zu erhöhen. Auch das ist Benutzer-unabhängig, denn es gibt nur eine Soundkarte (auf den meisten Systemen).

# Lower volume (Fn + F11)
00000031)
amixer sset Master Playback Volume 5%- &> /dev/null
;;

# Raise volume (Fn + F12)
00000030)
amixer sset Master Playback Volume 5%+ &> /dev/null
;;

Wir benutzen einen kleinen Trick um den Ton auszustellen, da die Real Mute Funktion von amixer ein großes Problem verursacht - die meisten Player brechen zusammen, wenn Du sie verwendest. Wenn die Mute-Funktionstaste gedrückt wird, überprüft das Skript, ob der Sound momentan aktiviert. Wenn ja, schreibt es den derzeitigen Status in eine Datei bevor es die Lautstärke auf 0% stellt. Wenn Du diese Funktionstaste erneut drückst (und die Lautstärke immer noch 0% ist), bezieht das Skript den letzten Lautstärken-Status aus der Datei und stellt ihn wieder her.

# Toggle mute (0% - last state) (Fn + F10)
00000032)
snd_status=(`amixer sget Master Playback Volume | egrep "[on|off]$"`)
cur_vol=$(echo ${snd_status[4]} | tr '[|]|%' ' ')

if [ $cur_vol != "0" ]
then
cat /dev/null > /opt/.volume
echo $cur_vol > /opt/.volume
amixer sset Master Playback Volume 0% &> /dev/null
else
sav_vol=$(cat /opt/.volume)
if [ $sav_vol = "" ]
then amixer sset Master Playback Volume 50% &> /dev/null
else amixer sset Master Playback Volume $sav_vol% &> /dev/null
fi
fi
;;

Zuguterletzt schließen wir die Case Abfrage und beenden das Skript.

esac

exit 0

Speichere die Datei und mach sie ausführbar.

chmod +x /etc/acpi/events/hotkeys.sh

Als Beispiel hier einam das komplette Script.
#!/bin/sh
PATH=/sbin:/bin:/usr/bin
# Possible values:
# "0" = multi user system # "your_username" = single user system user="olli"
# Detect the currently active user on multi user systems
checkuser() { if [ $user = "0" ] then uid_session=$( ck-list-sessions | awk ' /^Session[0-9]+:$/ { uid = active = x11 = "" ; next } { gsub(/'''/, "", $3) } $1 == "uid" { uid = $3 } $1 == "active" { active = $3 } $1 == "x11-display" { x11 = $3 } active == "TRUE" && x11 != "" { print uid exit }' ) user_data=(`cat /etc/passwd | grep $uid_session | tr ':' ' '`) user=${user_data[0]} fi }
# Assign actions to the hotkeys
case $3 in # Start Evolution (email button) 00000050) checkuser su - $user -c "evolution --component=mail &> /dev/null &" ;; # Start Firefox (browser button) 00000051) checkuser su - $user -c "firefox &> /dev/null &" ;; # Toggle touchpad on|off (touchpad button) 0000006b) tp_status=(`synclient -l | grep TouchpadOff`) if [ ${tp_status[2]} = "1" ] then synclient TouchpadOff=0 echo 1 > /sys/class/leds/asus:touchpad/brightness else synclient TouchpadOff=1 echo 0 > /sys/class/leds/asus:touchpad/brightness fi ;; # Lower volume (Fn + F11) 00000031) amixer sset Master Playback Volume 5%- &> /dev/null ;; # Raise volume (Fn + F12) 00000030) amixer sset Master Playback Volume 5%+ &> /dev/null ;; # Toggle mute (0% - last state) (Fn + F10) 00000032) snd_status=(`amixer sget Master Playback Volume | egrep "[on|off]$"`) cur_vol=$(echo ${snd_status[4]} | tr '[|]|%' ' ') if [ $cur_vol != "0" ] then cat /dev/null > /opt/.volume echo $cur_vol > /opt/.volume amixer sset Master Playback Volume 0% &> /dev/null else sav_vol=$(cat /opt/.volume) if [ $sav_vol = "" ] then amixer sset Master Playback Volume 50% &> /dev/null else amixer sset Master Playback Volume $sav_vol% &> /dev/null fi fi ;;
esac
exit 0
Aber Eines müssen wir immer noch tun. Es gibt einen Fehler, der den ACPI Daemon davon abhalten wird, die Befehle in unserem Skript auszuführen, nachdem Du Dein System gestartet/neu gestartet hast. Du musst den ACPI Daemon jedes Mal neu starten, nachdem Du Dich in ein GNOME Session eingeloggt hast. Ich nehme mal an, dass Du das nicht manuell machen möchtest :) Also habe ich einen kleinen Trick für Dich (Root Privilegien werden benötigt).

vi /etc/gdm/Init/Default

Füge folgende Zeilen am Ende der Datei vor "Exit" ein.

# acpid workaround
/etc/init.d/acpid restart

Der entsprechende Teil der Datei sollte wie folgt aussehen:

[...]
# acpid workaround
/etc/init.d/acpid restart
exit 0
Nun wird der ACPI Daemon nach jedem Login automatisch gestartet.

3 Die Xev Events handhaben

Vielleicht hast Du einige Funktionstasten entdeckt, die keinen ACPI Event in Schritt 1.3.1 aber einen Keycode Event in Schritt 1.3.2 erzeugt haben. Wir müssen diese nun konfigurieren - zuerst müssen wir die notwendige Konfigurationsdatei erstellen (ohne Root Privilegien!).

xbindkeys --defaults > $HOME/.xbindkeysrc

Lass sie uns nun bearbeiten.

vi ~/.xbindkeysrc

In der Datei siehst Du eine Beispiel-Konfiguration und einige Notizen. Die Konfiguration ist sehr einfach - füge einfach eine Zeile mit dem Befehl ein, der ausgeführt werden soll und unter dem Keycode (c:%keycode%), der zu dieser Aktion gehört. Hier ist ein Beispiel der Konfiguration auf meinem Laptop (einige Multimedia Funktionstasten wie Start/Pause, Stop etc...).
# MM button actions
# MM play/pause
"/usr/bin/audacious -p" c:162
# MM stop
"/usr/bin/audacious -s" c:164
# MM rewind
"/usr/bin/audacious -r" c:144
# MM forward
"/usr/bin/audacious -f" c:153
Speichere nun die Änderungen und füge xbindkeys (/usr/bin/xbindkeys) den Autostart Programmen (System - Preferences - Personal - Sessions) hinzu. Bitte beachte, dass Du Dich abmelden und wieder anmelden musst damit die Änderungen übernommen werden können.

4 Links