MiniGUI源码走读

注:这里是针对以下配置的MiniGUI v1.3.3进行解读:
使用thread模式
资源内置(Resource Incore)
使用旧版本GAL
使用native gal引擎
支持RBF字体
不支持鼠标

Author: Hily Jiang
Email&Gtalk: hilyjiang at Gmail
Blog: http://hily.me/blog/

0. 主函数main()
主函数main()在src/main/main.c中定义,主要运行过程如下:
InitGUI():用于初始化GUI;
MiniGUIMain():进入用户应用程序主体;
TerminateGUI():用户应用程序退出后执行它释放资源,最后退出minigui。

1 初始化GUI:InitGUI()
位于src/kernel/init.c中,主要过程:
InitMisc():初始化配置;
InitGAL():初始化图形抽象层;
InstallSEGVHandler():指定信号处理函数;
InitGDI():初始化图形设备接口;
InitWindowElementColors():初始化窗体颜色;
InitLWEvent():初始化底层事件;
InitFixStr():初始化固定字符串;
InitMenu():初始化菜单;
InitControlClass():初始化控制类;
InitAccel():初始化加速器;
SystemThreads():开辟系统线程;
SetKeyboardLayout():设置键盘布局;
SetCursor():设置鼠标;
SetCursorPos():设置鼠标位置;
TerminateMgEtc():INCORE_RES时该函数为空。

1.1 初始化配置:InitMisc()
位于src/misc/misc.c中,函数主体就是调用这个文件头文件misc.h中的InitMgEtc()。
InitMgEtc()的作用就是获取src/sysres/mgetc.c中定义的MiniGUI运行时的配置,并分配一个句柄hMgEtc指向配置对象。
配置信息保存在一个ETC_S类型的结构MGETC中,它在src/sysres/mgetc.c中定义。

1.2 初始化图形抽象层:InitGAL()
位于src/gal/gal.c中,运行过程如下:
检查可用的图形引擎数NR_GFXES,即该文件中gfxes[]数组的元素个数,若无可用引擎信息,则返回错误;
GetMgEtcValue()从配置中读取配置的GAL引擎名称;
接着查找gfxes[]数组中是否有匹配的引擎,找到后用cur_gfx指向该引擎信息,如果没有找到,则返回错误;
接着用GAL_InitGfx()检测当前引擎的初始化函数是否返回成功。

1.2.1 初始化GAL引擎:GAL_InitGfx()
GAL_InitGfx是一个宏定义,位于include/oldgal.h中,它调用src/gal/native/native.c中对当前引擎的图像函数进行初始化。

1.3 指定信号处理函数:InstallSEGVHandler()
位于src/kernel/init.c中,它的作用就是指定一些信号和信号处理函数。
指定的信号有:SIGSEGV(段错误)、SIGTERM(终止信号)和SIGINT(中断信号)。
指定的信号处理函数为:segvsig_handler,也在这个文件中定义。
在程序接收到指定的三个信号时,segvsig_handler会释放资源并退出程序执行。

1.4 初始化图形设备接口:InitGDI()
位于src/gdi/gdi.c中,运行过程如下:
InitTextBitmapBuffer():这个函数始终返回true,似乎没什么用了;
InitIncoreRBFonts():初始化内嵌的RBF字体;
InitSysFont():初始化系统字体;
InitFreeClipRectList():初始化空闲方形区域块列表;
初始化互斥锁__mg_gdilock(GDI锁)和dcslot(DCSlot锁);
dc_InitClipRgnInfo():初始化Device Context(设备环境)的范围;
dc_Init_ScreenDC():初始化屏幕的DC。

1.4.1 初始化RBF字体:InitIncoreRBFonts()
位于src/font/rawbitmap.c中,运行过程如下:
可用字体数为NR_RBFONTS,即该文件中incore_rbfonts[]数组的元素个数;
检查当前所有可用的字体的信息是否正确,包括:
字符集:fontGetCharsetFromName();
是否支持该字符集:GetCharsetOps();
字体宽度:fontGetWidthFromName();
字体高度:fontGetHeightFromName()。
接着初始化设备字体信息,包括字体信息,操作函数等;
最后把设备字体增加到字体列表中。

1.4.2 初始化系统字体:InitSysFont()
位于src/font/sysfont.c中,运行过程如下:
利用GetMgEtcIntValue()从配置中读取系统字体的数量,若字体数小于1则返回,若字体数大于6,则只使用前6种字体;
接着检测这些字体信息是否正确,并创建逻辑字体;
最后将合法的字体根据配置一一填入对应的逻辑字体数组中。

1.4.3 初始化空闲方形区域块列表:InitFreeClipRectList()
该宏定义位于include/gdi.h,它调用include/gdi.h中的InitBlockDataHeap()初始化空闲方形区域块的信息(包括大小和个数)。

1.4.4 初始化设备环境的范围:dc_InitClipRgnInfo()
位于src/gdi/gdi.c中,
InitClipRgn()

1.4.5 初始化屏幕的DC:dc_Init_ScreenDC()
位于src/gdi/gdi.c中,运行过程如下:
初始化DC设置:
调用SetClipRgn()设置该DC的区域范围。

1.4.5.1 设置DC的区域范围:SetClipRgn()
位于src/gdi/cliprect.c,运行过程如下:
IsRectEmpty():位于src/gdi/rect.c中,检测区域是否为空;
NormalizeRect():位于src/gdi/rect.c中,纠正错误的区域信息,即使区域left ClipRectAlloc():该宏定义位于include/gdi.h,它调用src/kernel/blockheap.c中的BlockDataAlloc()从分配该区域的堆空间。

1.5 初始化窗体颜色:InitWindowElementColors()
位于src/sysres/syscfg.c中,通过调用src/gdi/draw.c中的RGB2Pixel()对颜色进行转换。

1.6 初始化底层事件:InitLWEvent()
位于src/kernel/event.c中,运行过程如下:
GetDblclickTime():获取双击间隔时间;
GetTimeout():获取超时时间;
InitIAL():初始化输入引擎;
ResetMouseEvent():重置鼠标事件;
ResetKeyEvent():重置键盘事件。

1.6.1 获取双击间隔时间:GetDblclickTime()
位于src/kernel/event.c中,因为不支持鼠标,配置文件中没有mouse相关选项,该函数直接返回。

1.6.2 获取超时时间:GetTimeout()
位于src/kernel/event.c中,因为不支持鼠标,配置文件中没有mouse相关选项,该函数直接返回。

1.6.3 初始化输入引擎:InitIAL()
位于src/ial/ial.c中,运行过程如下:
获取配置中ial_engine、mdev和mtype的配置信息;
查找配置的IAL引擎是否在该文件的inputs[]数组中,存在的话就把该引擎做为当前的IAL引擎;
IAL_InitInput():调用inputs数组中的IAL引擎初始化函数初始化IAL引擎。

1.7 初始化固定字符串:InitFixStr()
位于src/kernel/fixstr.c中,初始化一个结构体FixStrHeap,暂时不能理解它的用处。

1.8 初始化菜单:InitMenu()
位于src/gui/menu.c中。

1.9 初始化控制类:InitControlClass()
位于src/gui/ctrlclass.c中,注册配置中支持的控件类。

1.10 初始化加速器:InitAccel()
位于src/gui/accelkey.c中。

1.11 开辟系统线程:SystemThreads()
位于src/kernel/init.c中,运行过程如下:
InitDesktop():初始化桌面;
InitFreeQMSGList():初始化空闲消息队列;
InitMsgQueue():初始化消息队列;
DesktopMain:创建桌面线程;
TimerEntry:创建定时器线程;
EventLoop:创建事件循环线程。

1.11.1 初始化桌面:InitDesktop()
位于src/kernel/desktop.c中,运行过程如下:
InitZOrderInfo():初始化桌面叠放次序;
InitFreeClipRectList():初始化空闲方形区域块列表;
InitSystemRes():初始化系统资源;
InitWndManagementInfo():初始化窗体管理信息。

1.12 设置键盘布局:SetKeyboardLayout()
位于src/gui/keyboard.c中,在数组layouts[]中查找与指定键盘布局名称相同的键盘设置,找到后调用相应的键盘初始化函数对按键图和按键函数。

— EOF —