DirectFB視窗管理器(unique)研究筆記

來源:互聯網
上載者:User

DirectFB內建有兩個視窗管理器:default和unique,可以在設定檔中用wm=xxx來選擇用哪一個作為當前的視窗管理器。

兩個視窗管理器的功能都很簡單,與案頭環境流行的視窗管理器幾乎沒有可比性。尤其是前者,提供的功能更是簡陋,僅僅是管理一下視窗棧而已。後者雖然簡陋,但其架構設計還算不錯,很容易在上面擴充自己需要的功能。

什麼是視窗管理器呢?根據EWMH的要求,視窗管理器的準系統有以下這些:

模態視窗(Modality)。一般用來實現模態對話方塊,所謂模態對話方塊,就是具有這樣特性的對話方塊,除非你把它關掉,否則無法切換回到它的父視窗上。

大案頭(Large Desktop)。顯示器的大小是有限的,比如顯示器的解析度為1024x768,那麼傳統的案頭就只能這麼大一點。視窗管理器可以實現一個邏輯上的大案頭,較顯示器的物理解析度,擁有更大的顯示範圍。當然你在某個時刻只能看到案頭的一部分,這部分也稱為viewport,通過變換viewport可以看到案頭的其它地區。

固定視窗(Sticky windows)。固定視窗要求視窗的位置被固定到顯示器的物理位置,viewport的變換對它的位置都沒有影響。

虛擬桌面(VirtualDesktops)。同時開啟的視窗太多時,可以把這些視窗分成不同的組,同一時刻只顯示其中一組的視窗,每一組視窗就是一個虛擬桌面。

任務條(Taskbars)、分頁器(Pagers) 。顯示當前所有的開啟的視窗,並且可以在這些視窗之間切換。

視窗棧序(Z-Order) 。就是視窗之間的上下關係。

保留地區(reserve space)。讓某個視窗獨佔某塊靠邊的地區,比如任務條,一般都獨佔案頭最下面的一長條地區。

視窗狀態(Window State)。視窗有最大化、最小化、全屏等的狀態,這些由視窗管理器負責管理。當然,上層應用也可以調用視窗管理器提供的函數,來改變視窗的狀態。

視窗裝飾。在unix下,GUI的慣例是,視窗的標題和四周的邊框,都稱為裝飾,這些裝飾的顯示是由視窗管理器負責的。這樣的好處時,應用程式無須做任何修改,僅通過配置視窗管理器,就可以得到風格各異的顯示效果。

視窗協議。這主要用於實現視窗僵死狀態檢測,視窗之間的同步處理等功能。

對於嵌入式系統來說,並不要求實現案頭環境上的一些花梢的功能。unique的實現雖然簡單,也可以滿足基本需求,更重要的是它提供了較好的擴充機制。

DirectFB採用模組化設計,它並不依賴於某種具體的視窗管理器,只要具體的視窗管理器實現介面CoreWMFuncs中定義的函數,就可以掛到DirectFB中運行。

Reactor在DirectFB中無處不在,要理解DirectFB的架構一定要理解reactor模式才行。不過,這裡的reactor與POSA中講解的reactor類似,但並不完全相同,它更類似於signal機制,如果你理解glib中的signal或者boost中的signal機制,理解reactor並不難。DirectFB中reactor最大的優點在於它是跨進程的,通過fusion核心模組中轉,在一個進程中觸發的事件可以方便的中轉到另外一個進程。

Unqiue的原始碼在wm/unique目錄下,下面我們以輸入事件流把它們貫穿起來分析一下:

在DirectFB中,每一種輸入裝置,都有一個線程掛在上面,只要輸入裝置有事件上報,該線程就通過reactor把事件轉寄給相應的reactor處理函數。視窗管理在初始時(unique_wm_module_init),調用dfb_input_add_global把_unique_device_listener設定為事件處理函數。

在_unique_device_listener中,並沒有對事件直接處理,而又把它轉給相應的UniqueDeviceClass對象,實現UniqueDeviceClass介面的有keyboard、pointer、wheel三種,每一種都有一個執行個體。

在這裡,UniqueDeviceClass作為一個中介層,是否是多此一舉呢?開始我也這樣認為,過好長一段時間後,我才明白這樣做是有道理的。原因是從不同裝置讀到的事件格式並不統一,比如有的絕對座標,有的是相對座標,索引值映射關係也不一致。這個中介層可以把這些事件轉換成統一的格式,上層無需要再關係這些底層細節。

把事件轉換之後,然後通過reactor分發出去,就到_unique_input_switch_device_listener函數裡。_unique_input_switch_device_listener裡面通過當前的上下文以及事件的內容,決定誰是該事件的目標。

這裡有兩點比較有趣。

第一是StretRegion。StretRegion就是一塊地區,StretRegion與視窗的關係又是什麼樣的呢?這種關係很很簡單,一般的視窗(帶裝飾的視窗)有十個StretRegion組成,它們分別是四邊、四角、視窗客戶區以及這九個StretRegion的父StretRegion(也稱為frame)。

對於鍵盤事件,一般是焦點視窗的客戶區收到事件,如果是筆時間點事件,則由筆點的位置決定是哪個StretRegion收到事件。

第二是決定了目標StretRegion之後,並不是直接把事件投遞給這個StretRegion,而是調用StretRegion的GetInput函數,擷取一個input_channel的對象。這似乎也是多此一舉,實則不然,視窗的四邊、四角、視窗客戶區九個地區是完全獨立的,它不知道也不應該知道其它八的存在,另外這個九個地區的地位也不是等同的,有的要自己處理事件,有的不用,只有每個StretRegion自己才知道,所以由GetInput去決定把事件給誰。

事件經過input_channel之後,就輪到_unique_window_input_channel_listener函數處理了。這時,事件才真正被投遞到相應的視窗,之後事情與視窗管理器就無關了。

對Z-Order的管理,實際上比較簡單,無非就是調整視窗在棧的位置,所謂棧其實並不是真正的棧,只是一個雙向鏈表,大家都習慣的稱為棧罷了。

Unique實現了簡單的裝飾功能,相關代碼在foo_update裡(並沒有用到decoration.c/.h)。它的圖片資料在data目錄中。Unique的裝飾功能最大的缺陷是,沒有根據不同類型的視窗實現不同的裝飾。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.