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

标签 linux keyboard linux-device-driver keyboard-events xlib

在将Linux事件传递到任何应用程序之前,我想在Linux下对其进行钩挂,拦截和生成。更准确地说,我想检测关键事件流中的模式,并能够根据检测到的模式将事件丢弃/插入流中。
我在SO上看到了一些相关的问题,但是:

  • 或者它们只处理如何获取关键事件(关键记录器等),而不涉及如何操纵它们的传播(它们仅监听,但不拦截/生成)。
  • 或它们在X中使用被动/主动抓取(请参阅下文中的更多内容)。

  • 小型DSL
    我在下面解释了这个问题,但是为了使其更加紧凑和易于理解,首先是一个小的DSL定义。
  • A_:用于制作(按)键A
  • A^:换行(释放)键A
  • A^->[C_,C^,U_,U^]:在A^上,向C发送一个make/break组合,然后向处理链的最后一个U发送(最后到应用程序)。如果没有->,则不发送任何内容(但可以修改内部状态以检测后续事件)。
  • $X:执行任意操作。这可以发送一些可配置的按键事件序列(例如emacs的C-x C-s之类的东西),或执行一个函数。如果我只能发送键事件,那就足够了,因为然后我可以根据事件的应用程序在窗口管理器中进一步处理这些键事件。

  • 问题描述
    好的,因此使用此符号,这是我要检测的模式以及要在处理链中传递的事件。
  • A_, A^->[A_,A^]:爆炸。参见上文,请注意发送发生在A^上。
  • A_, B_, A^->[A_,A^], B^->[B_,B^]:与1基本相同。但是重叠的事件不会改变处理流程。
  • A_, B_, B^->[$X], A^:如果在按住另一个键(A)的同时完全完成了键(B)的创建/断开,则执行X(请参见上文),并丢弃A的断开。

  • (原则上,这是在键事件上实现的简单状态机,它可以生成(多个)键事件作为输出)。
    补充笔记
  • 该解决方案必须以打字速度工作。
  • 修改后的键事件流的使用者在Linux上的X下运行(控制台,浏览器,编辑器等)。
  • 仅键盘事件会影响处理(无鼠标等)。
  • 匹配可以发生在keyyms(容易一些)或keycodes(更困难一些)上。对于后者,我将只需要阅读映射即可将代码转换为键符。
  • 如果可能的话,我更喜欢一个既可以在USB键盘上也可以在虚拟机内使用的解决方案(如果在驱动程序层工作可能会出现问题,其他层应该没问题)。
  • 我对实现语言很开放。

  • 可能的解决方案和问题
    因此,基本问题是如何实现这一点。
    我已经在窗口管理器中使用被动抓取(XGrabKey)和XSendEvent实现了一个解决方案。不幸的是,被动抓取在这种情况下不起作用,因为它们无法在上面的第二种模式中正确捕获B^。原因是转换后的抓取以A^结尾,而不是继续到B^。如果仍保持但仅在约1秒后,新的抓斗将转换为捕获B。否则,将普通的B^发送到应用程序。可以使用xev进行验证。
    我可以将实现转换为使用主动抓取(XGrabKeyboard),但是如果窗口管理器始终一直在键盘上进行主动抓取,则我不确定对其他应用程序的影响。 X文档将主动抓取称为侵入性的,并且设计用于短期使用。如果有人对此有经验,并且长期积极争取并没有重大弊端,那么我认为这是一个解决方案。
    除了窗口管理器(作为X客户端运行)之外,我还愿意查看其他关键事件处理层。键盘驱动程序或映射是可能的,只要我能用它们解决以上问题。这也意味着解决方案不必是单独的应用程序。我可以让驱动程序或内核模块为我做这件事。请注意,尽管我从未做过任何内核或驱动程序编程,所以我将感谢一些不错的资源。
    感谢您的指导!

    最佳答案

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

    关于linux - 在Linux下删除/重写/生成键盘事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3781831/

    相关文章:

    linux - GTK2 与 GTK3 : detect GTK3 theme in bash script

    ios - 处理外部键盘按下而不在 iOS 应用程序的屏幕上显示键盘

    linux - 我如何从内核空间中缩小 Linux 页面缓存?

    linux - 从用户空间向 printk 缓冲区发送消息——不起作用

    linux - 什么是 linux irq 域,为什么需要它们?

    linux - 通过bash交换两个字符串的位置

    python - 如何在 Ubuntu 中安装 python 3.7 模块?

    linux - 如何监控 Linux UDP 缓冲区可用空间?

    events - 使用Node.JS进行键盘事件模拟

    eclipse : shift + 8 button is not working