爲了保持QtEmbedded對硬件最小化的依賴程度,QtEmbedded全部硬件相關的操做都採用插件的封裝形式,而且大部分功能均可以從程序外部運用環境變量的方式來配置。這樣一來咱們只要針對不一樣的硬件寫好不一樣的插件,爲不一樣硬件平臺提供不一樣的啓動腳本就能夠了,換了硬件,代碼卻不須要修改。
Qt Embedded的鍵盤操做是這種插件封裝形式的典範,咱們就以此爲例,對Qt Embedded的硬件操做一窺究竟。
一、告訴QtEmbedded你須要哪一個驅動
QWS_KEYBOARD這個環境變量就是你須要瞭解的所有。
設置該變量的方法爲在運行QtE server程序以前用下面的命令設置:
export QWS_KEYBOARD= <driver>[:<driver specific options>]
driver參數即驅動的類型, 如「usb」、「tty」等, 在下篇中咱們再詳細討論這個。
options則指定硬件設備名, 如/dev/input/event0, 這個參數就要按你的硬件實際狀況來提供了。
二、載入用戶須要的驅動插件
這個環境變量是如何工做的呢? 今天咱們講述的重點放在QtE的幾個文件上:
讀取環境變量, 載入相應的鍵盤驅動插件:src/gui/embedded/qwindowsystem_qws.cpp
建立鍵盤處理函數類的實例:src/gui/embedded/qkbddriverfactory_qws.cpp
故事從QWSServerPrivate::initServer開始, 這個函數在QWSServer構造時被調用, 它會完成初始化的工做, 包括按順序初始化各個硬件接口(鼠標、鍵盤等等外設), 這個函數接近最後的幾行代碼調用了openKeyboard來初始化鍵盤。
第二步進到同一源碼文件的QWSServer::openKeyboard(), 該函數負責解析環境變量 QWS_KEYBOARD的設定, 從中取得鍵盤設備的名稱和driver handler的類型,並最終調用QKbdDriverFactory::create函數載入對應的鍵盤處理插件。
第三步也是本場大戲的重頭, 打開qkbddriverfactory_qws.cpp找到QKbdDriverFactory::create函數。 前面咱們說到過這個函數包含了建立鍵盤處理函數的類的實例的代碼, 簡單看一下這個函數咱們發現,前面大段的code是一堆跟硬件類型相關的宏包裹住的代碼, 這部分表明了Qt裏內嵌的driver handler,而非插件形式提供的。QtE自身支持的每一個鍵盤設備都有一個預約義的宏和預約義的driver handler類與之對應, 根據代碼顯示,設備的類型必須在configure階段就肯定,以X86模擬器環境下爲例,在這個環境下configure的時候須要加 -qvfb參數,這個參數就會去掉 QT_NO_QWS_KBD_QVFB這個宏,在此函數中就表示爲調用到return new QVFbKeyboardHandler(device);這行。
那麼,若是上面全部的QT_NO都被定義了呢? 固然代碼就會跳過這一堆無用的code, 直接調用到
if (QWSKeyboardHandlerFactoryInterface *factory = qobject_cast<QWSKeyboardHandlerFactoryInterface*>(loader()->instance(driver)))
return factory->create(driver, device);
這段代碼就比較有意思了,它表明的是以插件形式存在的各個鍵盤處理插件。在你不使用Qt預約義鍵盤處理的狀況下就須要有與環境變量請求的driver handler鍵值一致的插件。鍵盤處理插件如何定義不是本文探討的內容(請參看下篇),咱們只要知道這個插件會提供一個標識本身的鍵值,這樣loader比較建立插件的請求和插件的鍵值就知道該返回哪一個插件提供的服務了。 還有幾點有意思的地方: 一、 driver的類型信息不區分大小寫。 二、 QtE內嵌的driver類型默認是都不支持的,只有在configure的時候加上-qt-kbd-xxx才能支持某種driver類型。(詳情 configure –help) 三、 同一時刻只能有一個driver處理函數生效。 四、 因爲這部分代碼都在QWSServer構造時調用,也就是說QtE不支持動態的更改鍵盤處理。