WinCE显示驱动设计(一)

来源:互联网 发布:量化程序员 编辑:程序博客网 时间:2024/06/06 13:13

http://blog.163.com/lifemap@126/blog/static/96859351200891644142341/


根据以前的知识, 用户使用GDI, 如CreateDC, ReleaseDC这样的api和WinCE的图形系统交互. GDI并不是显示驱动, GDI位于显示驱动上层, 它和显示驱动通过DDI接口交互.DDI既是设备驱动接口Device Driver Interface, 也是显示驱动接口Display Driver Interface.以前分析过, DDI一共20几个函数.但不是全部公开函数指针给GDI, 而是透过唯一公开的DrvEnableDriver()来传递这所有的DDI函数指针,并且从GDI获得回调接口.写个伪代码会是这样的:

BOOL DrvEnableDriver(ULONG iEngineVersion,

ULONG cj,

DRVENABLEDATA *pded, //

PENGCALLBACKS pEngCAllbacks) // gdi提供的回调函数

{

保存回调函数指针,供以后使用.

把DDI的函数指针数组赋值给第三个参数pded. 这样GDI就得到了DDI接口;

}

GDI已经获得了和显示驱动的接口, 此后会透过DDI接口传递下来,所以显示驱动要做的就是实现这所有的DDI接口函数. 在public\common\oak\drivers\display\gpe下面有一个ddi_if.cpp的源码文件, 就是实现DDI接口. 但在这里没有DrvEnableDriver, 所以设计显示驱动, 必须完成并公开一个DrvEnableDriver接口函数, 并链接这个ddi_if.cpp, 把里面其他ddi接口指针传递给GDI, 实际上. 只要直接调用ddi_if.cpp中的GPEEnableDriver函数, 它替你完成了这个. 因此在你的显示驱动将会见到如下代码:

BOOL APIENTRY DrvEnableDriver(

ULONG engineVersion,

ULONG cj,

DRVENABLEDATA * data,

PENGCALLBACKS engineCallbacks

)

{

return GPEEnableDriver(engineVersion, cj, data, engineCallbacks);

}

 

使用ddi_if.cpp来完成一个显示驱动. 还需要给ddi_if.cpp提供这些接口:

 

AllocConverters

FreeConverters

GetGammaValue

SetGammaValue

GetGPE

DrvGetMask

 

GetGammaValue和SetGammaValue是读写伽马值的接口. DDI接到上层读写伽马值的请求后直接调用这2个外部函数.

GetGPE这个函数返回一个GPE的指针.使用ddi_if构造一个显示驱动需要基于GPE.意思是你需要实例化new一个GPE, 然后实现GetGPE返回这个GPE的指针.因此你要提供下面的接口给ddi_if.cpp:

GPE * gGPE = (GPE *)NULL;

GPE* GetGPE() {gGPE=new GPE(); return gGPE;}

GPE是一个类,DDGPE是继承自GPE的类,扩展了directdraw功能.GPE里面成员函数大部分是virtual函数.因此你可以从GPE继承,也可以从DDGPE继承, 可以定义同名函数,c++的多态.我有限的C++知识差点不够用了.

DrvGetMask是返回RGB位域的. 前面说了ddi_if.cpp透过DrvEnableDisplay到处所有其他接口, 并且在ddi_if.cpp中实现了这些接口. 但DrvGetMask除外.因此你要实现DrvGetMask这个函数, 返回一个数组,如下

ULONG gBitMasks[] = {0xf800, 0x7e0, 0x1f};

ULONG * APIENTRY DrvGetMasks(DHPDEV dhpdev){return gBitMasks;}

上面这个数组的值是RGB565的配置. 三个值分别代表R,G,B的所占的位域.多说几句,16bit色深有RGB565, RGB555, 常见的是RGB565. 24bit的一般RGB888了数字代表所占的位.比如RGB565, R占5bit, G占6bit, B占5bit.

另外, WinCE提供了一个AABLT的库, 这个是抗锯齿功能的, 在初始化时候调用AATextBltInit(AAGetMaskBits)把RGB位域也要告诉这个库.当然, 你也可以不使用这个库, 写一个AATEXTBltInit函数, 返回FALSE即可.

总结一下, 使用微软的MDD来完成一个显示驱动需要的基本工作:

1. 你需要继承一个GPE类并实例化gGPE=new GPE, 然后实现GetGPE函数,把这个gGPE指针交给ddi_if.

2. 需要实现DrvEnableDriver.

3. 你需要定义一个全局数组gBitMasks, 透过DrvGetMask把这个数组指针返回给ddi_if.


原创粉丝点击