【问题标题】:Linux & C: Communicating with X server from outside of X?Linux & C:从 X 外部与 X 服务器通信?
【发布时间】:2012-10-19 21:14:23
【问题描述】:

我正在开发一个小型服务器程序,该程序从网络接收数据并执行各种操作。其中一项操作是打开与系统上运行的 X 服务器的连接并模拟按键。当我的服务器从 X 内的终端启动时,这很好,但我希望我的程序在系统启动时作为系统服务启动,然后在客户端请求时与 X 通信。

我遇到的基本问题是在不是从 X 内部启动的进程中调用 XOpenDisplay(NULL) 失败。据我了解,我无法从 X 外部打开 X 显示器,因此我能想到的最佳解决方法是编写一个单独的程序,该程序在用户登录 X 时启动,等待信号或消息从服务器,然后执行请求的操作。如果此帮助程序未运行或由于某种原因失败,假设服务器可以将错误发送回客户端是完全可以的。

所以问题:我上面描述的是最好的(虽然是混乱的)解决方案,还是有更好的方法?事实上,有没有一种从 X 外部打开 X 显示的方法?谢谢!

【问题讨论】:

  • @jweyrich Gah,当我在玩 DISPLAY envvar 时,我正在分配它,然后运行我的程序,但忘记了 export 并假设有其他问题。这确实有效,但这仍然意味着我假设显示实际上是:0:

标签: c linux xserver


【解决方案1】:

“在 X 内部”只是设置 DISPLAY 环境变量的问题。您可以在任何地方执行此操作。

如果有问题的 X 服务器正在为不同的用户运行,您可能还需要处理身份验证令牌,例如 Xauthority 票证。

但是——对于您描述的用例,我强烈建议您运行您自己的 X 服务器进程,独立于系统的实际显示硬件。这可能是Xvnc,如果您想连接以进行交互检查,或者简单的无头实现,或者Xvfb,如果您根本不需要显示缓冲区。这种方法还可以防止您的软件在用户登录和注销时需要重新启动,否则会出现这种情况。

【讨论】:

  • 您对DISPLAY envvar 的看法是正确的,但我不想将显示硬编码为:0:。我查看了Xvfb,但也许我应该再解释一下。我的目标是模拟媒体按键以播放/暂停在用户启动的 X 进程中运行的媒体播放器(以免仅使用特定的媒体播放器)。据我了解,创建一个新的 X 进程将使这些模拟的按键无效。
  • @shanet 如果您创建自己的 X 服务器,例如 Xvnc,您可以告诉它使用哪个 DISPLAY
  • @shanet 顺便问一下,这是哪个媒体播放器?更好的具有控制套接字机制,对接收按键没有任何依赖或要求;使用更适合用途的东西可能更合适。
  • 我对 X 不是很熟悉,所以我试图理解这一切;假设我使用了 Xvnc,我可以继续使用 XOpenDisplay 吗?我目前正在使用 Clementine,但我经常更换媒体播放器,这就是为什么我试图构建一个独立于播放器的解决方案,因为我需要的只是简单的播放/暂停/下一个命令。
  • @shanet 是的,从客户端的角度来看,Xvnc 就像一个普通的 X 服务器;相同的调用将与任何其他调用一样。
【解决方案2】:

可以从机器上运行的任何进程连接到 X 显示器 - 您需要设置 DISPLAY 变量来指示要连接到哪个 X 会话,并且可能需要正确的 XAuthority 令牌。

但是,对于您的情况,这将被视为“混乱”的解决方案,因为您基本上需要猜测显示编号并解决授权问题。您还必须处理守护程序启动时 X 服务器尚未启动的情况,或者当您的守护程序运行时 X 服务器重新启动时(X 客户端库并非真正设计用于处理X 服务器离开又回来)。

“干净”的解决方案实际上是您建议的解决方法 - 在 X 会话中运行的客户端通过 UNIX 域套接字或类似的连接到您的守护程序。

【讨论】:

  • 不知道要使用的DISPLAY 很好。我想我可以为我的程序创建一个配置文件,如果没有另外指定,则默认显示为:0。如果我将我的程序设置为服务(在/etc/init.d中)假设它将以有足够的权限与任何 X 会话通信?
  • @shanet: 否 - 这取决于 X 的配置方式,但通常您需要存储在登录用户家中 .Xauthority 文件中的“magic cookie”值或密钥目录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-16
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多