MTK MMI event 小结 6

在 MTK MMI event 小结 5 中,提到了event 处理函数 mmi_frm_key_handle,这个函数主要作用是判断是否需要处理按键,从按键缓存里面持续的读取按键信息,然后调用 mmi_frm_convert_process_key_event 进行处理。这个函数没有什么可说的,最多是在屏幕旋转的情况下,把 导航键 转换一下,接着它调用了 ProcessKeyEvent, 这个函数主要是对于一些状态的处理,防止key down 和up 不成对,出现混乱。

void ProcessKeyEvent(U32 MsgType, U16 DeviceKeyCode) {     MMI_BOOL isKeyPaired;     U16      KeyMapIndex;      /*----------------------------------------------------------------*/     /* Code Body                                                      */     /*----------------------------------------------------------------*/         // 按键影射,把驱动的按键码,转换成MMI 的 按键消息     KeyMapIndex = mmi_frm_get_idx_from_device_key_code(DeviceKeyCode);        if (KeyMapIndex >= MAX_KEYS)     {         return;     }      // 处理各种按键事件,没有什么可以多说的,     // 主体结构都一样,     // 1 判断状态是否正常     // 2 正常 则调用 KeyEventHandler 处理, 否则忽略该事件     if (MsgType == WM_KEYPRESS)     {         // 这里处理 多案件同时按下的情况。这里需要硬件支持         if ((KeyMapIndex != prevKeyMapIndex) && (g_kbd_concurrent_key_mode == CONCURRENT_KEY_MODE_1_KEY))         {             isKeyPaired = (nKeyPadStatus[prevKeyMapIndex] == KEY_EVENT_UP);                      prevKeyMapIndex = KeyMapIndex;         }         //判断案件状态是否正常,防止不匹配         if (nKeyPadStatus[KeyMapIndex] == KEY_EVENT_UP)         {              KEYBRD_MESSAGE KeyBrdMsg;              KeyBrdMsg.nKeyCode = nKeyPadMap[KeyMapIndex].nMMIKeyCode;             if (mmi_frm_is_2step_keyCode(KeyBrdMsg.nKeyCode))             {                 nKeyPadStatus[KeyMapIndex] = KEY_HALF_PRESS_DOWN;                 key_is_pressing_count++;                 KeyBrdMsg.nMsgType = KEY_HALF_PRESS_DOWN;             }             else             {                 nKeyPadStatus[KeyMapIndex] = KEY_EVENT_DOWN;    /* same with KEY_FULL_PRESS_DOWN */                 key_is_pressing_count++;                 KeyBrdMsg.nMsgType = KEY_EVENT_DOWN;             }             // 处理按键事件             KeyEventHandler((KEYBRD_MESSAGE*) & KeyBrdMsg);          }         else         {             /* Ignore the event */         }     }      else if (MsgType == WM_KEYRELEASE)     {         if ((nKeyPadStatus[KeyMapIndex] == KEY_EVENT_DOWN)             || (nKeyPadStatus[KeyMapIndex] == KEY_LONG_PRESS)             || (nKeyPadStatus[KeyMapIndex] == KEY_REPEAT) || (nKeyPadStatus[KeyMapIndex] == KEY_HALF_PRESS_DOWN))         {              KEYBRD_MESSAGE KeyBrdMsg;              nKeyPadStatus[KeyMapIndex] = KEY_EVENT_UP;             key_is_pressing_count--;             KeyBrdMsg.nMsgType = KEY_EVENT_UP;             KeyBrdMsg.nKeyCode = nKeyPadMap[KeyMapIndex].nMMIKeyCode;             KeyEventHandler((KEYBRD_MESSAGE*) & KeyBrdMsg);          }         else         {             /* Ignore the event */         }     }     /* ++Robin, modified by Max Chen */     else if (MsgType == DRV_WM_KEYLONGPRESS)     {         if (nKeyPadStatus[KeyMapIndex] == KEY_EVENT_DOWN)         {             KEYBRD_MESSAGE KeyBrdMsg;              nKeyPadStatus[KeyMapIndex] = KEY_LONG_PRESS;             KeyBrdMsg.nMsgType = KEY_LONG_PRESS;             KeyBrdMsg.nKeyCode = nKeyPadMap[KeyMapIndex].nMMIKeyCode;             KeyEventHandler((KEYBRD_MESSAGE*) & KeyBrdMsg);         }         else         {             /* Ignore the event */         }     }     else if (MsgType == DRV_WM_KEYREPEATED)     {         if ((nKeyPadStatus[KeyMapIndex] == KEY_LONG_PRESS) || (nKeyPadStatus[KeyMapIndex] == KEY_REPEAT))         {             KEYBRD_MESSAGE KeyBrdMsg;              nKeyPadStatus[KeyMapIndex] = KEY_REPEAT;             KeyBrdMsg.nMsgType = KEY_REPEAT;             KeyBrdMsg.nKeyCode = nKeyPadMap[KeyMapIndex].nMMIKeyCode;             KeyEventHandler((KEYBRD_MESSAGE*) & KeyBrdMsg);         }         else         {             /* Ignore the event */         }     }     else if (MsgType == DRV_WM_KEYFULLPRESS)     {         /*          * Only in two-stage key will have KEY_FULL_PRESS_DOWN, and it followed after KEY_HALF_PRESS_DOWN          */         if (nKeyPadStatus[KeyMapIndex] == KEY_HALF_PRESS_DOWN)         {             KEYBRD_MESSAGE KeyBrdMsg;              nKeyPadStatus[KeyMapIndex] = KEY_EVENT_DOWN;             KeyBrdMsg.nMsgType = KEY_EVENT_DOWN;             KeyBrdMsg.nKeyCode = nKeyPadMap[KeyMapIndex].nMMIKeyCode;             KeyEventHandler((struct KEYBRD_MESSAGE*)&KeyBrdMsg);         }         else         {             /* Ignore the event */         }     }     else if ((MsgType == DRV_WM_ENABLE_TWOKEY_DETECTION) || (MsgType == DRV_WM_ENABLE_THREEKEY_DETECTION) ||                 (MsgType == DRV_WM_DISABLE_MULTIKEY_DETECTION))     {         /* Ignore the event */     }     else     {         MMI_TRACE(MMI_FW_TRC_G6_FRM_DETAIL, MMI_FRM_ERROR_PROC_KEYEVENT_HDLR);          MMI_ASSERT(0);     }  }


KeyEventHandler 函数主要判断是否要真的处理该事件,可以看成是一个按键事件的拦截,比如应用切换过程中,需要一个切换动画,而这个动画工程中,需要处理忽略这些按键。就需要特殊的处理。

static void KeyEventHandler(KEYBRD_MESSAGE *eventKey) {      MMI_BOOL is_hdlr_enabled = MMI_TRUE;         // 主要处理一些特殊相应:屏幕背光,屏幕锁定,按键声音     mmi_kbd_app_key_hdlr(eventKey);      // 判断是否有前置处理函数     if (g_mmi_frm_cntx.kbd_pre_func)     {         is_hdlr_enabled = g_mmi_frm_cntx.kbd_pre_func(eventKey);     }         // 根据前置处理函数结果,判断是否要处理该 key event     if (is_hdlr_enabled)     {         //处理 案件事件         ExecuteCurrKeyHandler((S16) eventKey->nKeyCode, (S16) eventKey->nMsgType);     }      // 是否有后置处理函数,可以进行一些监视     if (g_mmi_frm_cntx.kbd_post_func)     {         g_mmi_frm_cntx.kbd_post_func(eventKey);     }  }


 

接下来是 ExecuteCurrKeyHandler 这个函数就是根据 按键事件,获得处理函数,进行处理。

void ExecuteCurrKeyHandler(S16 keyCode, S16 keyType) {   FuncPtr currFuncPtr = NULL;      // 重新设定 键盘锁和屏保timer     mmi_idle_restart_keypad_lock_timer();     mmi_idle_restart_screensaver_timer();      frm_p->currKeyCode = keyCode;     frm_p->currKeyType = keyType;          // 对电话状态下,挂电话键的特殊处理.         if (frm_p->currKeyType == KEY_EVENT_DOWN &&              isInCall() && !GetWapCallPresent() &&              IsBitReset(g_mmi_frm_cntx.end_key_flag, frm_p->currKeyType) )         {                       RegisterEndKeyHandlerInCall();         }           // 获得按键处理函数         currFuncPtr = currKeyFuncPtrs[keyCode][keyType];         // 导航的选择键,默认和左功能键的效果一样。         if (keyCode == KEY_ENTER && currFuncPtr == NULL)         {                if (currKeyFuncPtrs[KEY_ENTER][KEY_EVENT_UP] == NULL &&                 currKeyFuncPtrs[KEY_ENTER][KEY_EVENT_DOWN] == NULL &&                 currKeyFuncPtrs[KEY_ENTER][KEY_HALF_PRESS_DOWN] == NULL &&                 currKeyFuncPtrs[KEY_ENTER][KEY_REPEAT] == NULL && currKeyFuncPtrs[KEY_ENTER][KEY_LONG_PRESS] == NULL)              {                 currFuncPtr = currKeyFuncPtrs[KEY_LSK][keyType];             }         }                // 处理按键 消息         if (currFuncPtr)         {             (*currFuncPtr)();         }     }        // 重置状态     if (keyType == KEY_EVENT_UP)     {             frm_p->currKeyCode = KEY_INVALID;         frm_p->currKeyType = MAX_KEY_TYPE;     }  }


从整个按键事件的处理流程来看,也没有什么特殊的地方,就是收到消息后,从按键buffer里取出按键事件,然后处理。如果有有别的事件要处理,那么就break出来,等到处理完这个消息后,在 MMI task 调用 mmi_frm_key_handle 继续处理剩下的按键事件。

这里无非多了很多的判断,是否要进行按键处理,MTK的代码函数名字上虽然看不出什么东西,但是一层一层函数,每一层函数的功能还是比较独立的,所以也不是很难看懂。

转自:

http://blog.csdn.net/yanwuxufeng/archive/2010/08/08/5797645.aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值