1

I bought my mom a laptop some time ago with an unfortunate keyboard layout. OS is Linux Mint 18.2 Cinnamon 64-bit.

The thing is, instead of having F1 - F12 keys, she has different buttons for multimedia and more importantly an Airplane mode button. The F1 - F12 keys can be reached via Fn.

Because we have quite many pets, they often jump on the keyboard pressing multiple buttons including the Airplane mode button, thus disconnecting her from internet, which she complains about lately.

In BIOS I don't see a way to switch to normal keyboard layout. So, question for you is:

Is there a way to disable Airplane mode button on laptop keyboard?

EDIT1:

It is impossible to keep the pets out of the room, because they are integral part of our household.

Of course, when mom is not at the computer, she closes the lid. But they jump on the laptop when she is at the laptop. Cats can be real pain in this sense :)

EDIT2:

When Airplane mode is turned off, i.e. wireless is on, the following command:

rfkill list all

outputs:

0: ideapad_wlan: Wireless LAN
    Soft blocked: no
    Hard blocked: no
1: ideapad_bluetooth: Bluetooth
    Soft blocked: yes
    Hard blocked: no
2: hci0: Bluetooth
    Soft blocked: yes
    Hard blocked: no
3: phy0: Wireless LAN
    Soft blocked: no
    Hard blocked: no

EDIT3:

Once Airplane button is pressed the wireless according to the previous command is blocked Soft.

EDIT4:

acpi_listen

when the button is pressed, outputs:

button/wlan WLAN 00000080 00000000 K 

EDIT5:

sudo evtest

output:

No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:    Lid Switch
/dev/input/event1:    Power Button
/dev/input/event2:    Power Button
/dev/input/event3:    AT Translated Set 2 keyboard
/dev/input/event4:    MOSART Semi. 2.4G Wireless Mouse
/dev/input/event5:    Video Bus
/dev/input/event6:    Video Bus
/dev/input/event7:    ETPS/2 Elantech Touchpad
/dev/input/event8:    Ideapad extra buttons
/dev/input/event9:    Lenovo EasyCamera
/dev/input/event10:    HDA Intel PCH Mic
/dev/input/event11:    HDA Intel PCH Headphone
/dev/input/event12:    HDA Intel HDMI HDMI/DP,pcm=3
/dev/input/event13:    HDA Intel HDMI HDMI/DP,pcm=7
/dev/input/event14:    HDA Intel HDMI HDMI/DP,pcm=8 
Select the device event number [0-14]: 8
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x0 product 0x0 version 0x0
Input device name: "Ideapad extra buttons"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 1 (KEY_ESC)
    Event code 148 (KEY_PROG1)
    Event code 149 (KEY_PROG2)
    Event code 186 (KEY_F16)
    Event code 192 (KEY_F22)
    Event code 193 (KEY_F23)
    Event code 202 (KEY_PROG3)
    Event code 203 (KEY_PROG4)
    Event code 212 (KEY_CAMERA)
    Event code 227 (KEY_SWITCHVIDEOMODE)
    Event code 238 (KEY_WLAN)
    Event code 240 (KEY_UNKNOWN)
    Event code 248 (KEY_MICMUTE)
  Event type 4 (EV_MSC)
    Event code 4 (MSC_SCAN)
Properties:
Testing ... (interrupt to exit)
Event: time 1508927031.158643, type 4 (EV_MSC), code 4 (MSC_SCAN), value 0d
Event: time 1508927031.158643, type 1 (EV_KEY), code 238 (KEY_WLAN), value 1
Event: time 1508927031.158643, -------------- SYN_REPORT ------------
Event: time 1508927031.158680, type 1 (EV_KEY), code 238 (KEY_WLAN), value 0
Event: time 1508927031.158680, -------------- SYN_REPORT ------------
  • What about using a hard keyboard cover when the computer is unattended? Or keeping pets out of the table/room? – dr01 Oct 25 '17 at 9:17
  • @dr01 We've rendered both options not possible. I'll update my question. – LinuxSecurityFreak Oct 25 '17 at 9:18
  • 1
    If you disable Airplane mode: what rfkill list all say? I mean if you switch Airplane mode does it make "hard bocked" your wifi? Other question: What acpi_listen show when you press the Airplane mode? There is another event checking program evtest, but here we need the keyboard input handler (for me it is /dev/input/event3). – V-Mark Oct 25 '17 at 9:21
  • @V-Mark I added the information except for evtest, do you need it too? – LinuxSecurityFreak Oct 25 '17 at 9:38
  • @GAD3R Wouldn't this affect all these keys? – LinuxSecurityFreak Oct 25 '17 at 9:40
2

I do not have the exact hadware, but I tried to find a "similar case" in my system:

  • One was the power button. Target is to enter a key (eg key "4") instead of power. (for me it sits in /dev/input/event2 and emits a

    root# evtest /dev/input/event2
    Event: time 1509218410.222521, type 1 (EV_KEY), code 116 (KEY_POWER), value 1
    Event: time 1509218410.222521, -------------- SYN_REPORT ------------
    Event: time 1509218410.222552, type 1 (EV_KEY), code 116 (KEY_POWER), value 0
    Event: time 1509218410.222552, -------------- SYN_REPORT ------------

  • The other is (this is why I am interested in soo deeply): I also have a WIFI button, but "does not do anything". While I understand input events, I wanna correct this - for fun. Here the target is to do something.
    This Fn+F3 emits (from normal keyboard input device)

    root# evtest /dev/input/event3
    Event: time 1509218870.384483, type 4 (EV_MSC), code 4 (MSC_SCAN), value 86
    Event: time 1509218870.384483, -------------- SYN_REPORT ------------

This Fn+F3 originally gave a warning line in syslog

kernel: [44802.485207] atkbd serio0: Unknown key released (translated set 2, code 0x86 on isa0060/serio0).
kernel: [44802.485210] atkbd serio0: Use 'setkeycodes e006 ' to make it known.

What I did so far:

  • run many series of setkeycodes
    Neither evdev nor "real life" ever saw any changes, however with setkeycodes e006 5 or setkeycodes 86 5 the syslog entry was gone.
  • created hwdb file in /etc/udev/hwdb similar like - this eliminated the syslog message also - BUT DID NOTHING ELSE:

    evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*
    KEYBOARD_KEY_86=5

  • created udev rule in /etc/udev/rules.d (and made it effect)
    it runs (because I see the "Power button INHIBIT string" and see all modified tags), I can change any attribute (played mainly for power button)
    Here is my rule file:

    ACTION!="add|change", GOTO="pwr_kbd_end"
    SUBSYSTEM!="input", GOTO="pwr_kbd_end"
    KERNEL!="event[0-9]*", GOTO="pwr_kbd_end"
    ENV{ID_PATH_TAG}=="acpi-LNXPWRBN_00", OPTIONS+="last_rule", RUN+="/usr/bin/logger -t Power button INHIBIT %k", ENV{KEYBOARD_KEY_116}="KEY_A",\ TAG:="whatisthis", ENV{EV_KEY_116}="KEY_B", \ ENV{BTN_116}="KEY_C",ENV{BTN_POWER}="KEY_D", ENV{KEY_POWER}="KEY_E" LABEL="pwr_kbd_end"

    However I read and realized that rules are for "system changes", like connecting or disconnecting something, modifying (like making new partition, or playing with modechange 3G dongles), but they are nothing to do with the actual key event handling (however they could have influence). Meanwhile OPTIONS+="last_rule" seems not working - I entered this file as 01-myrule.rule and as a hard link 98-myrule.rule - both are "working".

  • Then I focused my interest to handle the events:
    I copied a evtest.py python script and played a bit.
    My concept was "intercept the power putton event, do not pass through and inject another one (eg KEY_4 - value 5 - as I tried in my previous tests).

    THIS was almost total success. (this could be your solution as well)

    from __future__ import print_function
    
    import sys
    import select
    
    from evdev import ecodes, list_devices, AbsInfo, InputDevice, UInput
    
    def main():
      device = InputDevice("/dev/input/event2") # yours should be checked... NOT necessalirly always event8 
      device.grab()
      ui = UInput()
    
      print('Listening for events (press ctrl-c to exit) ...')
      fd_to_device = {device.fd: device}
    
      while True:
        r, w, e = select.select(fd_to_device, [], [])
    
        for fd in r:
          for event in fd_to_device[fd].read():
            if (event.type == 1) and (event.code==116): # yours is 238
              print_event(event)
              event.code=5
              event.value=1
              ui.write(event.type, event.code, event.value) # just delete/comment this section if you do not wanna do anything
              ui.syn
              event.value=0
              ui.write(event.type, event.code, event.value)
              ui.syn
            else:
              ui.write(event.type, event.code, event.value)
              ui.syn
    
    
    def print_event(e):
      if e.type == ecodes.EV_SYN:
        if e.code == ecodes.SYN_MT_REPORT:
          msg = 'time {:<16} +++++++++ {} ++++++++'
        else:
          msg = 'time {:<16} --------- {} --------'
        print(msg.format(e.timestamp(), ecodes.SYN[e.code]))
      else:
        if e.type in ecodes.bytype:
          codename = ecodes.bytype[e.type][e.code]
        else:
          codename = '?'
    
      evfmt = 'time {:<16} type {} ({}), code {:<4} ({}), value {}'
      print(evfmt.format(e.timestamp(), e.type, ecodes.EV[e.type], e.code, codename, e.value))
    
    
    if __name__ == '__main__':
      try:
        ret = main()
      except KeyboardInterrupt:
        ret = 0
      sys.exit(ret)
    

Again, no matter if I am in console or X - when this script is running, I get a key (currently it is doubble somehow) instead of "power switch".

  • I intercepted (but let them pass through the keyboard events) and when I found my magical 86 code, I injected an EV_KEY sequence (EV_KEY KEY_4 down, SYN, EV_KEY KEY_4 up, SYN)
    This is partial success however, because events somehow stuck and wait for each other and they show up as a bunch of 4 (I used python -u wifi.py) - so I try to be unbuffered. Here there is no doubbling: I press the Wifi button 4 times, I get '4444' - in console, as well as in X.
  • I highly appreciate your help. I'll try it out probably tomorrow. In the meantime I leave it with upvote. I'll accept it if working. – LinuxSecurityFreak Oct 29 '17 at 7:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.