?? minigui體系結構之一 體系結構概覽.htm
字號:
pthread_mutex_unlock (&pMsgQueue->lock);
</PRE></TD></TR></TBODY></TABLE>
<P>信號量 wait 用來同步消息循環。一般來說,一個線程在建立窗口之后,要進入消息循環持續地從消息隊列中獲取消息(通過 GetMessage()
函數)。當消息隊列中沒有任何消息時,該線程將進入休眠狀態,而當其他線程將消息郵寄或發送到該消息隊列之后,將通過信號量 wait 喚醒該線程:</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> sem_getvalue (&pMsgQueue->wait, &sem_value);
if (sem_value == 0)
sem_post(&pMsgQueue->wait);
</PRE></TD></TR></TBODY></TABLE>
<P>在 MiniGUI 的消息隊列結構中,第一個成員是消息隊列的狀態字。該狀態字通過標志位表示如下狀態:</P>
<UL>
<LI>消息隊列中是否有郵寄消息;
<LI>消息隊列中是否有通知消息;
<LI>消息隊列中是否有同步消息;
<LI>消息隊列中是否有退出消息;
<LI>消息隊列中是否有重繪消息;
<LI>消息隊列中是否有定時器消息。 </LI></UL>
<P>通過這些標志,GetMessage()
可判斷是否需要檢查郵寄消息隊列、通知消息鏈表和同步消息鏈表等等。同時,利用這些標志還可以處理上面提到的一些特殊消息。這里以定時器為例進行說明。</P>
<P>在 MiniGUI 中,一個創建了窗口的線程一般擁有一個消息隊列,使用該消息隊列所有窗口,包括子窗口在內,一共可以建立 8
個定時器。這些定時器是否到期,體現在消息隊列的狀態字上――狀態字的最低 8 位分別用來表示這 8
個定時器是否到期。消息隊列中同時還有三個成員:</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> HWND TimerOwner[8]; // 定時器所有者
int TimerID[8]; // 定時器標識符
BYTE TimerMask; // 已使用的定時器掩碼
</PRE></TD></TR></TBODY></TABLE>
<P>其中 TimerMask 表示當前有效的定時器,每位表示一個定時器;TimerID 表示這 8 個定時器的標識符(整數);而
TimerOwner 則表示定時器的所有者(窗口句柄)。這種定時器的實現方法類似 Linux
內核中的信號實現。定時器是否有效以及是否到期均由二進制字節的一個位來表示。當 GetMessage
檢查這些標志時發現有某個定時器到期才會獲得一個定時器消息。也就是說,定時器消息是不排隊的。這樣就解決了排隊時可能塞滿消息隊列的問題。</P><A
id=5 name=5></A>
<P><STRONG class=subhead>5 面向對象技術在 MiniGUI 中的應用</STRONG></P><STRONG>5.1
控件類和控件</STRONG>
<P>MiniGUI 中的每個控件都屬于某種子窗口類,是對應子窗口類的實例。這類似于面向對象技術中類和對象的關系。圖 3 給出了 MiniGUI
中控件和控件類之間的關系。</P>
<P align=center><IMG alt="" src="MiniGUI體系結構之一 體系結構概覽.files/image03.gif"
border=0><BR>圖 3 控件類和控件之間的關系</P>
<P>每個控件的消息實際都是有該控件所屬控件類的回調函數處理的,從而可以讓每個屬于統一控件類的控件均保持有相同的用戶界面和處理行為。</P>
<P>但是,如果我們在調用某個控件類的回調函數之前,首先調用自己定義的某個回調函數的話,我們就可以讓該控件重載控件類的某些處理行為,從而讓該控件一方面繼承控件類的大部分處理行為,另一方面又具有自己的特殊行為。這實際就是面向對象中的繼承和派生。比如,一般的編輯框會接收所有的鍵盤輸入,當我們希望自己的編輯框只接收數字時,就可以用這種辦法屏蔽非數字的字符輸入。</P><STRONG>5.2
GAL 和 IAL</STRONG>
<P>在 MiniGUI 0.3.xx 的開發中,我們引入了圖形和輸入抽象層(Graphics and Input Abstract
Layer,GAL 和 IAL)的概念。抽象層的概念類似 Linux
內核虛擬文件系統的概念。它定義了一組不依賴于任何特殊硬件的抽象接口,所有頂層的圖形操作和輸入處理都建立在抽象接口之上。而用于實現這一抽象接口的底層代碼稱為“圖形引擎”或“輸入引擎”,類似操作系統中的驅動程序。這實際是一種面向對象的程序結構。利用
GAL 和 IAL,MiniGUI 可以在許多圖形引擎上運行,比如 SVGALib 和 LibGGI,并且可以非常方便地將 MiniGUI
移植到其他 POSIX 系統上,只需要根據我們的抽象層接口實現新的圖形引擎即可。目前,我們已經編寫了基于 SVGALib 和 LibGGI
的圖形引擎。利用 LibGGI, MiniGUI 應用程序可以運行在 X Window 上,將大大方便應用程序的調試。我們目前正在進行
MiniGUI 私有圖形引擎的設計開發。通過 MiniGUI
的私有圖形引擎,我們可以最大程度地針對窗口系統對圖形引擎進行優化,最終提高系統的圖形性能和效率。</P>
<P>GAL 和 IAL 的結構是一樣的,我們這里只拿 GAL 作為實例說明面向對象技術的運用,參見圖 4。</P>
<P>系統維護一個已注冊圖形引擎數組,保存每個圖形引擎數據結構的指針。系統利用一個指針保存當前使用的圖形引擎。一般而言,系統中至少有兩個圖形引擎,一個是“啞”圖形引擎,不進行任何實際的圖形輸出;一個是實際要使用的圖形引擎,比如
LibGGI 或者 SVGALib。每個圖形引擎的數據結構定義了該圖形引擎的一些信息,比如標識符、屬性等,更重要的是,它實現了 GAL
所定義的各個接口,包括初始化和終止、圖形上下文管理、畫點處理函數、畫線處理函數、矩形框填充函數、調色板函數等等。</P>
<P align=center><IMG alt="" src="MiniGUI體系結構之一 體系結構概覽.files/image04.gif"
border=0><BR>圖 4 GAL 結構</P>
<P>如果在某個實際項目中所使用的圖形硬件比較特殊,現有的圖形引擎均不支持。這時,我們就可以安照 GAL 所定義的接口實現自己的圖形引擎,并指定
MiniGUI 使用這種私有的圖形引擎即可。這種軟件技術實際就是面向對象多態性的具體體現。</P>
<P>利用 GAL 和 IAL,大大提高了 MiniGUI 的可移植性,并且使得程序的開發和調試變得更加容易。我們可以在 X Window
上開發和調試自己的 MiniGUI 程序,通過重新編譯就可以讓 MiniGUI 應用程序運行在特殊的嵌入式硬件平臺上。</P><STRONG>5.3
字符集和字體支持</STRONG>
<P>在成功引入 GAL 和 IAL 之后,我們又在處理字體和字符集的模塊當中引入了邏輯字體的概念。邏輯字體是 MiniGUI
用來處理文本(包括文本輸出和文本分析)的頂層接口。邏輯字體接口將各種不同的字體(比如宋體、黑體和揩體)和字體格式(比如等寬字體、變寬字體等光柵字體和
TrueType
等矢量字體),以及各種不同字符集(ISO-8859、GB2312、Big5、UNICODE等)綜合了起來,從而可以通過統一的接口顯示不同字符集的不同字體的文本,并且還可以分析各種字符集文本的組成,比如字符、單詞等。在多字體和多字符集的支持中,我們也采用了面向對象的軟件技術,使得添加新的字體支持和新的字符集支持非常方便。目前,MiniGUI
能夠支持各種光柵字體和 TrueType、Adobe Type 1 等矢量字體,并能夠支持 GB2312、Big5 等多字節字符集,UNICODE
的支持正在開發當中。</P>
<P>相對 GAL 和 IAL 而言,MiniGUI
中的字符集和字體支持更加復雜,涉及到的內容也較多。前面提到,我們通過邏輯字體這一接口,實現了文字輸出和文本分析兩個功能。實際這兩個功能是相互關聯的。在進行文本輸出時,尤其在處理多字節字符集,比如
GB2312 或者 Big5 時,首先要對文本進行分析,以便判斷是否是一個屬于該字符集的雙字節字符。</P>
<P>圖 5 給出了邏輯字體、設備字體以及字符集之間的關系。</P>
<P align=center><IMG alt="" src="MiniGUI體系結構之一 體系結構概覽.files/image05.gif"
border=0><BR>圖 5 邏輯字體以及相關數據結構</P><A id=6 name=6></A>
<P><STRONG class=subhead>6 在 MiniGUI 2.0 中的考慮</STRONG></P>
<P>盡管 MiniGUI 采用多線程機制實現了一個小巧、高效的窗口系統,但有很多理由希望 MiniGUI
能夠采用多進程機制實現(盡管多進程機制可能帶來通訊上的額外開支):</P>
<UL>
<LI>良好的地址保護。窗口本身的崩潰不會影響 MiniGUI 的運行,而目前的多線程機制無法提供地址保護。
<LI>信號處理上的問題。在多線程程序中,所有的多線程共享同一個信號處理方式,包括是否忽略、是否捕獲等等。這對某些大型軟件是很難接受的。
<LI>多線程程序對程序員要求較高。在編寫多線程程序時,通常要考慮到函數的“線程安全”問題,即函數是否是可重入的,因此,我們通常不能使用全局或者靜態變量。
</LI></UL>
<P>鑒于上述需求,我們將在接下來的 MiniGUI 2.0
開發中,進行一些體系結構上的調整,其中最為重要的就是采用進程機制替代線程機制。</P><A id=resources
name=resources></A>
<P><STRONG class=subhead>參考資料</STRONG></P>
<UL>
<LI><B>POSIX 及線程資源</B><BR>有關 POSIX 線程的網絡資源:
<LI style="LIST-STYLE-TYPE: none">
<UL>
<LI><A href="http://pauillac.inria.fr/~xleroy/linuxthreads/">The
LinuxThreads Library</A> [Xavier Leroy]
<LI><A href="http://www.aa.net/~mtp/PCthreads.html">POSIX .1c and DCE
Threads For Linux</A>
<LI><A
href="ftp://ftp.informatik.uni-erlangen.de/local/cip/mskuhn/misc/linux-posix.1b">A
Vision for Linux 2.2 -- POSIX.1b Compatibility and Real-Time
Support</A>
<LI><A href="http://www.knosof.co.uk/posix.html">POSIX Related Web
Sites</A> </LI></UL>
<LI><B>MiniGUI 資源</B>
<LI style="LIST-STYLE-TYPE: none">
<UL>
<LI><A href="http://www.minigui.org/">MiniGUI 主頁</A>
<LI><A href="ftp://ftp.minigui.org/pub/minigui">MiniGUI FTP 站點</A>
</LI></UL>
<LI><B>MiniGUI 郵件列表</B>
<LI style="LIST-STYLE-TYPE: none">
<UL>
<LI>發信:<A
href="mailto:minigui-devel@egroups.com">minigui-devel@egroups.com</A>
<LI>訂閱:<A
href="mailto:minigui-devel-subscribe@egroups.com">minigui-devel-subscribe@egroups.com</A>
<LI>解除訂閱:<A
href="mailto:minigui-devel-unsubscribe@egroups.com">minigui-devel-unsubscribe@egroups.com</A>
</LI></UL></LI></UL><A id=author name=author></A>
<P><STRONG class=subhead>關于作者</STRONG><BR>魏永明(ymwei@minigui.org),男,27
歲,工學碩士,現任藍點軟件(深圳)有限公司北京研發中心技術主管。國內最有影響的自由軟件項目之一-- MiniGUI
的創始人以及主要開發人員。著有《Linux 實用教程》與《學用 Linux 與 Windows NT》,并主持翻譯了《Red Hat Linux
奧秘》、《Linux 編程寶典》 等大量優秀的 Linux 技術著作。是清華大學 AKA Linux 編程技術系列講座的主講人。</P><!-- table border="1" cellspacing="1" cellpadding="3"> <tr> <td><font face="helvetica,helv,arial" size="-1">trademark or attribution statements (possibly with image) that are required for publishing or reprinting</font> </td> </tr> </table--><!-- End paper --><BR></TD>
<TD vAlign=top width=8><IMG height=1 alt=""
src="MiniGUI體系結構之一 體系結構概覽.files/c.gif" width=8></TD></TR>
<TR vAlign=top height=8>
<TD vAlign=top width=8></TD>
<TD vAlign=top width=8></TD>
<TD vAlign=top width=8></TD></TR>
<TR vAlign=top height=8>
<TD vAlign=top width=8><!-- gutter --></TD>
<TD vAlign=top width=8><!-- comments #7: rate article form -->
<TABLE cellSpacing=0 cellPadding=0 width=150 border=0>
<TBODY>
<TR>
<TD width="100%" bgColor=#cc6633 height=3><IMG height=3 alt=""
src="MiniGUI體系結構之一 體系結構概覽.files/c.gif" width=150 border=0></TD></TR>
<TR>
<TD width="100%" bgColor=#333333 height=1><IMG height=1 alt=""
src="MiniGUI體系結構之一 體系結構概覽.files/c.gif" width=150 border=0></TD></TR>
<TR>
<TD width="100%" bgColor=#000000 height=1><IMG height=1 alt=""
src="MiniGUI體系結構之一 體系結構概覽.files/c.gif" width=150 border=0></TD></TR>
<TR>
<TD width="100%" bgColor=#ffffff height=5><IMG height=5 alt=""
src="MiniGUI體系結構之一 體系結構概覽.files/c.gif" width=150 border=0></TD></TR>
<TR vAlign=top>
<TD>
<FORM
action=/developerWorks/cn/cnratings.nsf/RateArticle?CreateDocument
method=post><!-- comments #7: paste title here --><INPUT type=hidden
value="MiniGUI體系結構之一 體系結構概覽" name=ArticleTitle> <!-- comments #7: paste zone here --><INPUT type=hidden value=Linux
name=Zone> <INPUT type=hidden value=簡體中文 name=region> <INPUT
type=hidden value=/developerWorks/cn/thankyou/feedback-linux.html
name=RedirectURL> <FONT face=helvetica,helv,arial
size=-1><B>您對這篇文章的看法如何?</B></FONT>
<P></P>
<TABLE cellSpacing=0 cellPadding=0 width=570 border=0>
<TBODY>
<TR vAlign=top>
<TD><INPUT type=radio value=5 name=Rating><FONT
face=helvetica,helv,arial size=-1>真棒!</FONT></TD>
<TD><INPUT type=radio value=4 name=Rating><FONT
face=helvetica,helv,arial size=-1>好文章</FONT></TD>
<TD><INPUT type=radio value=3 name=Rating><FONT
face=helvetica,helv,arial size=-1>一般,尚可</FONT></TD>
<TD><INPUT type=radio value=2 name=Rating><FONT
face=helvetica,helv,arial size=-1>需提高</FONT></TD>
<TD><INPUT type=radio value=1 name=Rating><FONT
face=helvetica,helv,arial
size=-1>太差!</FONT></TD></TR></TBODY></TABLE><BR><FONT
face=helvetica,helv,arial size=-1><B>評價</B></FONT><BR><TEXTAREA name=Comments rows=3 wrap=virtual cols=52></TEXTAREA><BR><BR><INPUT type=submit value=提交反饋意見></FORM></TD></TR></TBODY></TABLE><!-- end rate article form --></TD>
<TD vAlign=top width=8></TD></TR>
<TR vAlign=top height=8>
<TD vAlign=top width=8></TD>
<TD vAlign=top width=8></TD>
<TD vAlign=top
width=8></TD></TR></TBODY></TABLE><!-- end content --><BR><BR>******>> An
error has occurred while processing a Server Side Include file
<BR><BR></BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -