• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    對DirectFB窗口管理器(unique)的研究

    發布: 2008-4-21 14:00 | 作者: 李先靜 | 來源: 李先靜Blog | 查看: 750次 | 進入軟件測試論壇討論

    領測軟件測試網

    DirectFB自帶有兩個窗口管理器:default和unique,可以在配置文件中用wm=xxx來選擇用哪一個作為當前的窗口管理器。

     

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

     

    什么是窗口管理器呢?根據EWMH的要求,窗口管理器的基本功能有以下這些:

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

     

    大桌面(Large Desktop)。顯示器的大小是有限的,比如顯示器的分辨率為1024x768,那么傳統的桌面就只能這么大一點。窗口管理器可以實現一個邏輯上的大桌面,較顯示器的物理分辨率,擁有更大的顯示范圍。當然你在某個時刻只能看到桌面的一部分,這部分也稱為viewport,通過變換viewport可以看到桌面的其它區域。

     

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

     

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

     

    任務條(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的裝飾功能最大的缺陷是,沒有根據不同類型的窗口實現不同的裝飾。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: DirectFB 研究 管理器 unique 窗口


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>