基于GWES的WinCE Display驅動(dòng)開(kāi)發(fā)介紹
引言
本文引用地址:http://dyxdggzs.com/article/148946.htm在WinCE中,Display驅動(dòng)由GWES模塊來(lái)管理。WinCE提供了兩種架構的Display驅動(dòng)模型,可以滿(mǎn)足不同的硬件需求。一種是基于WinCE DDI的Display驅動(dòng)模型,另一種是基于DirectDraw的Display驅動(dòng)模型。下面將對兩種架構作簡(jiǎn)單介紹。
1 Display驅動(dòng)模型
WinCE下的Display驅動(dòng)直接由GWES模塊管理,它會(huì )直接被GWES模塊管理和調用。Display驅動(dòng)實(shí)際上也是分層的,其中包括GPE庫,該庫處理一些默認的繪圖,相當于驅動(dòng)的MDD層。用戶(hù)只需要開(kāi)發(fā)和硬件相關(guān)的PDD層驅動(dòng)就可以了。在WinCE中,整個(gè)架構如圖1:

圖1
如圖,ApplicatiON為一個(gè)應用程序,該程序會(huì )調用圖形設備接口函數(GDI),而GDI函數是由Coredll.dll模塊導出的。Coredll.dll會(huì )將函數調用的參數打包,然后觸發(fā)對另一個(gè)進(jìn)程的本地過(guò)程調用(LPC),所有的繪圖和開(kāi)窗口的工作被傳給內核中GWES模塊。GWES模塊被稱(chēng)為圖形,窗口和事件子系統,專(zhuān)門(mén)處理圖形輸出和用戶(hù)輸入等事件及相關(guān)的所有交互。GWES模塊會(huì )調用Display驅動(dòng)完成對顯示硬件的操作。Display驅動(dòng)由GPE和DDL.dll組成,GPE完成基本的默認繪圖工作,而DDI.dll實(shí)際上從GPE類(lèi)上繼承而來(lái)的,并實(shí)現了相關(guān)的顯示硬件的操作。
2 DirectDraw Display驅動(dòng)模型
DirectDraw提供了獨立于硬件的直接訪(fǎng)問(wèn)顯示設備的能力。它可以通過(guò)直接訪(fǎng)問(wèn)硬件抽象層(HAL)中的一些函數來(lái)達到直接操作顯示設備的目的,在這個(gè)過(guò)程中,不再需要圖形設備接口(GDI)的轉換。這種直接的方法可以使圖像更加連貫,也提高了顯示的性能。為了實(shí)現這樣的功能,需要在顯示驅動(dòng)上擴展能夠直接訪(fǎng)問(wèn)相關(guān)硬件的函數。這些函數會(huì )被DirectDraw模塊調用,并形成DirectDraw的硬件抽象層(DDHAL)。DirectDraw顯示驅動(dòng)架構如圖2:

如圖,DirectDraw的真正實(shí)現代碼都駐在gwes.dll模塊中,應用程序只是連接了一個(gè)小的客戶(hù)端,被稱(chēng)為DDRAW.dll代理,該代理主要負責用戶(hù)進(jìn)程與系統之間的遠程DirectDraw COM接口連接。這樣,用戶(hù)請求會(huì )被傳送到內核的GWES模塊中。針對DirectDraw,WinCE提供了一個(gè)名為DirectDraw的GPE庫(DDGPE),它是從GPE類(lèi)上面繼承而來(lái)的。實(shí)際上,DirectDraw顯示驅動(dòng)是由DDGPE和DDHAL組成,而DDGPE中已經(jīng)包含了DDHAL的功能。用戶(hù)需要從DDGPE類(lèi)繼承并實(shí)現相關(guān)函數即可。GWES.dll模塊中包含GDI和DDRAW兩個(gè)組件,這兩個(gè)組件會(huì )調用驅動(dòng)中的DDGPE的相關(guān)接口完成對硬件的操作。
在上述兩種架構中,用戶(hù)可以根據自己的硬件情況選擇相應的架構。第一種架構是基于GPE類(lèi)繼承來(lái)實(shí)現的,第二種架構是基于DDGPE類(lèi)繼承來(lái)實(shí)現的,而第二種架構的DDGPE類(lèi)又是從第一種架構的GPE類(lèi)繼承而來(lái)。關(guān)于兩種類(lèi)的具體定義,可參見(jiàn)” WINCE600PUBLICCOMMONOAKINC”路徑下的gpe.h和ddgpe.h文件。
本Blog將基于Display驅動(dòng)模型來(lái)介紹,DirectDraw Display驅動(dòng)模型不在這里介紹。
WinCE下的Display驅動(dòng)是基于GPE類(lèi)來(lái)實(shí)現的,其中GPE中已經(jīng)實(shí)現了基本的繪制工作,相當于MDD層。用戶(hù)需要繼承該類(lèi),并實(shí)現里面的其他一些函數,所以用戶(hù)實(shí)現的相當于PDD層。
GPE類(lèi)是一個(gè)抽象類(lèi),其中包含很多純虛函數,只能用于繼承。用戶(hù)在繼承了GPE類(lèi)以后,要對GPE類(lèi)中的純虛函數做相應的實(shí)現。開(kāi)發(fā)Display驅動(dòng)的大致步驟如下:
(1) 繼承GPE類(lèi)并定義一個(gè)該類(lèi)的實(shí)例。
(2) 實(shí)現GetGPE()函數,把該類(lèi)的實(shí)例返回給上層的DDI接口。
(3) 實(shí)現DrvEnabLEDriver()和DisplayInit()函數并導出這兩個(gè)接口。
(4) 實(shí)現GPE類(lèi)中的函數。
下面將具體介紹實(shí)現的步驟:
2.1 繼承GPE類(lèi)
首先,基于GPE類(lèi)進(jìn)行繼承,如果想在Display驅動(dòng)支持Rotation可以從GPERotate類(lèi)上面繼承。實(shí)際上,在”gpe.h”中有如下定義:
typedef GPE GPERotate;
可以看出GPERotate類(lèi)就是GPE類(lèi)。在這里,用戶(hù)從GPE類(lèi)上面繼承就可以了,舉個(gè)例子如下:
class NewGPE: public GPE
{
private:
GPEMode m_ModeInfo;
DWORD m_colorDepth;
DWORD m_VirtualFrameBuffer;
DWORD m_FrameBufferSize;
BOOL m_CursorDisabLED;
BOOL m_CursorVisible;
…
public:
NewGPE(void);
virtual INT NumModes(void);
virtual SCODE SetMode(INT modeId, HPALETTE *palette);
virtual INT InVBlank(void);
virtual SCODE SetPalette(conST PALETTEENTRY *source, USHORT firstEntry, USHORT numEntries);
virtual SCODE GetModeInfo(GPEMode *pMode, INT modeNumber);
virtual SCODE SetPointerShape(GPESurf *mask, GPESurf *colorSurface, INT xHot, INT yHot, INT cX, INT cY);
virtual SCODE MovePointer(INT xPosition, INT yPosition);
virtual void WaitForNotBusy(void);
virtual INT IsBusy(void);
virtual void GetPhysicalVideoMemory(unsigned long *physicalMemoryBase, unsigned long *videoMemorySize);
virtual SCODE AllocSurface(GPESurf **surface, INT width, INT height, EGPEFormat format, INT surfaceFlags);
virtual SCODE Line(GPELineParms *lineParameters, EGPEPhase phase);
virtual SCODE BltPrepare(GPEBltParms *blitParameters);
virtual SCODE BltComplete(GPEBltParms *blitParameters);
virtual ULONG GetGraphicsCaps();
virtual ULONG DrvEscape(
SURFOBJ *pso,
ULONG iEsc,
ULONG cjIn,
PVOID pvIn,
ULONG cjOut,
PVOID pvOut);
SCODE WrappedEmulatedLine (GPELineParms *lineParameters);
評論