内容摘要:为了满足嵌入式系统的界面设计需求,给出了一种图形用户界面系统SKY-GUI 的设计思路和其在嵌入式Linux 环境下的实现方法。SKY-GUI 有四大组成部分:输入抽象层、显示抽象层、事件系统和窗口系统。其特点是界面美观、占用资源少、运行效率高,现已应用于嵌入式视频监控项目。实验证明其设计思路可行,性能优良,适用于典型的嵌入式系统项目。
嵌入式图形用户界面( GUI, GraphIC UserInterface)系统作为嵌入式系统中的一大关键技术,为用户提供设备的控制接口,其性能的好坏,界面的美观程度,影响着用户对产品的购买意愿和使用感受。
当前嵌入式系统中GUI 的实现方式主要有两种:一是采用现有的GUI 库;第二种是开发商基于嵌入式操作系统设计特有的GUI 系统。采用第1种方式一般要对通用GUI 库进行剪裁和个性化定制,也往往要支出额外的成本来获得软件授权。相对而言,第2 种方法实现的GUI 占用资源较小、容易满足嵌入式系统的实时性和个性化需求。
本文采用第2 种方式,在嵌入式Linux下使用C 语言实现了一个界面美观、轻量级、占用资源少、执行效率高的图形用户界面系统SKY-GUI.本文的结构如下:第1 部分介绍SKY-GUI 的基本结构;第2部分给出具体的模块设计;第3 部分给出其实验和测试结果;最后总结。
1 SKY-GUI 基本结构
SKY-GUI 系统的功能主要有以下四点:
(1)接收各种输入设备的输入。
(2)建立消息循环,将设备的输入翻译为抽象的事件。
(3)建立窗口和控件对象系统,组织好各个抽象模块的关系,处理各种GUI 事件。
(4)将GUI 对象通过具体形状显示在屏幕上,通过动画将系统的状态变化呈现给用户。
基于这样的设计目标,SKY-GUI 结构如图1 所示。
图1 SKY-GUI 的整体架构
它主要由输入抽象层、显示抽象层、事件系统和窗口系统四大部分组成。输入抽象层管理所有的输入设备,将用户的操作转化成消息送入事件系统。
显示抽象层操作显示设备,提供给窗口系统绘画、贴图、显示字体接口。事件系统为窗口系统提供消息获取、存储和处理的机制。窗口系统是SKY-GUI 的核心,定义了各种控件和窗口,描述它们之间的逻辑关系和消息循环关系。下面将分别对这四大组成部分的设计进行介绍。
2 SKY-GUI 模块设计
2. 1 输入抽象层
输入抽象层为各种输入设备对事件系统的输入接口,它是一个单独的线程,其流程如图2 所示。
图2 输入抽象层流程。
输入抽象层首先对GUI 所需的各种输入设备初始化,而后等待各个设备的输入。当接到设备输入,就把用户对设备的操作翻译成消息,送至事件系统最底层消息队列(在异2. 3. 2 详细讨论)中。
设备输入的翻译过程根据具体的输入设备而定。对于键盘,只要将其键值和该键的状态封成消息。对于鼠标,除了要记录其按键状态,还要根据鼠标当前的位置和屏幕的大小将输入的位移分量转化成鼠标的新位置封入消息。
2. 2 显示抽象层
显示抽象层的作用是为窗口系统提供显示接口函数,包括基本图形接口(画点、画线、填充矩形、区域拷贝、Alpha 混合等)、贴图接口和字体接口三大功能,其结构如图3 所示。
图3 显示抽象层的结构。
显示抽象层在嵌入式Linux 下的基础设备为帧缓冲,对其按坐标写入或读出颜色值即可实现基本的图形接口的功能。
简单的贴图功能用基本图形接口加bmp 格式的文件(图片不经过压缩,其颜色分量按坐标顺序存储)就可以实现。为了让界面更加美观,SKY-GUI移植了开源的jpeg 库和png 库来解压相应格式的压缩图片文件,实现了对这两种图片格式的支持。
对字体的支持当然必不可少。点阵字体把字体的位图按12伊12、16伊16 等格式存入二进制文件,可以比较容易地实现字体接口,但字体不能随意放大缩小,且放大后字体有明显的锯齿。矢量字体用数学方程加字形上的关键点来描述字体,可以进行无级缩放,为界面的绘制带来极大的灵活性。SKY-GUI 移植了开源的Freetype 库,用其寻址矢量字体文件并生成字体位图,实现了对矢量字体的支持。
2. 3 事件系统
事件系统为SKY-GUI 的其他三大部分提供消息发送、存储、获取和处理的功能。其核心为消息、消息队列和消息处理函数。
2. 3. 1 消息定义
SKY-GUI 的消息定义为:
typedef STruct __MSG {
HWND hWnd;摇/ / 窗口指针
int event;摇/ / 事件编号
void* wParam;摇/ / 事件附加参数1
void* lParam;摇/ / 事件附加参数2
} MSG;
hWnd 为指向窗口的指针,表明此消息需要发给哪个窗口。event 为事件编号,用不同的整数代表不同的事件。wParam 和lParam 为事件的附加参数,它们的含义根据事件类型的不同而定,例如,在鼠标消息中这两个参数就代表光标在屏幕上的坐标位置。