MTK 按鍵處理流程和高亮處理機制

聲明:以上資料來自網上


1.按鍵處理流程


主要簡單分析一下左右軟件的事件,以左軟鍵事件爲例

牽涉到的常用函數:

     void SetKeyHandler( FuncPtr funcPtr, U16 keyCode, U16 keyType );

     void SetLeftSoftkeyFunction( void (*f)(void), MMI_key_event_type k );

     void ChangeLeftSoftkey( U16 s, U16 i );

    

1.   SetKeyHandlerSetLeftSoftkeyFunction

     (1). SetKeyHandler

           主要作用就是將需要起作用的函數的指針(funcPtr)

        -->全局矩陣數組currKeyFuncPtrs[keyCode][keyType]的指定位置 ;

     (2). SetLeftSoftkeyFunction

           該函數內部主要流程:

           Step1. call register_left_softkey_handler( )

                  這個函數call SetKeyHandler: 存儲需要起作用的函數(left_softkey_down/left_softkey_up)

                      left_softkey爲例, 該函數首先首先刷新按鍵區域圖像(redraw_softkey),

                  然後執行關聯函數(softkey_functions[key][k]).

           Step2. 在上一步裏我們會發現,softkey_functions[key][k]裏的函數指針沒有初始化

                  通過 call set_left_softkey_function(f, k);

                   --->softkey_functions[key][k] = f;

                  這樣,就成功的把按鍵按下/放開的作用函數與具體的動作關聯起來了。

           Step3. 最後call SetInputboxLSKFunction(f)

                  --->將上述函數與特定的輸入(如觸摸筆)關聯起來。

     (3). 以上兩個函數的主要區別:

           SetLeftSoftkeyFunction可以識別長按狀態並且可以關聯觸摸筆操作等。

 

2.   ChangeLeftSoftkey

     主要執行流程:

     Step1. call change_left_softkey: 設置左軟鍵圖表,文字

     Step2. redraw_softkey: 刷新左軟鍵顯示區域



2.高亮處理機制


相關函數和變量列表:

voidRegisterHighlightHandler(void(*f)(S32item_index))

註冊窗口的通用高亮處理函數。

MMI_list_highlight_handler

通用高亮處理函數的全局變量指針。

voidExecuteCurrHiliteHandler(S32hiliteid)

當前高亮菜單項的通用處理函數,它會找到菜單項對應的處理函數。一般在窗口創建過程中被創建RegisterHighlightHandler(ExecuteCurrHiliteHandler)

FuncPtrmmi_frm_get_hilite_hdlr(U16menu_id)

獲取menu_id對應的菜單高亮函數,從兩個函數指針數組裏獲取。先查找動態菜單的高亮函數指針數組,這個是在程序中動態添加的數組;如果找不到,再到靜態數組裏查找,這個數組是在編譯過程中生成的,通常我們在res_mainmenu.c等函數裏增加的菜單會被資源生成工具編譯成一個靜態數組。

mmi_frm_int_hilite_hdlr_table[]動態數組。

mmi_frm_const_hilite_hdlr_table[]靜態數組。

 

currParentID

當前父窗口全局變量

 

voidSetHiliteHandler(U16itemid,FuncPtrhiliteFuncPtr)

設置動態高亮數組的MENUID及它相對應的處理函數,一般用在自定義的菜單項。比如在圖片瀏覽、JAVA應用、WAP記錄等不可預期菜單項數目的環境,我們不可能做靜態的MENUID和處理函數,就需要用到動態的實現方式。

hintData[][]

[待確認]:這是一個動態菜單的數據緩衝,和MENUID一一對應。通俗一點說,就是菜單的顯示字符串。網上有文章對此以及ConstructHintsList()理解應該有誤,主要是因爲代碼裏該函數註釋說是處理靜態的,應該是註釋錯了。引用一段描述:

2ConstructHintsList()

ConstructsHintListforastaticmenuscreen

voidConstructHintsList(U16parentID,U8**hintArray)

{。。。。。。

(*maxHiliteInfo[hiliteItemID[i]].hintFuncPtr)(idx);//SetHintHandler註冊的函數的函數在此被執行

hintArray[idx]=hintData[idx];//該語句是該函數的核心,就是將全局變量hintData[idx]數組地址

//賦給用戶傳過來的指針數組;至於hintData[idx]中是否有數據不

//管;hintData[idx]的數據會在調用SetHintHandler註冊的函數時對其

//進行初始化;要記住SetHintHandler註冊的函數在SetHiliteHandler註冊的

//函數之前執行。

我認爲ConstructHintsList()是創建動態菜單的,時間關係,待分析。

 

3高亮機制說明:

3.1使用流程

每個窗口進入後基本都有類似下面的一段程序:

。。。。。。

EntryNewScreen(EM_DEBUG_INFO_SCR,NULL,EntryEMDebugInfo,NULL);

 

guiBuffer=GetCurrGuiBuffer(EM_DEBUG_INFO_SCR);

nItems=GetNumOfChild(EM_DEBUG_INFO_MENUID);

GetSequenceStringIds(EM_DEBUG_INFO_MENUID,ItemList);

SetParentHandler(EM_DEBUG_INFO_MENUID);

RegisterHighlightHandler(ExecuteCurrHiliteHandler);

ShowCategory52Screen(。。。)

SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);

。。。。。。

3.2分析

這是窗口建立過程的一個通用處理結構,這裏簡單說明一下,每個函數的具體實現和功能請閱讀代碼。

EntryNewScreen初始化建立一個窗口需要的變量和過程,並退出上一個窗口,清除按鍵處理函數等;

SetParentHandler很重要,設置當前父窗口全局變量的MENUID,用來定位到當前是在哪一個窗口,後面依據他來在菜單樹中查找到高亮的菜單項的MENUID,找到菜單項的MENUID後,通過mmi_frm_get_hilite_hdlr(U16menu_id)可以找到菜單項對應的高亮函數;RegisterHighlightHandlerExecuteCurrHiliteHandler註冊成一個通用的高亮處理函數,我們只要告訴ExecuteCurrHiliteHandler當前高亮的菜單項的MENUID,它就能找到執行函數並開始執行了。到這裏就應該已經基本明白了高亮機制了,弄明白了其實也很簡單的^_^

ShowCategory52Screen()只是一個窗口界面繪製函數,和事件處理邏輯沒有關係。

SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP)等函數設置這個窗口要響應哪些按鍵事件,並設置好相應的處理函數。

 

3.3高亮函數觸發過程

RegisterHighlightHandlerExecuteCurrHiliteHandler註冊成一個通用的高亮處理函數,實際上是給MMI_list_highlight_handler函數指針賦值。觸發則需要調用MMI_list_highlight_handler

由於MTK平臺支持各種菜單形式,比如純文本的菜單、帶CHECKBOX的、帶RADIO的、帶一個圖片的、帶兩個圖片的、兩行的。我們現在只對一種標準菜單進行分析,其他形式的分析方法相同。

standard_list_highlight_handler(S32item_index)裏會執行註冊的高亮處理函數MMI_list_highlight_handler,而standard_list_highlight_handler本身又是一個註冊函數,在wgui_fixed_list_create_text_menu()裏會被註冊到MMI_fixed_list_menu.item_highlightedMMI_fixed_list_menu是菜單組件的數據結構,包含有菜單組件從顯示到功能處理函數的所有數據,具體每個組件怎麼被顯示,怎麼響應功能按鍵就不在這裏討論了,後續我可能會寫出文檔,有興趣的同學自己看代碼,效果會更好。

這裏簡單說一下,MMI_fixed_list_menu.item_highlighted在這個組件裏,會被gui_fixed_list_menu_switch_highlighted_item()函數來執行,而gui_fixed_list_menu_switch_highlighted_item()則在上下按鍵執行的時候被執行,比響應上按鍵的函數是voidfixed_list_goto_previous_item(void),它調用voidgui_fixed_list_menu_goto_previous_item(fixed_list_menu*m),而voidgui_fixed_list_menu_goto_previous_item(fixed_list_menu*m)則調用gui_fixed_list_menu_switch_highlighted_item(),整個觸發過程就完成了。

關於上下按鍵的註冊,則在wgui_fixed_list_create_text_menu()裏有:

if(flag&WGUI_LIST_MENU_DISABLE_VOL_KEY)

register_fixed_list_keys_ex();

else

register_fixed_list_keys();

來註冊按鍵事件處理函數,其實現過程很簡單:

voidregister_fixed_list_keys(void)

{

/*----------------------------------------------------------------*/

/*LocalVariables*/

/*----------------------------------------------------------------*/

 

/*----------------------------------------------------------------*/

/*CodeBody*/

/*----------------------------------------------------------------*/

SetKeyHandler(fixed_list_goto_previous_item,KEY_UP_ARROW,KEY_EVENT_DOWN);

SetKeyHandler(fixed_list_goto_next_item,KEY_DOWN_ARROW,KEY_EVENT_DOWN);

SetKeyHandler(fixed_list_goto_previous_item,KEY_VOL_UP,KEY_EVENT_DOWN);

SetKeyHandler(fixed_list_goto_next_item,KEY_VOL_DOWN,KEY_EVENT_DOWN);

}

 

關於如何實現按鍵事件的響應、按鍵的處理邏輯,又是一個專題了。大致包括鍵盤中斷、去抖、鍵盤映射、檢測、進程通信、應用部分按鍵處理機制等,有機會再寫出文檔。

 

4相關知識點說明:

4.1初始化相關

 

高亮的一些全局變量會在InitEvents()裏進行初始化,在event.c文件裏。這個函數在開機過程中的一個調用棧關係如下:

InitEvents();

InitEventHandlersBeforePowerOn();

voidMMI_task(oslEntryType*entry_param)

 

InitEvents();還會在InitFramework()中被調用,而InitFramework()會由於開機的狀態不同,如USB開機、鬧鐘開機等,調用流程也不盡相同。具體的可參見我的另一篇應用開機流程的文檔。

 

4.2菜單結構及查找

4.2.1菜單數數組示意

constCUSTOM_MENUmtk_nCustMenus[]={

{1,0,18,0,16,2,10933,11062,(U16*)nOrderMenuItem_0},

{2,0,3,1,0,1,26218,26085,(U16*)nOrderMenuItem_1},

{3,2,0,1,0,1,555,0,(U16*)0},

{4,2,0,1,0,1,552,0,(U16*)0},

{5,2,0,1,0,1,26173,0,(U16*)0},

{0,0,0,0,0,0,0,0,(U16*)0},

{0,0,0,0,0,0,0,0,(U16*)0},

{0,0,0,0,0,0,0,0,(U16*)0},

{0,0,0,0,0,0,0,0,(U16*)0},

{0,0,0,0,0,0,0,0,(U16*)0},

{0,0,0,0,0,0,0,0,(U16*)0},

。。。。。。。。

}


CUSTOM_MENUnCustMenus[MAX_MENU_ITEMS];

 

4.2.2通過父窗口MENUID及高亮INDEX找到高亮窗口MENUID

U16GetSeqItemId_Ext(U16parent_item_id,U16index)

{

/*----------------------------------------------------------------*/

/*LocalVariables*/

/*----------------------------------------------------------------*/

U8i=0,idx=0;

U16item_id=0;

U8child_count=(U8)nCustMenus[parent_item_id-1].nNumofMenuItem;

 

/*----------------------------------------------------------------*/

/*CodeBody*/

/*----------------------------------------------------------------*/

#ifdefDEVAPP_RESOURCE

if(parent_item_id>=MENU_ID_DEVAPP_START)

{

returnDevAppGetSeqItemId_Ext(parent_item_id,index);

}

#endif

 

for(i=0;i<child_count;i++)

{

item_id=nCustMenus[parent_item_id-1].nOrderMenuItemId[i];

if(!mmi_frm_test_menu_item_hide(item_id))/*theitemisnothidden*/

{

if(idx==index)

{

break;

}

else

{

idx++;

}

}

}

MMI_TRACE(MMI_FW_TRC_G2_GUI,MMI_RESGEN_ALL_MENU_HIDE,parent_item_id);

returnitem_id;

}

 

42.3通過高亮窗口MENUID找到對應的高亮函數

FuncPtrmmi_frm_get_hilite_hdlr(U16menu_id)

{

/*----------------------------------------------------------------*/

/*LocalVariables*/

/*----------------------------------------------------------------*/

U32index;

 

/*----------------------------------------------------------------*/

/*CodeBody*/

/*----------------------------------------------------------------*/

 

/*Firstlysearchthedynamictable*/

if(mmi_frm_binary_search((U32)menu_id,(mmi_frm_pair_data_struct*)mmi_frm_int_hilite_hdlr_table,

(U32)mmi_frm_int_hilite_hdlr_count,&index))

{

returnmmi_frm_int_hilite_hdlr_table[index].hilite_hdlr;

}

/*Andthensearchtheconstanttable.Theconstanttableisgenerantedbyresgen.*/

elseif(mmi_frm_binary_search((U32)menu_id,

(mmi_frm_pair_data_struct*)mmi_frm_const_hilite_hdlr_table,

(U32)ARRAY_COUNT(mmi_frm_const_hilite_hdlr_table),&index))

{

returnmmi_frm_const_hilite_hdlr_table[index].hilite_hdlr;

}

else

{

returnNULL;

}

}

 

發佈了55 篇原創文章 · 獲贊 4 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章