基于GWES的WinCE Display驱动开发介绍-基础电子_第1页
基于GWES的WinCE Display驱动开发介绍-基础电子_第2页
基于GWES的WinCE Display驱动开发介绍-基础电子_第3页
基于GWES的WinCE Display驱动开发介绍-基础电子_第4页
基于GWES的WinCE Display驱动开发介绍-基础电子_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

精品文档-下载后可编辑基于GWES的WinCEDisplay驱动开发介绍-基础电子引言

在WinCE中,Display驱动由GWES模块来管理。WinCE提供了两种架构的Display驱动模型,可以满足不同的硬件需求。一种是基于WinCEDDI的Display驱动模型,另一种是基于DirectDraw的Display驱动模型。下面将对两种架构作简单介绍。

1Display驱动模型

WinCE下的Display驱动直接由GWES模块管理,它会直接被GWES模块管理和调用。Display驱动实际上也是分层的,其中包括GPE库,该库处理一些默认的绘图,相当于驱动的MDD层。用户只需要开发和硬件相关的PDD层驱动就可以了。在WinCE中,整个架构如图1:

图1

如图,Application为一个应用程序,该程序会调用图形设备接口函数(GDI),而GDI函数是由Coredll.dll模块导出的。Coredll.dll会将函数调用的参数打包,然后触发对另一个进程的本地过程调用(LPC),所有的绘图和开窗口的工作被传给内核中GWES模块。GWES模块被称为图形,窗口和事件子系统,专门处理图形输出和用户输入等事件及相关的所有交互。GWES模块会调用Display驱动完成对显示硬件的操作。Display驱动由GPE和DDL.dll组成,GPE完成基本的默认绘图工作,而DDI.dll实际上从GPE类上继承而来的,并实现了相关的显示硬件的操作。

2DirectDrawDisplay驱动模型

DirectDraw提供了独立于硬件的直接访问显示设备的能力。它可以通过直接访问硬件抽象层(HAL)中的一些函数来达到直接操作显示设备的目的,在这个过程中,不再需要图形设备接口(GDI)的转换。这种直接的方法可以使图像更加连贯,也提高了显示的性能。为了实现这样的功能,需要在显示驱动上扩展能够直接访问相关硬件的函数。这些函数会被DirectDraw模块调用,并形成DirectDraw的硬件抽象层(DDHAL)。DirectDraw显示驱动架构如图2:

如图,DirectDraw的真正实现代码都驻在gwes.dll模块中,应用程序只是连接了一个小的客户端,被称为DDRAW.dll代理,该代理主要负责用户进程与系统之间的远程DirectDrawCOM接口连接。这样,用户请求会被传送到内核的GWES模块中。针对DirectDraw,WinCE提供了一个名为DirectDraw的GPE库(DDGPE),它是从GPE类上面继承而来的。实际上,DirectDraw显示驱动是由DDGPE和DDHAL组成,而DDGPE中已经包含了DDHAL的功能。用户需要从DDGPE类继承并实现相关函数即可。GWES.dll模块中包含GDI和DDRAW两个组件,这两个组件会调用驱动中的DDGPE的相关接口完成对硬件的操作。

在上述两种架构中,用户可以根据自己的硬件情况选择相应的架构。种架构是基于GPE类继承来实现的,第二种架构是基于DDGPE类继承来实现的,而第二种架构的DDGPE类又是从种架构的GPE类继承而来。关于两种类的具体定义,可参见”\WINCE600\PUBLIC\COMMON\OAK\INC”路径下的gpe.h和ddgpe.h文件。

本Blog将基于Display驱动模型来介绍,DirectDrawDisplay驱动模型不在这里介绍。

WinCE下的Display驱动是基于GPE类来实现的,其中GPE中已经实现了基本的绘制工作,相当于MDD层。用户需要继承该类,并实现里面的其他一些函数,所以用户实现的相当于PDD层。

GPE类是一个抽象类,其中包含很多纯虚函数,只能用于继承。用户在继承了GPE类以后,要对GPE类中的纯虚函数做相应的实现。开发Display驱动的大致步骤如下:

(1)继承GPE类并定义一个该类的实例。

(2)实现GetGPE()函数,把该类的实例返回给上层的DDI接口。

(3)实现DrvEnabLEDriver()和DisplayInit()函数并导出这两个接口。

(4)实现GPE类中的函数。

下面将具体介绍实现的步骤:

2.1继承GPE类

首先,基于GPE类进行继承,如果想在Display驱动支持Rotation可以从GPERotate类上面继承。实际上,在”gpe.h”中有如下定义:

typedefGPEGPERotate;

可以看出GPERotate类就是GPE类。在这里,用户从GPE类上面继承就可以了,举个例子如下:

classNewGPE:publicGPE

{

private:

GPEModem_ModeInfo;

DWORDm_colorDepth;

DWORDm_VirtualFrameBuffer;

DWORDm_FrameBufferSize;

BOOLm_CursorDisabled;

BOOLm_CursorVisible;

public:

NewGPE(void);

virtualINTNumModes(void);

virtualSCODESetMode(INTmodeId,HPALETTE*palette);

virtualINTInVBlank(void);

virtualSCODESetPalette(constPALETTEENTRY*source,USHORTfirstEntry,USHORTnumEntries);

virtualSCODEGetModeInfo(GPEMode*pMode,INTmodeNumber);

virtualSCODESetPointerShape(GPESurf*mask,GPESurf*colorSurface,INTxHot,INTyHot,INTcX,INTcY);

virtualSCODEMovePointer(INTxPosition,INTyPosition);

virtualvoidWaitForNotBusy(void);

virtualINTIsBusy(void);

virtualvoidGetPhysicalVideoMemory(unsignedlong*physicalMemoryBase,unsignedlong*videoMemorySize);

virtualSCODEAllocSurface(GPESurf**surface,INTwidth,INTheight,EGPEFormatformat,INTsurfaceFlags);

virtualSCODELine(GPELineParms*lineParameters,EGPEPhasephase);

virtualSCODEBltPrepare(GPEBltParms*blitParameters);

virtualSCODEBltComplete(GPEBltParms*blitParameters);

virtualULONGGetGraphicsCaps();

virtualULONGDrvEscape(

SURFOBJ*pso,

ULONGiEsc,

ULONGcjIn,

PVOIDpvIn,

ULONGcjOut,

PVOIDpvOut);

SCODEWrappedEmulatedLine(GPELineParms*lineParameters);

voidCursorOn(void);

voidCursorOff(void);

#ifdefROTATE

voidSetRotateParms();

LONGDynRotate(intangle);

#endif

};

类NewGPE从GPE类上面继承,其中包括一些属性,如下:

m_ModeInfo:显示模式,结构如下

structGPEMode{

intmodeId;//开发者定义的显示模式的索引号

intwidth;//显示宽度

intheight;//显示高度

intBpp;//显示深度

intfrequency;//显示频率

EGPEFormatformat;//RGB格式,各占多少bit

};

m_colorDepth:显示深度

m_VirtualFrameBuffer:FrameBuffer的地址

m_FrameBufferSize:FrameBuffer的大小

m_CursorDisabled:光标使能标记

m_CursorVisible:光标可视标记

用户可以根据需要定义相应的属性,在NewGPE类中,需要定义并实现基类中的纯虚函数,上面的NewGPE类中已经包含了这些函数的定义,还包括了其他一些函数,将在下面介绍。

2.2实现GetGPE函数

在定义了NewGPE类之后,我们需要实现一个实例,首先定义一个该类的指针:

staticGPE*gGPE=(GPE*)NULL;

然后实现GetGPE函数,如下:

GPE*GetGPE(void)

{

if(!gGPE)

{

gGPE=newNewGPE();

}

returngGPE;

}

在该函数中,创建了一个NewGPE的实例。在这个时候NewGPE构造函数会被调用,一般我们会在这里面作一些与显示相关的初始化的工作。该函数返回gGPE指针给上层接口。

2.3实现DrvEnableDriver和DisplayInit函数

Display驱动对上层的GWES模块提供了20多个函数接口,但是这些函数并不是直接提供出来的,实际上只是通过一个DrvEnableDriver()函数来完成的。该函数在Display驱动的MDD层中没有实现,所以需要在PDD层中定义,如下:

BOOLAPIENTRYDrvEnableDriver(ULONGengineVersion,ULONGcj,DRVENABLEDATA*data,PENGCALLBACKSengineCallbacks)

{

BOOLfOk=FALSE;

//makesureweknowwhereourregistryconfigurationis

if(gszBaseInstance[0]!=0){

fOk=GPEEnableDriver(engineVersion,cj,data,engineCallbacks);

}

returnfOk;

}

engineVersion:DDI版本号,目前为DDI_DRIVER_VERSION。

cj:DRVENABLEDATA结构的大小。

data:指向DRVENABLEDATA结构体。

engineCallbacks:指向一个回调函数结构体,传入一些GDI函数到Display驱动中。

其中,DRVENABLEDATA结构中包含了Display驱动中的设备接口函数的指针,在DrvEnableDriver函数中调用了GPEEnableDriver函数,该函数会导出GWES模块所需的所有Display驱动的接口函数。同时GWES模块通过第四个参数engineCallbacks提供回调函数供Display驱动调用。该函数在”ddi_if”中定义。

另一个重要的函数是DisplayInit函数,它是个被执行的Display驱动中的函数,该函数主要用于读取注册表中的一些信息并作判断。该函数是可选的,也可以不在驱动中实现它。

BOOLAPIENTRYDisplayInit(LPCTSTRpszInstance,DWORDdwNumMonitors)

{

DWORDdwStatus;

HKEYhkDisplay;

BOOLfOk=FALSE;

if(pszInstance!=NULL){

_tcsncpy(gszBaseInstance,pszInstance,dim(gszBaseInstance));

}

//sanitycheckthepathbymakingsureitexists

dwStatus=RegOpenKeyEx(HKEY_LOCAL_MACHINE,gszBaseInstance,0,0,hkDisplay);

if(dwStatus==ERROR_SUCCESS){

RegCloseKey(hkDisplay);

fOk=TRUE;

}

else

{

RETAILMSG(0,(_T("SALCD2:DisplayInit:can'topen'%s'\r\n"),gszBaseInstance));

}

returnfOk;

}

pszInstance:注册表中显示驱动的相关注册表值

dwNumMonitors:支持的Monitor的个数

在该函数中主要通过读取注册表信息判断显示驱动的存在,如果返回错误,则GWES会停止Display驱动的初始化。当然,用户可以根据自己的要求灵活掌握,也可以在这里初始化显示设备或做其他的初始化工作。

2.4实现GPE类中的函数

由于NewGPE继承于GPE类,所以必须实现GPE类中的所有纯虚函数,这些函数实际上就是PDD层驱动中需要实现的函数,如下:

2.4.1virtualSCODEGetModeInfo(GPEMode*pMode,INTmodeNumber)

获得显示模式。

pMode:输出显示模式结构

modeNumber:显示模式索引号

2.4.2virtualintNumModes(void)

获得当前驱动支持的显示模式的个数

2.4.3virtualSCODESetMode(INTmodeId,HPALETTE*palette)

设置显示模式。

modeId:显示模式索引号

palette:调色板指针,指向一个由EngCreatePalette函数创建的调色板

2.4.4virtualSCODEAllocSurface(GPESurf**surface,INTwidth,INTheight,EGPEFormatformat,INTsurfaceFlags)

在系统内存中创建一个绘图平面。

surface:指向被分配的内存的指针

width:宽度

height:高度

format:绘图平面格式

surfaceFlags:标记位,标明在哪分配内存

2.4.5virtualSCODESetPointerShape(GPESurf*pMask,GPESurf*pColorSurface,INTxHot,INTyHot,INTcX,INTcY);

设置光标形状。

pMask:指向一个包含光标形状的掩码

pColorSurface:指向被光标使用的颜色绘图平面

xHot:光标热点的X坐标

yHot:光标热点的Y坐标

cX:光标宽度

cY:光标高度

2.4.6virtualSCODEMovePointer(intx,inty)

移动光标到指定位置或者隐藏光标

x:光标移动位置的x坐标,若为-1表示隐藏光标。

y:光标移动位置的y坐标

2.4.7virtualSCODEBltPrepare(GPEBltParms*blitParameters)

在做位块传输前会先执行该函数,用于确定执行BLT的函数

blitParameters:指向一个GPE的位块传输参数的结构体

2.4.8virtualSCODEBltComplete(GPEBltParms*blitParameters)

该函数用于释放在BltPrepare中申请的资源

blitParameters:指向一个GPE的位块传输参数的结构体

2.4.9virtualSCODELine(GPELineParms*lineParameters,EGPEPhasephase)

画线函数

lineParameters:指向一个GPE的Line结构体,描述所画的线

phase:画线所处的阶段,具体描述如下

gpeSingle:画单根线

gpePrepare:准备画线

gpeContinue:画线过程中

gpeComplete:画线完成

在这里要提一点,有时我们会看到在该函数中调用另一个函数WrappedEmulatedLine(),这个函数在WinCE的PUBLIC目录下的参考Display驱动中也可以找到,该函数是一个快速的画线函数,里面采用了Bresenham画线算法,通过采用运行速度快的加减和移位运算来完成画线。

2.4.10virtualSCODESetPalette(constPALETTEENTRY*pSource,USHORTfirstEntry,USHORTnumEntries)

设置调色板

pSource:指向一个调色板入口信息的结构体

firstEntry:个入口

numEntries:入口的个数

2.4.11virtualintInVBlank(void)

显示设备是否处于垂直消隐期间

上述函数在GPE类中均被定义为纯虚函数,需要在继承类中实现,也就是在我们的驱动程序中实现。这些函数是必须实现的。根据显示的需

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论