基于GTK+和X-window的GUI在嵌入式Linux中的應用
在大多數開發人員的印象里,X 系統很龐大,但實際上,你聽到的,是那些對 X 不夠了解的人的一種誤解。在經過裁剪后的情況下,GTK+/X 要比 GTK+/FB 與 Qt/E 還要來得有效,且 XLIB 對一般的應用程序有著更好的支持作用,應用程序的開發會變得更高效。
如何裁剪 GTK+
我們可以從標準的 GTK+ 發行版本來裁剪,裁剪掉其中的不需要的,修改已經有的代碼,并加入新的特性所需要的代碼。裁剪的范圍包括小的改動,也包括一些大的結構性的、核心的改變。
一、 去除 Widgets 窗口
最開始,我們把不需要的 Widgets 去除掉,比如:GtkGamma、GtkHRuler、過時了的 GtkList(被 GtkCList所替代了)、和我們不需要的 GtkFrame 邊框。
二、 Widgets 窗口尺寸與繪制
接著,修改Widgets的大小與繪制方法,GTK+提供了一個主題引擎機制,來控制窗口的外觀與效果。它允許在運行中設置字體,設置行間隔,設置繪制特性。這樣的機制很不錯,但不夠靈活,代碼中很多設置的地方都是使用硬編碼的方式;另外,一種主題,就是一堆額外的代碼段和參數,這樣會增加整體的尺寸。
需要找出影響到窗口系統整體尺寸的內容,再來修改它。比如,一個按鈕的大小與繪制,包括這樣的參數:邊框的寬度,x/y的位置(主題引擎需要的參數),缺省的間隔(常量),缺省的左上角的位置(常量),獲得焦點。這些在嵌入系統中并不需要那么完整,我們可以根據實際的需求來簡化代碼,來避免 GTK+的復雜性。
另外,使用面向對象的方法,來繼承窗口Widgets的特性,作為子類也是一個有效的方法。
三、GtkWindow
GTK+總是假定一個窗口里面包含了另一個窗口,它們就是嵌套關系。但對于我們經常會碰到的有軟鍵盤的應用時,就不完全正確了。軟鍵盤雖然是屬于一個窗口的,但卻會超出那個窗口。所以為了突破這個假定,需要對GtkWindow增加一些特性,將軟鍵盤處理成一種特殊的子窗口。
軟鍵盤所在的窗口,需要處理軟鍵盤的按鍵事件,并將按鍵轉發給軟鍵盤工具條。當軟鍵盤按下,軟鍵盤的回調函數就被注冊到原始窗口上,這樣軟鍵盤就會響應按鍵事件。在GtkWindow上增加接口,可以創建,響應按鍵。
在小屏幕的嵌入系統中,可以將滾動條做得更簡化些,去掉邊框,使用單個滾動條。這些都更適合嵌入系統。
字體管理系統
在字體管理方面,要找到一個輕型的機制來在嵌入式系統顯示各種字體,并不是那么簡單,困難在于GTK+ 的大型的 Widget 風格與 X 系統的老式的字體管理機制的結合所引起的問題。
前面提到的,主題引擎方式的GTK+ 是用來控制窗口的樣式與外觀的。在一個窗口顯示之前,它會得到一個式樣對象,GtkStyle,它可以是一個指向父窗口的式樣對象指針,或者是一個新的類型,這些式樣對象將被應用到這個窗口及它的子窗口。這個式樣由缺省值、rc 文本文件、應用來確定。
要改變一個窗口的字體,你必須克隆窗口的式樣,并使用X字體加載一個新的字體,類似adobe-helvetica-bold-r-normal--12-*-*-*-p-*-iso8859-1。
但實際中會有些問題,GtkStyle是一個大的對象。如果一個屏幕上有很多種不同字體大小的多個窗口,每個都有一個唯一的GtkStyle對象,我們就會浪費大量的內存。到最后,X系統就不能支持類似字體的各種變化了。你甚至不能使X完成讓某個字體變粗的操作,因為X系統是將不同外型的字體作為不同的字體的。X系統是假定你會硬編碼一個希望的字體或者分析出一個字體名,改變字體及驗證結果都將在字體服務器上。
還可以使用一個更好的方法來完善字體管理系統,即包裝GtkStyle,這樣開發者就可以通過屬性來獲得一個窗口的字體,這比直接使用 X 系統字體的名字要更靈活。比如要顯示一個比基本字體要大一號,并且是黑體字就可以調用:
gtk_widget_set_font_bold (widget, TRUE);
gtk_widget_set_font_enlarge (widget, 1);
這是通過在 GtkWidget 結構中加入一個 GdkFont * font 來實現的,GtkWidget 是所有窗口類的父類。如果設置widget->font 那么就使用它,否則就使用widget->style->font。
窗口管理
在嵌入系統GUI中,還需要建立一個窗口管理器。我們可以選擇一個開放代碼的,輕量級的X管理器,Aewm。在嵌入系統中,我們會將最上層的窗口設置為獲得焦點,并且只有對話框能移動,能顯示其標題欄。
窗口管理器是一個交互端,它可以管理內部與外部的應用程序的窗口。每一個應用程序的窗口,都會建立一個 socket 連接,并取一個名字。一個應用可以把請求將自己放在窗口堆棧的最下面,或者將一個命名的應用往上移。如果一個對話框要在最上層的窗口上打開,那么窗口管理器就將告訴這個最上層的窗口它將不再獲得焦點,而新對話框將獲得焦點。
評論