在Linux下删除/重写/生成键盘事件

Her*_*ron 7 linux keyboard xlib keyboard-events linux-device-driver

我想在Linux下交付,拦截并生成键盘(make/break)事件,然后才能将它们传送到任何应用程序.更准确地说,我想检测关键事件流中的模式,并能够根据检测到的模式丢弃/插入事件到流中.

我在SO上看过一些相关的问题,但是:

  • 或者他们只处理如何获得关键事件(关键记录器等),而不是如何操纵它们的传播(它们只是监听,但不拦截/生成).
  • 或者他们在X中使用被动/主动抓取(详见下文).

小型DSL

我解释下面的问题,但为了使它更紧凑和易懂,首先是一个小的DSL定义.

  • A_:用于制作(按)键A.
  • A^:用于中断(释放)键A.
  • A^->[C_,C^,U_,U^]:on A^为C发送一个make/break组合,然后在处理链中向下发送U(最后到应用程序).如果没有->则没有发送任何内容(但可能会修改内部状态以检测后续事件).
  • $X:执行任意操作.这可以发送一些可配置的键事件序列(可能类似于C-x C-semacs),或执行一个函数.如果我只能发送关键事件,那就足够了,因为我可以在窗口管理器中进一步处理这些事件,具体取决于哪个应用程序处于活动状态.

问题描述

好吧,所以使用这种表示法,这里是我想要检测的模式以及我想在处理链中传递的事件.

  1. A_, A^->[A_,A^]:探索.见上文,请注意发送A^.
  2. A_, B_, A^->[A_,A^], B^->[B_,B^]:基本上与1.相同但重叠事件不会改变处理流程.
  3. A_, B_, B^->[$X], A^:如果在保持另一个键(A)的同时完成了键(B)的完成/中断,则执行X(参见上文),并且丢弃A的中断.

(原则上,它是一个简单的状态机,可以在关键事件上实现,可以生成(多个)关键事件作为输出).

补充说明

  • 解决方案必须在打字速度上工作.
  • 修改后的密钥事件流的消费者在Linux上运行X(控制台,浏览器,编辑器等).
  • 只有键盘事件会影响处理(没有鼠标等)
  • 匹配可以发生匹配(更容易)或键码(更难一点).对于后者,我将只需要阅读映射以从代码转换为keysym.
  • 如果可能的话,我更喜欢适用于USB键盘以及虚拟机内部的解决方案(如果在驱动程序层工作则可能会出现问题,其他层应该没问题).
  • 我对实现语言非常开放.

可能的解决方案和问题

所以基本问题是如何实现这一点.

我已经在窗口管理器中使用被动grabs(XGrabKey)和实现了一个解决方案XSendEvent.不幸的是,被动抓取在这种情况下不起作用,因为它们B^在上面的第二种模式中没有正确捕获.原因是转换后的抓斗结束A^并且不继续B^.如果仍然保持,则新的抓取转换为捕获B,但仅在约1秒后.否则,将平原B^发送到应用程序.这可以通过验证xev.

我可以将我的实现转换为使用活动的grab(XGrabKeyboard),但是如果窗口管理器一直在键盘上有活跃的抓取,我不确定对其他应用程序的影响.X文档将活动抓取称为侵入式并且是为短期使用而设计的.如果有人有这方面的经验并且长期积极争夺没有重大缺点,那么我认为这是一个解决方案.

除了窗口管理器(作为X客户端运行)之外,我愿意查看其他关键事件处理层.键盘驱动程序或映射是可能的,只要我可以用它们解决上述问题.这也意味着解决方案不必是单独的应用程序.我很高兴有一个驱动程序或内核模块为我做这个.请注意,我从未做过任何内核或驱动程序编程,所以我会很感激一些好的资源.

感谢您的任何指示!

小智 3

使用XInput2使设备(键盘)浮动,然后监视设备上的KeyPress和KeyRelease事件,使用XTest重新生成KeyPress和KeyRelease事件。