关于directfb下的inputdriver里的键盘设备

来源:互联网 发布:12c5a60怎么使用p4端口 编辑:程序博客网 时间:2024/06/05 12:40
我正在试图添加自己的键盘设备,花了快两个星期了,读了keyboard.c和 /src/core/input.c 两个文件头大死了,发现directfb的键盘设备是针对标准键盘的,好像没有为自定义键盘留有任何额外的接口,而且键值的获取、翻译、传递过程及其复杂,看的我是相当迷糊,在此提出一些问题,看看读过directfb键盘设备源码的朋友能不能给指点一下?  在keyboard.c中,好像通过了两种方法都获得了标准键盘的键盘值(不是扫描值,用的是MEDIUMRAW 模式),一种是在driver_open_device里通过建立一个keyboardEventThread线程,然后在keyboardEventThread里使用系统调用read()从设备驱动里读取键值,另一种是通过在driver_get_keymap_entry模块里的keyboard_read_value()里,使用系统调用ioctl(),来获取键值,然后在把这个值通过别的函数转换成一种DFBInputDevicekeySymbol。。。等等等。。。
回过头来再看通过read()方法得到的键值,是通过调用dfb_input_dispatch--》fixup_key_event,然后在fixup_key_event这个函数里根据不同的情况来分别调用
lookup_from_table()
find_key_code_by_id()
find_key_code_by_symbol()
id_to_symbol()
symbol_to_id()
来得到相应的新的键值,让我头大的是,event结构体里的key_code、key_id、key_symbol,到底是什么关系,有一个实际的键盘值对应一个directfb可以识别的键值就行了,个干吗还要key_id,key_symbol,这种多重复杂的来回转换,到底有什么用?通过read()传过来的键值并通过转换后得到的新值与通过ioctl得到的那个键值有什么区别和联系?我要添加自己的键盘,不使用标准键盘,到底从哪个地方开始切入??

zhyuzhyu1985 发表于 2008-8-14 18:22

代码里面有说明的,key_id是更上层的抽象,跟硬件无关,key_symbol硬件相关。你要使用自己的键盘的话,可以全部用key_symbol,把自己键盘的键值全部读出来,再全部转换成key_symbol,就直接可以用了,跟遥控器一样实现原理。它的keyboard.c本来就是实现标准键盘的。你要添加,自己建个keyborad1.c。

tiansun7k 发表于 2008-8-15 18:20

谢谢,LS的解答,我今天又仔细的分析了一下这部分的源码,麻烦你能不能给一下细节的指点:
1 .  如果我自己重新写一个keyboard.c,其格式是不是要和原keyboard.c一样,包括一些实现的细节,是不是还是需要以下这几个宏和函数
      DFB_INPUT_DRIVER(这个宏肯定是必须的,它的实现在input_driver.h中)
     keyboard_get_symbol()
     keyboard_get_identifier()
     keyboard_read_value()
     keyboard_set_lights()
     keyboardEventThread()
     driver_get_available()
     driver_get_info()
     driver_open_device()
    driver_get_keymap_entry()
    driver_close_device()
2.  keyboard.c并不是孤立的,他里面的好多函数都是与/src/core下的input.c相关联的,  如果重新写一个keyboard.c肯定也要有于input.c中的函数相联系的地方,input.c不需
    要改动吗?

3  我自己的键盘驱动已经在内核里运行了,而且我写了个测试程序,在终端下可以直接通过read的方法成功捕获键值,其实我只要有五个键能用就行了(上,下,左,右,确定),我在自己的keyboard.c中肯定也需要通过read来获取这个键值,而ioctl肯定就没用了(我自己的键盘驱动里就没有实现 ioctl方法),而我在自己的keyboard.c中诸如
   driver_open_device(),keyboard_read_value()中的  ioctl( dfb_fbdev->vt->fd, KDSKBMODE, K_MEDIUMRAW )、ioctl( data->vt->fd, KDGKBENT, &entry )还要写吗?

4  原keyboard.c 中所得到的标准的键盘值到底是通过read得到的?还是通过ioctl得到的? 我看了一下代码:ioctl( data->vt->fd, KDGKBENT, &entry )得到的好像不是单纯的键盘码,因为键盘值传递给了entry这个结构体变量,而entry却有好多个成员:kb_table、kb_index、 kb_value,可以确定这个kb_value肯定是键值,但table和index是干什么用的呢?假如传过来的键值是一个字节,它是怎么正好就放在 kb_value里的呢?

5 我个人认为键值是通过keyboardEventThread()里的read 得到的,因为通过read以后的相关代码可以明显的看到:

for (i = 0; i < readlen; i++) {
    DFBInputEvent evt;                         //定义了一个输入事件                  

     evt.type     = ((buf[i] & 0x80) ? DIET_KEYRELEASE : DIET_KEYPRESS);       //标准键盘的                                                                                 键值(MEDIUMRAW 模式)的最高位通 过是0还是1来区别按键的press和release
      evt.flags    = DIEF_KEYCODE;             //标明是是键值,而不是KEYID或KEYSYMBOL
      evt.key_code = buf[i] & 0x7f;                              //屏蔽最高位,低7位才是所需要的                                                                                                 标准键盘值 key_code

     dfb_input_dispatch( data->device, &evt );   //通过evt指针把键值和其他信息传递给                                                             input.c文件里的dfb_input_dispatch()具体实现
      keyboard_set_lights( data, evt.locks );
          }
        在dfb_input_dispatch()里通过switch (event->type)来判断是不是 DIET_KEYRELEASE : DIET_KEYPRESS,然后对标准键盘的特殊键caps Lock进行处理,然后直接调用 fixup_key_event(),在这个函数里面,源码注释分了好多项: /* Add missing flags */、 /* Use cached values for modifiers/locks if they are missing.*/、/* With translation table*/、 /*Without translation table*/.、/* Update cached values for modifiers.*/....... 对这几部分看了好长时间也没弄清楚是怎么把相应的id,symnol,code处理的,特别是那个modifiers,搞不清他表示的到底是什么意思,因为在DFBInputEvent结构体里,分别对key_id和key_symbol是这样解释的:
   key_id;     /* basic mapping, modifier independent */
   key_symbol; /* advanced mapping, unicode compatible,modifier dependent */

     这个modifier是你说的“硬件”吗?根据上面的解释,key_id是不依赖modifier的,而key_symbol则依赖于modifier。
     我个人感觉如果想让我自定义的键盘可以使用,input.c文件里的fixup_key_event()也要做很大的改动。


6    你在回贴里说的,“可以全部用key_symbol,把自己键盘的键值全部读出来,再全部转换成key_symbol,就直接可以用了,跟遥控器一样实现原理”,是说的在keyboard.c里实现吗?怎么把我自己的键值(假设驱动传过来的“确定键”的十六进制键值为41H)直接转换为key_symbol,你能写一小段代码举个例子吗? key_symbol好像是由directfb定义的,每个数值对应一个symbol(我不是很清楚),假如你添加过自定义键盘,能不能把你自己写的 keyboard.c和在input.c里作的改动发给我一份,让我参考一下?

非常感谢!!!!!!!!!!!!!

sword_lzr 发表于 2008-9-3 22:17

我已经实现了,给你参考我的修改

input.c
void
dfb_input_dispatch( CoreInputDevice *device, DFBInputEvent *event )
{
     D_DEBUG_AT( Core_Input, "%s( %p, %p )\n", __FUNCTION__, device, event );

     D_MAGIC_ASSERT( device, CoreInputDevice );

     D_ASSERT( core_input != NULL );
     D_ASSERT( device != NULL );
     D_ASSERT( event != NULL );

     D_ASSUME( device->shared != NULL );

     /*
      * 0. Sanity checks & debugging...
      */
     if (!device->shared) {
          D_DEBUG_AT( Core_Input, "  -> No shared data!\n" );
          return;
     }

     D_ASSUME( device->shared->reactor != NULL );

     if (!device->shared->reactor) {
          D_DEBUG_AT( Core_Input, "  -> No reactor!\n" );
          return;
     }

     D_DEBUG_AT( Core_InputEvt, "  -> (%02x) %s%s%s\n", event->type,
                 dfb_input_event_type_name( event->type ),
                 (event->flags & DIEF_FOLLOW) ? " [FOLLOW]" : "",
                 (event->flags & DIEF_REPEAT) ? " [REPEAT]" : "" );

#if D_DEBUG_ENABLED
     if (event->flags & DIEF_TIMESTAMP)
          D_DEBUG_AT( Core_InputEvt, "  -> TIMESTAMP  %lu.%06lu\n", event->timestamp.tv_sec, event->timestamp.tv_usec );
     if (event->flags & DIEF_AXISABS)
          D_DEBUG_AT( Core_InputEvt, "  -> AXISABS    %d at %d\n",  event->axis, event->axisabs );
     if (event->flags & DIEF_AXISREL)
          D_DEBUG_AT( Core_InputEvt, "  -> AXISREL    %d by %d\n",  event->axis, event->axisrel );
     if (event->flags & DIEF_KEYCODE)
          D_DEBUG_AT( Core_InputEvt, "  -> KEYCODE    %d\n",        event->key_code );
     if (event->flags & DIEF_KEYID)
          D_DEBUG_AT( Core_InputEvt, "  -> KEYID      0x%04x\n",    event->key_id );
     if (event->flags & DIEF_KEYSYMBOL)
          D_DEBUG_AT( Core_InputEvt, "  -> KEYSYMBOL  0x%04x\n",    event->key_symbol );
     if (event->flags & DIEF_MODIFIERS)
          D_DEBUG_AT( Core_InputEvt, "  -> MODIFIERS  0x%04x\n",    event->modifiers );
     if (event->flags & DIEF_LOCKS)
          D_DEBUG_AT( Core_InputEvt, "  -> LOCKS      0x%04x\n",    event->locks );
     if (event->flags & DIEF_BUTTONS)
          D_DEBUG_AT( Core_InputEvt, "  -> BUTTONS    0x%04x\n",    event->buttons );
     if (event->flags & DIEF_GLOBAL)
          D_DEBUG_AT( Core_InputEvt, "  -> GLOBAL\n" );
#endif

     /*
      * 1. Fixup event...
      */
     event->clazz     = DFEC_INPUT;
     event->device_id = device->shared->id;

     if (!(event->flags & DIEF_TIMESTAMP)) {
          gettimeofday( &event->timestamp, NULL );
          event->flags |= DIEF_TIMESTAMP;
     }

     switch (event->type) {
          case DIET_BUTTONPRESS:
          case DIET_BUTTONRELEASE:
               D_DEBUG_AT( Core_InputEvt, "  -> BUTTON     0x%04x\n", event->button );

               if (dfb_config->lefty) {
                    if (event->button == DIBI_LEFT)
                         event->button = DIBI_RIGHT;
                    else if (event->button == DIBI_RIGHT)
                         event->button = DIBI_LEFT;

                    D_DEBUG_AT( Core_InputEvt, "  -> lefty!  => 0x%04x <=\n", event->button );
               }
               /* fallthru */

          case DIET_AXISMOTION:
               fixup_mouse_event( device, event );
               break;

          case DIET_KEYPRESS:
          case DIET_KEYRELEASE:
            #if 0
               if (dfb_config->capslock_meta) {
                    if (device->shared->keymap.num_entries && (event->flags & DIEF_KEYCODE))
                         lookup_from_table( device, event, (DIEF_KEYID |
                                                            DIEF_KEYSYMBOL) & ~event->flags );

                    if (event->key_id == DIKI_CAPS_LOCK || event->key_symbol == DIKS_CAPS_LOCK) {
                         event->flags     |= DIEF_KEYID | DIEF_KEYSYMBOL;
                         event->key_code   = -1;
                         event->key_id     = DIKI_META_L;
                         event->key_symbol = DIKS_META;
                    }
               }

               fixup_key_event( device, event );
               #endif
               printf("event->key_code=%d\n",event->key_code);
               switch(event->key_code){
                case 1:
                  event->key_symbol=DIKS_1;
                  event->key_id=DIKI_A;
                  break;
                case 2:
                  event->key_symbol=DIKS_2;
                  event->key_id=DIKI_B;
                  break;
                case 3:
                  event->key_symbol=DIKS_3;
                  event->key_id=DIKI_C;
                  break;
                case 4:
                  event->key_symbol=DIKS_4;
                  event->key_id=DIKI_D;
                  break;
                case 5:
                  event->key_symbol=DIKS_5;
                  event->key_id=DIKI_E;
                  break;
                case 6:
                  event->key_symbol=DIKS_6;
                  event->key_id=DIKI_F;
                  break;
                  
                  
               }
               break;

          default:
               ;
     }

#if D_DEBUG_ENABLED
     if (event->flags & DIEF_TIMESTAMP)
          D_DEBUG_AT( Core_InputEvt, "  => TIMESTAMP  %lu.%06lu\n", event->timestamp.tv_sec, event->timestamp.tv_usec );
     if (event->flags & DIEF_AXISABS)
          D_DEBUG_AT( Core_InputEvt, "  => AXISABS    %d at %d\n",  event->axis, event->axisabs );
     if (event->flags & DIEF_AXISREL)
          D_DEBUG_AT( Core_InputEvt, "  => AXISREL    %d by %d\n",  event->axis, event->axisrel );
     if (event->flags & DIEF_KEYCODE)
          D_DEBUG_AT( Core_InputEvt, "  => KEYCODE    %d\n",        event->key_code );
     if (event->flags & DIEF_KEYID)
          D_DEBUG_AT( Core_InputEvt, "  => KEYID      0x%04x\n",    event->key_id );
     if (event->flags & DIEF_KEYSYMBOL)
          D_DEBUG_AT( Core_InputEvt, "  => KEYSYMBOL  0x%04x\n",    event->key_symbol );
     if (event->flags & DIEF_MODIFIERS)
          D_DEBUG_AT( Core_InputEvt, "  => MODIFIERS  0x%04x\n",    event->modifiers );
     if (event->flags & DIEF_LOCKS)
          D_DEBUG_AT( Core_InputEvt, "  => LOCKS      0x%04x\n",    event->locks );
     if (event->flags & DIEF_BUTTONS)
          D_DEBUG_AT( Core_InputEvt, "  => BUTTONS    0x%04x\n",    event->buttons );
     if (event->flags & DIEF_GLOBAL)
          D_DEBUG_AT( Core_InputEvt, "  => GLOBAL\n" );
#endif

     if (core_input_filter( device, event ))
     {
          printf( "  ****>> FILTERED\n" );
     }
     else
     {
      printf("fusion_reactor_dispatch()\n");
          fusion_reactor_dispatch( device->shared->reactor, event, true, dfb_input_globals );
         
     }
}
原创粉丝点击