KDGKBENT 返回错误的键符号值?

问题描述 投票:0回答:1

示例代码:

#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”背后的解释,但我需要找到关于这个理论的确认。

c unicode linux-kernel keyboard keycode
1个回答
0
投票

我也遇到了这个问题,所以我决定检查为什么转储键在我的代码中不起作用,并找到了这段代码:

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)。

它解决了我的问题

© www.soinside.com 2019 - 2024. All rights reserved.