xkb: problem in key-mapping for the acpi video event keycodes
Hong Liu
hong.liu at intel.com
Thu Jan 3 23:33:48 PST 2008
Currently in Linux kernel, there are some new keys defined for ACPI
video events, like KEY_SWITCHVIDEOMODE(227)
KEY_BRIGHTNESSUP(224) /KEY_BRIGHTNESSDOWN(225) ...
These keycodes will be reported to the input layer of Linux kernel by
ACPI video driver when pressing the hotkeys on laptop.
f.e pressing Fn+F7 on a thinkpad T61, KEY_SWITCHVIDEOMODE will be
reported.
The problem is the keycode received by X server that will be delivered
to X clients is not what supposed to be.
For KEY_SWITCHVIDEOMODE (227), X are supposed to receive 235 (227 + 8).
But we are receiving 214 instead.
After some investigation, I found the reason.
There are two parts involved.
1. kernel(Linux) part (driver/char/keyboard.c)
This file implements an input handler (kbd_handler) used to receive key
events from the kernel input layer. So when acpi video driver sends
KEY_SWITCHVIDEOMODE(227) to the input layer, kbd_event() will be called
for this event.
kbd_event -> emulate_raw (with keycode == 227)
use x86_keycodes[] to map keycode 227 -> 342
**I am still not sure about the meaning of this mapping**
and then it will put "0xe0 0x56(342 & 0x7f)" to the input queue
of the associated tty device. (for X server, usually it
is /dev/tty7)
2. X server keyboard driver (xf86-input-keyboard)
This keyboard driver will listen to the /dev/tty7 file for keyboard
input from kernel. Once there is new data coming, it will call this
keyboard's PostEvent function to post the event to X server.
stdReadInput -> kbdPostEvent
We will read "0x60 0x56" for the above "0xe0 0x56" input.
(It seems the tty layer also has done some mapping)
0x60 is a special keycode (KEY_Prefix0), it is used to
mapping the following keycode to a new scancode.
-> RemapScanCode (ATScancode)
in this func, scancode 0x56 will be converted to a new
scan code 0x56+0x78 (206).
later in kbdPostEvent, all the scancodes will be added by
MIN_KEYCODE (8), thus we get 214 for the KEY_SWITCHVIDEOMODE.
So there are 2 options here:
1. We accept 214 as the mapping of the KEY_SWITCHVIDEOMODE from kernel.
So we can bind the XF86Display keysym of Xserver to keycode 214.
2. We can have a patch for the xf86-input-keyboard driver, adding a new
mapping for KEY_SWITCHVIDEOMODE like the following one:
diff --git a/src/at_scancode.c b/src/at_scancode.c
index b945914..c5c627a 100644
--- a/src/at_scancode.c
+++ b/src/at_scancode.c
@@ -109,6 +109,7 @@ ATScancode(InputInfoPtr pInfo, int *scanCode)
case KEY_F6: *scanCode = KEY_F16; break;
case KEY_F7: *scanCode = KEY_F17; break;
case KEY_KP_Plus: *scanCode = KEY_KP_DEC; break;
+ case 0x56: *scanCode = 227; break;
case 0x2A:
case 0x36:
return TRUE;
Thus we can get keycode 235 in X server for KEY_SWITCHVIDEOMODE.
I am not sure whether one is the correct choice.
Thanks,
Hong
More information about the xorg
mailing list