开始时有想法,既然自己去实现evdevmouse,那么直接添加进自己的程序就好了。但是,想想,qt默认是调用它自己的evdev,自己写的myevdev是不起作用的。直接替换,当然省事,但要使用原来的时候就又得弄回去。所以要按照QT的QPA配置规则,添加自己的myevdev进去,就OK了。
首先qt的配置,要想使用鼠标等,需要添加-evdev配置项,要实现热插拔,需要libudev,即内部的-libudev项。
现在基本不使用其他模块,所以可以选择qtbase单模块编译,有需要时再选其他模块。而一开始就需要很多模块的可以直接编译qt-everywhere。现在才知道qt模块话的好处。之前去编译qt-everywhere太浪费时间了,一开始就选择qtbase的话省很多时间。
搜索
[root@localhost qtbase]# grep "contains(QT_CONFIG, libudev)" -n -r .
./src/platformsupport/devicediscovery/devicediscovery.pri:4: contains(QT_CONFIG, libudev) {
./src/platformsupport/input/evdevkeyboard/evdevkeyboard.pri:10:contains(QT_CONFIG, libudev) {
./src/platformsupport/input/evdevmouse/evdevmouse.pri:9:contains(QT_CONFIG, libudev) {
./src/platformsupport/input/evdevtouch/evdevtouch.pri:9:contains(QT_CONFIG, libudev) {
./src/platformsupport/input/evdevtablet/evdevtablet.pri:7:contains(QT_CONFIG, libudev) {
[root@localhost qtbase]# grep "contains(QT_CONFIG, evdev)" -n -r .
./src/platformsupport/devicediscovery/devicediscovery.pri:9: } else: contains(QT_CONFIG, evdev) {
./src/platformsupport/input/input.pri:1:contains(QT_CONFIG, evdev) {
./src/plugins/generic/generic.pro:5:contains(QT_CONFIG, evdev) {
evdev就是 plugins/generic下的插件,对应libqevdevxxxplugin.so,同时还有platformsupport插件。之前尝试添加,这些东西放的地方把我绕晕了,估计接下来还会把我绕晕。
libudev,影响的是devicediscovery机制。
从之前的qpa.input打印及evdev代码来看,程序运行时,首先从环境变量中获取,没有的话就使用devicediscovery机制,找到的dev节点交给evdev来处理,evdev处理数据,然后再“上报”给qt的input系统。platformsupport提供了devicediscovery、evdev及对外接口。而plugins就是针对input系统规范接口以供input使用。
一般我们会有错觉,plugins是给应用程序使用QT系统资源的,但不是。plugin是QT系统内部的插件化部分,不跟应用程序有直接关系。
这样总结了之后,应该不会被QT绕晕了。
第一步,修改configure配置,防止下次修改配置时丢失myevdev的修改。当然不修改,-evdev还是可以保留下myevdev的,但这样看着别扭。还是添加一个-myevdev选项好。
[root@localhost qtbase-5.6.0]# grep "evdev" -n -r configure
1786: xkbcommon-evdev)
1876: evdev)
2569: -no-xkbcommon-evdev . Do not use X-less xkbcommon when compiling libinput support.
2570: * -xkbcommon-evdev .... Use X-less xkbcommon when compiling libinput support.
2636: -no-evdev .......... Do not compile support for evdev.
2637: * -evdev ............. Compile support for evdev.
5400: if compileTest unix/evdev "evdev"; then
5402: QT_CONFIG="$QT_CONFIG evdev"
5404: echo "The evdev functionality test failed!"
5439: QT_CONFIG="$QT_CONFIG xkbcommon-evdev"
5441: echo "The xkbcommon-evdev functionality test failed!"
7381:report_support " xkbcommon-evdev........." "$CFG_XKBCOMMON_EVDEV"
没几个地方,
1. 1876附近,添加myevdev)
相关的CFG_EVDEV,添加CFG_MYEVDEV,
这样-myevdev=yes即可(添加yes,就直接配置了,不会去test测试了)
2. 2637附近,添加 选项说明
这里,想到了,默认是-evdev,所以是不是在配置-myevdev=yes时 -evdev=no呢
查找CFG_EVDEV
[root@localhost qtbase-5.6.0]# grep "CFG_EVDEV" -n -r configure
693:CFG_EVDEV=auto
1879: CFG_EVDEV=no
1886: CFG_EVDEV="$VAL"
5409:if [ "$CFG_EVDEV" != "no" ]; then
5411: CFG_EVDEV=yes
5413: elif [ "$CFG_EVDEV" = "yes" ]; then
5417: CFG_EVDEV=no
5420:if [ "$CFG_EVDEV" = "no" ]; then
6842:[ "$CFG_EVDEV" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EVDEV"
7301:report_support " Evdev .................." "$CFG_EVDEV"
693处,初始化值,
1879处,我刚添加的,
1886处,-evdev=yes|no决定的,但配置只是-evdev、-no-evdev,
899 #Qt style no options
900 -no-*)
901 VAR=`echo $1 | sed 's,^-no-\(.*\),\1,'`
902 VAL=no
903 ;;
1096 #General options, including Qt style yes options
1097 -*)
1098 VAR=`echo $1 | sed 's,^-\(.*\),\1,'`
1099 VAL="yes"
1100 ;;
这里会做处理
5409处开始是test部分,如果不是直接的no,那么会进行test
理一下,开始auto,
不配置为auto,配置了-evdev后为yes,会test后决定yes还是no;
配置了-no-evdev后为no,不test,直接为no
设置-myevdev=yes时,-evdev=no,这样evdev不会去test,(myevdev的test,暂不会添加了)
设置-myevdev=no时,看配置-evdev=xxx
所以我们也提供-mydev和-no-mydev选项
3. CFG_MYEVDEV
初始化为no(添加了test,可以设置为auto),-myevdev=yes时设置CFG_EVDEV为no
CFG_EVDEV初始化为auto
CFG_MYEVDEV = yes时,已设置了CFG_EVDEV=no
CFG_MYEVDEV = no时,=val
暂不考虑CFG_MYEVDEV = auto
4. 添加report
第一步完成。执行./configure -myevdev测试
但在开头,比较的是QT_CONFIG的内容。第一步测试成功后搜索一下看看
[root@localhost qtbase-5.6.0]# grep "QT_CONFIG" -n -r . | grep "myevdev"
[root@localhost qtbase-5.6.0]# grep "QT_CONFIG" -n -r . | grep "evdev"
./configure:5419: QT_CONFIG="$QT_CONFIG evdev"
./configure:5456: QT_CONFIG="$QT_CONFIG xkbcommon-evdev"
./src/platformsupport/devicediscovery/devicediscovery.pri:9: } else: contains(QT_CONFIG, evdev) {
./src/platformsupport/input/input.pri:1:contains(QT_CONFIG, evdev) {
./src/platformsupport/input/libinput/libinput.pri:16:contains(QT_CONFIG, xkbcommon-evdev) {
./src/platformsupport/input/evdevkeyboard/evdevkeyboard.pri:10:contains(QT_CONFIG, libudev) {
./src/platformsupport/input/evdevmouse/evdevmouse.pri:9:contains(QT_CONFIG, libudev) {
./src/platformsupport/input/evdevtouch/evdevtouch.pri:9:contains(QT_CONFIG, libudev) {
./src/platformsupport/input/evdevtouch/evdevtouch.pri:13:contains(QT_CONFIG, mtdev) {
./src/platformsupport/input/evdevtablet/evdevtablet.pri:7:contains(QT_CONFIG, libudev) {
./src/plugins/generic/generic.pro:5:contains(QT_CONFIG, evdev) {
当然这样搜索是不对了,不过可以看到,还是需要QT_CONFIG="$QT_CONFIG evdev"来添加进去的
第二步,就是添加这些东西。
if [ "$CFG_MYEVDEV" != "no" ]; then
QT_CONFIG="$QT_CONFIG myevdev"
fi
if [ "$CFG_MYEVDEV" = "no" ]; then
QMakeVar add DEFINES QT_NO_MYEVDEV
fi
可以看到两个东西,一个是QT_CONFIG,一个是QT_NO_MYEVDEV。QT_CONFIG就是开头那几个了。
QMakeVar()
{
case "$1" in
set)
eq="="
;;
add)
eq="+="
;;
del)
eq="-="
;;
*)
echo >&2 "BUG: wrong command to QMakeVar: $1"
;;
esac
echo "$2" "$eq" "$3" >> "$QMAKE_VARS_FILE"
}
DEFINES += QT_NO_MYEVDEV >> (var file)
QMAKE_VARS_FILE=.qmake.vars
[root@localhost qtbase-5.6.0]# grep "contains(DEFINES" -n -r .
./examples/widgets/graphicsview/graphicsview.pro:16:contains(DEFINES, QT_NO_CURSOR)|contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= dragdroprobot
./examples/widgets/widgets.pro:30:contains(DEFINES, QT_NO_CURSOR): SUBDIRS -= mainwindows
./examples/widgets/widgets.pro:31:contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= draganddrop
./examples/widgets/tools/tools.pro:18:contains(DEFINES, QT_NO_TRANSLATION): SUBDIRS -= i18n
./examples/widgets/dialogs/dialogs.pro:16:contains(DEFINES, QT_NO_WIZARD): SUBDIRS -= trivialwizard licensewizard classwizard
./examples/widgets/itemviews/itemviews.pro:22:contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= puzzle
./src/widgets/statemachine/statemachine.pri:2:!contains(DEFINES, QT_NO_STATEMACHINE_EVENTFILTER) {
./src/widgets/widgets.pro:37:contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri)
./src/corelib/mimetypes/mimetypes.pri:23:!contains(DEFINES, QT_NO_MIMETYPE) {
./src/corelib/statemachine/statemachine.pri:25:!contains(DEFINES, QT_NO_STATEMACHINE_EVENTFILTER) {
./src/corelib/corelib.pro:70:contains(DEFINES,QT_EVAL):include(eval.pri)
./src/3rdparty/xkbcommon.pri:50:!contains(DEFINES, QT_NO_XKB):contains(QT_CONFIG, use-xkbcommon-x11support): {
./src/plugins/platforms/eglfs/eglfs_device_lib.pro:54:!contains(DEFINES, QT_NO_CURSOR): RESOURCES += $$PWD/cursor.qrc
./src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri:37: !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb
./src/plugins/platforms/xcb/xcb_qpa_lib.pro:96: !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb
./src/plugins/platforms/qnx/qnx.pro:137: !contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard
./tests/manual/dialogs/dialogs.pro:16:!contains(DEFINES, QT_NO_PRINTER) {
可以联想到,QT_CONFIG和DEFINES是将configure项的东西做下区分,QT_CONFIG关联的是一些重要的部分,DEFINES关联的是一些插件项。
第三步就是项目的添加了。从上往下走,
1. plugins
plugins/generic/generic.pro
contains(QT_CONFIG, evdev) {
SUBDIRS += evdevmouse evdevtouch evdevkeyboard evdevtablet
}
contains(QT_CONFIG, myevdev) {
SUBDIRS += myevdevtouch
}
我自己的OK210开发板移植USB HOST驱动有问题,所以先测触摸屏
拷贝evdevtouch为myevdevtouch,并做修改。
2. platformsupport
platformsupport/input/input.pri
contains(QT_CONFIG, myevdev) {
include($$PWD/myevdevtouch/myevdevtouch.pri)
}
platformsupport/devicediscovery/devicediscovery.pri
HEADERS += $$PWD/qdevicediscovery_p.h
linux {
contains(QT_CONFIG, libudev) {
SOURCES += $$PWD/qdevicediscovery_udev.cpp
HEADERS += $$PWD/qdevicediscovery_udev_p.h
INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
} else: contains(QT_CONFIG, evdev) {
SOURCES += $$PWD/qdevicediscovery_static.cpp
HEADERS += $$PWD/qdevicediscovery_static_p.h
} else {
SOURCES += $$PWD/qdevicediscovery_dummy.cpp
HEADERS += $$PWD/qdevicediscovery_dummy_p.h
}
} else {
SOURCES += $$PWD/qdevicediscovery_dummy.cpp
}
这里如果使用了libudev就用_udev的,前面configure没有对udev做处理,这里修改
HEADERS += $$PWD/qdevicediscovery_p.h
linux {
contains(QT_CONFIG, myevdev) {
SOURCES += $$PWD/qdevicediscovery_myevdev.cpp
HEADERS += $$PWD/qdevicediscovery_myevdev_p.h
} else: contains(QT_CONFIG, libudev) {
SOURCES += $$PWD/qdevicediscovery_udev.cpp
HEADERS += $$PWD/qdevicediscovery_udev_p.h
INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
} else: contains(QT_CONFIG, evdev) {
SOURCES += $$PWD/qdevicediscovery_static.cpp
HEADERS += $$PWD/qdevicediscovery_static_p.h
} else {
SOURCES += $$PWD/qdevicediscovery_dummy.cpp
HEADERS += $$PWD/qdevicediscovery_dummy_p.h
}
} else {
SOURCES += $$PWD/qdevicediscovery_dummy.cpp
}
让myevdev优先,这样即使配置了myevdev同时有libudev,会使用myevdev然后跳过。
这里可以尝试编译看下是否会出错。还没修改过代码,所以应该会编译通过,并生成libqmyevdevtouchplugin.so。
第四步就是代码修改了。