原文
即将到来的Qt5.5将在没有窗口系统的Linux上得到一系列的改善。这些设备大多是嵌入式设备,也可能是在没有如X11和Wayland的窗口系统的桌面Linux控制台运行。
现在我们仔细看看支持内核模式设置方式以及直接渲染引擎的新方法,附带介绍刚引入不久的libinput。
在之前的版本,一般都有一个kms平台插件。这个插件在5.5上依然存在,不过不再是默认选项。当各种特性累加起来,要想让各种平台插件独立的工作,变得越来越复杂。从应用程序的角度看,kms和eglfs非常相同:他们都基于EGL和OpenGL ES2.0。支持KMS/DRM在,与提供其他设备或者提供商指定的eglfs后台,在概念上是一致的。(device hooks用来提供EGL和fbdev之间的关联)
为了用一种持续集成的方式实现这个目标,传统的静态内置编译的hooks方法需要进一步加强。有过移植Qt5的童鞋们都知道,在板卡支持的mkspecs文件(qtbase/mkspecs/devices)里面,需要添加这么一句话:
EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/qeglfshooks_imx6.cpp
这可以将给定的文件,编译进eglfs插件里面。当为某个特定的板卡构建时,这可以很好的工作。但是当存在多个eglfs后台时,这种硬编码的方式就无法接受了。所以,引入一种替代方案,基于插件形式的方法。当Qt5.5结束构建后,它会在文件夹qtbase/plugins/egldeviceintegrations下寻找插件:(假设必要的头文件和库文件已经配置好了)
libqeglfs-kms-integration.so
libqeglfs-x11-integration.so
正如名字所示,它们是eglfs的后台KMS/DRM和X11。后一个是内置的,仅仅用来做开发的解决方案(),除非是在Jetson TK1中,EGL和OpenGL驱动是和X11相连的。前一个现在对我们来说,更有意思了:这个一个新的KMS/DRM后台。当没有指定makespecs中的static hooks时,系统会自动使用这个后台,应用程序并不是运行在X窗口下。作为替换方案,插件需要显式地用QT_QPA_EGLFS_INTEGRATION环境变量指定,例如eglfs_kms或者eglfs_x11。由于当前代码中的板卡指定的hooks还是旧的方式,即内置编译方式,所以不用担心使用新的插件系统,除非依然要使用KMS/DRM。在以后,估计会有更多的平台适配通过插件的形式提供。
libinput是一个支持输入设备的库,提供设备检测,鼠标,键盘以及触摸等事件,还提供额外的功能,如鼠标加速和一定程度支持触摸板。Weston,即Wayland也使用它,未来X.org也有可能集成这个库。
使用libinput代替传统的输入方式,有很多好处。它可以和其他应用程序,比如Weston保持一致的操作方式、配置方式和校准方式。它也简化了程序导入流程,因为就不用单独处理Qt自带的输出设备驱动,libinput库总是可以很好的工作。
这个库依赖一些其他库,比如libudev,libevdev,也可能需要libmtdev。更多的键盘映射可以利用xkbcommon。这对桌面电脑和大多数嵌入式设备,都不是问题,但也许在手动系统(handcrafted systems)上会出问题,或者Android的baselayer。所以,libinput仅仅是一个可选项,默认选项还是Qt自带的事件处理句柄。
如何在桌面电脑上运行它呢?很容易,假设KMS/DRM可用,(例如,当使用带有KMS和DRM支持的Mesa)。下面是我们的应用程序(一个典型的Qt例子,在qtbase/examples/opengl/qopenglwidget),运行在一个普通的X11客户端上,使用xcb平台插件,使用Intel集成显卡。
现在让我们切换到另一个虚拟控制台下,在程序运行之前,设置如下环境变量:
export QT_QPA_PLATFORM=eglfs
export QT_QPA_GENERIC_PLUGINS=libinput
export QT_QPA_EGLFS_DISABLE_INPUT=1
这表明,我们使用eglfs平台插件,不使用内置的键盘、鼠标、触摸屏的支持(内置的方式是直接读取输入设备,而不是依赖第三方库,比如libinput),而是使用libinput来处理输入事件。
如果一切运行正常,结果就是下面这样:
这个应用程序运行良好,即使没有窗口系统。OpenGL和传统的QWidgets都可以工作。另外,多个顶层widgets也都可以运行。这在旧的KMS平台插件下,是不支持的,因为eglfs实现了这部分功能。键盘和鼠标也都工作正常。
如果一切正常运行,那当然很美好。如果没有,那就需要调试了。下面是一些有用的参考:
(1)
在一切一切之前,查看configure是不是准备好了所有必要的东西。看一下qtbase/config.summary,确定是如下面这样:
libinput................ yes
OpenGL / OpenVG:
EGL .................. yes
OpenGL ............... yes (OpenGL ES 2.0+)
pkg-config ............. yes
QPA backends:
EGLFS ................ yes
KMS .................. yes
udev ................... yes
xkbcommon-evdev......... yes
如果不是这样子,就可能会出问题。一般都是在sysroot路径下找不到头文件和库文件。许多新特性依赖pkg-config这个工具,所以很有必要先把这个工具配置好。
(2)
屏幕没有输出?响应不了输入?开启日志输出功能。目录日志在Qt中使用得越来越多。这里面包括输入子系统和eglfs。一些相关的目录如下:
qt.qpa.input – Enables debug output both from the evdev and libinput input handlers. Very useful to check if a given input device was correctly recognized and opened.
qt.qpa.eglfs.kms – Enables logging from the KMS/DRM backend of eglfs.
qt.qpa.egldeviceintegration – Enables plugin-related logging in eglfs.
另外,把QT_QPA_EGLFS_DEBUG环境变量置1,可以获得额外的信息,比如EGLConfig。
(3)
检查文件权限。/dev/fb0和/dev/input/event*要能够被应用程序访问。另外,保证没有其他设备正在使用输入设备(EVIOCGRAB)。
(4)
提问:我在控制台开启了应用程序,没有配备应用程序使用的键盘输入,我无法退出了,CTRL+C也没用。
回答:在应用程序运行之前,设置如下环境变量:
export QT_QPA_ENABLE_TERMINAL_KEYBOARD=1
这仅仅用于开发调试使用,输入设备问题一旦解决,就要关闭这个功能。缺点是,键盘按键直接流向了终端,所以在随后这个设置要禁止。
所以Qt5.5的发行版本还有几个月才能出来,所以以上提到的新特性,都会出现在qtbase的dev分,这还需要进行测试。这部分工作当然还没有完成。还有很多地方需要改善,比如在应用程序生命周期开始和关闭屏幕连接,以及使用其他的键盘布局。
最后,the Embedded Linux documentation page这个页面已经更新了,提供了新的显卡和输入设备。Don’t hesitate to check it out.