如何将X11键码可靠地转换回扫描码或隐藏使用ID

h.n*_*h.n 6 linux hid

几乎自我解决了.

背景信息

linux keycode

以下是:linux_xmodmap_tutorial

  • 扫描码→键盘发送到计算机的号码.对于USB键盘,它由USB标准定义.

  • 键码→Linux内核用来表示键(或鼠标键/滚轮)的数字.Linux内核将scancode转换为keycode.

  • Keysym→密钥的名称.keysym由X11应用程序接收.

我可能错了,但是什么sudo evtest打印看起来像扫描码设置1,因为/dev/input/event*输出类似,至少我的系统扫描码和linux键码大致相同.

X11键码

xev命令打印keycode和keysym,我观察到键码不会改变,无论我使用的键盘布局如何; qwerty和dvorak布局产生不同的键,但是相同的键码.
然而,它不是linux密钥代码,也不是隐藏使用id,也不是任何一个扫描代码集; set1,set2也不是set3.

linux keycode是如何生成的?

根据arch wiki(我无法发布链接):
/etc/udev/hwdb.bin将scancode转换为keycode.

显而易见的是:

  1. 维基说有可以编译的非默认*.hwdb文件 hwdb.bin
  2. hwdb.bin 可以检测不同的键盘,并可以不同地将扫描码转换为键码.

对于ubuntu,我能找到的唯一的hwdb文件是:/etc/udev/hwdb.d/61-keyboard-local.hwdb这几乎是空的.因此,默认情况下,ubuntu会保留默认扫描码并将其用作我认为的密钥代码.

如何生成X11键码

一些黑客在这里给我们留下了线索:https
://www.charvolant.org/doug/xkb/html/index.html扫描码到键码映射规则文件(正在使用哪一个是问题)在:/usr/share/X11/xkb/keycodes

setxkbmap -print -verbose 10 版画

Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Run Code Online (Sandbox Code Playgroud)

所以,上面的文件应该控制Xkb的加载行为(Linux变化很多,所以不应该期待将来相同).

示例:
setxkbmap -print -verbose 10

Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      pc105
layout:     us,us
variant:    dvp,
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us(dvp)+us:2+inet(evdev)
geometry:   pc(pc105)
xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)" };
    xkb_types     { include "complete"  };
    xkb_compat    { include "complete"  };
    xkb_symbols   { include "pc+us(dvp)+us:2+inet(evdev)"   };
    xkb_geometry  { include "pc(pc105)" };
Run Code Online (Sandbox Code Playgroud)

A节中/usr/share/X11/xkb/rules/evdev这很可能是控制键码文件装载行为:

! model         =       keycodes
  pc98          =       evdev(pc98)
  applealu_jis  =       evdev+macintosh(jisevdev)
  olpc          =       evdev+olpc(olpc)
  olpcm         =       evdev+olpc(olpcm)
  *             =       evdev

! layout[1]     =       keycodes
  $azerty       =       +aliases(azerty)
  $qwertz       =       +aliases(qwertz)
  *             =       +aliases(qwerty)
Run Code Online (Sandbox Code Playgroud)

我猜

XServer查看键盘的供应商ID和设备ID,并应用不同的规则将scancode转换为keycode.

我可以从X11键码获取扫描码吗?

xkb/keycodes/evdev 似乎被用作大多数键盘的转换规则,使用它可能会成功.

它可靠吗?


传统的X11核心协议不提供生成键盘事件的键盘的供应商ID和设备ID.

潜在解决方案

XI2 - X输入扩展2.x
https://www.x.org/releases/X11R7.7/doc/inputproto/XI2proto.txt

A RawEvent provides the information provided by the driver to the
client. RawEvent provides both the raw data as supplied by the driver and
transformed data as used in the server.   
Run Code Online (Sandbox Code Playgroud)

现在我尝试了RawKeyPress

我无法提取隐藏使用ID和扫描码;虽然也许我只是忽略了它们.
捕获XI2 RawKeyPress事件并使用python解释它