?
在嵌入式 Linux 下有很多圖形界面系統(tǒng) GUI,包括 Qt/Embedded,F(xiàn)LTK,Microwindows 和 GTK+ 等。作為一個(gè)開發(fā)者,到底使用什么樣的 GUI 系統(tǒng)呢?對一個(gè)系統(tǒng),將它改造為符合你的需求,你要做多少修改呢?修改后的系統(tǒng)的尺寸一般會(huì)有多大呢?這些都是開發(fā)人員會(huì)遇到的問題。我們在這里討論的就是要對這些內(nèi)容做一個(gè)具體細(xì)致的分析,通過我們的討論,大家會(huì)對基于 GTK+ 和 X 的 GUI 在嵌入式Linux 下的應(yīng)用有一個(gè)確切的了解。
在嵌入式系統(tǒng)應(yīng)用日益發(fā)展的今天,越來越多的應(yīng)用都需要使用到 GUI 來進(jìn)行開發(fā),以此來獲得更好的交互性。
嵌入式 Linux 下 GUI 的選擇,對大多數(shù)開發(fā)人員來說是一個(gè)需要權(quán)衡對比的過程。選擇 GTK+ 運(yùn)行在 X 系統(tǒng)上,然后 X 系統(tǒng)運(yùn)行在嵌入系統(tǒng)的 framebuffer 上,這會(huì)是一個(gè)很好的選擇。
GTK+ 與 X 的優(yōu)點(diǎn)
當(dāng)然,GTK+ 與 X 一般都是被大家考慮為體積較大的桌面系統(tǒng)的好搭配,但實(shí)際上對于嵌入系統(tǒng)來說,它也有著諸多的優(yōu)點(diǎn):
1、 X-window 系統(tǒng)與 GTK+ 都非常穩(wěn)定可靠,X-window 系統(tǒng)是經(jīng)歷了長期的開發(fā)及應(yīng)用實(shí)踐的,GTK+ 也是一個(gè)比較成熟的開放源代碼項(xiàng)目。
2、 X-window 系統(tǒng)是一個(gè)靈活的 client/server 的模型結(jié)構(gòu),一個(gè)應(yīng)用客戶端的崩潰不會(huì)影響到圖形系統(tǒng)的其他部分,這是一個(gè)很重要的特性,它有利于支持第三方應(yīng)用的擴(kuò)展開發(fā),而不影響到主體部分。
3、 GTK+有兩個(gè)重要的庫:GDK和GLIB。GDK抽象了底層的窗口管理,要移植 GTK+ 到另一個(gè)不同的窗口系統(tǒng)的話,我們只需要移植 GDK 就可以了。GLIB 是一個(gè)工具集合,它包括了數(shù)據(jù)類型,各種宏定義,類型轉(zhuǎn)化,字符串處理,任何應(yīng)用程序都可以鏈接這個(gè) GLIB 庫,使用其中的各種數(shù)據(jù)類型、方法,來避免重復(fù)代碼,或者說避免開發(fā)人員重新發(fā)明輪子,這樣有利于減少整個(gè)系統(tǒng)的尺寸。
4、 對 GTK+/X 的裁剪是很容易的,它們有著很好的可配置的選項(xiàng),有著清晰的代碼結(jié)構(gòu),可以保證安全正確地去掉大段的不需要的代碼。
5、 GTK+ 有著大量的應(yīng)用,GTK+ 已經(jīng)被用在了很多重要的應(yīng)用系統(tǒng)中。
6、 GTK+ 的授權(quán)是 LGPL 方式的,X 是 non-copyleft free license 的,第三方開發(fā)的系統(tǒng)都能與它們進(jìn)行鏈接。
7、 GTK+/X 二者都是基于 C 代碼的,而不是C++。
8、 GTK+ 使用 C 來實(shí)現(xiàn)了面向?qū)ο蟮募軜?gòu)。
其他 GUI 系統(tǒng)
其他可以選擇的圖形系統(tǒng)包括:Qt/Embedded,F(xiàn)LTK 和 Microwindows。
1、 Qt/E 是其中較高級的,它是一個(gè)完整的,基于 framebuffer 的 GUI 系統(tǒng),由 Trolltech 公司開發(fā)。
2、 Qt/E 有著高效的圖形渲染效果,還包括 TrueType 字體系統(tǒng),及 alpha blending 半透明處理。
3、 但 Qt/E 不是使用 LGPL 授權(quán)方式,而是使用兩種授權(quán)方式:開發(fā)使用 GPL,而商用需要授權(quán)與版稅。
4、 Qt/E 是用 C++ 編寫的。
5、 Qt/E 非常大,一個(gè) iPAQ QPE 就包括了 3.3MB 的 Qt/E 庫和一個(gè) 718KB 的 QPE 庫(和 Xlib 類似的一種庫)。
6、 Qt/E 不夠穩(wěn)定,QPE demo 不錯(cuò),但出現(xiàn)過崩潰。
7、 FLTK (the Fast Light Toolkit) 是一個(gè)小型的 GUI 圖形系統(tǒng),它也是用 C++ 寫的,特性太少,應(yīng)用范圍較少,不夠成熟。
8、 Microwindows 和 X-Window 相比也是一個(gè)不錯(cuò)的選擇,它占用大約 100KB-600KB 大小的內(nèi)存,和文件存儲(chǔ)空間,雖然已經(jīng)有了一個(gè)其上的 GTK+ 移植,但還是不夠成熟。
X-window:比你想象的要小很多
對于X-window系統(tǒng),廣大的網(wǎng)絡(luò)開發(fā)者已經(jīng)做了大量的工作來減小其的尺寸,最知名的有TinyX??梢酝ㄟ^對不需要的代碼的裁剪及去除XLIB中靜態(tài)數(shù)據(jù)來減少總體的尺寸,如:color管理系統(tǒng),弧形,粗線條等。
在大多數(shù)開發(fā)人員的印象里,X 系統(tǒng)很龐大,但實(shí)際上,你聽到的,是那些對 X 不夠了解的人的一種誤解。在經(jīng)過裁剪后的情況下,GTK+/X 要比 GTK+/FB 與 Qt/E 還要來得有效,且 XLIB 對一般的應(yīng)用程序有著更好的支持作用,應(yīng)用程序的開發(fā)會(huì)變得更高效。
如何裁剪 GTK+
我們可以從標(biāo)準(zhǔn)的 GTK+ 發(fā)行版本來裁剪,裁剪掉其中的不需要的,修改已經(jīng)有的代碼,并加入新的特性所需要的代碼。裁剪的范圍包括小的改動(dòng),也包括一些大的結(jié)構(gòu)性的、核心的改變。
一、 去除 Widgets 窗口
最開始,我們把不需要的 Widgets 去除掉,比如:GtkGamma、GtkHRuler、過時(shí)了的 GtkList(被 GtkCList所替代了)、和我們不需要的 GtkFrame 邊框。
二、 Widgets 窗口尺寸與繪制
接著,修改Widgets的大小與繪制方法,GTK+提供了一個(gè)主題引擎機(jī)制,來控制窗口的外觀與效果。它允許在運(yùn)行中設(shè)置字體,設(shè)置行間隔,設(shè)置繪制特性。這樣的機(jī)制很不錯(cuò),但不夠靈活,代碼中很多設(shè)置的地方都是使用硬編碼的方式;另外,一種主題,就是一堆額外的代碼段和參數(shù),這樣會(huì)增加整體的尺寸。
需要找出影響到窗口系統(tǒng)整體尺寸的內(nèi)容,再來修改它。比如,一個(gè)按鈕的大小與繪制,包括這樣的參數(shù):邊框的寬度,x/y的位置(主題引擎需要的參數(shù)),缺省的間隔(常量),缺省的左上角的位置(常量),獲得焦點(diǎn)。這些在嵌入系統(tǒng)中并不需要那么完整,我們可以根據(jù)實(shí)際的需求來簡化代碼,來避免GTK +的復(fù)雜性。
另外,使用面向?qū)ο蟮姆椒?,來繼承窗口Widgets的特性,作為子類也是一個(gè)有效的方法。
三、GtkWindow
GTK+總是假定一個(gè)窗口里面包含了另一個(gè)窗口,它們就是嵌套關(guān)系。但對于我們經(jīng)常會(huì)碰到的有軟鍵盤的應(yīng)用時(shí),就不完全正確了。軟鍵盤雖然是屬于一個(gè)窗口的,但卻會(huì)超出那個(gè)窗口。所以為了突破這個(gè)假定,需要對GtkWindow增加一些特性,將軟鍵盤處理成一種特殊的子窗口。
軟鍵盤所在的窗口,需要處理軟鍵盤的按鍵事件,并將按鍵轉(zhuǎn)發(fā)給軟鍵盤工具條。當(dāng)軟鍵盤按下,軟鍵盤的回調(diào)函數(shù)就被注冊到原始窗口上,這樣軟鍵盤就會(huì)響應(yīng)按鍵事件。在GtkWindow上增加接口,可以創(chuàng)建,響應(yīng)按鍵。
在小屏幕的嵌入系統(tǒng)中,可以將滾動(dòng)條做得更簡化些,去掉邊框,使用單個(gè)滾動(dòng)條。這些都更適合嵌入系統(tǒng)。
字體管理系統(tǒng)
在字體管理方面,要找到一個(gè)輕型的機(jī)制來在嵌入式系統(tǒng)顯示各種字體,并不是那么簡單,困難在于GTK+ 的大型的 Widget 風(fēng)格與 X 系統(tǒng)的老式的字體管理機(jī)制的結(jié)合所引起的問題。
前面提到的,主題引擎方式的GTK+ 是用來控制窗口的樣式與外觀的。在一個(gè)窗口顯示之前,它會(huì)得到一個(gè)式樣對象,GtkStyle,它可以是一個(gè)指向父窗口的式樣對象指針,或者是一個(gè)新的類型,這些式樣對象將被應(yīng)用到這個(gè)窗口及它的子窗口。這個(gè)式樣由缺省值、rc 文本文件、應(yīng)用來確定。
要改變一個(gè)窗口的字體,你必須克隆窗口的式樣,并使用X字體加載一個(gè)新的字體,類似adobe-helvetica-bold-r-normal--12-*-*-*-p-*-iso8859-1。
但實(shí)際中會(huì)有些問題,GtkStyle是一個(gè)大的對象。如果一個(gè)屏幕上有很多種不同字體大小的多個(gè)窗口,每個(gè)都有一個(gè)唯一的GtkStyle對象,我們就會(huì)浪費(fèi)大量的內(nèi)存。到最后,X系統(tǒng)就不能支持類似字體的各種變化了。你甚至不能使X完成讓某個(gè)字體變粗的操作,因?yàn)閄系統(tǒng)是將不同外型的字體作為不同的字體的。X系統(tǒng)是假定你會(huì)硬編碼一個(gè)希望的字體或者分析出一個(gè)字體名,改變字體及驗(yàn)證結(jié)果都將在字體服務(wù)器上。
還可以使用一個(gè)更好的方法來完善字體管理系統(tǒng),即包裝GtkStyle,這樣開發(fā)者就可以通過屬性來獲得一個(gè)窗口的字體,這比直接使用 X 系統(tǒng)字體的名字要更靈活。比如要顯示一個(gè)比基本字體要大一號,并且是黑體字就可以調(diào)用:
gtk_widget_set_font_bold (widget, TRUE);
gtk_widget_set_font_enlarge (widget, 1);
這是通過在 GtkWidget 結(jié)構(gòu)中加入一個(gè) GdkFont * font 來實(shí)現(xiàn)的,GtkWidget 是所有窗口類的父類。如果設(shè)置widget->font 那么就使用它,否則就使用widget->style->font。
X-window:比你想象的要小很多
對于X-window系統(tǒng),廣大的網(wǎng)絡(luò)開發(fā)者已經(jīng)做了大量的工作來減小其的尺寸,最知名的有TinyX??梢酝ㄟ^對不需要的代碼的裁剪及去除XLIB中靜態(tài)數(shù)據(jù)來減少總體的尺寸,如:color管理系統(tǒng),弧形,粗線條等。
在大多數(shù)開發(fā)人員的印象里,X 系統(tǒng)很龐大,但實(shí)際上,你聽到的,是那些對 X 不夠了解的人的一種誤解。在經(jīng)過裁剪后的情況下,GTK+/X 要比 GTK+/FB 與 Qt/E 還要來得有效,且 XLIB 對一般的應(yīng)用程序有著更好的支持作用,應(yīng)用程序的開發(fā)會(huì)變得更高效。
如何裁剪 GTK+
我們可以從標(biāo)準(zhǔn)的 GTK+ 發(fā)行版本來裁剪,裁剪掉其中的不需要的,修改已經(jīng)有的代碼,并加入新的特性所需要的代碼。裁剪的范圍包括小的改動(dòng),也包括一些大的結(jié)構(gòu)性的、核心的改變。
一、 去除 Widgets 窗口
最開始,我們把不需要的 Widgets 去除掉,比如:GtkGamma、GtkHRuler、過時(shí)了的 GtkList(被 GtkCList所替代了)、和我們不需要的 GtkFrame 邊框。
二、 Widgets 窗口尺寸與繪制
接著,修改Widgets的大小與繪制方法,GTK+提供了一個(gè)主題引擎機(jī)制,來控制窗口的外觀與效果。它允許在運(yùn)行中設(shè)置字體,設(shè)置行間隔,設(shè)置繪制特性。這樣的機(jī)制很不錯(cuò),但不夠靈活,代碼中很多設(shè)置的地方都是使用硬編碼的方式;另外,一種主題,就是一堆額外的代碼段和參數(shù),這樣會(huì)增加整體的尺寸。
需要找出影響到窗口系統(tǒng)整體尺寸的內(nèi)容,再來修改它。比如,一個(gè)按鈕的大小與繪制,包括這樣的參數(shù):邊框的寬度,x/y的位置(主題引擎需要的參數(shù)),缺省的間隔(常量),缺省的左上角的位置(常量),獲得焦點(diǎn)。這些在嵌入系統(tǒng)中并不需要那么完整,我們可以根據(jù)實(shí)際的需求來簡化代碼,來避免GTK +的復(fù)雜性。
另外,使用面向?qū)ο蟮姆椒?,來繼承窗口Widgets的特性,作為子類也是一個(gè)有效的方法。
三、GtkWindow
GTK+總是假定一個(gè)窗口里面包含了另一個(gè)窗口,它們就是嵌套關(guān)系。但對于我們經(jīng)常會(huì)碰到的有軟鍵盤的應(yīng)用時(shí),就不完全正確了。軟鍵盤雖然是屬于一個(gè)窗口的,但卻會(huì)超出那個(gè)窗口。所以為了突破這個(gè)假定,需要對GtkWindow增加一些特性,將軟鍵盤處理成一種特殊的子窗口。
軟鍵盤所在的窗口,需要處理軟鍵盤的按鍵事件,并將按鍵轉(zhuǎn)發(fā)給軟鍵盤工具條。當(dāng)軟鍵盤按下,軟鍵盤的回調(diào)函數(shù)就被注冊到原始窗口上,這樣軟鍵盤就會(huì)響應(yīng)按鍵事件。在GtkWindow上增加接口,可以創(chuàng)建,響應(yīng)按鍵。
在小屏幕的嵌入系統(tǒng)中,可以將滾動(dòng)條做得更簡化些,去掉邊框,使用單個(gè)滾動(dòng)條。這些都更適合嵌入系統(tǒng)。
字體管理系統(tǒng)
在字體管理方面,要找到一個(gè)輕型的機(jī)制來在嵌入式系統(tǒng)顯示各種字體,并不是那么簡單,困難在于GTK+ 的大型的 Widget 風(fēng)格與 X 系統(tǒng)的老式的字體管理機(jī)制的結(jié)合所引起的問題。
前面提到的,主題引擎方式的GTK+ 是用來控制窗口的樣式與外觀的。在一個(gè)窗口顯示之前,它會(huì)得到一個(gè)式樣對象,GtkStyle,它可以是一個(gè)指向父窗口的式樣對象指針,或者是一個(gè)新的類型,這些式樣對象將被應(yīng)用到這個(gè)窗口及它的子窗口。這個(gè)式樣由缺省值、rc 文本文件、應(yīng)用來確定。
要改變一個(gè)窗口的字體,你必須克隆窗口的式樣,并使用X字體加載一個(gè)新的字體,類似adobe-helvetica-bold-r-normal--12-*-*-*-p-*-iso8859-1。
但實(shí)際中會(huì)有些問題,GtkStyle是一個(gè)大的對象。如果一個(gè)屏幕上有很多種不同字體大小的多個(gè)窗口,每個(gè)都有一個(gè)唯一的GtkStyle對象,我們就會(huì)浪費(fèi)大量的內(nèi)存。到最后,X系統(tǒng)就不能支持類似字體的各種變化了。你甚至不能使X完成讓某個(gè)字體變粗的操作,因?yàn)閄系統(tǒng)是將不同外型的字體作為不同的字體的。X系統(tǒng)是假定你會(huì)硬編碼一個(gè)希望的字體或者分析出一個(gè)字體名,改變字體及驗(yàn)證結(jié)果都將在字體服務(wù)器上。
還可以使用一個(gè)更好的方法來完善字體管理系統(tǒng),即包裝GtkStyle,這樣開發(fā)者就可以通過屬性來獲得一個(gè)窗口的字體,這比直接使用 X 系統(tǒng)字體的名字要更靈活。比如要顯示一個(gè)比基本字體要大一號,并且是黑體字就可以調(diào)用:
gtk_widget_set_font_bold (widget, TRUE);
gtk_widget_set_font_enlarge (widget, 1);
這是通過在 GtkWidget 結(jié)構(gòu)中加入一個(gè) GdkFont * font 來實(shí)現(xiàn)的,GtkWidget 是所有窗口類的父類。如果設(shè)置widget->font 那么就使用它,否則就使用widget->style->font。
優(yōu)化
在ARM7的系統(tǒng)上,由于沒有浮點(diǎn)運(yùn)算FPU,所以GTK+中的浮點(diǎn)運(yùn)算部分最好是去掉,否則會(huì)大大影響性能。GTK+使用到的浮點(diǎn)變量只分布在少數(shù)的幾個(gè)窗口中,并且去掉它們會(huì)帶來3%到12%的性能提高。
高像素的應(yīng)用會(huì)導(dǎo)致速度較慢,這大多是由于GTK+與X中對高像素的效率低下的處理有關(guān)。如涉及到的XPM,XPM (X pixmap)格式是被設(shè)計(jì)來做到較好的兼容性,而不是更加快速。X系統(tǒng)是一個(gè)像素一個(gè)像素地畫到server的pixmap的。GTK+的像素處理也很低效,它是使用fgetc()來讀取XPM文件的,這就會(huì)帶來大量的上下文切換開銷。
X窗口系統(tǒng)的結(jié)構(gòu)也導(dǎo)致了像素的加載變慢。GTK+客戶端需要加載,分析XPM文件,將像素值通過傳輸協(xié)議發(fā)送給server,然后server才將像素值放入framebuffer。如果客戶端直接將數(shù)據(jù)寫到framebuffer server那將會(huì)有效很多。
處理的GTK+像素的辦法就是,寫一個(gè)臨時(shí)的中間過程,取得render過的像素,使用這個(gè)原始數(shù)據(jù)來替換XPM數(shù)據(jù),這個(gè)原始數(shù)據(jù)就可以直接強(qiáng)制寫到X server上。從結(jié)構(gòu)上來看,這雖然不是一個(gè)很好的處理辦法,但在效率上卻要比使用XPM要快上80%。
總結(jié)
現(xiàn)在的消費(fèi)電子大多需要一個(gè)美觀,實(shí)用的圖形界面系統(tǒng)GUI。在嵌入系統(tǒng)linux下,有很多種GUI可供選擇。使用開放代碼的GUI的優(yōu)點(diǎn)就是你可以將其裁剪得滿足你的各種各樣的特殊需求。GTK+就是一個(gè)很好的選擇,而X-window系統(tǒng)提供了一個(gè)穩(wěn)定可靠的client/server模型。當(dāng)你得到一個(gè)只有2.9M大小的定制過的GUI時(shí),對大多數(shù)的嵌入系統(tǒng)還是很有參考價(jià)值的。
評論
查看更多