QtEmbedded鼠標驅動流程分析(上)

 

注:此驅動對應英文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)
openmouse
從上面代碼我們可以得出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裏的設計,將放在本文的下篇裏去講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章