Pergunta
Existe alguma maneira de negociar e ativar programaticamente o NKRO (N-Key Rollover) para teclados conectados quando esse recurso estiver disponível? Além disso, como distinguir corretamente entre o manipulador de "modo padrão" e o NKRO?
Justificativa
Eu tenho três teclados diferentes que se comportam de maneira um pouco diferente um do outro e até mesmo entre plataformas. Todos eles apoiam o NKRO à sua maneira. Meu principal problema é que um deles não possui nenhuma combinação de teclas para impor/alternar o modo NKRO, isso só pode ser feito pelo driver/SO.
Testes
Joguei com meus teclados em plataformas Windows 10
e Linux 5.10.17+
(Pi Zero). Meus dispositivos são Razer Ornata Chroma
, HyperX HX-KB1BR1-NA
e Havit HV-KB390L
. Acho que posso colocar algumas descrições de comportamento desses dispositivos aqui.
Estou standard mode
me referindo a um pacote USB de baixa velocidade e tamanho de 8 bytes, que é comumente usado. Estou game-mode
me referindo a um recurso específico do teclado, se disponível.
Windows
- Razer: NKRO enabled by default regardless of game-mode state, game-mode only disables Win key,
game-mode state stored only by platform driver
(Razer Central installed)
- Havit: NKRO enabled by default, game-mode does nothing (probably configured via software)
(no additional software installed)
- HyperX: stores NKRO state internally in keyboard and enforces it, game-mode disables Win key only
(no additional software installed)
Linux
- Razer: standard mode by default, game-mode enforces NKRO and disables Win key
- Havit: standard mode by default, game-mode does nothing, There is no key sequence to enforce NKRO
- HyperX: behaves the same as on Windows, internal state changes works between platforms
Então, com isso, HyperX
a implementação do modo padrão/comutação NKRO é a mais preferida por mim, Razer
pelo menos fornece uma combinação de teclas para impor o NKRO (embora necessário em cada conexão/inicialização), Havit
infelizmente não oferece uma opção para ativar o NKRO através qualquer combinação de teclas.
Pesquisei o código-fonte e a documentação do Linux - /drivers/input
, /Documentation/input
, /drivers/hid/hid-input.c
, mas não encontrei nada que me ajudasse a aplicar o NKRO, e entender o código C também não é a tarefa mais fácil para mim. A única coisa que descobri que menciona NKRO é esta linha:
#define HP_SDC_CFG_ROLLOVER 0x08 /* WTF é "n-key rollover"? */
Bem, não é realmente útil.
Então, é possível habilitar o NKRO do lado do sistema operacional?
Diferencie manipuladores padrão e NKRO
Durante meus testes, descobri que esses dois modos diferentes estão relacionados a dois eventX
manipuladores diferentes. Podemos inspecionar /proc/bus/input/devices
o arquivo e encontrar mais contexto.
I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard"
P: Phys=usb-20980000.usb-1.1/input0
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.0/0003:0951:16B7.0001/input/input0
U: Uniq=
H: Handlers=sysrq kbd leds event0
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f
I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard Mouse"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input1
U: Uniq=
H: Handlers=mouse0 event1
B: PROP=0
B: EV=17
B: KEY=1f0000 0 0 0 0 0 0 0 0
B: REL=1943
B: MSC=10
I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard System Control"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input2
U: Uniq=
H: Handlers=kbd event2
B: PROP=0
B: EV=13
B: KEY=c000 100000 0 0 0
B: MSC=10
I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard Consumer Control"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input3
U: Uniq=
H: Handlers=kbd event3
B: PROP=0
B: EV=1f
B: KEY=3f 301ff 0 0 0 0 483ffff 17aff32d bfd44446 0 0 1 130ff3 8b17c000 677bfa d9415fed 19ed680 4400 0 10000002
B: REL=1040
B: ABS=1 0
B: MSC=10
I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input5
U: Uniq=
H: Handlers=sysrq kbd event4
B: PROP=0
B: EV=100013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
Esse formato de arquivo é bem explicadoaqui
No HyperX
caso, existem cinco manipuladores diferentes disponíveis (pode ser mais/menos em outros):
- manipulador para eventos de teclado, modo padrão
- manipulador de mouse (por exemplo, teclado USB remoto com touchpad). Presumo que esteja sempre lá por design
- apenas referindo-se ao seu nome "Controle do Sistema", ele fornece eventos de energia, suspensão, etc.
- referindo-se a "Controle do Consumidor", fornece eventos para multimídia e teclas especiais relacionadas
- manipulador para eventos NKRO
Posso encontrar facilmente o manipulador de teclado do "modo padrão" procurando EV=120013
(também não tenho certeza se é a maneira correta). Nesse caso específico, eu poderia procurar outras entradas com um bitmap idêntico de chaves suportadas, mas infelizmente caso Havit
esse bitmap seja bem diferente. Outro padrão que vejo e que pode ser útil é procurar sysrq
em manipuladores, porém não sei o que significa.
E é isso.
Como posso encontrar corretamente ambos standard mode
os NKRO
manipuladores para um determinado teclado?