Revision: 16460
          http://sourceforge.net/p/edk2/code/16460
Author:   vanjeff
Date:     2014-12-01 08:51:50 +0000 (Mon, 01 Dec 2014)
Log Message:
-----------
Fixed user input arrow down/ page down caused form display highlight menu error.

When scroll menu to the one not shows in current form, and this menu has option 
mismatch error, current display engine will not highlight this menu.

(Sync patches r16447 and r16451 from main trunk.)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <[email protected]>
Reviewed-by: Liming Gao <[email protected]>

Revision Links:
--------------
    http://sourceforge.net/p/edk2/code/16447
    http://sourceforge.net/p/edk2/code/16451

Modified Paths:
--------------
    branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
    branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h
    
branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
    branches/UDK2014.SP1/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c

Modified: 
branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
===================================================================
--- branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c  
2014-12-01 08:40:59 UTC (rev 16459)
+++ branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c  
2014-12-01 08:51:50 UTC (rev 16460)
@@ -98,8 +98,7 @@
   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;
@@ -1475,6 +1474,238 @@
 }
 
 /**
+  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 (BOOLEAN) (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 (BOOLEAN) (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 (BOOLEAN) (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 (BOOLEAN) (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.
 
   @param  FormData               The data info for this form.
@@ -1491,160 +1722,223 @@
   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) {
-    *TopOfScreen   = gMenuOption.ForwardLink;
-    *HighlightMenu = gMenuOption.ForwardLink;
-    if (!IsListEmpty (&gMenuOption)) {
-      MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);
-    }
-    *SkipValue     = 0;
-    return;
-  }
+  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);
 
-  //
-  // 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);
+    *HighlightMenu = FindHighLightMenuOption(NULL);
+    if (*HighlightMenu != NULL) {
+      //
+      // Update skip info for this highlight menu.
+      //
+      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);
+      UpdateOptionSkipLines (MenuOption);
 
-  while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) ||
-         (SavedMenuOption->Sequence != gSequence)) {
-    NewPos     = NewPos->ForwardLink;
-    if (NewPos == &gMenuOption) {
       //
-      // Not Found it, break
+      // Found the last time highlight menu.
       //
-      break;
-    }
-    SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-  }
-  ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement);
+      *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);
 
-  *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 = gHighligthMenuInfo.SkipValue;
+      } else {
         //
-        // 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.
+        // 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.
         //
-        TmpValue = gHighligthMenuInfo.SkipValue;
+        if (MenuOption->Skip >= BottomRow - TopRow) {
+          *TopOfScreen = *HighlightMenu;
+          TmpValue     = 0;
+        } else {
+          *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - 
TopRow - MenuOption->Skip, &TmpValue);
+        }
+
+        *SkipValue   = TmpValue;
       }
-    } else if (gHighligthMenuInfo.OpCode != NULL){
-      if (!CompareMem (gHighligthMenuInfo.OpCode, 
SavedMenuOption->ThisTag->OpCode, gHighligthMenuInfo.OpCode->Length)) {
-        BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
+    } 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) {
         //
-        // 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.
+        // 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.
         //
-        TmpValue = gHighligthMenuInfo.SkipValue;
+        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;
     }
-  }
-
-  if (SavedMenuOption->Skip >= BottomRow - TopRow) {
-    *TopOfScreen = NewPos;
+    AdjustDateAndTimePosition(TRUE, TopOfScreen);
   } else {
-    *TopOfScreen = FindTopOfScreenMenu(NewPos, BottomRow - TopRow - 
SavedMenuOption->Skip, &TmpValue);
+    //
+    // 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;
   }
-  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.HLTOpCode = AllocateCopyPool 
(Statement->OpCode->Length, Statement->OpCode);
+      ASSERT (gHighligthMenuInfo.HLTOpCode != NULL);
+
+      gHighligthMenuInfo.HLTIndex = GetIndexInfoForOpcode(Statement->OpCode);
     }
-    gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;
-    gHighligthMenuInfo.SkipValue  = (UINT16) SkipValue;
+
+    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 {
-    gHighligthMenuInfo.HiiHandle  = NULL;
-    gHighligthMenuInfo.QuestionId = 0;
-    if (gHighligthMenuInfo.OpCode != NULL) {
-      FreePool (gHighligthMenuInfo.OpCode);
-      gHighligthMenuInfo.OpCode = NULL;
+    gUserInput->SelectedStatement    = NULL;
+
+    gHighligthMenuInfo.HLTSequence   = 0;
+    gHighligthMenuInfo.HLTQuestionId = 0;
+    if (gHighligthMenuInfo.HLTOpCode != NULL) {
+      FreePool (gHighligthMenuInfo.HLTOpCode);
     }
-    gHighligthMenuInfo.DisplayRow = 0;
-    gHighligthMenuInfo.SkipValue  = 0;
+    gHighligthMenuInfo.HLTOpCode     = NULL;
+    gHighligthMenuInfo.HLTIndex      = 0;
+
+    gHighligthMenuInfo.TOSQuestionId = 0;
+    if (gHighligthMenuInfo.TOSOpCode != NULL) {
+      FreePool (gHighligthMenuInfo.TOSOpCode);
+    }
+    gHighligthMenuInfo.TOSOpCode     = NULL;
+    gHighligthMenuInfo.TOSIndex      = 0;
   }
-
-  RefreshKeyHelp(gFormData, Statement, FALSE);
 }
 
 /**
@@ -2138,6 +2432,10 @@
   }
 
   FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);
+  if (!IsListEmpty (&gMenuOption)) {
+    NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+    gUserInput->SelectedStatement = NextMenuOption->ThisTag;
+  }
 
   gST->ConOut->EnableCursor (gST->ConOut, FALSE);
 
@@ -2243,7 +2541,11 @@
           }
 
           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.
@@ -2306,10 +2608,12 @@
       //
       ControlFlag = CfUpdateHelpString;
 
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
+
       if (SkipHighLight) {
+        SkipHighLight = FALSE;
         MenuOption    = SavedMenuOption;
-        SkipHighLight = FALSE;
-        UpdateHighlightMenuInfo (MenuOption, TopOfScreen == &MenuOption->Link 
? SkipValue : 0);
+        RefreshKeyHelp(gFormData, SavedMenuOption->ThisTag, FALSE);
         break;
       }
 
@@ -2351,10 +2655,8 @@
         // This is the current selected statement
         //
         MenuOption = MENU_OPTION_FROM_LINK (NewPos);
-        Statement = MenuOption->ThisTag;
+        RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE);
 
-        UpdateHighlightMenuInfo (MenuOption, Temp2);
-
         if (!IsSelectable (MenuOption)) {
           break;
         }
@@ -2588,6 +2890,7 @@
       }
 
       if (EventType == UIEventDriver) {
+        gMisMatch = TRUE;
         gUserInput->Action = BROWSER_ACTION_NONE;
         ControlFlag = CfExit;
         break;
@@ -2795,13 +3098,6 @@
         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;
@@ -2914,6 +3210,8 @@
       //
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);
       AdjustDateAndTimePosition (TRUE, &NewPos);
+
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
       break;
 
     case CfUiPageUp:
@@ -2953,6 +3251,8 @@
       //
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);
       AdjustDateAndTimePosition (TRUE, &NewPos);
+
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
       break;
 
     case CfUiPageDown:
@@ -3014,6 +3314,8 @@
       //
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);
       AdjustDateAndTimePosition (TRUE, &NewPos);
+
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
       break;
 
     case CfUiDown:
@@ -3075,6 +3377,8 @@
         //
         AdjustDateAndTimePosition (TRUE, &TopOfScreen);
         AdjustDateAndTimePosition (TRUE, &NewPos);
+
+        UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
         break;
       }        
 
@@ -3172,6 +3476,8 @@
       //
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);
       AdjustDateAndTimePosition (TRUE, &NewPos);
+
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
       break;
 
     case CfUiNoOperation:
@@ -3581,9 +3887,13 @@
 
   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;
 }

Modified: 
branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h
===================================================================
--- branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h  
2014-12-01 08:40:59 UTC (rev 16459)
+++ branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h  
2014-12-01 08:51:50 UTC (rev 16460)
@@ -63,6 +63,7 @@
 extern CHAR16            gOptionBlockWidth;
 extern CHAR16            gHelpBlockWidth;
 extern CHAR16            *mUnknownString;
+extern BOOLEAN           gMisMatch;
 
 //
 // Screen definitions
@@ -196,9 +197,31 @@
 
 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;
 

Modified: 
branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
===================================================================
--- 
branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c   
    2014-12-01 08:40:59 UTC (rev 16459)
+++ 
branches/UDK2014.SP1/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c   
    2014-12-01 08:51:50 UTC (rev 16460)
@@ -1036,7 +1036,7 @@
           // Exit current DisplayForm with new value.
           //
           gUserInput->SelectedStatement = Question;
-          
+          gMisMatch = TRUE;
           ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen);
           ASSERT (ValueArray != NULL);
           gUserInput->InputValue.Buffer    = ValueArray;
@@ -1121,7 +1121,7 @@
           // 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;
@@ -1198,7 +1198,7 @@
             break;
           }
           gUserInput->SelectedStatement = Question;
-
+          gMisMatch = TRUE;
           FreePool (*OptionString);
           *OptionString = NULL;
           return EFI_NOT_FOUND;

Modified: 
branches/UDK2014.SP1/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
===================================================================
--- branches/UDK2014.SP1/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c  
2014-12-01 08:40:59 UTC (rev 16459)
+++ branches/UDK2014.SP1/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c  
2014-12-01 08:51:50 UTC (rev 16460)
@@ -1445,21 +1445,20 @@
   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 @@
   // 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 @@
   EFI_STATUS               Status;
   USER_INPUT               UserInput;
   FORM_ENTRY_INFO          *CurrentMenu;
-  BOOLEAN                  ChangeHighlight;
 
   ZeroMem (&UserInput, sizeof (USER_INPUT));
 
@@ -1636,9 +1607,6 @@
 
   gCurrentSelection->CurrentMenu = CurrentMenu;
 
-  //
-  // Find currrent highlight statement.
-  //
   if (gCurrentSelection->QuestionId == 0) {
     //
     // Highlight not specified, fetch it from cached menu
@@ -1646,9 +1614,6 @@
     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 @@
 
   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;
 }
 


------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to