操控键盘防鬼影

操控键盘防鬼影

假设我同时按顺序按住 3 个键 E、R、F。

由于按键重影,键盘无法将该组合与其他组合(可能是 ERFG、ERG 或 EFG)区分开来,并假定只按下了 2 个键 E 和 R。

我理解这是硬件限制。但是,是否可以将键盘状态映射到另一种组合,例如 ERF?

换句话说,我希望每当我按住 ERF 或与 ERF 无法区分的其他组合键时,系统都会注册 ERF 被持有的情况。

作为参考,我的操作系统是 Arch Linux,我的键盘型号是 Fühlen L411。

答案1

如果键盘不需要额外的(自定义或特定于供应商的)驱动程序就能像 USB 键盘一样工作,那么我认为……部分可能。

人机接口设备 (HID) 的设备类别定义文件来自usb.org 文档库。相关部分如下:

第 62 页,键盘实现 [重点是我的]:

以下是USB键盘的设计要求:

  • 在输入(数组、绝对)项中必须报告非修饰键。报告必须包含当前按下的按键列表,而不是通断代码(相关数据)

  • [...]

  • 键盘必须以空闲速率或在接收到Get_Report请求时发送数据报告,即使没有新的键事件。

  • 每当按下的键数超过报告计数时,键盘必须在所有数组字段中报告幻影状态索引用法(ErrorRollOver)。[...]此外,当按下无效或无法识别的组合键时,键盘可能会报告幻影情况。

  • [...]

    Key Event   Modifier Byte  Array  Array  Array  Comment
    ---------------------------------------------------------------------
    None        00000000B      00H    00H    00H
    RALT down   01000000       00     00     00
    None        01000000       00     00     00     Report current key
                                                    state even when no
                                                    new key events.
    A down      01000000       04     00     00
    X down      01000000       04     1B     00
    B down      01000000       04     05     1B     Report order is
                                                    arbitrary and does
                                                    not reflect order of
                                                    events.
    Q down      01000000       01     01     01     Phantom state.
                                                    Four Array keys
                                                    pressed. Modifiers
                                                    still reported.
    A up        01000000       05     14     1B
    B and Q up  01000000       1B     00     00     Multiple events in
                                                    one report. Event
                                                    order is
                                                    indeterminate.
    None        01000000       1B     00     00
    RALT up     00000000       1B     00     00
    X up        00000000       00     00     00 
    

注意:此示例使用 4 字节报告,以便更容易演示幻影情况。大多数键盘的报告应包含 8 个或更多字节。

请注意,尽管“大多数键盘的报告应包含 8 个或更多字节”,但键盘“在按下无效或无法识别的组合键时可能会报告幻影情况”。这意味着,如果键盘本身无法识别组合键(例如,内部接线使得某些组合键甚至对于键盘电子设备都无法区分),它会在所有数组字段中报告幻影状态。

此外,即使键盘本身可以区分,您也无法区分一个幻像状态与另一个幻像状态(例如,所有包含的幻像状态E可能与所有包含的幻像状态区分开来M,但键盘仍必须以相同的方式报告它们以遵守规范)。您可以使用的唯一有用信息是最后一个非幻像状态。

一般来说,键盘输入被处理为扫描码,然后输入键码(参见这篇关于键盘输入的文章)。扫描码是按下/释放事件,而不是绝对数据。由于 USB 键盘的报告“必须包含当前按下的按键列表,而不是接通/断开代码”,我猜是驱动程序将报告转换为扫描码。

我不知道幻影状态是否反映在扫描码中。我估计不是,但我现在无法检查(答案将被编辑)。showkey -ask我尝试使用(tty2 和 X11)和(X11)测试xinput --test幻影状态是否反映在扫描码、键码中。我使用了笔记本电脑键盘(可能不使用 USB,没有踪迹lsusb)和外部 USB 键盘。没有迹象表明幻影状态在此级别报告。如果我是对的,所有“正常”的重新映射键的方法都对您不起作用。

但是,如果您编写了可以访问键盘发送的报告的自定义驱动程序,那么您肯定可以检测到幻影状态。但是,由于上述限制,您能做的最好的事情是:

  • 制作任何幻影状态就像按下了E++R一样;F
  • 制作任何按下+ +后立即进入幻影状态(非幻影)ERERF

答案2

最好的办法是定义一个自定义控制台键盘映射

请注意,这仅在硬件级别上尚未发生键盘重影时才会起作用,即,当同时按下时,键盘不会为键 E、F、R 发送事件,而只会为这三个键中的一个发送事件。

您可以在调用“sudo showkey”或“sudo showkey -s”时检查键盘生成了哪些键码/扫描码(-s)。

相关内容