视频
视频驱动负责实现 LCUI 应用程序与操作系统中的视窗系统的交互,这些交互包括向 LCUI 应用程序提供屏幕尺寸、将组件的信息和渲染结果同步到对应的窗口中,是 LCUI 的几个驱动模块中最为复杂的一个。
表面
表面(Surface)是窗口的抽象,也是 LCUI 的组件与操作系统的窗口进行交互的中间层,它屏蔽了各个操作系统中的视窗操作接口的差异和实现细节,使得 LCUI 应用程序只需要专注于将图形内 容渲染到表面上,剩下的工作则交给视频驱动,它会将表面的尺寸、位置、标题等信息以及图形内容同步到对应的窗口。
LCUI 将表面的数据结构交由视频驱动在内部定义,应用层代码仅靠 LCUI_Surface
类型的指针来引用表面,对表面的操作都是靠调用表面的函数来实现的。
显示模式
有三种显示模式:
LCUI_DMODE_WINDOWED
:窗口化模式,将根组件绑定到表面上,组件的宽高与表面宽高相同。LCUI_DMODE_FULLSCREEN
:全屏模式,将根组件绑定到表面上,表面宽高与屏幕宽高相同。LCUI_DMODE_SEAMLESS
:无缝模式,为根组件的每个直系子组件绑定一个表面。
初始显示模式是窗口化模式,你可以使用 LCUIDisplay_SetMode()
函数更改显示模式。
驱动接口
视频驱动接口在 include/LCUI/display.h 中的定义如下:
typedef struct LCUI_DisplayDriverRec_ {
char name[256];
int (*getWidth)(void);
int (*getHeight)(void);
LCUI_Surface (*create)(void);
void (*destroy)(LCUI_Surface);
void (*close)(LCUI_Surface);
void (*resize)(LCUI_Surface, int, int);
void (*move)(LCUI_Surface, int, int);
void (*show)(LCUI_Surface);
void (*hide)(LCUI_Surface);
void (*update)(LCUI_Surface);
void (*present)(LCUI_Surface);
LCUI_BOOL (*isReady)(LCUI_Surface);
LCUI_PaintContext (*beginPaint)(LCUI_Surface, LCUI_Rect *);
void (*endPaint)(LCUI_Surface, LCUI_PaintContext);
void (*setCaptionW)(LCUI_Surface, const wchar_t *);
void (*setRenderMode)(LCUI_Surface, int);
void *(*getHandle)(LCUI_Surface);
int (*getSurfaceWidth)(LCUI_Surface);
int (*getSurfaceHeight)(LCUI_Surface);
void (*setOpacity)(LCUI_Surface, float);
int (*bindEvent)(int, LCUI_EventFunc, void *, void (*)(void *));
} LCUI_DisplayDriverRec, *LCUI_DisplayDriver;
接下来让我们深入了解这个结构体中的成员。
name
视频驱动的名称,用于标识当前使用的是哪个视频驱动。
getWidth
获取屏幕的宽度。
getHeight
获取屏幕的高度。
create
创建表面。你可以在这里初始化帧缓存、初始化表面信息、调用系统提供的接口创建窗口。
destroy
销毁表面。你可以在这里释放帧缓存、释放表面信息、调用系统提供的接口关闭窗口。
close
关闭表面。你可以在这里做销毁窗口的准备工作。这个函数是参考 Windows 的窗口关闭流程而设计的,关闭窗口时会收到 WM_CLOSE
消息,DefWindowProc()
函数对这个消息的处理就是调用 DestroyWindow()
销毁窗口。
resize
调整表面尺寸。你可以在这里重新分配帧缓存、调用系统提供的接口调整窗口尺寸。
move
移动表面位置。你可以在这里调用系统提供的接口调整窗口位置。
show
显示表面。你可以在这里调用系统提供的接口显示窗口。
hide
隐藏表面。你可以在这里调用系统提供的接口隐藏窗口。
update
更新表面。现有的视频驱动由于考虑到在其它线程上操作表面的情况,所以被设计成需要调用 update 函数才会应用所有的表面操作。不过现在还没有这种情况,你可以忽略这个函数。
present
呈现表面的最新内容。你可以在这里将帧缓存中的内容同步到主窗口中。
isReady
表面是否已经准备就绪。如果你的表面在 create()
函数中因某些原因无法立刻完成初始化,那么可以用这个函数返回 FALSE
告知 LCUI 这个表面暂时不能用,需要等待一会,直到返回 TRUE
为止。
beginPaint
开始绘制。你可以在这里完成绘制前的准备工作,例如创建绘制缓存区来存储接下来绘制的内容,然后返回绘制上下文。
endPaint
结束绘制。你可以在这里将已绘制的内容更新到帧缓存中。
setCaptionW
设置表面的说明文字。你可以在这里将表面的说明文字更新到窗口标题上。
setRenderMode
设置表面的渲染模式。现在的渲染模式有拉伸和直接填充这两种,不过自定义渲染模式的场景很少,你可以忽略这个函数。