MTK MMI event 小结 8

MTK MMI event 小结 7 中,说到,init 时候, 注册了触摸屏消息MSG_ID_TP_EVENT_IND 的处理函数 mmi_pen_touch_panel_event_ind,

static void mmi_pen_touch_panel_event_ind(void *param )
{
     // 这个用于控制 只有一个 MSG_ID_TP_EVENT_IND 在 消息队列里
     g_pen_is_driver_indication_in_queue = 0;
    // 判断是否启动了timer 在定时读取 pen event 缓存
    if (!g_pen_polling_timer_started)
    {
       //真正的处理函数
        mmi_pen_poll_hdlr();
    }
}

这个函数其实没有做什么真正的处理,只是简单的判断的了一下是否要处理这个消息。这里需要注意的是, 跟按键事件不同的是,这里通过timer来控制处理 pen event 消息缓存里剩余的消息, 按键事件 是在 MMI task 消息循环里,直接调用 按键事件的处理函数。从要实现的效果上没有什么太多的区别。
static void mmi_pen_poll_hdlr(void)
{
    TouchPanelEventStruct data;
    MMI_BOOL is_stroke_move = MMI_FALSE;
    MMI_BOOL has_incoming_event = MMI_FALSE;
    MMI_BOOL delay_polling_timer = MMI_FALSE;
    MMI_BOOL pen_abort_happen = MMI_FALSE;
    U16      interval = 0;

    
    g_pen_polling_timer_started = MMI_FALSE;
    ResetBit(g_input_msg_in_queue, MMI_DEVICE_PEN);

    
    // 判断 pen event 是否开启,按键和pen 是冲突的。
    if (!g_pen_cntx.is_enabled)
    {
        return;
    }
    
    // 判断是否还有数据要处理
    // delay_polling_timer 表示是否启动了timer,来稍后处理这些pen event 事件,开始时初始化为 false
    while (!delay_polling_timer && mmi_pen_lookahead_buffer_get_event(&data))
    {       
        mmi_pen_point_struct pos;

        // 检测背光情况,是否要开启
        mmi_idle_key_event_backlight_check();
        // 重置 屏幕保护和键盘锁的时间
        mmi_idle_restart_screensaver_timer();
        mmi_idle_restart_keypad_lock_timer();

        // 获取 x,y。坐标点
        pos.x = (S16) data.x_adc;
        pos.y = (S16) data.y_adc;


	


        has_incoming_event = MMI_TRUE;

    #ifdef __MMI_TOUCH_PANEL_SHORTCUT__
        if(!mmi_pen_check_tp_shortcut(&pos, data.event))
    #endif /* __MMI_TOUCH_PANEL_SHORTCUT__ */
        {
            // 判断 是否是 stroke move 事件结束
            // is_stroke_move 表示前一个pen event 事件是否是 stroke move
            if (is_stroke_move && (data.event != STROKE_MOVE))
            {
                is_stroke_move = MMI_FALSE;
                // 这个函数眼熟吧
                if (g_pen_stroke_post_move)
                {
                    g_pen_stroke_post_move();
                }
            }
            // 保存现在状态
            g_pen_cntx.pen_current_pos = pos;
            g_pen_cntx.pen_event = data.event;
    
            switch (data.event)
            {
                    
                case PEN_DOWN:
                   
                    g_pen_cntx.is_pen_down = 1;
                    g_pen_cntx.is_in_pen_handler = 1;

                    // 计算最近两次 点击事件的 事件间隔
                    // 这里这么判断是当时间溢出 short的时候,需要特殊处理
                    if (g_pen_cntx.previous_pen_down_time > data.time_stamp)
                    {
                        interval = 0XFFFF - g_pen_cntx.previous_pen_down_time + data.time_stamp;
                    }
                    else
                    {
                        interval = data.time_stamp - g_pen_cntx.previous_pen_down_time;
                    }

                    //判断两次pen down 的时间是否足够短,间隔距离足够短,从而判断是否是 双击
                    if ((interval <= MMI_PEN_DOUBLE_CLICK_THRESHOLD) && 
                        (mmi_pen_get_distance_square(g_pen_cntx.pen_down_pos, pos) < MMI_PEN_SKIP_DOUBLE_CLICK_OFFSET_SQUARE))
                    {                        
                        if (g_pen_event_table[MMI_PEN_EVENT_DOUBLE_CLICK] && g_pen_cntx.is_enabled)
                        {
                            // 前置处理函数
                            MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_DOUBLE_CLICK);
                            // 回调double click 注册函数
                            (g_pen_event_table[MMI_PEN_EVENT_DOUBLE_CLICK]) (pos);
                            // 后置处理函数
                            MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_DOUBLE_CLICK);
                           
                        } 

                        g_pen_cntx.previous_pen_down_time = 0;
                    }
                    else
                    {
                        g_pen_cntx.previous_pen_down_time = data.time_stamp;
                    }

                    g_pen_cntx.pen_down_pos = pos;
                    
                    
                    if (g_pen_event_table[MMI_PEN_EVENT_DOWN] && g_pen_cntx.is_enabled)
                    {
                       // 前置处理函数
                        MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_DOWN);
                        // 回调pen down注册函数
                        (g_pen_event_table[MMI_PEN_EVENT_DOWN]) (pos);
                        // 后置处理函数
                        MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_DOWN);
                      
                    }
                   

                    break;
                    
                case PEN_UP:
                    
                    g_pen_cntx.is_pen_down = 0;

                   
                    if (g_pen_event_table[MMI_PEN_EVENT_UP] && g_pen_cntx.is_enabled)
                    {
                       
                        MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_UP);
                        (g_pen_event_table[MMI_PEN_EVENT_UP]) (pos);
                        MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_UP);
                        
                    }
                   
                   
                    // 判断是否要进行pen event reset
                    if (g_pen_cntx.reset_stroke_on_pen_up)
                    {
                        // 判读是否有 stroke event
                        if (g_pen_stroke_max_points > 0)
                        {  
                            // 结束 stroke event,注意,stroke event 会把所有的点push到一个数组里,供注册的程序使用,当然这个数组大小也是程序设定的。这里设置结束标志。
                            mmi_pen_end_strokes_of_character();
                            mmi_pen_reset();
                            mmi_pen_begin_strokes_of_character();
                        }
                        else
                        {
                            mmi_pen_reset();
                        }
                    }
    
                    // 一对 down move up 后,即时还有pen事件,通过timer 来取下一组信息
                    delay_polling_timer = MMI_TRUE;
    
                    
                    g_pen_cntx.is_in_pen_handler = 0;
                    g_pen_cntx.pen_event = TP_UNKNOWN_EVENT;
                    break;
                    
                case PEN_MOVE:
                    
                    if (g_pen_event_table[MMI_PEN_EVENT_MOVE] && g_pen_cntx.is_enabled)
                    {
                       
                        MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_MOVE);
                        (g_pen_event_table[MMI_PEN_EVENT_MOVE]) (pos);
                        MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_MOVE);
                        
                    }

                 
                    
                    break;
                    
                case PEN_LONGTAP:
                   
                    if (g_pen_event_table[MMI_PEN_EVENT_LONG_TAP] && g_pen_cntx.is_enabled)
                    {
                      
                        MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_LONG_TAP);
                        (g_pen_event_table[MMI_PEN_EVENT_LONG_TAP]) (pos);
                        MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_LONG_TAP);
                       
                    }

                  
                    
                    break;
                    
                case PEN_REPEAT:
                   
                    if (g_pen_event_table[MMI_PEN_EVENT_REPEAT])
                    {
                       
                        MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_REPEAT);
                        (g_pen_event_table[MMI_PEN_EVENT_REPEAT]) (pos);
                        MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_REPEAT);
                       
                    }
                    
                   
                    
                    break;
                    
                case PEN_ABORT:
                   
					pen_abort_happen = MMI_TRUE;
			        g_pen_drvq_full_abort = MMI_TRUE;
                    mmi_pen_reset();
                    break;
                    
                case TP_UNKNOWN_EVENT:
                    MMI_ASSERT(0);
                    break;
                    
                case STROKE_MOVE:
                   
                   
                    // 这个主要是用于当只有一个手写区域时使用
                    if (g_pen_cntx.is_pending_stroke_event)
                    {
                        // 判断是第一stroke move点是否符合标准(最小距离)
                        if (mmi_pen_get_distance_square(g_pen_cntx.pen_down_pos, pos) > g_pen_stroke_min_offset_square)
                        {
                            g_pen_cntx.is_pending_stroke_event = 0;
                            g_pen_stroke_min_offset_square = 0; 
                            g_pen_cntx.reset_stroke_on_pen_up = 0;
                            g_pen_cntx.pen_event = PEN_ABORT;
    
                            // 先产生 pen_abort 事件,告诉应用普通的pen 事件被中断,也就是光有pen down 没有pen up事件了
                            if (g_pen_event_table[MMI_PEN_EVENT_ABORT]&& g_pen_cntx.is_enabled)
                            {
                                
                                MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_ABORT);
                                (g_pen_event_table[MMI_PEN_EVENT_ABORT]) (g_pen_cntx.pen_down_pos);
                                MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_ABORT);
                               
                            }
    
                            g_pen_cntx.pen_event = STROKE_DOWN;

                            // 把 stroke down 时间事件 保存到数组里
                            mmi_pen_push_stroke_point(g_pen_cntx.pen_down_pos.x, g_pen_cntx.pen_down_pos.y);
                            // 发送 stroke down 事件
                            if (g_pen_stroke_table[MMI_PEN_STROKE_DOWN] && g_pen_cntx.is_enabled)
                            {
                                
                                MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_STROKE_DOWN);
                                (g_pen_stroke_table[MMI_PEN_STROKE_DOWN]) (g_pen_cntx.pen_down_pos);
                                MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_STROKE_DOWN);
                               
                            }
                           
                            g_pen_cntx.pen_event = STROKE_MOVE;
                            
                            // 预处理
                            is_stroke_move = MMI_TRUE;
                            if (g_pen_stroke_pre_move)
                            {
                                g_pen_stroke_pre_move();
                            }
                            
                            // 发送 stroke move
                            mmi_pen_push_stroke_point(pos.x, pos.y);
                            if (g_pen_stroke_table[MMI_PEN_STROKE_MOVE] && g_pen_cntx.is_enabled)
                            {
                               
                                MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_STROKE_MOVE);
                                (g_pen_stroke_table[MMI_PEN_STROKE_MOVE]) (pos);
                                MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_STROKE_MOVE);
                                
                            }
                        }
                    }
                    else
                    {
                        // 判断在哪个区域里面
                        if (g_pen_num_stroke_area > 1)
                        {
                            mmi_pen_fix_multi_block_pen_position(&pos);
                        }
                        
                        // 预处理
                        if (!is_stroke_move)
                        {
                            is_stroke_move = MMI_TRUE;
                            if (g_pen_stroke_pre_move)
                            {
                                g_pen_stroke_pre_move();
                            }
                        }
                        // 保存 stroke move 并发送
                        mmi_pen_push_stroke_point(pos.x, pos.y);
                        if (g_pen_stroke_table[MMI_PEN_STROKE_MOVE] && g_pen_cntx.is_enabled)
                        {
                           
                            MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_STROKE_MOVE);
                            (g_pen_stroke_table[MMI_PEN_STROKE_MOVE]) (pos);
                            MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_STROKE_MOVE);
                           
                        }
                    }
                    break;
                    
                case STROKE_DOWN:
                   
                   
                    g_pen_cntx.is_stroke_down = 1;
                    g_pen_cntx.is_pen_down = 1;
                    g_pen_cntx.pen_down_pos = pos;
    
                    g_pen_cntx.stroke_down_block_index = mmi_pen_lookup_handwriting_block(pos.x, pos.y);
                    
    
                    // 单个区域特殊处理
                    if (g_pen_stroke_min_offset_square > 0)
                    {
                        g_pen_cntx.is_pending_stroke_event = 1;
                        g_pen_cntx.pen_event = PEN_DOWN;
    
                        
                        if (g_pen_event_table[MMI_PEN_EVENT_DOWN] && g_pen_cntx.is_enabled)
                        {
                            
                            MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_DOWN);
                            (g_pen_event_table[MMI_PEN_EVENT_DOWN]) (g_pen_cntx.pen_down_pos);
                            MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_DOWN);
                           
                        }
                    }
                    else
                    {
                        g_pen_cntx.is_pending_stroke_event = 0;
                        g_pen_cntx.pen_event = STROKE_DOWN;
    
                        if (g_pen_stroke_table[MMI_PEN_STROKE_DOWN] && g_pen_cntx.is_enabled)
                        {
                           
                            MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_STROKE_DOWN);
                            (g_pen_stroke_table[MMI_PEN_STROKE_DOWN]) (pos);
                            MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_STROKE_DOWN);
                            
                        }
                        
                       
                        if (g_pen_cntx.is_enabled && g_pen_cntx.is_pen_down && g_pen_stroke_max_points > 0)
                        {
                            mmi_pen_push_stroke_point(pos.x, pos.y);
                        }                    
                    }
                    

                    break;
                    
                case STROKE_UP:
                   
                    MMI_DBG_ASSERT(g_pen_stroke_max_points > 0);
                    g_pen_cntx.is_stroke_down = 0;
                    g_pen_cntx.is_pen_down = 0;
    
                    

                    if (g_pen_cntx.is_pending_stroke_event)
                    {
                        g_pen_cntx.is_pending_stroke_event = 0;
    
                        
                        g_pen_cntx.reset_stroke_on_pen_up = 1;
                        g_pen_cntx.pen_event = PEN_UP;
    
                        
                        if (g_pen_event_table[MMI_PEN_EVENT_UP] && g_pen_cntx.is_enabled)
                        {
                           
                            MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_EVENT_UP);
                            (g_pen_event_table[MMI_PEN_EVENT_UP]) (g_pen_cntx.pen_down_pos);
                            MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_EVENT_UP);
                           
                        }
    
                       
                        delay_polling_timer = MMI_TRUE;
                    }
                    else
                    {
                        
                        g_pen_cntx.pen_event = STROKE_UP;
                        if (g_pen_num_stroke_area > 1)
                        {
                            mmi_pen_fix_multi_block_pen_position(&pos);
                        }
                        
                        mmi_pen_push_stroke_end();
                        if (g_pen_stroke_table[MMI_PEN_STROKE_UP] && g_pen_cntx.is_enabled)
                        {
                            
                            MMI_PEN_EXECUTE_PRE_CALLBACK_FUNC(MMI_PEN_STROKE_UP);
                            (g_pen_stroke_table[MMI_PEN_STROKE_UP]) (pos);
                            MMI_PEN_EXECUTE_POST_CALLBACK_FUNC(MMI_PEN_STROKE_UP);
                           
                        }
                    }
    
                   
                    if (g_pen_cntx.reset_stroke_on_pen_up)
                    {
                        if (g_pen_stroke_max_points > 0)
                        {
                            mmi_pen_end_strokes_of_character();
                            mmi_pen_reset();
                            mmi_pen_begin_strokes_of_character();
                        }
                        else
                        {
                            mmi_pen_reset();
                        }
                    }
                   

                    /* leave pen handler procedure */
                    g_pen_cntx.is_in_pen_handler = 0;
                    g_pen_cntx.pen_event = TP_UNKNOWN_EVENT;
    
                    break;
    
                
                
                default:
                    MMI_ASSERT(0);
            }
    
        } /* if(!mmi_pen_check_tp_shortcut(&pos, data.event)) */

        // 把外部消息放入到内部循环消息队列
        mmi_frm_fetch_msg_from_extQ_to_circularQ();
        
        OslCircularDump();
        // 如果内部消息积压大于 MMI_PENDING_MSG_THRESHOLD,就跳出循环,进行处理
        if (OslNumOfCircularQMsgs() > MMI_PENDING_MSG_THRESHOLD)
        {
           
            break; 
        }
        
    }

    if (is_stroke_move)
    {
        if (g_pen_stroke_post_move)
        {
            g_pen_stroke_post_move();
        }
    }


    if (has_incoming_event)
    {
        if (!mmi_shutdown_is_in_power_off_period())
        {
            mmi_idle_key_event_backlight_check();
        }
   
    }

    if (g_pen_cntx.is_in_pen_handler == 0)
    {
        g_pen_cntx.pen_event = TP_UNKNOWN_EVENT;
    }
   
    // 启动定时期
    if (delay_polling_timer)
    {
       
        StartTimer(PEN_POLLING_TIMER, MMI_PEN_DEBOUNCE_POLLING_DELAY, mmi_pen_poll_hdlr);
        g_pen_polling_timer_started = MMI_TRUE;
        SetBit(g_input_msg_in_queue, MMI_DEVICE_PEN);

       
    }
    else if (g_pen_cntx.is_pen_down || pen_abort_happen)
    {
        
       
        StartTimer(PEN_POLLING_TIMER, MMI_PEN_POLLING_PERIOD, mmi_pen_poll_hdlr);
        g_pen_polling_timer_started = MMI_TRUE;
        SetBit(g_input_msg_in_queue, MMI_DEVICE_PEN);
        if(pen_abort_happen)
        {
            pen_abort_happen = MMI_FALSE;
        }
    }
}

这里其实也是比较简单:

1: 取pen event 事件

2: 根据时间类型处理事件

3:是否有额外消息要处理,是 退出,否继续 1

这里有点点复杂的是手写输入法,这个事件比较乱,全局变量一堆,分析起来比较头疼。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值