`
jinghuainfo
  • 浏览: 1527723 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

嵌入式GUI FTK设计与实现-事件源(FtkSource)

 
阅读更多

转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli@gmail.com>

在《主循环》一节中, 我们介绍了MainLoop 处理各个事件源的方法,它在事件源上等待事件发生,然后调用事件源的处理函数去处理事件。事件源(FtkSource)是对事件来源的一种抽象,事件的来源可能是一个输入设备(如键盘和触摸屏),可能是一个定时器,也可能是一个网络套接字或管道。总之,只要实现FtkSource要求的接口,就可以让 MainLoop来处理了。

FtkSource 要求实现下列接口函数:

* ftk_source_get_fd 用来获取文件描述符,这个文件描述符不一定是真正的文件描述符,只要是能MainLoop挂在上面等待的句柄(Handle)即可。

* ftk_source_check 用来检查事件源要求等待的时间。-1表示不关心等待时间。0表示要马上就有事件发生,正数表示在指定的时间内将有事件发生。

* ftk_source_dispatch 用来处理事件,每个事件源都有自己的处理函数,这样可以简化程序的实现。

目前FTK内部使用的事件源主要有:

1.ftk_source_input(.c/.h)

在Linux下,输入设备文件都在/dev /input/下,并用一致的事件结构(input_event)将事件上报给应用程序,ftk_source_input是针对这些设备文件实现的事件源。

由于是从设备文件读取输入事件,那主循环可以挂在这些设备文件上等待事件发生。所以ftk_source_get_fd只要返回文件描述符,而 ftk_source_check返回-1即可。

static int ftk_source_input_get_fd(FtkSource* thiz)
{
DECL_PRIV(thiz, priv);

return priv->fd;
}

static int ftk_source_input_check(FtkSource* thiz)
{
return -1;
}

ftk_source_dispatch中读取事件(input_event),将它转换成FTK的事件结构,然后通过将事件分发(调用 ftk_wnd_manager_queue_event)出去。

键值的映射是放在表 s_key_mapp中的:

static unsigned short s_key_map[0x100] =
{
[KEY_1] = FTK_KEY_1,
[KEY_2] = FTK_KEY_2,
[KEY_3] = FTK_KEY_3,
[KEY_4] = FTK_KEY_4,
[KEY_5] = FTK_KEY_5,
[KEY_6] = FTK_KEY_6,
[KEY_7] = FTK_KEY_7,
...
};

如果有特殊键值或其它需求,修改这个结构即可。

2.ftk_source_dfb(.c/.h)

FTK可以用DirectFB作为 backend,ftk_source_dfb是针对DirectFB输入事件实现的事件源。DirectFB可以通从EventBuffer直接读取,也可以从EventBuffer获取一个管道的文件描述符,然后从这个管道读取事件。为了方便,我们使用后者来实现ftk_source_dfb,主循环可以挂在这个文件描述符上等待事件。所以ftk_source_get_fd只要返回文件描述符,而 ftk_source_check返回-1即可。

static int ftk_source_dfb_get_fd(FtkSource* thiz)
{
DECL_PRIV(thiz, priv);

return priv->fd;
}

static int ftk_source_dfb_check(FtkSource* thiz)
{
return -1;
}

ftk_source_dispatch中读取事件(DFBEvent),将它转换成FTK的事件结构,然后通过将事件分发(调用 ftk_wnd_manager_queue_event)出去。

键值的映射是放在表 s_key_mapp中的:

static const int s_key_map[] =
{
[DIKI_A-DIKI_UNKNOWN] = FTK_KEY_a,
[DIKI_B-DIKI_UNKNOWN] = FTK_KEY_b,
[DIKI_C-DIKI_UNKNOWN] = FTK_KEY_c,
[DIKI_D-DIKI_UNKNOWN] = FTK_KEY_d,
[DIKI_E-DIKI_UNKNOWN] = FTK_KEY_e,
[DIKI_F-DIKI_UNKNOWN] = FTK_KEY_f,
[DIKI_G-DIKI_UNKNOWN] = FTK_KEY_g,
[DIKI_H-DIKI_UNKNOWN] = FTK_KEY_h,
...
};

如果有特殊键值或其它需求,修改这个结构即可。

3.ftk_source_tslib(.c/.h)

对于电阻式的触摸屏,虽然通常在Linux下也是通过(/dev/input)下的设备文件上报事件的,但是需要对输入事件进行去抖、滤波和校正之后才能使用,tslib是专门做这些工作的,所以这时我们用tslib读取事件是更明智的选择。

tslib 提供了一个函数用于获取文件描述符,主循环可以挂在这个文件描述符上等待事件。所以ftk_source_get_fd只要返回文件描述符,而 ftk_source_check返回-1即可。

static int ftk_source_tslib_get_fd(FtkSource* thiz)
{
DECL_PRIV(thiz, priv);
return_val_if_fail(priv != NULL && priv->ts != NULL, -1);

return ts_fd(priv->ts);
}

static int ftk_source_tslib_check(FtkSource* thiz)
{
return -1;
}

ftk_source_dispatch中读取事件(ts_sample),将它转换成FTK的事件结构,然后通过将事件分发(调用 ftk_wnd_manager_queue_event)出去。

4.ftk_source_primary(.c/.h)

ftk_source_primary的地位比较特别,相当于其它GUI中的事件队列。

ftk_source_primary 使用管道来实现队列先进先出(FIFO)的特性,这样可以避免引入互斥机制来保护队列,管道有自己的文件描述符,主循环可以挂在这个文件描述符上等待事件。所以ftk_source_get_fd只要返回文件描述符,而 ftk_source_check返回-1即可。

static int ftk_source_primary_get_fd(FtkSource* thiz)
{
DECL_PRIV(thiz, priv);
return_val_if_fail(priv != NULL, -1);

return ftk_pipe_get_read_handle(priv->pipe);
}

static int ftk_source_primary_check(FtkSource* thiz)
{
return -1;
}

ftk_source_primary_dispatch 函数中对FTK_EVT_ADD_SOURCE/FTK_EVT_REMOVE_SOURCE两个事件做了特殊处理,用于增加和移除事件源,对于其余事件只是调用窗口管理器的事件分发函数(ftk_wnd_manager_default_dispatch_event)去处理事件。

ftk_source_primary提供了 ftk_source_queue_event用于向管道中写入事件,向管道中写入事件当于其它GUI向事件队列中增加事件。

5.ftk_source_timer

ftk_source_timer主要用于定时执行一个动作,比如闪动光标和更新时间。它与前面的事件源不同的是,它没有相应的文件描述符,主循环无法通过挂在文件描述符上来等待事件的发生。所以 ftk_source_get_fd始终返回-1:

static int ftk_source_timer_get_fd(FtkSource* thiz)
{
return -1;
}

ftk_source_check返回下一次事件发生的时间间隔,告诉MainLoop 必须在这个时刻唤醒,并执行处理函数:

static int ftk_source_timer_check(FtkSource* thiz)
{
DECL_PRIV(thiz, priv);
int t = priv->next_time - ftk_get_relative_time();

t = t < 0 ? 0 : t;

return t;
}

ftk_source_timer_dispatch 的实现很简单,它计算下一次timer的时间,然后调用用户设置的回调函数。

tatic Ret ftk_source_timer_dispatch(FtkSource* thiz)
{
Ret ret = RET_FAIL;
DECL_PRIV(thiz, priv);
return_val_if_fail(priv->action != NULL, RET_REMOVE);

if(thiz->disable > 0)
{
ftk_source_timer_calc_timer(priv);
return RET_OK;
}

ret = priv->action(priv->user_data);
ftk_source_timer_calc_timer(priv);

return ret;
}

5.ftk_source_idle(.c/.h)

idle的主要用途有:

* 在空闲时执行低优先级任务。有的任务优先级比较低,但费耗时间相对较长,比如屏幕刷新等操作。如果为了避免它阻碍当前操作太久,此时我们把它放到idle 里去做。

* 将同步操作异步化。有的操作你可能不希望它在当前的处理函数中同步执行,这时也可以用idle来异步化 ,让它在后面的dispatch中执行。

* 串行化对GUI的访问。在FTK中,出于效率的考虑, GUI对象是没有加锁保护的,也就是只有GUI线程能访问这些对象。如果其它线程要访问GUI对象,此时就需要用idle来串行化了。idle是GUI线程(主线程)中执行的,所以它能访问GUI对象。

idle的实现有点timeout为0的定时器,把它独立出来主要为了概念上更清楚一点:

static int ftk_source_idle_get_fd(FtkSource* thiz)
{
return -1;
}

static int ftk_source_idle_check(FtkSource* thiz)
{
return 0;
}

ftk_source_idle_dispatch 只是简单的调用用户设置的回调函数。

static Ret ftk_source_idle_dispatch(FtkSource* thiz)
{
DECL_PRIV(thiz, priv);

return_val_if_fail(priv->action != NULL, RET_REMOVE);

if(thiz->disable > 0)
{
return RET_OK;
}

return priv->action(priv->user_data);
}

FTK中还有其它一些事件源,比如针对X11模拟运行的事件源,它们的实现都是类似的,这里就不再多说了。

分享到:
评论

相关推荐

    AccessData_FTK_Imager--4.2.1 最新版本

    AccessData_FTK_Imager--4.2.1 最新版本取证工具。镜像挂载,镜像制作等功能

    FTK用户使用手册-英文原版

    FTK用户使用手册-英文原版,内容非常详细!值得广大取证爱好者阅读!

    AccessData_FTK_Imager--4.2.1.exe

    FTK Imager 是免费的镜像工具,功能强大,支持几十种镜像格式,E01、DD、L01、DMG、VMDK、VHD、AD1,使用过程中几乎没有遇到挂在不了的镜像格式。FTK Imager强大之处还在于可以获取当前内存镜像、获取受保护的文件,...

    FTK-imager-OSX:FTK Imager MAC OS X的取证工具

    为Mac OSX安装FTK Imager git clone git@github.com:MrMugiwara/FTK-imager-OSX.git cd FTK-imager-OSX chmod +x ftkimager ./ftkimager --help如何在MAC OSX上...

    FTKImager用户手册-英文原版

    最新ftk imager用户使用手册,对取证新手而言,值得收藏一波!

    AccessData_FTK_Imager_-4.3.1.exe

    包括显着提高了镜像速度(我们将镜像时间缩短了一半), 4.3.1.1进行了其他证据处理方面的改进,包括对 XFS文件系统的支持。

    AccessData FTK Imager_x64_4.2.0 含中文语言包

    AccessData FTK Imager是经典的windows硬盘取证工具,可用于分析外来人员或者外来入侵人员对机器的操作,从中追踪溯源。此为安装版,可以减少很多不必要的麻烦。同时打包了中文语言包,直接使用中文版。

    FTK嵌入式图形系统

    FTK嵌入式图形系统,支持UCOS、RT-Thread等嵌入式操作系统。

    AccessData_FTK_Imager4.2.1最新版取证工具.rar

    AccessData_FTK_Imager 4.2.1为当前最新版本取证镜像工具。可挂载镜像,创建镜像文件。本版本为安装版,不是绿色版,需要安装后才能使用。支持E01、DD、L01、DMG、VMDK、VHD、AD1等几十种镜像格式,使用过程中几乎...

    FTK-Imager-Triage-Notes:这是有关如何使用FTK Imager提取Windows计算机的取证声音图像的分步指南

    FTK-Imager-Triage-Note抓取自定义分类图像时从Windows机器收集的东西$ MFT-主文件表,它是系统上每个文件和文件夹的索引。 Pageflle.sys -Windows页面文件(RAM的扩展名)。 Hiberfile.sys: -Hibernate文件是上次...

    AccessData FTK Imager 中文语言包

    FTK中文语言包 FTK Imager 是免费的镜像工具,功能强大,支持几十种镜像格式,E01、DD、L01、DMG、VMDK、VHD、AD1,使用过程中几乎没有遇到挂在不了的镜像格式。FTK Imager强大之处还在于可以获取当前内存镜像、获取...

    FTK-Imager

    取证工具包成像器 ... cd FTK-imager-OSX chmod +x ftkimager ./ftkimager --help 如何在MAC OSX上使用FTK Imager Usage: ./ftkimager source [dest_file] [options] AccessData FTK Imager Cop

    AccessData-FTK-Imager4.2.zip

    AccessData-FTK-Imager4.2.zip

    FTK Imager 4.2.0中文版安装包

    FTK Imager 4.2.0中文安装包,携带安装及中文设置视频教程 内含文件: AccessData_FTK_Imager_(x64)_4.2.0.exe FTK Imager安装及中文设置视频.mp4

    FTK Imager中英文切换

    FTK Imager中英文切换!!!注意,不是软件包,不是软件包,不是软件包,通过修改注册表来切换中文,需要下软件在另一个资源。

    AccessData FTK Imager 3.14

    FTK Imager 是免费的镜像工具,功能强大,支持几十种镜像格式,E01、DD、L01、DMG、VMDK、VHD、AD1,使用过程中几乎没有遇到挂在不了的镜像格式。FTK Imager强大之处还在于可以获取当前内存镜像、获取受保护的文件,...

    FTK Imager(v4.5.0.3)

    FTK Imager 最新版安装包,支持几十种镜像格式,E01、DD、L01、DMG、VMDK、VHD、AD1,使用过程中几乎没有遇到挂在不了的镜像格式。

Global site tag (gtag.js) - Google Analytics