【问题标题】:How to route X11 Keyboard events into stdin like ghostscript does?如何像 ghostscript 一样将 X11 键盘事件路由到标准输入?
【发布时间】:2011-10-11 16:19:22
【问题描述】:

我正在尝试编写 ghostscript 的克隆,但我不知道它们是如何制作的,因此您可以在图形窗口中键入,并且击键显示在终端窗口中,就像您在那里键入它们一样首先。因此,收到 KeyRelease 事件后,我可以以某种方式将 char 填充到 stdin 中,以便使用普通文件读取代码读取吗?或者我是否必须在标准输入前创建自己的内部缓冲区,以便可以将新字符插入其中?或者是否有一些简单的方法可以将键盘事件从我的应用程序窗口映射到 Xterm?

我愿意做这项工作,但我什至不知道我在这里寻找什么。救命?!!

【问题讨论】:

  • ghostscript 是否真的将按键事件重定向到它自己的stdin 或者它只是捕获按键并处理它们,就好像它们来自stdin
  • 不确定。我想这是在问之前要做的事情。 :(
  • “将它们都发送到同一个地方”的方法是我的做法,尝试将内容输入您自己的stdin 似乎是一堆毫无意义的忙碌工作。无论如何,很容易陷入错误的道路,提出问题是一种快速了解问题并指出您遗漏的明显事情的方法。
  • 我只花了一个小时查看 gs 源。还没找到。
  • 你找到X事件循环了吗?我很确定 ghostscript 使用原始 XLib 作为 UI,所以在某处应该有一个很丑的 switch 声明。 OTOH,十多年来我没有做过任何 X 编程,所以请相信我所说的。

标签: c unix x11 ghostscript stdio


【解决方案1】:

我认为 gs 不会这样做(至少在 linux 上)。

我尝试将它从 SSH 会话运行到我的 linux 机器,并将焦点切换到弹出渲染图像(老虎)的 X11 窗口,并且我在那里按下的键没有转到远程主机上的应用程序。

strace 的(结束)显示 GS 正在等待标准输入——使用 fd=0 读取

read(3, " } if\n psuserparams readonly p"..., 4096) = 3258 brk(0x1124000) = 0x1124000 读取(3,“”,4096)= 0 关闭(3)= 0 munmap(0x7f8ccaee5000, 4096) = 0 轮询([{fd=4,事件=POLLIN|POLLOUT}],1,-1)= 1([{fd=4,revents=POLLOUT}]) writev(4, [{"+\2\1\0", 4}, {NULL, 0}, {"", 0}], 3) = 4 轮询([{fd=4,事件=POLLIN}],1,-1)= 1([{fd=4,revents=POLLIN}]) 读(4, "\1\1'\0\0\0\0\0\1\0\200\0\0\0\0\0\1\0\0\0\264\2\0 \0008\0A\2\4\0\0\0", 4096) = 32 read(4, 0xc9bd54, 4096) = -1 EAGAIN(资源暂时不可用) fstat(1, {st_mode=S_IFREG|0644, st_size=143204, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8ccaee5000 写(1,“GS>”,3GS>)= 3 读(0,...未完成...

我必须将焦点切换回 ssh 窗口才能使按键 (Ctrl-C) 生效。当焦点是图像 X11 窗口时,我曾尝试“退出”以及 ctrl-C。

【讨论】:

  • 天哪!你是对的!它必须是窗口管理器的一个功能。我猜,对于 KDE,由于 ghostscript 不请求任何输入事件,图形窗口不能接受焦点。通过进入窗口特定选项,我能够强制接受焦点,果然,打字没有效果。谜团已揭开。谢谢!
【解决方案2】:

我不知道答案,但我知道找到它的方法。在strace 下运行ghostscript 并观察它在做什么。这通常比尝试阅读源代码更容易且信息量更大。

【讨论】:

  • strace 确实是完成这项工作的工具。谢谢。
【解决方案3】:

尤里卡!

在文件gdevxini.c

435             wm_hints.flags = InputHint;
436             wm_hints.input = False;
437             XSetWMHints(xdev->dpy, xdev->win, &wm_hints);       /* avoid input focus */

编辑:现在我知道了它的样子,我能够找到一些文档:

输入成员用于将应用程序使用的输入焦点模型传达给窗口管理器......从不期望任何键盘输入的应用程序......应该将此成员设置为False。 --X 窗口系统:C 库和协议参考,第 282 页

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    相关资源
    最近更新 更多