在pc上调试的时候按键会被处理两次,原因是:

注册设备的时候,注册了两个可用的设备,一个是linux input,一个是keyboard,

而这个两个设备又分别创建了两个线程去读keyboard,所以就上报了两次给上层的directfb应用程序

解决办法:删掉inputdrivers目录下的一个设备的so文件或只注册一个设备

 

输入事件流程分析:

无论是两种设备创建的线程去读的输入事件,最终都会调用 input.c中的 dfb_input_dispatch往上报,

上层接收事件有两种方式:

 

 1  IDirectFBWindow        *window2;

     //Create an event buffer for this window and attach it.

     window2->CreateEventBuffer( window2, &buffer );

     IDirectFBWindow侧创建的,和窗口绑定的,可以接收所有的事件:包括鼠标,键盘等输入事件,窗口事件

     其他的窗口可以通过IDirectFBWindow_AttachEventBuffer与已经创建的buffer绑定

 

2 IDirectFB *fb ;

    //eate a buffer for events with input devices connected.

     result = fb->CreateInputEventBuffer(fb, DICAPS_KEYS, DFB_TRUE,
                                        &eventBuffer);

     IDirectFB 创建的,这个是总的接口,接收所有的事件,可以通过参数选择接收事件的类型,比如:DICAPS_KEYS

   

以DirectFB-examples-1.2.0中的df_window.c为例

这个例子中使用的第一种方式

关键步骤:

1)dfb_input_dispatch 往上层派发,调用

fusion_reactor_dispatch( device->shared->reactor, event, true, dfb_input_globals ); 

2)执行dfb_input_globals ->_dfb_windowstack_inputdevice_listener(这一步unique的处理不一样)

3)dfb_wm_process_input->sawman_wm.c中的wm_process_input

4)  wm_process_input

     1) /* Call application manager executable. */
     ret = sawman_call( sawman, SWMCID_INPUT_FILTER, &sawman->manager.event );

     2)handle_key_press->send_key_event ->sawman_post_event-> 

          dfb_window_post_event-> dfb_window_dispatch

5)相关的React函数 IDirectFBEventBuffer_WindowReact(如果是IDirectFB 创建的,则是

    IDirectFBEventBuffer_InputReact) ,   IDirectFBWindow_React

  //  IDirectFBEventBuffer_WindowReact

    通过React机制接收底层上报的事件,并将事件放入事件队列中

    dfb_window_attach( window, IDirectFBEventBuffer_WindowReact,
                        data, &attached->reaction );

 

//  IDirectFBWindow_React,设置窗口的focus,unfocus,enter等标志

    dfb_window_attach( window, IDirectFBWindow_React, data, &data->reaction );

 

6) IDirectFBEventBuffer_AddItem( data, item )->direct_list_append( &data->events, &item->link );  //加入事件队列

7)上层应用调用 IDirectFBEventBuffer_GetEvent取走事件并从队列中删除

 

Logo

更多推荐