diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c index 4be8a96464..80b4bfdc4f 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c @@ -98,8 +98,7 @@ EFI_GUID gDisplayEngineGuid = { 0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62} }; -FORM_ENTRY_INFO gFormEntryInfo; -UINTN gSequence; +BOOLEAN gMisMatch; EFI_SCREEN_DESCRIPTOR gStatementDimensions; BOOLEAN mStatementLayoutIsChanged = TRUE; USER_INPUT *gUserInput; @@ -1474,6 +1473,238 @@ FindTopOfScreenMenu ( return TopOfScreen; } +/** + Get the index info for this opcode. + + @param OpCode The input opcode for the statement. + + @retval The index of this statement. + +**/ +UINTN +GetIndexInfoForOpcode ( + IN EFI_IFR_OP_HEADER *OpCode + ) +{ + LIST_ENTRY *NewPos; + UI_MENU_OPTION *MenuOption; + UINTN Index; + + NewPos = gMenuOption.ForwardLink; + Index = 0; + + for (NewPos = gMenuOption.ForwardLink; NewPos != &gMenuOption; NewPos = NewPos->ForwardLink){ + MenuOption = MENU_OPTION_FROM_LINK (NewPos); + + if (CompareMem (MenuOption->ThisTag->OpCode, OpCode, OpCode->Length) == 0) { + if (MenuOption->ThisTag->OpCode == OpCode) { + return Index; + } + + Index ++; + } + } + + return Index; +} + +/** + Is this the saved highlight statement. + + @param HighLightedStatement The input highlight statement. + + @retval TRUE This is the highlight statement. + @retval FALSE This is not the highlight statement. + +**/ +BOOLEAN +IsSavedHighlightStatement ( + IN FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement + ) +{ + if ((gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) && + (gFormData->FormId == gHighligthMenuInfo.FormId)) { + if (gHighligthMenuInfo.HLTQuestionId != 0) { + return (gHighligthMenuInfo.HLTQuestionId == GetQuestionIdInfo (HighLightedStatement->OpCode)); + } else { + if (CompareMem (gHighligthMenuInfo.HLTOpCode, HighLightedStatement->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) { + if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(HighLightedStatement->OpCode)) { + return TRUE; + } else { + return FALSE; + } + } + } + } + + return FALSE; +} + +/** + Is this the highlight menu. + + @param MenuOption The input Menu option. + + @retval TRUE This is the highlight menu option. + @retval FALSE This is not the highlight menu option. + +**/ +BOOLEAN +IsHighLightMenuOption ( + IN UI_MENU_OPTION *MenuOption + ) +{ + if (gHighligthMenuInfo.HLTQuestionId != 0) { + if (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.HLTQuestionId) { + return (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence); + } + } else { + if(CompareMem (gHighligthMenuInfo.HLTOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) { + if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) { + return (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence); + } else { + return FALSE; + } + } + } + + return FALSE; +} + +/** + Find the highlight menu. + + If the input is NULL, base on the record highlight info in + gHighligthMenuInfo to find the last highlight menu. + + @param HighLightedStatement The input highlight statement. + + @retval The highlight menu index. + +**/ +LIST_ENTRY * +FindHighLightMenuOption ( + IN FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement + ) +{ + LIST_ENTRY *NewPos; + UI_MENU_OPTION *MenuOption; + + NewPos = gMenuOption.ForwardLink; + MenuOption = MENU_OPTION_FROM_LINK (NewPos); + + if (HighLightedStatement != NULL) { + while (MenuOption->ThisTag != HighLightedStatement) { + NewPos = NewPos->ForwardLink; + if (NewPos == &gMenuOption) { + // + // Not Found it, break + // + break; + } + MenuOption = MENU_OPTION_FROM_LINK (NewPos); + } + + // + // Must find the highlight statement. + // + ASSERT (NewPos != &gMenuOption); + + } else { + while (!IsHighLightMenuOption (MenuOption)) { + NewPos = NewPos->ForwardLink; + if (NewPos == &gMenuOption) { + // + // Not Found it, break + // + break; + } + MenuOption = MENU_OPTION_FROM_LINK (NewPos); + } + + // + // Highlight statement has disappear (suppressed/disableed) + // + if (NewPos == &gMenuOption) { + NewPos = NULL; + } + } + + return NewPos; +} + +/** + Is this the Top of screen menu. + + @param MenuOption The input Menu option. + + @retval TRUE This is the Top of screen menu option. + @retval FALSE This is not the Top of screen menu option. + +**/ +BOOLEAN +IsTopOfScreeMenuOption ( + IN UI_MENU_OPTION *MenuOption + ) +{ + if (gHighligthMenuInfo.TOSQuestionId != 0) { + return (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.TOSQuestionId); + } + + if(CompareMem (gHighligthMenuInfo.TOSOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.TOSOpCode->Length) == 0) { + if (gHighligthMenuInfo.TOSIndex == 0 || gHighligthMenuInfo.TOSIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) { + return TRUE; + } else { + return FALSE; + } + } + + return FALSE; +} + +/** + Find the Top of screen menu. + + If the input is NULL, base on the record highlight info in + gHighligthMenuInfo to find the last highlight menu. + + @param HighLightedStatement The input highlight statement. + + @retval The highlight menu index. + +**/ +LIST_ENTRY * +FindTopOfScreenMenuOption ( + VOID + ) +{ + LIST_ENTRY *NewPos; + UI_MENU_OPTION *MenuOption; + + NewPos = gMenuOption.ForwardLink; + MenuOption = MENU_OPTION_FROM_LINK (NewPos); + + while (!IsTopOfScreeMenuOption(MenuOption)) { + NewPos = NewPos->ForwardLink; + if (NewPos == &gMenuOption) { + // + // Not Found it, break + // + break; + } + MenuOption = MENU_OPTION_FROM_LINK (NewPos); + } + + // + // Last time top of screen menu has disappeared. + // + if (NewPos == &gMenuOption) { + NewPos = NULL; + } + + return NewPos; +} + /** Find the first menu which will be show at the top. @@ -1491,160 +1722,223 @@ FindTopMenu ( OUT UINTN *SkipValue ) { - LIST_ENTRY *NewPos; UINTN TopRow; UINTN BottomRow; - UI_MENU_OPTION *SavedMenuOption; + UI_MENU_OPTION *MenuOption; UINTN TmpValue; - TmpValue = 0; TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT; BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT; - // - // If not has input highlight statement, just return the first one in this form. - // - if (FormData->HighLightedStatement == NULL) { + if (gMisMatch) { + // + // Reenter caused by option mismatch or auto exit caused by refresh form(refresh interval/guid), + // base on the record highlight info to find the highlight menu. + // + ASSERT (gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle && + gFormData->FormId == gHighligthMenuInfo.FormId); + + *HighlightMenu = FindHighLightMenuOption(NULL); + if (*HighlightMenu != NULL) { + // + // Update skip info for this highlight menu. + // + MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu); + UpdateOptionSkipLines (MenuOption); + + // + // Found the last time highlight menu. + // + *TopOfScreen = FindTopOfScreenMenuOption(); + if (*TopOfScreen != NULL) { + // + // Found the last time selectable top of screen menu. + // + AdjustDateAndTimePosition(TRUE, TopOfScreen); + MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen); + UpdateOptionSkipLines (MenuOption); + + *SkipValue = gHighligthMenuInfo.SkipValue; + } else { + // + // Not found last time top of screen menu, so base on current highlight menu + // to find the new top of screen menu. + // Make the current highlight menu at the bottom of the form to calculate the + // top of screen menu. + // + if (MenuOption->Skip >= BottomRow - TopRow) { + *TopOfScreen = *HighlightMenu; + TmpValue = 0; + } else { + *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue); + } + + *SkipValue = TmpValue; + } + } else { + // + // Last time highlight menu has disappear, find the first highlightable menu as the defalut one. + // + *HighlightMenu = gMenuOption.ForwardLink; + if (!IsListEmpty (&gMenuOption)) { + MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE); + } + *TopOfScreen = gMenuOption.ForwardLink; + *SkipValue = 0; + } + + gMisMatch = FALSE; + } else if (FormData->HighLightedStatement != NULL) { + if (IsSavedHighlightStatement (FormData->HighLightedStatement)) { + // + // Input highlight menu is same as last time highlight menu. + // Base on last time highlight menu to set the top of screen menu and highlight menu. + // + *HighlightMenu = FindHighLightMenuOption(NULL); + ASSERT (*HighlightMenu != NULL); + + // + // Update skip info for this highlight menu. + // + MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu); + UpdateOptionSkipLines (MenuOption); + + *TopOfScreen = FindTopOfScreenMenuOption(); + if (*TopOfScreen == NULL) { + // + // Not found last time top of screen menu, so base on current highlight menu + // to find the new top of screen menu. + // Make the current highlight menu at the bottom of the form to calculate the + // top of screen menu. + // + if (MenuOption->Skip >= BottomRow - TopRow) { + *TopOfScreen = *HighlightMenu; + TmpValue = 0; + } else { + *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue); + } + + *SkipValue = TmpValue; + } else { + AdjustDateAndTimePosition(TRUE, TopOfScreen); + MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen); + UpdateOptionSkipLines (MenuOption); + + *SkipValue = gHighligthMenuInfo.SkipValue; + } + AdjustDateAndTimePosition(TRUE, TopOfScreen); + } else { + // + // Input highlight menu is not save as last time highlight menu. + // + *HighlightMenu = FindHighLightMenuOption(FormData->HighLightedStatement); + MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu); + UpdateOptionSkipLines (MenuOption); + + // + // Make the current highlight menu at the bottom of the form to calculate the + // top of screen menu. + // + if (MenuOption->Skip >= BottomRow - TopRow) { + *TopOfScreen = *HighlightMenu; + TmpValue = 0; + } else { + *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue); + } + + *SkipValue = TmpValue; + } + AdjustDateAndTimePosition(TRUE, TopOfScreen); + } else { + // + // If not has input highlight statement, just return the first one in this form. + // *TopOfScreen = gMenuOption.ForwardLink; *HighlightMenu = gMenuOption.ForwardLink; if (!IsListEmpty (&gMenuOption)) { MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE); } *SkipValue = 0; - return; } - - // - // Now base on the input highlight menu to find the top menu in this page. - // Will base on the highlight menu show at the bottom to find the top menu. - // - NewPos = gMenuOption.ForwardLink; - SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos); - - while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) || - (SavedMenuOption->Sequence != gSequence)) { - NewPos = NewPos->ForwardLink; - if (NewPos == &gMenuOption) { - // - // Not Found it, break - // - break; - } - SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos); - } - ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement); - - *HighlightMenu = NewPos; - - AdjustDateAndTimePosition(FALSE, &NewPos); - SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos); - UpdateOptionSkipLines (SavedMenuOption); - - // - // FormRefreshEvent != NULL means this form will auto exit at an interval, display engine - // will try to keep highlight on the current position after this form exit and re-enter. - // - // HiiHandle + QuestionId can find the only one question in the system. - // - // If this question has question id, save the question id info to find the question. - // else save the opcode buffer to find it. - // - if (gFormData->FormRefreshEvent != NULL && gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) { - if (gHighligthMenuInfo.QuestionId != 0) { - if (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode)) { - BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip; - // - // SkipValue only used for menu at the top of the form. - // If Highlight menu is not at the top, this value will be update later. - // - TmpValue = gHighligthMenuInfo.SkipValue; - } - } else if (gHighligthMenuInfo.OpCode != NULL){ - if (!CompareMem (gHighligthMenuInfo.OpCode, SavedMenuOption->ThisTag->OpCode, gHighligthMenuInfo.OpCode->Length)) { - BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip; - // - // SkipValue only used for menu at the top of the form. - // If Highlight menu is not at the top, this value will be update later. - // - TmpValue = gHighligthMenuInfo.SkipValue; - } - } - } - - if (SavedMenuOption->Skip >= BottomRow - TopRow) { - *TopOfScreen = NewPos; - } else { - *TopOfScreen = FindTopOfScreenMenu(NewPos, BottomRow - TopRow - SavedMenuOption->Skip, &TmpValue); - } - AdjustDateAndTimePosition(TRUE, TopOfScreen); - - *SkipValue = TmpValue; } /** - Update highlight menu info. + Record the highlight menu and top of screen menu info. - @param MenuOption The menu opton which is highlight. - @param SkipValue The skipvalue info for this menu. - SkipValue only used for the menu at the top of the form. + @param Highlight The menu opton which is highlight. + @param TopOfScreen The menu opton which is at the top of the form. + @param SkipValue The skip line info for the top of screen menu. **/ VOID UpdateHighlightMenuInfo ( - IN UI_MENU_OPTION *MenuOption, - IN UINTN SkipValue + IN LIST_ENTRY *Highlight, + IN LIST_ENTRY *TopOfScreen, + IN UINTN SkipValue ) { + UI_MENU_OPTION *MenuOption; FORM_DISPLAY_ENGINE_STATEMENT *Statement; - // - // This is the current selected statement - // - Statement = MenuOption->ThisTag; + gHighligthMenuInfo.HiiHandle = gFormData->HiiHandle; + gHighligthMenuInfo.FormId = gFormData->FormId; + gHighligthMenuInfo.SkipValue = (UINT16)SkipValue; - // - // Get the highlight statement. - // - gUserInput->SelectedStatement = Statement; - gSequence = (UINT16) MenuOption->Sequence; + if (!IsListEmpty (&gMenuOption)) { + MenuOption = MENU_OPTION_FROM_LINK (Highlight); + Statement = MenuOption->ThisTag; - // - // FormRefreshEvent != NULL means this form will auto exit at an interval, display engine - // will try to keep highlight on the current position after this form exit and re-enter. - // - // HiiHandle + QuestionId can find the only one question in the system. - // - // If this question has question id, base on the question id info to find the question. - // else base on the opcode buffer to find it. - // - if (gFormData->FormRefreshEvent != NULL) { - gHighligthMenuInfo.HiiHandle = gFormData->HiiHandle; - gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode); + gUserInput->SelectedStatement = Statement; - // - // if question id == 0, save the opcode buffer for later use. - // - if (gHighligthMenuInfo.QuestionId == 0) { - if (gHighligthMenuInfo.OpCode != NULL) { - FreePool (gHighligthMenuInfo.OpCode); + gHighligthMenuInfo.HLTSequence = MenuOption->Sequence; + gHighligthMenuInfo.HLTQuestionId = GetQuestionIdInfo(Statement->OpCode); + if (gHighligthMenuInfo.HLTQuestionId == 0) { + // + // if question id == 0, save the opcode buffer.. + // + if (gHighligthMenuInfo.HLTOpCode != NULL) { + FreePool (gHighligthMenuInfo.HLTOpCode); } - gHighligthMenuInfo.OpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode); - ASSERT (gHighligthMenuInfo.OpCode != NULL); - } - gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row; - gHighligthMenuInfo.SkipValue = (UINT16) SkipValue; - } else { - gHighligthMenuInfo.HiiHandle = NULL; - gHighligthMenuInfo.QuestionId = 0; - if (gHighligthMenuInfo.OpCode != NULL) { - FreePool (gHighligthMenuInfo.OpCode); - gHighligthMenuInfo.OpCode = NULL; - } - gHighligthMenuInfo.DisplayRow = 0; - gHighligthMenuInfo.SkipValue = 0; - } + gHighligthMenuInfo.HLTOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode); + ASSERT (gHighligthMenuInfo.HLTOpCode != NULL); - RefreshKeyHelp(gFormData, Statement, FALSE); + gHighligthMenuInfo.HLTIndex = GetIndexInfoForOpcode(Statement->OpCode); + } + + MenuOption = MENU_OPTION_FROM_LINK (TopOfScreen); + Statement = MenuOption->ThisTag; + + gHighligthMenuInfo.TOSQuestionId = GetQuestionIdInfo(Statement->OpCode); + if (gHighligthMenuInfo.TOSQuestionId == 0) { + // + // if question id == 0, save the opcode buffer.. + // + if (gHighligthMenuInfo.TOSOpCode != NULL) { + FreePool (gHighligthMenuInfo.TOSOpCode); + } + gHighligthMenuInfo.TOSOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode); + ASSERT (gHighligthMenuInfo.TOSOpCode != NULL); + + gHighligthMenuInfo.TOSIndex = GetIndexInfoForOpcode(Statement->OpCode); + } + } else { + gUserInput->SelectedStatement = NULL; + + gHighligthMenuInfo.HLTSequence = 0; + gHighligthMenuInfo.HLTQuestionId = 0; + if (gHighligthMenuInfo.HLTOpCode != NULL) { + FreePool (gHighligthMenuInfo.HLTOpCode); + } + gHighligthMenuInfo.HLTOpCode = NULL; + gHighligthMenuInfo.HLTIndex = 0; + + gHighligthMenuInfo.TOSQuestionId = 0; + if (gHighligthMenuInfo.TOSOpCode != NULL) { + FreePool (gHighligthMenuInfo.TOSOpCode); + } + gHighligthMenuInfo.TOSOpCode = NULL; + gHighligthMenuInfo.TOSIndex = 0; + } } /** @@ -2128,6 +2422,10 @@ UiDisplayMenu ( } FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue); + if (!IsListEmpty (&gMenuOption)) { + NextMenuOption = MENU_OPTION_FROM_LINK (NewPos); + gUserInput->SelectedStatement = NextMenuOption->ThisTag; + } gST->ConOut->EnableCursor (gST->ConOut, FALSE); @@ -2233,7 +2531,11 @@ UiDisplayMenu ( } if (EFI_ERROR (Status)) { - return Status; + if (gMisMatch) { + return EFI_SUCCESS; + } else { + return Status; + } } // // 3. Update the row info which will be used by next menu. @@ -2296,10 +2598,12 @@ UiDisplayMenu ( // ControlFlag = CfUpdateHelpString; + UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); + if (SkipHighLight) { - MenuOption = SavedMenuOption; SkipHighLight = FALSE; - UpdateHighlightMenuInfo (MenuOption, TopOfScreen == &MenuOption->Link ? SkipValue : 0); + MenuOption = SavedMenuOption; + RefreshKeyHelp(gFormData, SavedMenuOption->ThisTag, FALSE); break; } @@ -2341,9 +2645,7 @@ UiDisplayMenu ( // This is the current selected statement // MenuOption = MENU_OPTION_FROM_LINK (NewPos); - Statement = MenuOption->ThisTag; - - UpdateHighlightMenuInfo (MenuOption, Temp2); + RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE); if (!IsSelectable (MenuOption)) { break; @@ -2578,6 +2880,7 @@ UiDisplayMenu ( } if (EventType == UIEventDriver) { + gMisMatch = TRUE; gUserInput->Action = BROWSER_ACTION_NONE; ControlFlag = CfExit; break; @@ -2785,13 +3088,6 @@ UiDisplayMenu ( break; } - // - // When user press ESC, it will try to show another menu, should clean the gSequence info. - // - if (gSequence != 0) { - gSequence = 0; - } - gUserInput->Action = BROWSER_ACTION_FORM_EXIT; ControlFlag = CfExit; break; @@ -2904,6 +3200,8 @@ UiDisplayMenu ( // AdjustDateAndTimePosition (TRUE, &TopOfScreen); AdjustDateAndTimePosition (TRUE, &NewPos); + + UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); break; case CfUiPageUp: @@ -2943,6 +3241,8 @@ UiDisplayMenu ( // AdjustDateAndTimePosition (TRUE, &TopOfScreen); AdjustDateAndTimePosition (TRUE, &NewPos); + + UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); break; case CfUiPageDown: @@ -3004,6 +3304,8 @@ UiDisplayMenu ( // AdjustDateAndTimePosition (TRUE, &TopOfScreen); AdjustDateAndTimePosition (TRUE, &NewPos); + + UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); break; case CfUiDown: @@ -3065,6 +3367,8 @@ UiDisplayMenu ( // AdjustDateAndTimePosition (TRUE, &TopOfScreen); AdjustDateAndTimePosition (TRUE, &NewPos); + + UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); break; } @@ -3162,6 +3466,8 @@ UiDisplayMenu ( // AdjustDateAndTimePosition (TRUE, &TopOfScreen); AdjustDateAndTimePosition (TRUE, &NewPos); + + UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); break; case CfUiNoOperation: @@ -3571,8 +3877,12 @@ UnloadDisplayEngine ( FreeDisplayStrings (); - if (gHighligthMenuInfo.OpCode != NULL) { - FreePool (gHighligthMenuInfo.OpCode); + if (gHighligthMenuInfo.HLTOpCode != NULL) { + FreePool (gHighligthMenuInfo.HLTOpCode); + } + + if (gHighligthMenuInfo.TOSOpCode != NULL) { + FreePool (gHighligthMenuInfo.TOSOpCode); } return EFI_SUCCESS; diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h index f369877386..968d293afd 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h @@ -63,6 +63,7 @@ extern CHAR16 gPromptBlockWidth; extern CHAR16 gOptionBlockWidth; extern CHAR16 gHelpBlockWidth; extern CHAR16 *mUnknownString; +extern BOOLEAN gMisMatch; // // Screen definitions @@ -196,9 +197,31 @@ typedef struct { typedef struct { EFI_HII_HANDLE HiiHandle; - EFI_QUESTION_ID QuestionId; - EFI_IFR_OP_HEADER *OpCode; - UINT16 DisplayRow; + UINT16 FormId; + + // + // Info for the highlight question. + // HLT means highlight + // + // If one statement has questionid, save questionid info to find the question. + // If one statement not has questionid info, save the opcode info to find the + // statement. If more than one statement has same opcode in one form(just like + // empty subtitle info may has more than one info one form), also use Index + // info to find the statement. + // + EFI_QUESTION_ID HLTQuestionId; + EFI_IFR_OP_HEADER *HLTOpCode; + UINTN HLTIndex; + UINTN HLTSequence; + + // + // Info for the top of screen question. + // TOS means Top Of Screen + // + EFI_QUESTION_ID TOSQuestionId; + EFI_IFR_OP_HEADER *TOSOpCode; + UINTN TOSIndex; + UINT16 SkipValue; } DISPLAY_HIGHLIGHT_MENU_INFO; diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c index 6e9e6ddfcc..84ae03eea7 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c @@ -1034,7 +1034,7 @@ ProcessOptions ( // Exit current DisplayForm with new value. // gUserInput->SelectedStatement = Question; - + gMisMatch = TRUE; ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen); ASSERT (ValueArray != NULL); gUserInput->InputValue.Buffer = ValueArray; @@ -1119,7 +1119,7 @@ ProcessOptions ( // Exit current DisplayForm with new value. // gUserInput->SelectedStatement = Question; - + gMisMatch = TRUE; ValueArray = AllocateCopyPool (Question->CurrentValue.BufferLen, Question->CurrentValue.Buffer); ASSERT (ValueArray != NULL); gUserInput->InputValue.Buffer = ValueArray; @@ -1196,7 +1196,7 @@ ProcessOptions ( break; } gUserInput->SelectedStatement = Question; - + gMisMatch = TRUE; FreePool (*OptionString); *OptionString = NULL; return EFI_NOT_FOUND; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c index 7db775e4b4..ad39d22a9d 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c @@ -1445,21 +1445,20 @@ ProcessQuestionConfig ( Process the user input data. @param UserInput The user input data. - @param ChangeHighlight Whether need to change the highlight statement. @retval EFI_SUCESSS This function always return successfully for now. **/ EFI_STATUS ProcessUserInput ( - IN USER_INPUT *UserInput, - IN BOOLEAN ChangeHighlight + IN USER_INPUT *UserInput ) { EFI_STATUS Status; FORM_BROWSER_STATEMENT *Statement; - Status = EFI_SUCCESS; + Status = EFI_SUCCESS; + Statement = NULL; // // When Exit from FormDisplay function, one of the below two cases must be true. @@ -1470,62 +1469,35 @@ ProcessUserInput ( // Remove the last highligh question id, this id will update when show next form. // gCurrentSelection->QuestionId = 0; + if (UserInput->SelectedStatement != NULL){ + Statement = GetBrowserStatement(UserInput->SelectedStatement); + ASSERT (Statement != NULL); + + // + // This question is the current user select one,record it and later + // show it as the highlight question. + // + gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId; + // + // For statement like text, actio, it not has question id. + // So use FakeQuestionId to save the question. + // + if (gCurrentSelection->CurrentMenu->QuestionId == 0) { + mCurFakeQestId = Statement->FakeQuestionId; + } else { + mCurFakeQestId = 0; + } + } // // First process the Action field in USER_INPUT. // if (UserInput->Action != 0) { Status = ProcessAction (UserInput->Action, UserInput->DefaultId); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Clear the highlight info. - // gCurrentSelection->Statement = NULL; - - if (UserInput->SelectedStatement != NULL) { - Statement = GetBrowserStatement(UserInput->SelectedStatement); - ASSERT (Statement != NULL); - // - // Save the current highlight menu in the menu history data. - // which will be used when later browse back to this form. - // - gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId; - // - // For statement like text, actio, it not has question id. - // So use FakeQuestionId to save the question. - // - if (gCurrentSelection->CurrentMenu->QuestionId == 0) { - mCurFakeQestId = Statement->FakeQuestionId; - } else { - mCurFakeQestId = 0; - } - } } else { - Statement = GetBrowserStatement(UserInput->SelectedStatement); ASSERT (Statement != NULL); - gCurrentSelection->Statement = Statement; - - if (ChangeHighlight) { - // - // This question is the current user select one,record it and later - // show it as the highlight question. - // - gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId; - // - // For statement like text, actio, it not has question id. - // So use FakeQuestionId to save the question. - // - if (gCurrentSelection->CurrentMenu->QuestionId == 0) { - mCurFakeQestId = Statement->FakeQuestionId; - } else { - mCurFakeQestId = 0; - } - } - switch (Statement->Operand) { case EFI_IFR_REF_OP: Status = ProcessGotoOpCode(Statement, gCurrentSelection); @@ -1612,7 +1584,6 @@ DisplayForm ( EFI_STATUS Status; USER_INPUT UserInput; FORM_ENTRY_INFO *CurrentMenu; - BOOLEAN ChangeHighlight; ZeroMem (&UserInput, sizeof (USER_INPUT)); @@ -1636,9 +1607,6 @@ DisplayForm ( gCurrentSelection->CurrentMenu = CurrentMenu; - // - // Find currrent highlight statement. - // if (gCurrentSelection->QuestionId == 0) { // // Highlight not specified, fetch it from cached menu @@ -1646,9 +1614,6 @@ DisplayForm ( gCurrentSelection->QuestionId = CurrentMenu->QuestionId; } - // - // Evaluate all the Expressions in this Form - // Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form); if (EFI_ERROR (Status)) { return Status; @@ -1656,34 +1621,15 @@ DisplayForm ( UpdateDisplayFormData (); - // - // Three possible status maybe return. - // - // EFI_INVALID_PARAMETER: The input dimension info is not valid. - // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid - // and an valid value has return. - // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter. - // ASSERT (gDisplayFormData.BrowserStatus == BROWSER_SUCCESS); Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput); - if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { + if (EFI_ERROR (Status)) { FreeDisplayFormData(); return Status; } - // - // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return. - // in this case, browser need to change the highlight menu. - // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist - // opcode and new valid value has return, browser core need to adjust - // value for this opcode and shows this form again. - // - ChangeHighlight = (Status == EFI_SUCCESS ? TRUE :FALSE); - - Status = ProcessUserInput (&UserInput, ChangeHighlight); - + Status = ProcessUserInput (&UserInput); FreeDisplayFormData(); - return Status; }