MTK MMI event 小结 5

昨天说了一下key event 的基本情况,今天直接从代码开始吧

先看执行key event 函数 mmi_frm_key_handle

 

void mmi_frm_key_handle(void *paraBuff)
{
    kbd_data k;
    U32 msg_count;
    mmi_eq_keypad_detect_ind_struct *p;

    // 判断参数是否为空
    // 在 初始化时,系统就注册了 MSG_ID_MMI_EQ_KEYPAD_DETECT_IND 的回调函数为 mmi_frm_key_handle
    // 当收到这个消息是,表示有按键事件要处理,
    // 这个paraBuff 是 keyTask 传过来的参数,里面的内容是获取按键信息的函数指针
    if (paraBuff != NULL)
    {
        drv_get_key_func new_key_ptr;

        p = (mmi_eq_keypad_detect_ind_struct*) paraBuff;

        new_key_ptr = (drv_get_key_func) (p->func);
        //判断是否是新的函数指针,如果是的话,需要进行一些清理工作		
        if (new_key_ptr != keypad_ptr)
        {
            // 新的函数指针,则进行清理,并且判断是否有按键需要处理
            if (!mmi_kbd_process_keyptr_change((void *)new_key_ptr))
            {             
                return;
            }
            //清理 按键 事件缓存buffer       
            ClearKeyEvents();
            keypad_ptr = new_key_ptr;
        }
    }


    // 通过 while 1 来 不停的从 按键缓存里获取按键信息
    // 当然这里不会无限死循环,后面会进行相应处理
    while (1)
    {
        //1)判读是否是挂起,2)是否key需要处理
        if ((g_mmi_suspend_key_flag == MMI_FALSE) && keypad_ptr &&((*(keypad_ptr))(&k) == MMI_TRUE))
        {
            if (k.Keydata[0] != KEY_INVALID)
            {
            #if defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__)
                kal_bool is_pen_enabled, is_pen_down;
                // 获得触摸屏状态
                mmi_pen_get_state(&is_pen_enabled, &is_pen_down);
            #endif /* defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__) */ 


            #if defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__)
                //如果触摸屏按下,那么保存状态
                if (is_pen_down && (k.Keyevent == WM_KEYPRESS))
                {
                   
                    U16 KeyMapIndex;
                    // 不允许 按键处理
                    is_allow_key_action = MMI_FALSE;
                    // 把驱动的按键和MMI 按键进行转换
                    KeyMapIndex = mmi_frm_get_idx_from_device_key_code(k.Keydata[0]);
                    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;
                            pressKey = HALF_DOWN_STATUS;
                            key_is_pressing_count++;
                        }
                        else
                        {
                            nKeyPadStatus[KeyMapIndex] = KEY_EVENT_DOWN;
                            pressKey = FULL_DOWN_STATUS;
                            key_is_pressing_count++;
                        }
                    }
                }
                else
            #endif /* defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__) */ 
                //如果按键是弹起,那么还原原来按键状态,也就是弹起状态
                //
                if ((k.Keyevent == WM_KEYRELEASE) && (is_allow_key_action == MMI_FALSE))
                {
                #if defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__)
                    /* Reset allow key flag and Update key status even if pen is down*/
                    U16 KeyMapIndex;

                    KeyMapIndex = mmi_frm_get_idx_from_device_key_code(k.Keydata[0]);
                    if ((nKeyPadStatus[KeyMapIndex] == KEY_EVENT_DOWN)
                        || (nKeyPadStatus[KeyMapIndex] == KEY_HALF_PRESS_DOWN)
                        || (nKeyPadStatus[KeyMapIndex] == KEY_LONG_PRESS)
                        || (nKeyPadStatus[KeyMapIndex] == KEY_REPEAT))
                    {
                        nKeyPadStatus[KeyMapIndex] = KEY_EVENT_UP;
                        key_is_pressing_count--;
                    }
                    prevKeyMapIndex = prevKeyMapIndex;
                #endif /* defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__) */

                    is_allow_key_action = MMI_TRUE;
                }
                // 按键是否可以处理
                if (is_allow_key_action == MMI_TRUE)
                {
                    if (((k.Keyevent == WM_KEYPRESS) && (mmi_kbd_get_key_is_pressing_count() == 0))
                        || k.Keyevent == DRV_WM_KEYLONGPRESS || k.Keyevent == DRV_WM_KEYREPEATED || k.Keyevent == DRV_WM_KEYFULLPRESS)
                    {
                    #if defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__)
                        //关闭触摸屏
                        mmi_pen_disable();
                    #endif
                    
                    
                    }
                    //真正处理按键事件
                    mmi_frm_convert_process_key_event(k.Keyevent, k.Keydata[0]);

                    if ((k.Keyevent == WM_KEYRELEASE) && (mmi_kbd_get_key_is_pressing_count() == 0))
                    {
                    #if defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__)
                        //重新打开触摸屏
                        mmi_pen_enable();
                    #endif
                    
                    }
                }
            }
            // 获得MMI task 消息队列消息个数
            msg_get_ext_queue_info(mmi_ext_qid, &msg_count);
            //如果外部有消息或者内部消息,则跳出该循环
            if (msg_count > 0 || OslNumOfCircularQMsgs() > 0)
            {
                //表示还有key需要处理,在MMI task 里会直接调用这个函数进行再处理
                g_keypad_flag = MMI_TRUE;
                break;
            }
        }
        else
        {   
            // 没有key消息要处理
            g_keypad_flag = MMI_FALSE;
            break;
        }
    }   /* while(1) */
    MMI_TRACE(MMI_FW_TRC_G1_FRM, MMI_FRM_KEY_HDLR_END);
}

 

1) 这里key 用while (1)来处理,不停的从key 消息buffer里取出按键信息,然后处理,这么做可以防止task中不停的发送消息,可以理解为共享内存。同样当有其他消息来时,需要跳出来处理其他消息,处理完毕后还需要再来处理。

2)这里跟触摸屏的事件进行了冲突处理,也就是按键和触摸屏不能同时工作,这两者也没有优先级。

3)实际真正处理按键 是在 mmi_frm_convert_process_key_event里面,下次在分析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值