示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <linux/keyboard.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
int
main(int argc, char **argv) {
struct kbentry ke;
ke.kb_table = (unsigned char)atoi(argv[1]);
ke.kb_index = (unsigned char)atoi(argv[2]);
ioclt(0, KDGKBENT, &ke);
printf("keycode %u = %04x\n", ke.kb_index, ke.kb_value);
return 0;
}
当我尝试使用例如获取键码的值时上面的代码中,KDGKBENT 返回奇怪的值。它向 ASCII 字符添加“0B”:0x0B61 表示“a”而不是 0x0061,0x0B41 表示“A”而不是 0x0041。
我在互联网上找不到有关此情况的任何答案。
我只找到了同样的问题,没有任何答案: https://www.unix.com/unix-for-advanced-and-expert-users/178627-questions-about-linux-console-keyboard-driver-translation-tables.html
运行 dumpkeys -l 时,0x0Bxx 中的值不会出现(字母具有正常的 ASCII 值),也不会出现在此列表中: https://wiki.linuxquestions.org/wiki/List_of_keysyms
为什么会出现这种情况?我该如何获得正确的转换?
实际上,仔细查看转储键表,字母键符号是“+a”、“+A”等,即它们是通过大写锁定来改变大小写的。可能是“0x0B”背后的解释,但我需要找到关于这个理论的确认。
我也遇到了这个问题,所以我决定检查为什么转储键在我的代码中不起作用,并找到了这段代码:
if (KTYP(code) == KT_LETTER)
code = K(KT_LATIN, KVAL(code));
其中 code 是来自的 ke.kb_value
struct kbentry ke;
ke.kb_table = 0; // no mdifiers
ke.kb_index = 16; //q
ke.kb_value = 0;
ioctl(fd, KDGKBENT, (unsigned long)&ke);
它检查字母键并将它们转换为拉丁版本(通过将 KTYP 从 KT_LETTER 更改为 KT_LATIN)。
它解决了我的问题