![将视频渲染到帧缓冲区时隐藏虚拟控制台的最佳实践](https://linux22.com/image/60171/%E5%B0%86%E8%A7%86%E9%A2%91%E6%B8%B2%E6%9F%93%E5%88%B0%E5%B8%A7%E7%BC%93%E5%86%B2%E5%8C%BA%E6%97%B6%E9%9A%90%E8%97%8F%E8%99%9A%E6%8B%9F%E6%8E%A7%E5%88%B6%E5%8F%B0%E7%9A%84%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5.png)
我目前正在使用 GStreamer 将 Linux 中的视频直接渲染到帧缓冲区。
我想知道如何在渲染时隐藏虚拟控制台。我可以阻止光标闪烁,但这仅在控制台上没有文本更改时才有效。
X 似乎创建了一个可以通过 Ctrl(+Alt)+F7 访问的新屏幕 – 我自己可以做类似的事情吗?以某种方式能够使用 Ctrl+Alt+F1 和 Ctrl+Alt+F2 在控制台和渲染屏幕之间切换。
答案1
X 不创建新屏幕。
要使用内核内置终端仿真器所使用的相同显示和输入事件设备(以显示其虚拟终端),程序必须安排共享它们。内核的终端仿真器提供了一个 API,这样的程序可以通过该 API 来协商何时负责输入和输出,以及内核的内置终端仿真器何时负责。
此 API 通过ioctl()
调用向内核虚拟终端字符设备开放的文件描述符来实现。 Linux 中有 64 个这样的设备,FreeBSD/PC-BSD 中有 16 个。 X 不会创建这些。它打开一个现有的终端——按照惯例,没有 TUI 程序同时尝试将其用作内核虚拟终端。换句话说:按照惯例,X 打开和使用的内核虚拟终端设备上没有运行 TUI 登录会话。
与内核终端仿真器共享的程序必须……
- ...告诉内核终端模拟器停止写入帧缓冲区以显示输出或光标。这是通过
KDSETMODE
ioctl()
设置当今命名错误的KD_GRAPHICS
模式来完成的。当处于KD_TEXT
模式时,内核终端仿真器现在通常与处于实际文本模式的显示硬件没有任何关系。所谓的帧缓冲控制台让显示硬件处于图形模式。KD_TEXT
和模式之间的区别KD_GRAPHICS
在于,在前一种模式中,当终端行规则向帧缓冲区传送输出时,内核的终端仿真器将在帧缓冲区上绘制字符字形,并且还会绘制光标;而在后一种模式下,它根本不会进行任何绘图。如今,如果不命名为“图形”是错误的,那么实际上最好将它们视为“绘制图形”和“不绘制图形”模式。 ☺ - …协商虚拟终端切换(如果适用)。这是通过 来完成的,当用于呼叫的虚拟终端切换到或离开时,
VT_SETMODE
ioctl()
程序可以使用它来安排接收信号。ioctl()
- …与内核终端仿真器协商输入处理。
- 在 Linux 上,人们可能会直接从输入事件子系统读取数据,在这种情况下,程序会告诉内核的终端仿真器停止读取它收到的副本的相同输入事件,停止将它们转换为字符,并停止发送它们以线路纪律作为输入。完成此操作的方式各不相同:
- 最初的方法是使用
KDSKBMODE
ioctl()
,将虚拟终端切换到K_RAW
模式。在此模式下,内核终端仿真器仍然从内核的输入事件子系统接收输入事件,但它不对它们执行任何处理,而是将它们作为字符输入传递给线路规则。然而,这种机制(其根源在于 X 在存在输入事件子系统之前的工作方式)被破坏了,因为输入仍然被发送到线路规则并且仍然必须被排出。并且它要求termios
终端的输入状态也处于原始模式,否则原始扫描码将被行规则误解为特殊字符,例如 STOP 或 INTR 字符。 - 曾经被认为更好的一种方法是使用
KDSKBMODE
ioctl()
将虚拟终端切换到K_OFF
模式。在这种模式下,内核终端模拟器不仅不会处理输入事件,而且不会将它们发送到线路规则。然而,这个机制被破坏了,因为它是K_OFF
///模式开关K_RAW
的一部分。 systemd 和其他类似系统将管理虚拟终端模式,并最终切换虚拟终端K_CODE
K_XLATE
出去的K_OFF
模式。 - 如今更好的方法是使用标志
KDSKBMUTE
。这将关闭所有输入事件处理没有K_RAW
//影响或受K_CODE
模式K_XLATE
开关影响。
- 最初的方法是使用
- 在 FreeBSD/PC-BSD 上,首先没有单独的输入事件字符设备。一是通过内核虚拟终端读取键盘输入反正,因此,虽然人们可能希望将其切换为扫描码 (
K_RAW
) 或键码 (K_CODE
) 模式,但不想将其关闭。
- 在 Linux 上,人们可能会直接从输入事件子系统读取数据,在这种情况下,程序会告诉内核的终端仿真器停止读取它收到的副本的相同输入事件,停止将它们转换为字符,并停止发送它们以线路纪律作为输入。完成此操作的方式各不相同:
这里有一些交互。例如,X 服务器将虚拟终端切换到键码模式,读取键码并将它们转换为 X 键符号,然后通过 X 键盘处理机制传递它们。这意味着内核的内置终端仿真器永远无法对Alt+键盘序列执行特殊处理。 X 服务器必须自己识别++ 。FnCtrlAltFn
进一步阅读
- 阿瑟·泰勒 (2013-02-02)。 systemd 不应在带有 X 的 VT 上调用 KDSKBMODE。 systemd-开发。
- 亚当·杰克逊 (2012-11-16)。 [PATCH] vt:为 VC_MUTE 删除 K_OFF。 Linux 内核邮件列表。
- 亚当·杰克逊 (2012-11-16)。 [PATCH] linux:更喜欢 ioctl(KDSKBMUTE, 1) 而不是 ioctl(KDSKBMODE, K_OFF)。 xorg-开发。
- 迈克尔·K·约翰逊 (1994-06-01)。Linux 编程提示。 Linux 杂志。