您的位置:首页 > 其它

MTK MMI event 小结 8

2010-08-10 23:06 225 查看
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

这里有点点复杂的是手写输入法,这个事件比较乱,全局变量一堆,分析起来比较头疼。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: