DirectFB 源码解读之初始化-10
2017-01-23 10:48
537 查看
转载时请表明原文出处(http://blog.sina.com.cn/wyw1976)及作者邮箱(wyw1976@gmail.com)
现在我们看看input_core的初始化。
在进入具体的代码之前,我们先总结一下input_core这个核心部件的主要功能。我们知道计算机系统的外设有很多,不同的外设,接口不同,功能不同,提供的数据类型也不尽相同。例如键盘的事件是KEY_RELEASE
或KEY_PRESS, 而鼠标的事件是BUTTON_PRESS或BUTTON_RELEAASE,还有触摸屏,游戏杆等等。所以input_core的功能之一就是统一不同输入设备的差异。第二,上层可能有多个进程在等待某个输入,而下层的输入设备并不知道,这种向多个进程分发事件的功能也是input core完成的。第三,系统中可能有多个设备对应同一个driver,DFB需要建立设备与driver的对应关系。
根据以前的解读,我们可以直接跳到dfb_input_core_initialize()开始input_core
的初始化。这个函数做两件事:
(1)direct_modules_explore_directory():这个函数又出现了,它就是在指定的目录中搜索所有的动态链接库,依次打开这些库,将这些库的信息(主要是函数表)记录在一个结构中,并挂在一个链表里。
(2)init_devices():初始化input device。init_devices()的主体代码如下:
static void init_devices( CoreDFB *core )
{
//遍历每一个module,一个modeule对应一个input driver
direct_list_foreach_safe (module, next, dfb_input_modules.entries)
{
//得到该module的函数表
funcs = direct_module_ref( module );
if (!funcs)
continue;
driver = D_CALLOC( 1, sizeof(InputDriver) );
//得到当前系统中,该driver支持的设备总数,不同的设备driver实现自己的GetAvailabe
//GetAvailabe的实现分两类,一是调用access看节点是否存在,而是调用open看是否打开成功。
//同一driver可能对应多个设备。
driver->nr_devices = funcs->GetAvailable();
driver->module = module;
driver->funcs = funcs;
//所有有效的input driver会记录在全局变量core_local的drivers链表中。
direct_list_prepend( &core_local->drivers, &driver->link );
for (n=0; n<driver->nr_devices; n++)
{
device = D_CALLOC( 1, sizeof(CoreInputDevice) );
shared = SHCALLOC( pool, 1, sizeof(InputDeviceShared) );
device->core = core;
//打开设备,在成功打开设备后调用direct_thread_create(),为每个设备指定一个事件处理线程, 这个线程负责读取设备的事件,完成初次转发。
funcs->OpenDevice( device, n, &device_info, &driver_data );
//为每个设备创建一个reactor的结构,其中有一个reactions的链表将来会记录所有关心该设备事件的对象,事件的转发会最终在此完成。
shared->reactor = fusion_reactor_new( sizeof(DFBInputEvent), buf, dfb_core_world(core) );
//下面这一步与当前分析没有太多联系,略过。
fusion_call_init( &shared->call, input_device_call_handler, device, dfb_core_world(core) );
//device 与driver,device与share(即reactor)联系起来
device->shared = shared;
device->driver = driver;
//所有的device都会记录在全局变量core_local的devices链表中。
input_add_device( device );
}
}
}
上面有关fusion和reactor时,我们仍然只考虑单进程的情况。
在input_core_part初始化完成后,我们最终得到一个数据结构core_local, 将input drivers,
input devices, reactors联系起来。其结构图如下:
有关上面的图, 有几点说明:
(1)DFB中的input driver 与gfx driver 类似,只是DFB中的一个概念,不是真正意义的设备驱动。而上图中的input driver和input device只是对真正设备和驱动的一个抽象,在DFB中也数据结构的形式,将它们串联起来。
(2) 每一个设备对应一个EventThread, 一经创建,即开始工作,不断从设备中读取事件,并开始处理
分发这些事件。
(3)图中的reactor指向的是一个reactions链表,虚线表示这时并没有实际的reactions接入,也就是没有对这些设备及其事件感兴趣的应用。所以在上一步中,即使读到数据,在分发时都扔掉了。
(4)上图中的driver与device是一一对应的,但也可以是一对多的关系(一个driver,多个device)
(5)DFB中自带了各种input driver, 在实际运行时,只有系统中存在的设备的driver才会挂到上面的结构中。
(6)DFB中定义了一个DFBInputEvent的数据结构,各种输入设备的事件都需要mapping到这个结构中。因此EventThread在开始分发事件前,需要做mapping的工作。
(7) 上图只针对单进程的情况。
下节我们看看输入设备事件传送的流程。
现在我们看看input_core的初始化。
在进入具体的代码之前,我们先总结一下input_core这个核心部件的主要功能。我们知道计算机系统的外设有很多,不同的外设,接口不同,功能不同,提供的数据类型也不尽相同。例如键盘的事件是KEY_RELEASE
或KEY_PRESS, 而鼠标的事件是BUTTON_PRESS或BUTTON_RELEAASE,还有触摸屏,游戏杆等等。所以input_core的功能之一就是统一不同输入设备的差异。第二,上层可能有多个进程在等待某个输入,而下层的输入设备并不知道,这种向多个进程分发事件的功能也是input core完成的。第三,系统中可能有多个设备对应同一个driver,DFB需要建立设备与driver的对应关系。
根据以前的解读,我们可以直接跳到dfb_input_core_initialize()开始input_core
的初始化。这个函数做两件事:
(1)direct_modules_explore_directory():这个函数又出现了,它就是在指定的目录中搜索所有的动态链接库,依次打开这些库,将这些库的信息(主要是函数表)记录在一个结构中,并挂在一个链表里。
(2)init_devices():初始化input device。init_devices()的主体代码如下:
static void init_devices( CoreDFB *core )
{
//遍历每一个module,一个modeule对应一个input driver
direct_list_foreach_safe (module, next, dfb_input_modules.entries)
{
//得到该module的函数表
funcs = direct_module_ref( module );
if (!funcs)
continue;
driver = D_CALLOC( 1, sizeof(InputDriver) );
//得到当前系统中,该driver支持的设备总数,不同的设备driver实现自己的GetAvailabe
//GetAvailabe的实现分两类,一是调用access看节点是否存在,而是调用open看是否打开成功。
//同一driver可能对应多个设备。
driver->nr_devices = funcs->GetAvailable();
driver->module = module;
driver->funcs = funcs;
//所有有效的input driver会记录在全局变量core_local的drivers链表中。
direct_list_prepend( &core_local->drivers, &driver->link );
for (n=0; n<driver->nr_devices; n++)
{
device = D_CALLOC( 1, sizeof(CoreInputDevice) );
shared = SHCALLOC( pool, 1, sizeof(InputDeviceShared) );
device->core = core;
//打开设备,在成功打开设备后调用direct_thread_create(),为每个设备指定一个事件处理线程, 这个线程负责读取设备的事件,完成初次转发。
funcs->OpenDevice( device, n, &device_info, &driver_data );
//为每个设备创建一个reactor的结构,其中有一个reactions的链表将来会记录所有关心该设备事件的对象,事件的转发会最终在此完成。
shared->reactor = fusion_reactor_new( sizeof(DFBInputEvent), buf, dfb_core_world(core) );
//下面这一步与当前分析没有太多联系,略过。
fusion_call_init( &shared->call, input_device_call_handler, device, dfb_core_world(core) );
//device 与driver,device与share(即reactor)联系起来
device->shared = shared;
device->driver = driver;
//所有的device都会记录在全局变量core_local的devices链表中。
input_add_device( device );
}
}
}
上面有关fusion和reactor时,我们仍然只考虑单进程的情况。
在input_core_part初始化完成后,我们最终得到一个数据结构core_local, 将input drivers,
input devices, reactors联系起来。其结构图如下:
有关上面的图, 有几点说明:
(1)DFB中的input driver 与gfx driver 类似,只是DFB中的一个概念,不是真正意义的设备驱动。而上图中的input driver和input device只是对真正设备和驱动的一个抽象,在DFB中也数据结构的形式,将它们串联起来。
(2) 每一个设备对应一个EventThread, 一经创建,即开始工作,不断从设备中读取事件,并开始处理
分发这些事件。
(3)图中的reactor指向的是一个reactions链表,虚线表示这时并没有实际的reactions接入,也就是没有对这些设备及其事件感兴趣的应用。所以在上一步中,即使读到数据,在分发时都扔掉了。
(4)上图中的driver与device是一一对应的,但也可以是一对多的关系(一个driver,多个device)
(5)DFB中自带了各种input driver, 在实际运行时,只有系统中存在的设备的driver才会挂到上面的结构中。
(6)DFB中定义了一个DFBInputEvent的数据结构,各种输入设备的事件都需要mapping到这个结构中。因此EventThread在开始分发事件前,需要做mapping的工作。
(7) 上图只针对单进程的情况。
下节我们看看输入设备事件传送的流程。
相关文章推荐
- DirectFB 源码解读之初始化-10
- DirectFB 源码解读之初始化-1
- DirectFB 源码解读之初始化-2
- DirectFB 源码解读之初始化-3
- DirectFB 源码解读之初始化-4
- DirectFB 源码解读之初始化-5
- Spring源码解读——Spring容器初始化 2
- struct2源码解读(2)之struct2初始化
- DirectFB 源码解读之外设输入处理流程
- struct2源码解读(10)之执行action请求前篇
- Spring源码解读——Spring容器初始化 1
- Spring源码解读-Spring IoC容器初始化之资源定位
- DirectFB 源码解读之双缓存实现
- js便签笔记(10) - 分享:json.js源码解读笔记
- caffe源码解读(10)-hinge_loss_layer.cpp
- Spark源码解读之SparkContext初始化
- Spring源码解读-Spring IoC容器初始化之资源注册
- SpringMVC源码解读 - HandlerMapping - AbstractDetectingUrlHandlerMapping系列初始化
- SpringMVC源码解读 - HandlerMapping - RequestMappingHandlerMapping初始化
- Spring源码解读 IOC容器初始化