注:此驅動對應英文handler和內核的驅動(driver)不是一回事
如果認真看過shiroki寫的QtEmbedded鍵盤驅動分析(上篇,下篇),那麼自己再來看鼠標驅動的流程基本上也是大同小異,軟件的實現框架是一模一樣的。只不過搜索引擎可能不知道這個事情,那麼我就把鍵盤兩字改爲鼠標再寫一篇。
寫作本文的目的是爲了梳理QtEmbedded中鼠標的加載流程,在你的鼠標不工作的時候,可以一步一步的去排查問題所在,真正做到以不變應萬變。如果想只是通過修改某個變量或者文件而把問題解決的想法是不可靠的,也是本人不推薦的。
下面我們就來看看QtEmbedded是怎麼從main函數到加載鼠標驅動的。
1. 從QApplication開始,因爲每個帶GUI的main函數都會創建一個QApplication的實例
2. 構造函數中調用QApplicationPrivate::construct(…)
src/gui/kernel/qapplication.cpp
665 QApplication::QApplication(int &argc, char **argv)
666 : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
667 { Q_D(QApplication); d->construct(); }
3. construct(…)則會調用qt_init(…)函數
4. qt_init(…) 則會解析命令行參數,從而調用QWSServer::startup(flags);
src/gui/kernel/qapplication_qws.cpp
2279 if (type == QApplication::GuiServer) {
2280 qt_appType = QApplication::Type(type);
2281 qws_single_process = true;
2282 QWSServer::startup(flags);
2283 setenv(”QWS_DISPLAY”, qws_display_spec.constData(), 0);
2284 }
我們知道如果應用命令行加”-qws”選項,就會以server(GuiSever)方式運行。上面代碼中的startup的參數flags也是通過對命令行參數做運算得到的.
5. QWSServer::startup(flags) 會創建QWSServer的一個實例
src/gui/embedded/qwindowsystem_qws.cpp
4054 void QWSServer::startup(int flags)
4055 {
4056 if (qwsServer)
4057 return;
4058 unlink(qws_qtePipeFilename().toLatin1().constData());
4059 (void)new QWSServer(flags);
4060 }
6. QWSServer的構造函數則會調用QWSServerPrivate::initServer(…)
src/gui/embedded/qwindowsystem_qws.cpp
1303 QWSServer::QWSServer(int flags, QObject *parent) :
1304 QObject(*new QWSServerPrivate, parent)
1305 {
1306 Q_D(QWSServer);
1307 d->initServer(flags);
1308 }
7. initServer則會在這裏調用openMouse()
src/gui/embedded/qwindowsystem_qws.cpp
1440 if (!(flags&QWSServer::DisableMouse)) {
1441 q->openMouse();
1442 }
1443 #ifndef QT_NO_QWS_KEYBOARD
1444 if (!(flags&QWSServer::DisableKeyboard)) {
1445 q->openKeyboard();
1446 }
1447 #endif
鼠標相關的東西從這裏進入我們視野,1440行的判斷來自於命令行參數,如果運行server程序的時候帶了”-nomouse”選項,那麼這裏就1441行就不會被調用了。
我們還可以看到openKeyboard()也是在這個函數裏被調用的,可見他們還真是哥倆。
8.a openMouse()函數則根據Linux中的環境變量QWS_MOUSE_PROTO來判斷加載什麼樣的鼠標驅動(handler)
從上面代碼我們可以得出3個結論
A) 控制使用什麼鼠標的環境變量是QWS_MOUSE_PROTO
B) 如果QWS_MOUSE_PROTO沒有設置,系統會加載默認的鼠標驅動
C) 可以加載多個鼠標hanlder,也就是可以接多個鼠標設備.在QWS_MOUSE_PROTO變量中以空格分開
newMouseHandler(…)是被調用去創建鼠標驅動的函數
8.b newMouseHandler(QString spec)處理具體的某一個驅動規格
spec的形式可能是這樣的”Vr41xx:press=500:/dev/misc/ts”,該函數會對spec進行分離出不同的部分,然後調用QMouseDriverFactory::create(mouseProto, mouseDev)去創建真正的驅動。
src/gui/embedded/qwindowsystem_qws.cpp
3695 QWSMouseHandler *handler = 0;
3696 handler = QMouseDriverFactory::create(mouseProto, mouseDev);
如果返回值 handler爲0就有問題了:(
8.c QMouseDriverFactory::create 是真正創建QWSMouseHandler實例的具體地方,不同的鼠標類型處理都是QWSMouseHandler的子類,這些QWSMouseHandler子類有可能編譯成庫文件,也有可能以插件的形式存在,如果以插件形式存在那麼加載方法是
src/gui/embedded/qmousedriverfactory_qws.cpp
144 if (QWSMouseHandlerFactoryInterface *factory = qobject_cast<QWSMouse HandlerFactoryInterface*>(loader()->instance(driver)))
145 return factory->create(driver, device);
你的鼠標驅動是否加載成功,這第八步的3個函數很關鍵,前面的七步基本上不會出問題,作爲系統運行的一個瞭解就可以。
關於一個具體鼠標Handler裏的設計,將放在本文的下篇裏去講解。