个人觉得的有用的文档,贴出来和大家分享

Minigui学习

上一篇 / 下一篇  2008-07-08 11:59:36 / 个人分类:linux

miniguiGALIAL引擎各是什么东西?

GAL图形抽象层

IAL输入抽象层

 

  • 13.1.1 GAL 和 GDI

为了把底层图形设备和上层图形接口分离开来,提高 MiniGUI 图形系统的可移植性,

MiniGUI 中引入了图形抽象层(Graphics Abstract Layer,GAL)的概念。图形抽象层定义

了一组不依赖于任何特殊硬件的抽象接口, 所有顶层的图形操作都建立在这些抽象接口之上。

而用于实现这一抽象接口的底层代码称为“图形引擎” ,类似操作系统中的驱动程序。利用

GAL,MiniGUI 可以在许多已有的图形函数库上运行,比如 SVGALib 和 LibGGI。并且可以

非常方便地将 MiniGUI 移植到其他 POSIX 系统上,只需要根据我们的抽象层接口实现新的

图形引擎即可。比如,在基于 Linux 的系统上,我们可以在 Linux FrameBuffer 驱动程序的

基础上建立通用的 MiniGUI 图形引擎。实际上,包含在 MiniGUI 1.0.00 版本中的私有图形引

擎(Native Engine)就是建立在 FrameBuffer 之上的图形引擎。一般而言,基于 Linux 的嵌

入式系统均会提供 FrameBuffer 支持,这样私有图形引擎可以运行在一般的 PC 上,也可以

运行在特定的嵌入式系统上。

  • IAL内容

本章将介绍 MiniGUI 的 IAL 接口,并重点介绍如何开发针对特定嵌入式系统的输入引擎。尽管这个主题已经超出了一般的 MiniGUI 编程范围,但出于该主题的重要性考虑,我们在本篇最后一章中包含了该内容。

而输入设备的处理却没有统一的接口。在 PC 上,我们通常使用键盘和鼠标,而在嵌入式系统上,可能只有触摸屏和为数不多的几个键。在这种情况下,提供一个抽象的输入层,就显得格外重要

MiniGUI 的 IAL 接口

  typedef struct tagINPUT

  {

      char*  id;

      // Initialization and termination

      BOOL (*init_input) (struct tagINPUT *input, const char* mdev, const char* mtype);

      void (*term_input) (void);

  

      // Mouse operations

      int (*update_mouse) (void);

      int (*get_mouse_xy) (int* x, int* y);

      void (*set_mouse_xy) (int x, int y);

      int (*get_mouse_button) (void);

      void (*set_mouse_range) (int minx, int miny,int maxx,int maxy);

  

      // Keyboard operations

      int (*update_keyboard) (void);

     char* (*get_keyboard_state) (void);

      void (*suspend_keyboard) (void);

      void (*resume_keyboard) (void);

      void (*set_leds) (unsigned int leds);

  

      // Event

  #ifdef _LITE_VERSION

      int (*wait_event) (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except,

              struct timeval *timeout);

  #else

      int (*wait_event) (int which, fd_set *in, fd_set *out, fd_set *except,

              struct timeval *timeout);

  #endif

  

  char mdev [MAX_PATH + 1];

  } INPUT;

  

  extern INPUT* cur_input;

 

 

在 src/ial/ial.c 中,定义了 MiniGUI 支持的所有输入引擎信息:

 

#define LEN_ENGINE_NAME    16

#define LEN_MTYPE_NAME     16

 

static INPUT inputs [] =

{

#ifdef _SVGALIB

   {"SVGALib", InitSVGALibInput, TermSVGALibInput},

#endif

#ifdef _LIBGGI

   {"LibGGI", InitLibGGIInput, TermLibGGIInput},

#endif

#ifdef _EP7211_IAL

   {"EP7211", InitEP7211Input, TermEP7211Input},

#endif

#ifdef _ADS_IAL

   {"ADS", InitADSInput, TermADSInput},

#endif

#ifdef _IPAQ_IAL

   {"iPAQ", InitIPAQInput, TermIPAQInput},

#endif

#ifdef _VR4181_IAL

   {"VR4181", InitVR4181Input, TermVR4181Input},

#endif

#ifdef _HELIO_IAL

   {"Helio", InitHelioInput, TermHelioInput},

#endif

#ifdef _NATIVE_IAL_ENGINE

   {"Console", InitNativeInput, TermNativeInput},

#endif

#ifdef _TFSTB_IAL

   {"TF-STB", InitTFSTBInput, TermTFSTBInput},

#endif

#ifdef _T800_IAL

   {"T800", InitT800Input, TermT800Input},

#endif

#ifdef _DUMMY_IAL

   {"Dummy", InitDummyInput, TermDummyInput},

#endif

#ifdef _QVFB_IAL

   {"QVFB", InitQVFBInput, TermQVFBInput},

#endif

};

 

INPUT* cur_input;

  • IAL的添加:
  1. „ InitIPAQInput 函数就是我们在 src/ial/ial.c 中所定义的 iPAQ 输入引擎的初始化函数。该函数打开了两个设备:/dev/ h3600_ts 和 /dev/ h3600_key。前者是触摸屏的设备文件, 后者是按键的设备文件。 类似 PC 上的 /dev/psaux 设备和 /dev/tty 设备。在成功打开这两个设备文件之后,该函数设置了 INPUT 结构的其它一些成

员。注意,其中一些成员被赋值为 NULL。

  1. „ mouse_update 函数始终返回 1,表明更新鼠标状态成功。
  2. „ mouse_getxy 函数返回由其它函数准备好的鼠标位置数据,并做了适当的边界检
  3. „ mouse_getbutton 函数返回了触摸屏状态,即用户是否触摸了屏幕,相当于是否按

下了左键。

  1. „ keyboard_update 函数根据其它函数准备好的键盘信息,适当填充了 state 数组。
  2. „ keyboard_state 函数直接返回了 state 数组的地址。
  3. „ wait_event 函数是输入引擎的核心函数。这个函数首先将先前打开的两个设备的文件描述符与传入的 in 文件描述符集合并在了一起,然后调用了 select 系统调用。当 select 系统调用返回大于 0 的值时,该函数检查在两个文件描述符上是否有可

读的数据等待读取,如果是,则分别从两个文件描述符中读取触摸屏和按键数据

 

  1. minigui的配置文件中使用新的类型,在INPUT数组添加新的IAL

 

 

minigui桌面程序设计:

 

  1. 图层的概念。托管窗口的概念?

根窗口就是所有窗口的祖先。

CreateInfo.hHosting:该域表示的是将要建立的主窗口使用哪个主窗口的消息队列。

使用其他主窗口消息队列的主窗口,我们称为“被托管”的主窗口。在 MiniGUI 中,

托管的概念非常重要,一般要遵循如下规则:

„ MiniGUI-Threads 中每个线程创建的第一个主窗口,其托管窗口必须是桌面,即

HWND_DESKTOP,该线程的其他窗口,必须由属于同一线程的已有主窗口作为

托管窗口。系统在托管窗口为 HWND_DESKTOP 时创建新的消息队列,而在指

定非桌面的窗口作为托管窗口时,使用该托管窗口的消息队列,也就是说,同一

线程中的所有主窗口应该使用同一个消息队列。

„ MiniGUI-Processes 中的所有主窗口也应该以类似的规则指定托管窗口,将所有

主窗口看成是属于同一线程就可以了。

 

  1. 设备上下文的概念?

      应用程序一般在一个图形上下文(graphics context)上调用图形系统提供的绘制原语进行绘制。上下文是一个记录了绘制原语所使用的图形属性的对象。这些属性通常包括:

       设备上下文,应该是一种对于图形操作的封装和抽象,通过设备上下文进行图像方面的操作。

  1. Automake,autoconf简单使用

主要文件:

Configure.in

Make .am

源代码文件

 

操作:

Aclocal   :

Aclocal.m4(解释configure.in   

Autoconf:

根据configure.in生成configure

autoMake :

根据make.am生成Makefile.in文件

Configure

根据make.in文件生成makefile文件

Make

编译源代码

文档 <http://tech.sina.com.cn/s/2004-10-19/1115443045.shtml>

针对上面提到的各个命令,我们再做些详细的介绍。

 

1、 autoscan

 

autoscan是用来扫描源代码目录生成configure.scan文件的。autoscan可以用目录名做为参数,但如果你不使用参数的话,那么 autoscan将认为使用的是当前目录。autoscan将扫描你所指定目录中的源文件,并创建configure.scan文件。

 

2、 configure.scan

 

configure.scan包含了

系统配置的基本选项,里面都是一些宏定义。我们需要将它改名为configure.in

 

3、 aclocal

 

aclocal是一个perl 脚本程序。aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。

 

4、 autoconf

 

autoconf是用来产生configure文件的。configure是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile,从而可以使你的源代码能在不同的操作系统平台上被编译出来。

 

configure.in文件的内容是一些宏,这些宏经过autoconf 处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。configure.in文件中的宏的顺序并没有规定,但是你必须在所有宏的最前 面和最后面分别加上AC_INIT宏和AC_OUTPUT宏。

 

在configure.ini中:

 

#号表示注释,这个宏后面的内容将被忽略。

 

AC_INIT(FILE)

 

这个宏用来检查源代码所在的路径。

 

 

AM_INIT_AUTOMAKE(PACKAGE, VERSION)

这个宏是必须的,它描述了我们将要生成的软件包的名字及其版本号:PACKAGE是软件包的名字,VERSION是版本号。当你使用make dist命令时,它会给你生成一个类似helloworld-1.0.tar.gz的软件发行包,其中就有对应的软件包的名字和版本号。

 

AC_PROG_CC

 

这个宏将检查系统所用的C编译器。

 

AC_OUTPUT(FILE)

 

这个宏是我们要输出的Makefile的名字。

 

我们在使用automake时,实际上还需要用到其他的一些宏,但我们可以用aclocal 来帮我们自动产生。执行aclocal后我们会得到aclocal.m4文件。

 

产生了configure.in和aclocal.m4 两个宏文件后,我们就可以使用autoconf来产生configure文件了。

 

5、 Makefile.am

 

Makefile.am是用来生成Makefile.in的,需要你手工书写。Makefile.am中定义了一些内容:

 

AUTOMAKE_OPTIONS

 

这个是automake的选项。在执行automake时,它会检查目录下是否存在标准GNU软件包中应具备的各种文件,例如AUTHORS、ChangeLog、NEWS等文件。我们将其设置成foreign时,automake会改用一般软件包的标准来检查。

 

bin_PROGRAMS

 

这个是指定我们所要产生的可执行文件的文件名。如果你要产生多个可执行文件,那么在各个名字间用空格隔开。

 

helloworld_SOURCES

 

这个是指定产生“helloworld”时所需要的源代码。如果它用到了多个源文件,那么请使用空格符号将它们隔开。比如需要 helloworld.h,helloworld.c那么请写成helloworld_SOURCES= helloworld.h helloworld.c。

 

如果你在bin_PROGRAMS定义了多个可执行文件,则对应每个可执行文件都要定义相对的filename_SOURCES。

 

6、 automake

 

我们使用automake --add-missing来产生Makefile.in。

 

选项--add-missing的定义是“add missing standard files to package”,它会让automake加入一个标准的软件包所必须的一些文件。

 

我们用automake产生出来的Makefile.in文件是符合GNU Makefile惯例的,接下来我们只要执行configure这个shell 脚本就可以产生合适的 Makefile 文件了。

 

7、 Makefile

 

在符合GNU Makefiel惯例的Makefile中,包含了一些基本的预先定义的操作:

 

make

 

根据Makefile编译源代码,连接,生成目标文件,可执行文件。

 

make clean

 

清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。

 

make install

 

将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。

 

make dist

 

产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。

 

它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz”的文件。PACKAGE和VERSION,是我们在configure.in中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION)。

 

make distcheck

 

生成发布软件包并对其进行测试检查,以确定发布包的正确性。这个操作将自动把压缩包文件解开,然后执行configure命令,并且执行make,来确认编译不出现错误,最后提示你软件包已经准备好,可以发布了。

 

 

===============================================

helloworld-1.0.tar.gz is ready for distribution

===============================================

make distclean

类似make clean,但同时也将configure生成的文件全部删除掉,包括Makefile。

 

结束语

 

通过上面的介绍,你应该可以很容易地生成一个你自己的符合GNU惯例的Makefile文件及对应的项目文件。

 

如果你想写出更复杂的且符合惯例的Makefile,你可以参考一些开放代码的项目中的configure.in和Makefile.am文件,比如:嵌入式数据库sqlite,单元测试cppunit。


TAG: minigui 学习 Minigui GAL

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-09-08  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 59440
  • 日志数: 105
  • 图片数: 2
  • 文件数: 5
  • 书签数: 46
  • 建立时间: 2006-09-20
  • 更新时间: 2008-08-27

RSS订阅

Open Toolbar