# Configure hotkeys on Thinkpad X240



## Glats (Jul 24, 2020)

Hi!
if i understand correctly you can configure hotkeys (volume, brightness, etc) through devd(8) but i couldn't made it work.

Here is what i configured:
/etc/devd/x240.conf

```
notify 10 {
    match "system"      "ACPI";
    match "subsystem"   "IBM";
    action "/usr/local/sbin/acpi_oem_exec.sh $notify ibm";
};
```
/usr/local/sbin/acpi_oem_exec.sh

```
#!/bin/sh
if [ "$1" = "" -o "$2" = "" ]
then
    echo "usage: $0 notify oem_name"
    exit 1
fi
NOTIFY=`echo $1`
LOGGER="logger"
OEM=$2
DISPLAY_PIPE=/tmp/acpi_${OEM}_display
VOL_LEVEL=/tmp/vol_${OEM}
if [ ! -f $VOL_LEVEL ]
then
    VOL="`mixer -s vol | awk -F' ' '{split($2,a,":"); print (a[1]+a[2])/2}'`"
    echo $VOL > $VOL_LEVEL
fi
MIC_LEVEL=/tmp/mic_${OEM}
if [ ! -f $MIC_LEVEL ]
then
    VOL="`mixer -s mic | awk -F' ' '{split($2,a,":"); print (a[1]+a[2])/2}'`"
    echo $VOL > $MIC_LEVEL
fi
case ${NOTIFY} in
    0x01)
        MUTE=`sysctl -n dev.acpi_${OEM}.0.mute`
        if [ "$MUTE" = "1" ]
        then
            cat $VOL_LEVEL | xargs mixer vol
            sysctl dev.acpi_${OEM}.0.mute=0
            MESSAGE="vol unmute"
        else
            mixer vol 0
            sysctl dev.acpi_${OEM}.0.mute=1
            MESSAGE="vol mute"
        fi
        ;;
    0x02)
        mixer vol -5
        MESSAGE="vol down"
        ;;
    0x03)
        mixer vol +5
        MESSAGE="vol up"
        ;;
    0x04)
        LED=`sysctl -n dev.acpi_${OEM}.0.mic_led`
        if [ "$LED" = "1" ]
        then
            cat $MIC_LEVEL | xargs mixer mic
            sysctl dev.acpi_${OEM}.0.mic_led=0
            MESSAGE="mic unmute"
        else
            mixer mic 0
            sysctl dev.acpi_${OEM}.0.mic_led=1
            MESSAGE="mic mute"
        fi
        ;;
    0x05)
        BRI=`sysctl -n hw.acpi.video.lcd0.brightness`
        R=`echo $BRI-5 | bc`
        sysctl hw.acpi.video.lcd0.brightness=$R
        MESSAGE="brightness up"
    ;;
    0x06)
        BRI=`sysctl -n hw.acpi.video.lcd0.brightness`
        R=`echo $BRI+5 | bc`
        sysctl hw.acpi.video.lcd0.brightness=$R
        MESSAGE="brightness down"
        ;;
    0x08)
        WLAN=`sysctl -n dev.acpi_${OEM}.0.wlan`
        if [ "$WLAN" = "1" ]
        then
            sysctl dev.acpi_${OEM}.0.wlan=0
            MESSAGE="wlan down"
        else
            sysctl dev.acpi_${OEM}.0.wlan=1
            MESSAGE="wlan up"
        fi
        ;;
esac
${LOGGER} ${MESSAGE}
if [ -p ${DISPLAY_PIPE} ]
then
    ${ECHO} ${MESSAGE} >> ${DISPLAY_PIPE} &
fi
exit 0
```

Thanks!


----------



## George (Jul 24, 2020)

Hey,
Did you load acpi_ibm(4)? Did you restart devd() after editing the config file?
Did you chmod() the shell script to make it executable?


----------



## Mjölnir (Jul 24, 2020)

RTFM test(1) Sorry, bulls*t quick shot, I did not have my 2nd coffee yet.
EDIT: The acpi-ibm is very outdated.  It works for old IBM ThinkPads, but not for the newer Lenovo ones. You can disable most part of the script and just write out the value of $notify for each special key you press.  Then adjust the script.


----------



## JohnnySorocil (Jul 28, 2020)

Is it necessary to use devd? My T430s has working brightness (I think it only works after loading i915kms module), volume up&down, changing sound from internal speakers to headphones. Mute works but only when internal speakers are used (headphones will no be muted even mute LED is lit).
Did not try to disable WLAN with hotkeys (but suspend with hotkeys works).


----------



## Mjölnir (Jul 28, 2020)

JohnnySorocil said:


> Is it necessary to use devd? My T430s has working brightness (I think it only works after loading i915kms module), volume up&down, changing sound from internal speakers to headphones. Mute works but only when internal speakers are used (headphones will no be muted even mute LED is lit).
> Did not try to disable WLAN with hotkeys (but suspend with hotkeys works).


IMHO yes, you need devd(8) for this.  E.g. I have a T450s and only sound vol +/- & mute (w/ + w/o headphones) works out of the box via the function keys.  Don't remember if mic, WLAN, camera on/off works.  With (nearly?) every new model, some scancodes change... 
Off-topic: since you guys have ThinkPads, you may want to become victims to test my Howto hibernate.  I'd like to have more feedback if this is a good workaround to hibernation from OS.  You can use your swap partition & swap to a ZVOL instead.


----------



## Glats (Jul 30, 2020)

Elazar said:


> Hey,
> Did you load acpi_ibm(4)? Did you restart devd() after editing the config file?
> Did you chmod() the shell script to make it executable?


Indeed!



mjollnir said:


> RTFM test(1) Sorry, bulls*t quick shot, I did not have my 2nd coffee yet.
> EDIT: The acpi-ibm is very outdated.  It works for old IBM ThinkPads, but not for the newer Lenovo ones. You can disable most part of the script and just write out the value of $notify for each special key you press.  Then adjust the script.



How can debug it? To see what specials work in my laptop. 
Can you give an example?


----------



## George (Jul 30, 2020)

I would backup the script and then spam it with 30 or more `echo` statements. Let the script tell you what's going wrong.


----------



## Mjölnir (Jul 30, 2020)

For safety & convenience, you can set _noclobber_ & _nounset_, and source rc.subr(8) (among other useful functions _err(), warn(), info(), debug()_) in your script.


----------



## Glats (Jul 31, 2020)

do you all mean to run the script directly? but how do I know if 0x01 is Fn+F1 for example.


----------



## Mjölnir (Jul 31, 2020)

Glats said:


> do you all mean to run the script directly? but how do I know if 0x01 is Fn+F1 for example.


Because noone else could have pressed that key?  The objective is that you write a key logger.  You press a key, your script tells "42", you press the next key, ...
Yesterday I `cp /usr/local/share/examples/intel-backlight/acpi-video-intel-backlight.conf /usr/local/etc/devd/` and
`service devd restart`, now I have brightness +/- and not only sound +/-


----------

