MTK MMI event 小结 6

来源:互联网 发布:linux 命令行写入文件 编辑:程序博客网 时间:2024/05/16 14:31

在 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的代码函数名字上虽然看不出什么东西,但是一层一层函数,每一层函数的功能还是比较独立的,所以也不是很难看懂。

待续

原创粉丝点击