C 中的按键按下和按键释放中断
Key pressed and key released interrupts in C
有没有办法在简单的 C 程序中的 while (1)
循环中捕获 KEY PRESSED 和 KEY RELEASED 事件Linux 运行 来自终端机 window.
如果按下一个键,kbhit()
将 return true
,getch()
return 是按下的字符。
如何捕获 RELEASE 事件?
您不能以可移植的方式执行此操作。终端(以及 xterm 等终端的模拟器)只为您提供按下的键,而不是释放事件。图形用户界面通常提供接收单独的按下和释放事件的能力。
终端仿真器 运行 在图形环境中将这些事件组合成单独的字符。在图形环境中读取时,这些是 关键符号 ,其中可能包含 个字符 。除了按键事件本身的按下和释放事件外,您还可以使用 修饰符 ,例如 shift 修饰符、控制修饰符和元修饰符,它们是单独的事件。如果你 运行 xev
,你可以看到这些单独的事件。
将这些事件组合成一个字符后,终端仿真器可能会将其作为一系列数据字节发送到您的应用程序,例如,以 UTF-8 编码。当您使用 getch()
时,ncurses 库读取这些字节,并将它们再次组合成一个字符。在这两者(终端仿真器和应用程序)之间是伪终端和 its 转换,终端仿真器和应用程序都必须操作它们。
如果您不 运行宁愿使用图形环境,除了图形应用程序(例如xev
)之外,还有(并非总是)其他方式可以直接读取关键 press/release 事件。 Linux 控制台支持。例如,参见 Receiving key press and key release events in Linux terminal applications?
中引用的链接
这适用于我 xterm
和 openbox
window 经理:
xinput test-xi2 --root |
awk -v id="$(
xwininfo -children -id "$WINDOWID" |
awk ' == "Parent" {print }'
)" '
== "EVENT"{e = $NF}
== "detail:" {k = }
== "child" && == id && e ~ /Key/ {print e, k}'
输出类似:
(KeyRelease) 36
(KeyPress) 38
a(KeyRelease) 38
s(KeyPress) 39
d(KeyPress) 40
(KeyRelease) 39
(KeyRelease) 40
(a
、s
、d
是 xterm
在处理这些字符时写入伪终端主端的字符的本地回显KeyPress 事件并且不是输出的一部分)。
xinput test-xi2 --root
将报告当前 $DISPLAY
的每个 X Window 事件,包括但不限于类似于以下格式的按键和按键释放事件:
EVENT type 2 (KeyPress)
device: 14 (14)
detail: 54
flags:
root: 795.06/645.66
event: 795.06/645.66
buttons:
modifiers: locked 0 latched 0 base 0x4 effective: 0x4
group: locked 0 latched 0 base 0 effective: 0
valuators:
windows: root 0x252 event 0x252 child 0x1c0015b
从我的有限测试中,我发现其中的 child
字段似乎与终端仿真器主 window 的父级 ID 匹配(大多数终端仿真器在 $WINDOWID
环境变量)接收这些事件。我怀疑 window id 有点属于 window 经理。
因此,在这里,我们从 xwininfo -children
命令输出中检索该 ID,并使用它来过滤 xinput
.
报告的事件
要将这些键代码转换为键标签,请选中 this other answer。
现在,您需要检查 xinput
的源代码或使用 ltrace
(如果在 Linux 上)直接在 C 中做同样的事情而无需帮助这些公用事业。
有没有办法在简单的 C 程序中的 while (1)
循环中捕获 KEY PRESSED 和 KEY RELEASED 事件Linux 运行 来自终端机 window.
kbhit()
将 return true
,getch()
return 是按下的字符。
如何捕获 RELEASE 事件?
您不能以可移植的方式执行此操作。终端(以及 xterm 等终端的模拟器)只为您提供按下的键,而不是释放事件。图形用户界面通常提供接收单独的按下和释放事件的能力。
终端仿真器 运行 在图形环境中将这些事件组合成单独的字符。在图形环境中读取时,这些是 关键符号 ,其中可能包含 个字符 。除了按键事件本身的按下和释放事件外,您还可以使用 修饰符 ,例如 shift 修饰符、控制修饰符和元修饰符,它们是单独的事件。如果你 运行 xev
,你可以看到这些单独的事件。
将这些事件组合成一个字符后,终端仿真器可能会将其作为一系列数据字节发送到您的应用程序,例如,以 UTF-8 编码。当您使用 getch()
时,ncurses 库读取这些字节,并将它们再次组合成一个字符。在这两者(终端仿真器和应用程序)之间是伪终端和 its 转换,终端仿真器和应用程序都必须操作它们。
如果您不 运行宁愿使用图形环境,除了图形应用程序(例如xev
)之外,还有(并非总是)其他方式可以直接读取关键 press/release 事件。 Linux 控制台支持。例如,参见 Receiving key press and key release events in Linux terminal applications?
这适用于我 xterm
和 openbox
window 经理:
xinput test-xi2 --root |
awk -v id="$(
xwininfo -children -id "$WINDOWID" |
awk ' == "Parent" {print }'
)" '
== "EVENT"{e = $NF}
== "detail:" {k = }
== "child" && == id && e ~ /Key/ {print e, k}'
输出类似:
(KeyRelease) 36
(KeyPress) 38
a(KeyRelease) 38
s(KeyPress) 39
d(KeyPress) 40
(KeyRelease) 39
(KeyRelease) 40
(a
、s
、d
是 xterm
在处理这些字符时写入伪终端主端的字符的本地回显KeyPress 事件并且不是输出的一部分)。
xinput test-xi2 --root
将报告当前 $DISPLAY
的每个 X Window 事件,包括但不限于类似于以下格式的按键和按键释放事件:
EVENT type 2 (KeyPress)
device: 14 (14)
detail: 54
flags:
root: 795.06/645.66
event: 795.06/645.66
buttons:
modifiers: locked 0 latched 0 base 0x4 effective: 0x4
group: locked 0 latched 0 base 0 effective: 0
valuators:
windows: root 0x252 event 0x252 child 0x1c0015b
从我的有限测试中,我发现其中的 child
字段似乎与终端仿真器主 window 的父级 ID 匹配(大多数终端仿真器在 $WINDOWID
环境变量)接收这些事件。我怀疑 window id 有点属于 window 经理。
因此,在这里,我们从 xwininfo -children
命令输出中检索该 ID,并使用它来过滤 xinput
.
要将这些键代码转换为键标签,请选中 this other answer。
现在,您需要检查 xinput
的源代码或使用 ltrace
(如果在 Linux 上)直接在 C 中做同样的事情而无需帮助这些公用事业。