DirectFB 源码解读之初始化-10

来源:互联网 发布:淘宝苏宁易购是官网吗 编辑:程序博客网 时间:2024/05/22 14:27

转载时请表明原文出处(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联系起来。其结构图如下:

 

DirectFB <wbr>源码解读之初始化-10

 

 

有关上面的图, 有几点说明:

(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) 上图只针对单进程的情况。

 

下节我们看看输入设备事件传送的流程。

0 0
原创粉丝点击